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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions