Skip to content

CLI audit: mejorar reportes agregados, paginación, exports y UX multi-workspace #5

Description

@LucasLeguizamo

Context: Después de usar @freeticket/cli@0.4.1 desde Codex para listar eventos y responder "la cantidad de tickets por vender de cada evento", hice una inspección a fondo del CLI publicado: ayuda, README, dist generado, comandos reales y una corrida contra el workspace Boom Stand Up (36 eventos, 741 ventas confirmadas).

User signal: "haz inspeccion a fondo del cli y encuentra todos los puntos de mejoras" y, sobre el reporte de inventario, "que sea mucho mas dinamico como tal y que no se demoro mucho".

Findings / improvements

P0/P1: reportes agregados para evitar N+1

  • Falta un comando nativo para inventario: capacidad, vendidos, reservados/disponibles por evento/fecha/tipo de ticket.
  • Hoy el cliente tiene que hacer: events list -> event-dates list por evento -> ticket-types list por fecha -> sales list --status CONFIRMED -> sales get por venta para leer items[].
  • En una cuenta real esto se vuelve cientos de requests y tarda demasiado. También es fácil que el cálculo sea inconsistente si se reconstruye en el cliente.
  • Ya abrimos el contrato/backend específico: AppFreeticket/free-admin#165.

Propuesta CLI cuando exista endpoint:

ft reports inventory --group-by event --json
ft reports inventory --group-by date --csv
ft reports inventory --event <eventId>

P1: --json en listas pierde metadata de paginación

  • ft events list --json --limit 1 imprime solo el array data.
  • En modo tabla sí aparece el hint de --cursor, pero en JSON parseable se pierde page.nextCursor.
  • Esto rompe automatizaciones limpias porque no hay manera confiable de paginar sin mirar stderr/human hints.

Opciones:

  • --json debería devolver { "data": [...], "page": { "nextCursor": "..." } }.
  • O agregar --raw para el DTO completo y dejar --json como array legacy.
  • O agregar --all para autopaginar y devolver una lista completa cuando sea seguro.

P1: falta --all / autopaginación consistente

  • Listas y reportes grandes requieren un loop manual de cursor.
  • Para agentes, contabilidad y CSV, lo normal es querer "todo lo que matchea el filtro".

Propuesta:

ft sales list --status CONFIRMED --all --json
ft events list --all --csv
ft ticket-types list --event-date-id <id> --all

Con guardrails: límite máximo, progress en stderr, y error claro si el backend no puede completar.

P1: exports de compradores no sirven para auditoría por evento/ticket

  • ft reports export buyers --json devuelve comprador/orden (reference, name, email, phone, total, createdAt), pero no incluye eventId, eventName, eventDateId, ticketTypeId, ticketTypeName, ni quantity.
  • Para preguntas operativas ("cuántos tickets vendí de X", "qué evento tiene más compradores", "exportar asistentes de este show") obliga a cruzar ventas y detalles.
  • También descarga PII masiva sin filtros finos.

Propuesta:

  • Añadir filtros: --event, --event-date, --from, --to, --status.
  • Añadir --include-items o un export separado ft reports export attendees.
  • Incluir campos de evento/ticket cuando se exportan compradores.

P1: columnas visibles desalineadas con el DTO real

  • ticket-types list muestra columna stock, pero el DTO real expone capacity. Resultado: la tabla imprime aunque sí hay capacidad.
  • events list usa columna startsAt, pero el DTO de evento no trae startsAt; eso vive en event dates. Resultado: CSV/tabla de eventos deja esa columna vacía.
  • El --csv usa solo las columnas visibles (spec.columns), así que puede perder campos importantes aunque el API los devuelva.

Propuesta:

  • Cambiar ticket-types: stock -> capacity.
  • En events, quitar startsAt o resolverlo explícitamente como "next date" con un endpoint/DTO que lo incluya.
  • Agregar --columns o --full para CSV/tabla.

P2: workspace UX

  • Device login elige el primer workspace automáticamente y solo dice "switch with --workspace".
  • No hay comando visible para cambiar/persistir workspace por defecto después de login.
  • Para cuentas con muchos workspaces, esto produce errores sutiles o comandos contra el tenant equivocado.

Propuesta:

ft workspaces list
ft workspace use <id-or-slug>
ft config set workspace <id-or-slug>

También se podría pedir selección interactiva durante ft login cuando hay varios workspaces.

P2: filtros de ventas/reportes insuficientes

  • sales list solo filtra por --status.
  • Para análisis reales hacen falta --event, --event-date, --buyer, --reference, --from, --to, --channel.
  • Sin filtros, las automatizaciones terminan descargando mucho más de lo necesario.

P2: outputs humanos vs outputs para agentes

  • La tabla está bien para humanos, pero para agentes conviene tener:
    • --quiet para solo IDs/campos clave.
    • --no-banner o evitar banner fuera de help.
    • --format table|json|ndjson|csv.
    • errores JSON con --json para manejo programático.

P2: docs/skill/README deben sincronizarse con el binario publicado

  • La README publicada todavía dice que write operations "currently return 501", pero 0.4.1 ya expone create/update/delete/publish/cancel/refund.
  • La skill y la README hablan de device flow, que ahora sí existe en 0.4.1, pero versiones previas en cache (0.1.1 / 0.4.0) se comportaban distinto. Conviene documentar versión mínima y troubleshooting.

Acceptance criteria

  • ft reports inventory --group-by event --json responde en una sola llamada o en pocas llamadas controladas, sin hacer sales get por cada venta.
  • Las listas JSON preservan paginación o hay un modo raw/all claro.
  • ticket-types list muestra capacity correctamente.
  • events list no muestra columnas vacías por campos inexistentes.
  • Exports de compradores/asistentes pueden filtrarse por evento/fecha y traer detalle de ticket.
  • El usuario puede cambiar el workspace persistido sin editar ~/.freeticket/config.json.

Reported via the freeticket-cli skill.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions