diff --git a/CHANGELOG.md b/CHANGELOG.md index eac63c8..3e3a1c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,32 @@ versioning follows [SemVer](https://semver.org/). ## [Unreleased] +## [0.6.0] - 2026-07-01 + +### Added +- **Door check-in (`ft tickets`)** — `access ` reads a ticket's access + status, `checkin ` admits it at the door (idempotent, prevents double + entry), `resend ` re-sends the confirmation email/QR. Consumes + `GET/POST /tickets/{code}/access|checkin|resend` (free-admin#172, #173). +- **Create sales (`ft sales create`)** — register comps and programmatic sales + via `POST /sales` (`--data `) (free-admin#174). +- **`ft sales tickets `** — list the individual tickets/attendees of a sale + (free-admin#173). +- **Discount codes (`ft discounts`)** — `list`/`create`/`update`/`delete` + coupons, filterable by `--event`/`--active` (free-admin#176). +- **Webhooks (`ft webhooks`)** — `list`/`create`/`delete` HMAC-signed event + endpoints (free-admin#177). +- **Subscriptions** — `ft plans subscribers ` lists a plan's members and + `ft subscriptions cancel ` cancels a subscription (free-admin#175). +- **Reports** — `ft reports by-event`, `timeseries`, and `inventory`, plus the + `ft reports export attendees` CSV (free-admin#178, #165, #168). +- **Sales list filters** — `--channel`, `--event`, `--event-date`, + `--reference`, `--buyer`, `--from`, `--to` on `ft sales list`; matching + filters on the buyers/attendees exports (free-admin#167, #168). + +### Changed +- Regenerated the client from the B2B OpenAPI **1.4.0** contract. + ## [0.5.0] - 2026-06-30 ### Added diff --git a/README.md b/README.md index 00d4014..af2a3c8 100644 --- a/README.md +++ b/README.md @@ -85,15 +85,25 @@ ft sales list --status CONFIRMED --json | `ft event-dates list` · `create` · `update` · `delete` | Event dates | ADMIN | | `ft ticket-types list` · `get ` | Ticket types (`--event-date-id`) | VIEWER | | `ft ticket-types create` · `update ` · `delete ` | Manage ticket types (`--data `) | ADMIN | -| `ft sales list` · `get ` | Sales (`--status`) | STAFF | +| `ft sales list` · `get ` | Sales (filters: `--status` `--channel` `--event` `--event-date` `--reference` `--buyer` `--from` `--to`) | STAFF | +| `ft sales create` | Create a sale/order — comps & programmatic sales (`--data `) | ADMIN | | `ft sales cancel ` · `refund ` | Cancel / refund a sale (`--data` for partial refund) | ADMIN | +| `ft sales tickets ` | List the individual tickets/attendees of a sale | STAFF | +| `ft tickets access ` | Read a ticket's access status (no admit) | STAFF | +| `ft tickets checkin ` | Admit a ticket at the door (idempotent) | STAFF | +| `ft tickets resend ` | Resend the ticket's confirmation email (QR) | ADMIN | | `ft plans list` · `get ` | Membership plans | VIEWER | | `ft plans create` · `update ` · `delete ` | Manage membership plans (`--data `) | ADMIN | +| `ft plans subscribers ` | List a plan's subscribers/members | VIEWER | +| `ft subscriptions cancel ` | Cancel a subscription | ADMIN | +| `ft discounts list` · `create` · `update ` · `delete ` | Discount codes / coupons (`--event` `--active`; `--data `) | ADMIN | +| `ft webhooks list` · `create` · `delete ` | Webhook endpoints, HMAC-signed delivery (`--data `) | ADMIN | | `ft venues list` · `get ` | Venues | VIEWER | | `ft venues create` · `update ` · `delete ` | Manage venues (`--data `) | ADMIN | | `ft staff list` · `create` · `set-role ` | Workspace staff (`--data `) | ADMIN | | `ft reports summary` | KPIs (`--period 7d\|30d\|90d\|1y`) | VIEWER | -| `ft reports export buyers\|subscribers` | Export buyers / subscribers | ADMIN | +| `ft reports by-event` · `timeseries` · `inventory` | Revenue/tickets by event, over time, and capacity/availability | VIEWER | +| `ft reports export buyers\|attendees\|subscribers` | Export buyers / attendees / subscribers (CSV; filters `--event` `--event-date` `--from` `--to` `--status`) | ADMIN | > **Write operations** (`create`/`update`/`delete` and actions like `publish`, > `cancel`, `refund`) send a JSON body via `--data ` or diff --git a/openapi.json b/openapi.json index 2f591f2..05b845e 100644 --- a/openapi.json +++ b/openapi.json @@ -2,12 +2,12 @@ "openapi": "3.1.0", "info": { "title": "FreeTicket B2B API", - "version": "1.2.0", + "version": "1.4.0", "description": "API REST B2B de FreeTicket para integraciones y el CLI. Autenticación por API key (header `Authorization: Bearer ` o `x-api-key`); el workspace activo se selecciona con el header `X-Workspace-Id`." }, "servers": [ { - "url": "https://admin.appfreeticket.com/api/v1" + "url": "http://localhost:3000/api/v1" } ], "security": [ @@ -1479,7 +1479,7 @@ "sales" ], "summary": "Listar ventas del workspace", - "description": "Rol mínimo: `STAFF`. Workspace activo vía header `X-Workspace-Id`.", + "description": "Rol mínimo: `VIEWER`. Workspace activo vía header `X-Workspace-Id`.", "security": [ { "apiKey": [] @@ -1495,6 +1495,69 @@ "type": "string" } }, + { + "name": "channel", + "in": "query", + "required": false, + "description": "WEB|MOBILE|POS|ADMIN", + "schema": { + "type": "string" + } + }, + { + "name": "event", + "in": "query", + "required": false, + "description": "id del evento", + "schema": { + "type": "string" + } + }, + { + "name": "eventDate", + "in": "query", + "required": false, + "description": "id de la fecha del evento", + "schema": { + "type": "string" + } + }, + { + "name": "reference", + "in": "query", + "required": false, + "description": "referencia/código de la venta (parcial)", + "schema": { + "type": "string" + } + }, + { + "name": "buyer", + "in": "query", + "required": false, + "description": "nombre o email del comprador (parcial)", + "schema": { + "type": "string" + } + }, + { + "name": "from", + "in": "query", + "required": false, + "description": "fecha desde (ISO 8601, sobre created_at)", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "required": false, + "description": "fecha hasta (ISO 8601, sobre created_at)", + "schema": { + "type": "string" + } + }, { "name": "limit", "in": "query", @@ -1579,6 +1642,89 @@ } } } + }, + "post": { + "operationId": "postSales", + "tags": [ + "sales" + ], + "summary": "Crear una venta/orden (cortesías y ventas programáticas)", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaleCreate" + } + } + } + }, + "responses": { + "201": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SaleDetail" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } } }, "/sales/{id}": { @@ -3052,14 +3198,14 @@ } } }, - "/reports/reconciliation": { + "/reports/inventory": { "get": { - "operationId": "getReportsReconciliation", + "operationId": "getReportsInventory", "tags": [ "reports" ], - "summary": "Conciliación financiera CFO (MP ↔ venta ↔ factura Siigo)", - "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "summary": "Inventario agregado por evento/fecha/tipo (capacidad, vendidos, disponibles)", + "description": "Rol mínimo: `VIEWER`. Workspace activo vía header `X-Workspace-Id`.", "security": [ { "apiKey": [] @@ -3067,55 +3213,55 @@ ], "parameters": [ { - "name": "date_from", + "name": "eventId", "in": "query", - "required": true, - "description": "ISO 8601 (inicio, sobre Sale.created_at)", + "required": false, + "description": "Filtra por evento", "schema": { "type": "string" } }, { - "name": "date_to", + "name": "eventDateId", "in": "query", - "required": true, - "description": "ISO 8601 (fin)", + "required": false, + "description": "Filtra por fecha del evento", "schema": { "type": "string" } }, { - "name": "match_status", + "name": "from", "in": "query", "required": false, - "description": "Filtra por flag: OK|MISSING_INVOICE|MISSING_CUFE|AMOUNT_MISMATCH|MISSING_PAYMENT", + "description": "Inicio de función ≥ (ISO 8601)", "schema": { "type": "string" } }, { - "name": "provider", + "name": "to", "in": "query", "required": false, - "description": "Filtra por payment_provider (ej: mercadopago)", + "description": "Inicio de función ≤ (ISO 8601)", "schema": { "type": "string" } }, { - "name": "page", + "name": "includeDrafts", "in": "query", "required": false, - "description": "Página 1-based (default 1)", + "description": "Incluir eventos/fechas en DRAFT (default false)", "schema": { "type": "string" } }, { - "name": "page_size", + "name": "groupBy", "in": "query", "required": false, - "description": "Tamaño de página 1..500 (default 100)", + "description": "event | date | ticketType (default)", "schema": { "type": "string" } @@ -3132,7 +3278,7 @@ "data": { "type": "array", "items": { - "$ref": "#/components/schemas/ReconciliationRow" + "$ref": "#/components/schemas/InventoryRow" } } }, @@ -3186,13 +3332,13 @@ } } }, - "/reports/exports/reconciliation": { + "/reports/reconciliation": { "get": { - "operationId": "getReportsExportsReconciliation", + "operationId": "getReportsReconciliation", "tags": [ "reports" ], - "summary": "Export CSV de la conciliación financiera CFO", + "summary": "Conciliación financiera CFO (MP ↔ venta ↔ factura Siigo)", "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", "security": [ { @@ -3235,6 +3381,24 @@ "schema": { "type": "string" } + }, + { + "name": "page", + "in": "query", + "required": false, + "description": "Página 1-based (default 1)", + "schema": { + "type": "string" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "description": "Tamaño de página 1..500 (default 100)", + "schema": { + "type": "string" + } } ], "responses": { @@ -3243,7 +3407,18 @@ "content": { "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReconciliationRow" + } + } + }, + "required": [ + "data" + ] } } } @@ -3291,19 +3466,57 @@ } } }, - "/reports/exports/buyers": { + "/reports/exports/reconciliation": { "get": { - "operationId": "getReportsExportsBuyers", + "operationId": "getReportsExportsReconciliation", "tags": [ "reports" ], - "summary": "Export de compradores (máx 5000)", + "summary": "Export CSV de la conciliación financiera CFO", "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", "security": [ { "apiKey": [] } ], + "parameters": [ + { + "name": "date_from", + "in": "query", + "required": true, + "description": "ISO 8601 (inicio, sobre Sale.created_at)", + "schema": { + "type": "string" + } + }, + { + "name": "date_to", + "in": "query", + "required": true, + "description": "ISO 8601 (fin)", + "schema": { + "type": "string" + } + }, + { + "name": "match_status", + "in": "query", + "required": false, + "description": "Filtra por flag: OK|MISSING_INVOICE|MISSING_CUFE|AMOUNT_MISMATCH|MISSING_PAYMENT", + "schema": { + "type": "string" + } + }, + { + "name": "provider", + "in": "query", + "required": false, + "description": "Filtra por payment_provider (ej: mercadopago)", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "OK", @@ -3358,34 +3571,81 @@ } } }, - "/reports/exports/subscribers": { + "/reports/exports/attendees": { "get": { - "operationId": "getReportsExportsSubscribers", + "operationId": "getReportsExportsAttendees", "tags": [ "reports" ], - "summary": "Export de suscriptores (máx 5000)", + "summary": "Export de asistentes por ticket con filtros (máx 5000)", "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", "security": [ { "apiKey": [] } ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } + "parameters": [ + { + "name": "event", + "in": "query", + "required": false, + "description": "Filtra por Event.id", + "schema": { + "type": "string" } }, - "401": { - "description": "Credencial inválida o ausente.", - "content": { - "application/json": { + { + "name": "eventDate", + "in": "query", + "required": false, + "description": "Filtra por EventDate.id", + "schema": { + "type": "string" + } + }, + { + "name": "from", + "in": "query", + "required": false, + "description": "ISO 8601 — desde (sobre Sale.created_at)", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "required": false, + "description": "ISO 8601 — hasta (sobre Sale.created_at)", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "description": "PENDING|CONFIRMED|ABANDONED|CANCELLED|REFUNDED (default CONFIRMED)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/Error" } @@ -3424,40 +3684,2066 @@ } } } - } - }, - "components": { - "schemas": { - "Error": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "code": { - "type": "string" - }, - "message": { - "type": "string" - }, - "details": {} - }, - "required": [ - "code", - "message" - ], - "additionalProperties": false + }, + "/reports/exports/buyers": { + "get": { + "operationId": "getReportsExportsBuyers", + "tags": [ + "reports" + ], + "summary": "Export de compradores con filtros (máx 5000)", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] } - }, - "required": [ - "error" + ], + "parameters": [ + { + "name": "event", + "in": "query", + "required": false, + "description": "Filtra por Event.id", + "schema": { + "type": "string" + } + }, + { + "name": "eventDate", + "in": "query", + "required": false, + "description": "Filtra por EventDate.id", + "schema": { + "type": "string" + } + }, + { + "name": "from", + "in": "query", + "required": false, + "description": "ISO 8601 — desde (sobre Sale.created_at)", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "required": false, + "description": "ISO 8601 — hasta (sobre Sale.created_at)", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "description": "PENDING|CONFIRMED|ABANDONED|CANCELLED|REFUNDED (default CONFIRMED)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/reports/exports/subscribers": { + "get": { + "operationId": "getReportsExportsSubscribers", + "tags": [ + "reports" + ], + "summary": "Export de suscriptores (máx 5000)", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/reports/by-event": { + "get": { + "operationId": "getReportsByEvent", + "tags": [ + "reports" + ], + "summary": "KPIs de venta por evento del workspace", + "description": "Rol mínimo: `VIEWER`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "from", + "in": "query", + "required": false, + "description": "ISO 8601, filtra Sale.created_at (gte)", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "required": false, + "description": "ISO 8601, filtra Sale.created_at (lte)", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "description": "PENDING|CONFIRMED (default)|ABANDONED|CANCELLED|REFUNDED", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportByEventRow" + } + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/reports/timeseries": { + "get": { + "operationId": "getReportsTimeseries", + "tags": [ + "reports" + ], + "summary": "Serie temporal de ventas CONFIRMED por bucket (day|week|month)", + "description": "Rol mínimo: `VIEWER`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "interval", + "in": "query", + "required": true, + "description": "day | week | month", + "schema": { + "type": "string" + } + }, + { + "name": "from", + "in": "query", + "required": false, + "description": "ISO 8601, filtra Sale.created_at (gte)", + "schema": { + "type": "string" + } + }, + { + "name": "to", + "in": "query", + "required": false, + "description": "ISO 8601, filtra Sale.created_at (lte)", + "schema": { + "type": "string" + } + }, + { + "name": "event", + "in": "query", + "required": false, + "description": "ID de evento del workspace (opcional)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReportTimeseriesRow" + } + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/discounts": { + "get": { + "operationId": "getDiscounts", + "tags": [ + "discounts" + ], + "summary": "Listar cupones de descuento del workspace", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "event", + "in": "query", + "required": false, + "description": "id de evento para filtrar", + "schema": { + "type": "string" + } + }, + { + "name": "active", + "in": "query", + "required": false, + "description": "true|false", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Discount" + } + }, + "page": { + "$ref": "#/components/schemas/Page" + } + }, + "required": [ + "data", + "page" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "operationId": "postDiscounts", + "tags": [ + "discounts" + ], + "summary": "Crear cupón de descuento", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiscountCreate" + } + } + } + }, + "responses": { + "201": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/Discount" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/discounts/{id}": { + "patch": { + "operationId": "patchDiscountsId", + "tags": [ + "discounts" + ], + "summary": "Actualizar cupón de descuento", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DiscountUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/Discount" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "operationId": "deleteDiscountsId", + "tags": [ + "discounts" + ], + "summary": "Eliminar (soft) cupón de descuento", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/webhooks": { + "get": { + "operationId": "getWebhooks", + "tags": [ + "webhooks" + ], + "summary": "Listar webhooks del workspace", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Webhook" + } + }, + "page": { + "$ref": "#/components/schemas/Page" + } + }, + "required": [ + "data", + "page" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "operationId": "postWebhooks", + "tags": [ + "webhooks" + ], + "summary": "Crear webhook (devuelve el signingSecret una única vez)", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WebhookCreate" + } + } + } + }, + "responses": { + "201": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/WebhookCreated" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/webhooks/{id}": { + "delete": { + "operationId": "deleteWebhooksId", + "tags": [ + "webhooks" + ], + "summary": "Eliminar un webhook del workspace", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/membership-plans/{id}/subscribers": { + "get": { + "operationId": "getMembershipPlansIdSubscribers", + "tags": [ + "membership-plans", + "subscriptions" + ], + "summary": "Listar suscriptores de un plan de membresía", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "description": "PENDING|ACTIVE|EXPIRED|CANCELLED|PAUSED", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Subscriber" + } + }, + "page": { + "$ref": "#/components/schemas/Page" + } + }, + "required": [ + "data", + "page" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/subscriptions/{id}/cancel": { + "post": { + "operationId": "postSubscriptionsIdCancel", + "tags": [ + "subscriptions", + "membership-plans" + ], + "summary": "Cancelar una suscripción de membresía", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SubscriptionCancelResult" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/sales/{id}/tickets": { + "get": { + "operationId": "getSalesIdTickets", + "tags": [ + "sales" + ], + "summary": "Tickets individuales de una venta", + "description": "Rol mínimo: `STAFF`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SaleTicket" + } + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/tickets/{ticketCode}/checkin": { + "post": { + "operationId": "postTicketsTicketCodeCheckin", + "tags": [ + "tickets" + ], + "summary": "Registrar el ingreso (check-in) de un ticket en puerta", + "description": "Rol mínimo: `STAFF`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "ticketCode", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/CheckinResult" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/tickets/{ticketCode}/access": { + "get": { + "operationId": "getTicketsTicketCodeAccess", + "tags": [ + "tickets" + ], + "summary": "Consultar la validez de un ticket sin consumirlo", + "description": "Rol mínimo: `STAFF`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "ticketCode", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/TicketAccess" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/tickets/{ticketCode}/resend": { + "post": { + "operationId": "postTicketsTicketCodeResend", + "tags": [ + "tickets" + ], + "summary": "Reenviar el correo de confirmación con el ticket", + "description": "Rol mínimo: `ADMIN`. Workspace activo vía header `X-Workspace-Id`.", + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "name": "ticketCode", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ResendTicket" + } + }, + "required": [ + "data" + ] + } + } + } + }, + "401": { + "description": "Credencial inválida o ausente.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Rol insuficiente o recurso no accesible.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Recurso inexistente o fuera de alcance.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "Validación del cuerpo/parámetros.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Error": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "details": {} + }, + "required": [ + "code", + "message" + ], + "additionalProperties": false + } + }, + "required": [ + "error" + ], + "additionalProperties": false + }, + "Page": { + "type": "object", + "properties": { + "nextCursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "hasMore": { + "type": "boolean" + } + }, + "required": [ + "nextCursor", + "hasMore" + ], + "additionalProperties": false + }, + "Workspace": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "slug": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "slug" + ], + "additionalProperties": false + }, + "Me": { + "type": "object", + "properties": { + "userId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "string", + "enum": [ + "SUPER_ADMIN", + "ADMIN", + "STAFF", + "VIEWER", + "MINCULTURA" + ] + }, + "activeWorkspaceId": { + "type": "string" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Workspace" + } + } + }, + "required": [ + "userId", + "name", + "email", + "role", + "activeWorkspaceId", + "workspaces" + ], + "additionalProperties": false + }, + "DeviceCodeResponse": { + "type": "object", + "properties": { + "device_code": { + "type": "string" + }, + "user_code": { + "type": "string" + }, + "verification_uri": { + "type": "string" + }, + "verification_uri_complete": { + "type": "string" + }, + "expires_in": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "interval": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": [ + "device_code", + "user_code", + "verification_uri", + "verification_uri_complete", + "expires_in", + "interval" + ], + "additionalProperties": false + }, + "DeviceTokenRequest": { + "type": "object", + "properties": { + "device_code": { + "type": "string", + "minLength": 1 + }, + "grant_type": { + "type": "string", + "const": "urn:ietf:params:oauth:grant-type:device_code" + } + }, + "required": [ + "device_code" + ], + "additionalProperties": false + }, + "DeviceTokenResponse": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string", + "const": "Bearer" + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "string", + "enum": [ + "SUPER_ADMIN", + "ADMIN", + "STAFF", + "VIEWER", + "MINCULTURA" + ] + } + }, + "required": [ + "id", + "email", + "role" + ], + "additionalProperties": false + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Workspace" + } + } + }, + "required": [ + "access_token", + "token_type", + "user", + "workspaces" + ], + "additionalProperties": false + }, + "DeviceTokenError": { + "type": "object", + "properties": { + "error": { + "type": "string", + "enum": [ + "authorization_pending", + "slow_down", + "expired_token", + "access_denied", + "invalid_request" + ] + } + }, + "required": [ + "error" + ], + "additionalProperties": false + }, + "Event": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "status": { + "type": "string", + "enum": [ + "DRAFT", + "PUBLISHED", + "SOLD_OUT", + "CANCELLED", + "COMPLETED" + ] + }, + "coverImageUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "organizationId": { + "type": "string" + }, + "venueId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "slug", + "description", + "status", + "coverImageUrl", + "organizationId", + "venueId", + "createdAt", + "updatedAt" + ], + "additionalProperties": false + }, + "EventDate": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "eventId": { + "type": "string" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "startsAt": { + "type": "string" + }, + "endsAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "doorsOpenAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "timezone": { + "type": "string" + }, + "venueId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "status": { + "type": "string", + "enum": [ + "DRAFT", + "PUBLISHED", + "SOLD_OUT", + "CANCELLED", + "COMPLETED" + ] + }, + "streamType": { + "type": "string" + }, + "createdAt": { + "type": "string" + } + }, + "required": [ + "id", + "eventId", + "label", + "startsAt", + "endsAt", + "doorsOpenAt", + "timezone", + "venueId", + "status", + "streamType", + "createdAt" + ], + "additionalProperties": false + }, + "EventCreate": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "slug": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z0-9-]+$" + }, + "description": { + "type": "string" + }, + "venueId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "dates": { + "minItems": 1, + "type": "array", + "items": { + "type": "object", + "properties": { + "startsAt": { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + "endsAt": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" + }, + { + "type": "null" + } + ] + }, + "timezone": { + "default": "America/Bogota", + "type": "string" + } + }, + "required": [ + "startsAt", + "timezone" + ], + "additionalProperties": false + } + } + }, + "required": [ + "name", + "slug", + "dates" ], "additionalProperties": false }, - "Page": { + "EventUpdate": { "type": "object", "properties": { - "nextCursor": { + "name": { + "type": "string", + "minLength": 1 + }, + "description": { "anyOf": [ { "type": "string" @@ -3467,248 +5753,193 @@ } ] }, - "hasMore": { - "type": "boolean" + "venueId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "coverImageUrl": { + "anyOf": [ + { + "type": "string", + "format": "uri" + }, + { + "type": "null" + } + ] } }, - "required": [ - "nextCursor", - "hasMore" - ], "additionalProperties": false }, - "Workspace": { + "TicketType": { "type": "object", "properties": { "id": { "type": "string" }, - "name": { - "type": "string" - }, - "slug": { - "type": "string" - } - }, - "required": [ - "id", - "name", - "slug" - ], - "additionalProperties": false - }, - "Me": { - "type": "object", - "properties": { - "userId": { + "eventDateId": { "type": "string" }, "name": { "type": "string" }, - "email": { - "type": "string" - }, - "role": { - "type": "string", - "enum": [ - "SUPER_ADMIN", - "ADMIN", - "STAFF", - "VIEWER", - "MINCULTURA" + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ] }, - "activeWorkspaceId": { - "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Workspace" - } - } - }, - "required": [ - "userId", - "name", - "email", - "role", - "activeWorkspaceId", - "workspaces" - ], - "additionalProperties": false - }, - "DeviceCodeResponse": { - "type": "object", - "properties": { - "device_code": { - "type": "string" - }, - "user_code": { - "type": "string" - }, - "verification_uri": { - "type": "string" + "price": { + "type": "number" }, - "verification_uri_complete": { + "currency": { "type": "string" }, - "expires_in": { + "capacity": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, - "interval": { + "maxPerOrder": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 - } - }, - "required": [ - "device_code", - "user_code", - "verification_uri", - "verification_uri_complete", - "expires_in", - "interval" - ], - "additionalProperties": false - }, - "DeviceTokenRequest": { - "type": "object", - "properties": { - "device_code": { - "type": "string", - "minLength": 1 - }, - "grant_type": { - "type": "string", - "const": "urn:ietf:params:oauth:grant-type:device_code" - } - }, - "required": [ - "device_code" - ], - "additionalProperties": false - }, - "DeviceTokenResponse": { - "type": "object", - "properties": { - "access_token": { - "type": "string" - }, - "token_type": { - "type": "string", - "const": "Bearer" }, - "user": { - "type": "object", - "properties": { - "id": { + "saleStartsAt": { + "anyOf": [ + { "type": "string" }, - "email": { + { + "type": "null" + } + ] + }, + "saleEndsAt": { + "anyOf": [ + { "type": "string" }, - "role": { - "type": "string", - "enum": [ - "SUPER_ADMIN", - "ADMIN", - "STAFF", - "VIEWER", - "MINCULTURA" - ] + { + "type": "null" } - }, - "required": [ - "id", - "email", - "role" - ], - "additionalProperties": false + ] }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Workspace" - } + "isVisible": { + "type": "boolean" + }, + "organizerAbsorbsFee": { + "type": "boolean" + }, + "createdAt": { + "type": "string" } }, "required": [ - "access_token", - "token_type", - "user", - "workspaces" + "id", + "eventDateId", + "name", + "description", + "price", + "currency", + "capacity", + "maxPerOrder", + "saleStartsAt", + "saleEndsAt", + "isVisible", + "organizerAbsorbsFee", + "createdAt" ], "additionalProperties": false }, - "DeviceTokenError": { + "TicketTypeCreate": { "type": "object", "properties": { - "error": { + "eventDateId": { "type": "string", - "enum": [ - "authorization_pending", - "slow_down", - "expired_token", - "access_denied", - "invalid_request" - ] + "minLength": 1 + }, + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "type": "string" + }, + "price": { + "type": "number", + "minimum": 0 + }, + "currency": { + "default": "COP", + "type": "string" + }, + "capacity": { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 + }, + "maxPerOrder": { + "default": 10, + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 + }, + "isVisible": { + "default": true, + "type": "boolean" + }, + "organizerAbsorbsFee": { + "default": false, + "type": "boolean" } }, "required": [ - "error" + "eventDateId", + "name", + "price", + "currency", + "capacity", + "maxPerOrder", + "isVisible", + "organizerAbsorbsFee" ], "additionalProperties": false }, - "Event": { + "SaleItem": { "type": "object", "properties": { "id": { "type": "string" }, - "name": { - "type": "string" - }, - "slug": { + "ticketTypeId": { "type": "string" }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "quantity": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, - "status": { - "type": "string", - "enum": [ - "DRAFT", - "PUBLISHED", - "SOLD_OUT", - "CANCELLED", - "COMPLETED" - ] + "unitPrice": { + "type": "number" }, - "coverImageUrl": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "subtotal": { + "type": "number" }, - "organizationId": { + "ticketCode": { "type": "string" }, - "venueId": { + "checkedInAt": { "anyOf": [ { "type": "string" @@ -3717,51 +5948,66 @@ "type": "null" } ] - }, - "createdAt": { - "type": "string" - }, - "updatedAt": { - "type": "string" } }, "required": [ "id", - "name", - "slug", - "description", - "status", - "coverImageUrl", - "organizationId", - "venueId", - "createdAt", - "updatedAt" + "ticketTypeId", + "quantity", + "unitPrice", + "subtotal", + "ticketCode", + "checkedInAt" ], "additionalProperties": false }, - "EventDate": { + "Sale": { "type": "object", "properties": { "id": { "type": "string" }, - "eventId": { + "reference": { "type": "string" }, - "label": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } + "status": { + "type": "string", + "enum": [ + "PENDING", + "CONFIRMED", + "ABANDONED", + "CANCELLED", + "REFUNDED" ] }, - "startsAt": { + "channel": { "type": "string" }, - "endsAt": { + "subtotal": { + "type": "number" + }, + "discountAmount": { + "type": "number" + }, + "serviceFee": { + "type": "number" + }, + "iva": { + "type": "number" + }, + "total": { + "type": "number" + }, + "currency": { + "type": "string" + }, + "buyerName": { + "type": "string" + }, + "buyerEmail": { + "type": "string" + }, + "buyerPhone": { "anyOf": [ { "type": "string" @@ -3771,7 +6017,7 @@ } ] }, - "doorsOpenAt": { + "organizationId": { "anyOf": [ { "type": "string" @@ -3781,10 +6027,7 @@ } ] }, - "timezone": { - "type": "string" - }, - "venueId": { + "confirmedAt": { "anyOf": [ { "type": "string" @@ -3794,114 +6037,77 @@ } ] }, - "status": { - "type": "string", - "enum": [ - "DRAFT", - "PUBLISHED", - "SOLD_OUT", - "CANCELLED", - "COMPLETED" - ] - }, - "streamType": { - "type": "string" - }, "createdAt": { "type": "string" } }, "required": [ "id", - "eventId", - "label", - "startsAt", - "endsAt", - "doorsOpenAt", - "timezone", - "venueId", + "reference", "status", - "streamType", + "channel", + "subtotal", + "discountAmount", + "serviceFee", + "iva", + "total", + "currency", + "buyerName", + "buyerEmail", + "buyerPhone", + "organizationId", + "confirmedAt", "createdAt" ], "additionalProperties": false }, - "EventCreate": { + "SaleDetail": { "type": "object", "properties": { - "name": { - "type": "string", - "minLength": 1 + "id": { + "type": "string" }, - "slug": { + "reference": { + "type": "string" + }, + "status": { "type": "string", - "minLength": 1, - "pattern": "^[a-z0-9-]+$" + "enum": [ + "PENDING", + "CONFIRMED", + "ABANDONED", + "CANCELLED", + "REFUNDED" + ] }, - "description": { + "channel": { "type": "string" }, - "venueId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] + "subtotal": { + "type": "number" }, - "dates": { - "minItems": 1, - "type": "array", - "items": { - "type": "object", - "properties": { - "startsAt": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - "endsAt": { - "anyOf": [ - { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - { - "type": "null" - } - ] - }, - "timezone": { - "default": "America/Bogota", - "type": "string" - } - }, - "required": [ - "startsAt", - "timezone" - ], - "additionalProperties": false - } - } - }, - "required": [ - "name", - "slug", - "dates" - ], - "additionalProperties": false - }, - "EventUpdate": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1 + "discountAmount": { + "type": "number" }, - "description": { + "serviceFee": { + "type": "number" + }, + "iva": { + "type": "number" + }, + "total": { + "type": "number" + }, + "currency": { + "type": "string" + }, + "buyerName": { + "type": "string" + }, + "buyerEmail": { + "type": "string" + }, + "buyerPhone": { "anyOf": [ { "type": "string" @@ -3911,7 +6117,7 @@ } ] }, - "venueId": { + "organizationId": { "anyOf": [ { "type": "string" @@ -3921,28 +6127,62 @@ } ] }, - "coverImageUrl": { + "confirmedAt": { "anyOf": [ { - "type": "string", - "format": "uri" + "type": "string" }, { "type": "null" } ] + }, + "createdAt": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SaleItem" + } } }, + "required": [ + "id", + "reference", + "status", + "channel", + "subtotal", + "discountAmount", + "serviceFee", + "iva", + "total", + "currency", + "buyerName", + "buyerEmail", + "buyerPhone", + "organizationId", + "confirmedAt", + "createdAt", + "items" + ], "additionalProperties": false }, - "TicketType": { + "MembershipPlan": { "type": "object", "properties": { "id": { "type": "string" }, - "eventDateId": { - "type": "string" + "organizationId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, "name": { "type": "string" @@ -3963,27 +6203,190 @@ "currency": { "type": "string" }, - "capacity": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 + "billingCycle": { + "type": "string", + "enum": [ + "MONTHLY", + "QUARTERLY", + "ANNUAL", + "LIFETIME" + ] }, - "maxPerOrder": { + "benefits": { + "type": "object", + "properties": { + "presale": { + "type": "boolean" + }, + "freeTicket": { + "type": "boolean" + }, + "discount": { + "type": "boolean" + }, + "exclusiveContent": { + "type": "boolean" + }, + "merch": { + "type": "boolean" + } + }, + "required": [ + "presale", + "freeTicket", + "discount", + "exclusiveContent", + "merch" + ], + "additionalProperties": false + }, + "isActive": { + "type": "boolean" + }, + "sortOrder": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, - "saleStartsAt": { + "createdAt": { + "type": "string" + } + }, + "required": [ + "id", + "organizationId", + "name", + "description", + "price", + "currency", + "billingCycle", + "benefits", + "isActive", + "sortOrder", + "createdAt" + ], + "additionalProperties": false + }, + "MembershipPlanCreate": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "description": { + "type": "string" + }, + "price": { + "type": "number", + "minimum": 0 + }, + "currency": { + "default": "COP", + "type": "string" + }, + "billingCycle": { + "type": "string", + "enum": [ + "MONTHLY", + "QUARTERLY", + "ANNUAL", + "LIFETIME" + ] + }, + "benefitPresale": { + "default": false, + "type": "boolean" + }, + "benefitFreeTicket": { + "default": false, + "type": "boolean" + }, + "benefitDiscount": { + "default": false, + "type": "boolean" + }, + "benefitExclusiveContent": { + "default": false, + "type": "boolean" + }, + "benefitMerch": { + "default": false, + "type": "boolean" + }, + "isActive": { + "default": true, + "type": "boolean" + } + }, + "required": [ + "name", + "price", + "currency", + "billingCycle", + "benefitPresale", + "benefitFreeTicket", + "benefitDiscount", + "benefitExclusiveContent", + "benefitMerch", + "isActive" + ], + "additionalProperties": false + }, + "Venue": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "address": { + "type": "string" + }, + "city": { + "type": "string" + }, + "country": { + "type": "string" + }, + "latitude": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ] }, - "saleEndsAt": { + "longitude": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "capacity": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ] + }, + "googlePlaceId": { "anyOf": [ { "type": "string" @@ -3993,11 +6396,18 @@ } ] }, - "isVisible": { + "portalVisible": { "type": "boolean" }, - "organizerAbsorbsFee": { - "type": "boolean" + "organizationId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, "createdAt": { "type": "string" @@ -4005,41 +6415,38 @@ }, "required": [ "id", - "eventDateId", "name", - "description", - "price", - "currency", + "slug", + "address", + "city", + "country", + "latitude", + "longitude", "capacity", - "maxPerOrder", - "saleStartsAt", - "saleEndsAt", - "isVisible", - "organizerAbsorbsFee", + "googlePlaceId", + "portalVisible", + "organizationId", "createdAt" ], "additionalProperties": false }, - "TicketTypeCreate": { + "VenueCreate": { "type": "object", "properties": { - "eventDateId": { + "name": { "type": "string", "minLength": 1 }, - "name": { + "address": { "type": "string", "minLength": 1 }, - "description": { - "type": "string" - }, - "price": { - "type": "number", - "minimum": 0 + "city": { + "type": "string", + "minLength": 1 }, - "currency": { - "default": "COP", + "country": { + "default": "CO", "type": "string" }, "capacity": { @@ -4047,57 +6454,48 @@ "exclusiveMinimum": 0, "maximum": 9007199254740991 }, - "maxPerOrder": { - "default": 10, - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 9007199254740991 - }, - "isVisible": { - "default": true, - "type": "boolean" + "latitude": { + "type": "number", + "minimum": -90, + "maximum": 90 }, - "organizerAbsorbsFee": { - "default": false, - "type": "boolean" + "longitude": { + "type": "number", + "minimum": -180, + "maximum": 180 } }, "required": [ - "eventDateId", "name", - "price", - "currency", - "capacity", - "maxPerOrder", - "isVisible", - "organizerAbsorbsFee" + "address", + "city", + "country" ], "additionalProperties": false }, - "SaleItem": { + "StaffUser": { "type": "object", "properties": { "id": { "type": "string" }, - "ticketTypeId": { + "name": { "type": "string" }, - "quantity": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "unitPrice": { - "type": "number" - }, - "subtotal": { - "type": "number" - }, - "ticketCode": { + "email": { "type": "string" }, - "checkedInAt": { + "role": { + "type": "string", + "enum": [ + "SUPER_ADMIN", + "ADMIN", + "STAFF", + "VIEWER", + "MINCULTURA" + ] + }, + "organizationId": { "anyOf": [ { "type": "string" @@ -4106,66 +6504,127 @@ "type": "null" } ] + }, + "createdAt": { + "type": "string" } }, "required": [ "id", - "ticketTypeId", - "quantity", - "unitPrice", - "subtotal", - "ticketCode", - "checkedInAt" + "name", + "email", + "role", + "organizationId", + "createdAt" ], "additionalProperties": false }, - "Sale": { + "StaffCreate": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "reference": { - "type": "string" + "name": { + "type": "string", + "minLength": 1 }, - "status": { + "email": { + "type": "string", + "format": "email", + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" + } + }, + "required": [ + "name", + "email" + ], + "additionalProperties": false + }, + "RoleUpdate": { + "type": "object", + "properties": { + "role": { "type": "string", "enum": [ - "PENDING", - "CONFIRMED", - "ABANDONED", - "CANCELLED", - "REFUNDED" + "SUPER_ADMIN", + "ADMIN", + "STAFF", + "VIEWER", + "MINCULTURA" ] - }, - "channel": { + } + }, + "required": [ + "role" + ], + "additionalProperties": false + }, + "ReportSummary": { + "type": "object", + "properties": { + "period": { "type": "string" }, - "subtotal": { - "type": "number" - }, - "discountAmount": { - "type": "number" + "currency": { + "type": "string" }, - "serviceFee": { + "revenue": { "type": "number" }, - "iva": { - "type": "number" + "ticketsSold": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, - "total": { - "type": "number" + "salesCount": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, - "currency": { + "activeMemberships": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": [ + "period", + "currency", + "revenue", + "ticketsSold", + "salesCount", + "activeMemberships" + ], + "additionalProperties": false + }, + "MatchStatus": { + "type": "string", + "enum": [ + "OK", + "MISSING_INVOICE", + "MISSING_CUFE", + "AMOUNT_MISMATCH", + "MISSING_PAYMENT" + ] + }, + "InventoryRow": { + "type": "object", + "properties": { + "eventId": { "type": "string" }, - "buyerName": { + "eventName": { "type": "string" }, - "buyerEmail": { - "type": "string" + "eventStatus": { + "type": "string", + "enum": [ + "DRAFT", + "PUBLISHED", + "SOLD_OUT", + "CANCELLED", + "COMPLETED" + ] }, - "buyerPhone": { + "eventDateId": { "anyOf": [ { "type": "string" @@ -4175,7 +6634,7 @@ } ] }, - "organizationId": { + "startsAt": { "anyOf": [ { "type": "string" @@ -4185,7 +6644,7 @@ } ] }, - "confirmedAt": { + "ticketTypeId": { "anyOf": [ { "type": "string" @@ -4195,40 +6654,59 @@ } ] }, - "createdAt": { - "type": "string" + "ticketTypeName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "capacity": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "sold": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "reserved": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "available": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 } }, "required": [ - "id", - "reference", - "status", - "channel", - "subtotal", - "discountAmount", - "serviceFee", - "iva", - "total", - "currency", - "buyerName", - "buyerEmail", - "buyerPhone", - "organizationId", - "confirmedAt", - "createdAt" + "eventId", + "eventName", + "eventStatus", + "eventDateId", + "startsAt", + "ticketTypeId", + "ticketTypeName", + "capacity", + "sold", + "reserved", + "available" ], "additionalProperties": false }, - "SaleDetail": { + "ReconciliationRow": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "reference": { + "sale_reference": { "type": "string" }, - "status": { + "sale_status": { "type": "string", "enum": [ "PENDING", @@ -4238,34 +6716,10 @@ "REFUNDED" ] }, - "channel": { - "type": "string" - }, - "subtotal": { - "type": "number" - }, - "discountAmount": { - "type": "number" - }, - "serviceFee": { - "type": "number" - }, - "iva": { - "type": "number" - }, - "total": { + "sale_amount": { "type": "number" }, - "currency": { - "type": "string" - }, - "buyerName": { - "type": "string" - }, - "buyerEmail": { - "type": "string" - }, - "buyerPhone": { + "mp_payment_ref": { "anyOf": [ { "type": "string" @@ -4275,7 +6729,7 @@ } ] }, - "organizationId": { + "mp_provider": { "anyOf": [ { "type": "string" @@ -4285,54 +6739,17 @@ } ] }, - "confirmedAt": { + "mp_amount": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ] }, - "createdAt": { - "type": "string" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SaleItem" - } - } - }, - "required": [ - "id", - "reference", - "status", - "channel", - "subtotal", - "discountAmount", - "serviceFee", - "iva", - "total", - "currency", - "buyerName", - "buyerEmail", - "buyerPhone", - "organizationId", - "confirmedAt", - "createdAt", - "items" - ], - "additionalProperties": false - }, - "MembershipPlan": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "organizationId": { + "siigo_invoice_name": { "anyOf": [ { "type": "string" @@ -4342,10 +6759,7 @@ } ] }, - "name": { - "type": "string" - }, - "description": { + "siigo_invoice_status": { "anyOf": [ { "type": "string" @@ -4355,188 +6769,350 @@ } ] }, - "price": { - "type": "number" - }, - "currency": { - "type": "string" - }, - "billingCycle": { - "type": "string", - "enum": [ - "MONTHLY", - "QUARTERLY", - "ANNUAL", - "LIFETIME" + "siigo_cufe": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ] }, - "benefits": { + "match_status": { + "$ref": "#/components/schemas/MatchStatus" + } + }, + "required": [ + "sale_reference", + "sale_status", + "sale_amount", + "mp_payment_ref", + "mp_provider", + "mp_amount", + "siigo_invoice_name", + "siigo_invoice_status", + "siigo_cufe", + "match_status" + ], + "additionalProperties": false + }, + "SaleCreate": { + "type": "object", + "properties": { + "buyer": { "type": "object", "properties": { - "presale": { - "type": "boolean" - }, - "freeTicket": { - "type": "boolean" - }, - "discount": { - "type": "boolean" + "name": { + "type": "string", + "minLength": 1 }, - "exclusiveContent": { - "type": "boolean" + "email": { + "type": "string", + "format": "email", + "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" }, - "merch": { - "type": "boolean" + "phone": { + "type": "string", + "minLength": 1 } }, "required": [ - "presale", - "freeTicket", - "discount", - "exclusiveContent", - "merch" + "name", + "email" ], "additionalProperties": false }, - "isActive": { + "items": { + "minItems": 1, + "type": "array", + "items": { + "type": "object", + "properties": { + "ticketTypeId": { + "type": "string", + "minLength": 1 + }, + "quantity": { + "type": "integer", + "minimum": 1, + "maximum": 9007199254740991 + } + }, + "required": [ + "ticketTypeId", + "quantity" + ], + "additionalProperties": false + } + }, + "channel": { + "default": "ADMIN", + "type": "string", + "enum": [ + "WEB", + "MOBILE", + "POS", + "ADMIN" + ] + }, + "comp": { + "default": false, "type": "boolean" }, - "sortOrder": { + "notes": { + "type": "string" + } + }, + "required": [ + "buyer", + "items", + "channel", + "comp" + ], + "additionalProperties": false + }, + "ReportByEventRow": { + "type": "object", + "properties": { + "eventId": { + "type": "string" + }, + "eventName": { + "type": "string" + }, + "revenue": { + "type": "number" + }, + "ticketsSold": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 }, - "createdAt": { - "type": "string" + "salesCount": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "available": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 } }, "required": [ - "id", - "organizationId", - "name", - "description", - "price", - "currency", - "billingCycle", - "benefits", - "isActive", - "sortOrder", - "createdAt" + "eventId", + "eventName", + "revenue", + "ticketsSold", + "salesCount", + "available" + ], + "additionalProperties": false + }, + "ReportTimeseriesRow": { + "type": "object", + "properties": { + "bucket": { + "type": "string" + }, + "revenue": { + "type": "number" + }, + "ticketsSold": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "salesCount": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + }, + "required": [ + "bucket", + "revenue", + "ticketsSold", + "salesCount" ], "additionalProperties": false }, - "MembershipPlanCreate": { + "DiscountType": { + "type": "string", + "enum": [ + "PERCENT", + "FIXED" + ] + }, + "Discount": { "type": "object", "properties": { - "name": { - "type": "string", - "minLength": 1 + "id": { + "type": "string" }, - "description": { + "code": { "type": "string" }, - "price": { - "type": "number", - "minimum": 0 + "type": { + "$ref": "#/components/schemas/DiscountType" }, - "currency": { - "default": "COP", - "type": "string" + "value": { + "type": "number" }, - "billingCycle": { - "type": "string", - "enum": [ - "MONTHLY", - "QUARTERLY", - "ANNUAL", - "LIFETIME" + "eventId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ] }, - "benefitPresale": { - "default": false, + "active": { "type": "boolean" }, - "benefitFreeTicket": { - "default": false, - "type": "boolean" + "maxUses": { + "anyOf": [ + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ] }, - "benefitDiscount": { - "default": false, - "type": "boolean" + "uses": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, - "benefitExclusiveContent": { - "default": false, - "type": "boolean" + "startsAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, - "benefitMerch": { - "default": false, - "type": "boolean" + "endsAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, - "isActive": { - "default": true, - "type": "boolean" + "createdAt": { + "type": "string" } }, "required": [ - "name", - "price", - "currency", - "billingCycle", - "benefitPresale", - "benefitFreeTicket", - "benefitDiscount", - "benefitExclusiveContent", - "benefitMerch", - "isActive" + "id", + "code", + "type", + "value", + "eventId", + "active", + "maxUses", + "uses", + "startsAt", + "endsAt", + "createdAt" ], "additionalProperties": false }, - "Venue": { + "DiscountCreate": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" + "code": { + "type": "string", + "minLength": 1 }, - "slug": { - "type": "string" + "type": { + "$ref": "#/components/schemas/DiscountType" }, - "address": { - "type": "string" + "value": { + "type": "number", + "exclusiveMinimum": 0 }, - "city": { - "type": "string" + "eventId": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ] }, - "country": { - "type": "string" + "maxUses": { + "anyOf": [ + { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 + }, + { + "type": "null" + } + ] }, - "latitude": { + "startsAt": { "anyOf": [ { - "type": "number" + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" }, { "type": "null" } ] }, - "longitude": { + "endsAt": { "anyOf": [ { - "type": "number" + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" }, { "type": "null" } ] + } + }, + "required": [ + "code", + "type", + "value" + ], + "additionalProperties": false + }, + "DiscountUpdate": { + "type": "object", + "properties": { + "active": { + "type": "boolean" }, - "capacity": { + "value": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maxUses": { "anyOf": [ { "type": "integer", - "minimum": -9007199254740991, + "exclusiveMinimum": 0, "maximum": 9007199254740991 }, { @@ -4544,116 +7120,167 @@ } ] }, - "googlePlaceId": { + "startsAt": { "anyOf": [ { - "type": "string" + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" }, { "type": "null" } ] }, - "portalVisible": { - "type": "boolean" - }, - "organizationId": { + "endsAt": { "anyOf": [ { - "type": "string" + "type": "string", + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" }, { "type": "null" } ] + } + }, + "additionalProperties": false + }, + "Webhook": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "url": { + "type": "string" + }, + "events": { + "type": "array", + "items": { + "type": "string" + } + }, + "active": { + "type": "boolean" }, "createdAt": { "type": "string" + }, + "updatedAt": { + "type": "string" } }, "required": [ "id", - "name", - "slug", - "address", - "city", - "country", - "latitude", - "longitude", - "capacity", - "googlePlaceId", - "portalVisible", - "organizationId", - "createdAt" + "url", + "events", + "active", + "createdAt", + "updatedAt" ], "additionalProperties": false }, - "VenueCreate": { + "WebhookCreated": { "type": "object", "properties": { - "name": { - "type": "string", - "minLength": 1 + "id": { + "type": "string" }, - "address": { - "type": "string", - "minLength": 1 + "url": { + "type": "string" }, - "city": { - "type": "string", - "minLength": 1 + "events": { + "type": "array", + "items": { + "type": "string" + } }, - "country": { - "default": "CO", + "active": { + "type": "boolean" + }, + "createdAt": { "type": "string" }, - "capacity": { - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 9007199254740991 + "updatedAt": { + "type": "string" }, - "latitude": { - "type": "number", - "minimum": -90, - "maximum": 90 + "signingSecret": { + "type": "string" + } + }, + "required": [ + "id", + "url", + "events", + "active", + "createdAt", + "updatedAt", + "signingSecret" + ], + "additionalProperties": false + }, + "WebhookCreate": { + "type": "object", + "properties": { + "url": { + "type": "string", + "format": "uri" + }, + "events": { + "minItems": 1, + "type": "array", + "items": { + "type": "string", + "enum": [ + "sale.confirmed", + "sale.refunded" + ] + }, + "description": "Subconjunto de: sale.confirmed, sale.refunded" }, - "longitude": { - "type": "number", - "minimum": -180, - "maximum": 180 + "secret": { + "type": "string", + "minLength": 1 } }, "required": [ - "name", - "address", - "city", - "country" + "url", + "events" ], "additionalProperties": false }, - "StaffUser": { + "Subscriber": { "type": "object", "properties": { "id": { "type": "string" }, - "name": { - "type": "string" + "customerName": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, - "email": { + "customerEmail": { "type": "string" }, - "role": { + "status": { "type": "string", "enum": [ - "SUPER_ADMIN", - "ADMIN", - "STAFF", - "VIEWER", - "MINCULTURA" + "PENDING", + "ACTIVE", + "EXPIRED", + "CANCELLED", + "PAUSED" ] }, - "organizationId": { + "startedAt": { "anyOf": [ { "type": "string" @@ -4663,126 +7290,79 @@ } ] }, - "createdAt": { - "type": "string" + "currentPeriodEnd": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] } }, "required": [ "id", - "name", - "email", - "role", - "organizationId", - "createdAt" + "customerName", + "customerEmail", + "status", + "startedAt", + "currentPeriodEnd" ], "additionalProperties": false }, - "StaffCreate": { + "SubscriptionCancelResult": { "type": "object", "properties": { - "name": { - "type": "string", - "minLength": 1 + "id": { + "type": "string" }, - "email": { - "type": "string", - "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" - } - }, - "required": [ - "name", - "email" - ], - "additionalProperties": false - }, - "RoleUpdate": { - "type": "object", - "properties": { - "role": { + "status": { "type": "string", "enum": [ - "SUPER_ADMIN", - "ADMIN", - "STAFF", - "VIEWER", - "MINCULTURA" + "PENDING", + "ACTIVE", + "EXPIRED", + "CANCELLED", + "PAUSED" + ] + }, + "cancelledAt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ] } }, "required": [ - "role" + "id", + "status", + "cancelledAt" ], "additionalProperties": false }, - "ReportSummary": { + "SaleTicket": { "type": "object", "properties": { - "period": { + "ticketCode": { "type": "string" }, - "currency": { + "ticketTypeId": { "type": "string" }, - "revenue": { - "type": "number" - }, - "ticketsSold": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "salesCount": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 + "ticketTypeName": { + "type": "string" }, - "activeMemberships": { + "quantity": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991 - } - }, - "required": [ - "period", - "currency", - "revenue", - "ticketsSold", - "salesCount", - "activeMemberships" - ], - "additionalProperties": false - }, - "MatchStatus": { - "type": "string", - "enum": [ - "OK", - "MISSING_INVOICE", - "MISSING_CUFE", - "AMOUNT_MISMATCH", - "MISSING_PAYMENT" - ] - }, - "ReconciliationRow": { - "type": "object", - "properties": { - "sale_reference": { - "type": "string" - }, - "sale_status": { - "type": "string", - "enum": [ - "PENDING", - "CONFIRMED", - "ABANDONED", - "CANCELLED", - "REFUNDED" - ] - }, - "sale_amount": { - "type": "number" }, - "mp_payment_ref": { + "seatLabel": { "anyOf": [ { "type": "string" @@ -4792,7 +7372,7 @@ } ] }, - "mp_provider": { + "checkedInAt": { "anyOf": [ { "type": "string" @@ -4801,18 +7381,35 @@ "type": "null" } ] + } + }, + "required": [ + "ticketCode", + "ticketTypeId", + "ticketTypeName", + "quantity", + "seatLabel", + "checkedInAt" + ], + "additionalProperties": false + }, + "CheckinResult": { + "type": "object", + "properties": { + "ticketCode": { + "type": "string" }, - "mp_amount": { + "checkedInAt": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ] }, - "siigo_invoice_name": { + "checkedInBy": { "anyOf": [ { "type": "string" @@ -4822,17 +7419,61 @@ } ] }, - "siigo_invoice_status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } + "alreadyCheckedIn": { + "type": "boolean" + } + }, + "required": [ + "ticketCode", + "checkedInAt", + "checkedInBy", + "alreadyCheckedIn" + ], + "additionalProperties": false + }, + "TicketAccess": { + "type": "object", + "properties": { + "ticketCode": { + "type": "string" + }, + "valid": { + "type": "boolean" + }, + "status": { + "type": "string", + "enum": [ + "VALID", + "USED", + "INVALID" ] }, - "siigo_cufe": { + "saleStatus": { + "type": "string", + "enum": [ + "PENDING", + "CONFIRMED", + "ABANDONED", + "CANCELLED", + "REFUNDED" + ] + }, + "eventId": { + "type": "string" + }, + "eventName": { + "type": "string" + }, + "eventDateId": { + "type": "string" + }, + "startsAt": { + "type": "string" + }, + "ticketTypeName": { + "type": "string" + }, + "checkedInAt": { "anyOf": [ { "type": "string" @@ -4841,22 +7482,39 @@ "type": "null" } ] + } + }, + "required": [ + "ticketCode", + "valid", + "status", + "saleStatus", + "eventId", + "eventName", + "eventDateId", + "startsAt", + "ticketTypeName", + "checkedInAt" + ], + "additionalProperties": false + }, + "ResendTicket": { + "type": "object", + "properties": { + "ticketCode": { + "type": "string" }, - "match_status": { - "$ref": "#/components/schemas/MatchStatus" + "sentTo": { + "type": "string" + }, + "sentAt": { + "type": "string" } }, "required": [ - "sale_reference", - "sale_status", - "sale_amount", - "mp_payment_ref", - "mp_provider", - "mp_amount", - "siigo_invoice_name", - "siigo_invoice_status", - "siigo_cufe", - "match_status" + "ticketCode", + "sentTo", + "sentAt" ], "additionalProperties": false } diff --git a/package.json b/package.json index db74610..4e259bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@freeticket/cli", - "version": "0.5.0", + "version": "0.6.0", "description": "Official FreeTicket CLI — consumes the B2B REST API for events, sales, tickets, memberships, venues, staff, and reports.", "keywords": [ "freeticket", diff --git a/src/commands/reports.ts b/src/commands/reports.ts index 9be49c5..95f2d7e 100644 --- a/src/commands/reports.ts +++ b/src/commands/reports.ts @@ -1,10 +1,14 @@ import type { Command } from "commander"; import { + getReportsByEvent, + getReportsExportsAttendees, getReportsExportsBuyers, getReportsExportsReconciliation, getReportsExportsSubscribers, + getReportsInventory, getReportsReconciliation, getReportsSummary, + getReportsTimeseries, } from "../client/sdk.gen"; import { configureClient, unwrap } from "../lib/api"; import { print } from "../lib/output"; @@ -57,9 +61,81 @@ export function registerReports(program: Command): void { print(body.data, { json: opts.json }); }); + root + .command("by-event") + .description("Revenue / tickets sold / availability grouped by event") + .option("--from ", "created from (ISO 8601)") + .option("--to ", "created to (ISO 8601)") + .option("--status ", "filter by sale status") + .option("--workspace ", "workspace override") + .option("--json", "raw JSON output") + .action(async (opts) => { + configureClient(opts.workspace); + const body = unwrap( + await getReportsByEvent({ + query: { from: opts.from, to: opts.to, status: opts.status }, + }), + ); + print(body.data, { json: opts.json }); + }); + + root + .command("timeseries") + .description("Revenue / tickets sold bucketed over time") + .requiredOption("--interval ", "day | week | month") + .option("--from ", "created from (ISO 8601)") + .option("--to ", "created to (ISO 8601)") + .option("--event ", "filter by event") + .option("--workspace ", "workspace override") + .option("--json", "raw JSON output") + .action(async (opts) => { + configureClient(opts.workspace); + const body = unwrap( + await getReportsTimeseries({ + query: { + interval: opts.interval, + from: opts.from, + to: opts.to, + event: opts.event, + }, + }), + ); + print(body.data, { json: opts.json }); + }); + + root + .command("inventory") + .description("Capacity / sold / reserved / available per event·date·type") + .option("--event-id ", "filter by event") + .option("--event-date-id ", "filter by event date") + .option("--from ", "date from (ISO 8601)") + .option("--to ", "date to (ISO 8601)") + .option("--include-drafts", "include draft events") + .option("--group-by ", "ticketType | date | event") + .option("--workspace ", "workspace override") + .option("--json", "raw JSON output") + .action(async (opts) => { + configureClient(opts.workspace); + const body = unwrap( + await getReportsInventory({ + query: { + eventId: opts.eventId, + eventDateId: opts.eventDateId, + from: opts.from, + to: opts.to, + includeDrafts: opts.includeDrafts, + groupBy: opts.groupBy, + }, + }), + ); + print(body.data, { json: opts.json }); + }); + const exp = root .command("export") - .description("Export buyers, subscribers or reconciliation (CSV)"); + .description( + "Export buyers, attendees, subscribers or reconciliation (CSV)", + ); exp .command("reconciliation") @@ -85,19 +161,46 @@ export function registerReports(program: Command): void { print(body.data ?? body, { json: opts.json }); }); + // buyers = one row per sale, attendees = one row per ticket; both filterable. for (const [name, fn, label] of [ - ["buyers", getReportsExportsBuyers, "buyers"], - ["subscribers", getReportsExportsSubscribers, "subscribers"], + ["buyers", getReportsExportsBuyers, "buyers (one row per sale)"], + ["attendees", getReportsExportsAttendees, "attendees (one row per ticket)"], ] as const) { exp .command(name) .description(`Export ${label}`) + .option("--event ", "filter by event") + .option("--event-date ", "filter by event date") + .option("--from ", "created from (ISO 8601)") + .option("--to ", "created to (ISO 8601)") + .option("--status ", "filter by sale status") .option("--workspace ", "workspace override") .option("--json", "raw JSON output") .action(async (opts) => { configureClient(opts.workspace); - const body = unwrap(await fn({})); + const body = unwrap( + await fn({ + query: { + event: opts.event, + eventDate: opts.eventDate, + from: opts.from, + to: opts.to, + status: opts.status, + }, + }), + ); print(body.data ?? body, { json: opts.json }); }); } + + exp + .command("subscribers") + .description("Export subscribers") + .option("--workspace ", "workspace override") + .option("--json", "raw JSON output") + .action(async (opts) => { + configureClient(opts.workspace); + const body = unwrap(await getReportsExportsSubscribers({})); + print(body.data ?? body, { json: opts.json }); + }); } diff --git a/src/commands/tickets.ts b/src/commands/tickets.ts new file mode 100644 index 0000000..ccb8d08 --- /dev/null +++ b/src/commands/tickets.ts @@ -0,0 +1,60 @@ +import type { Command } from "commander"; +import { + getTicketsTicketCodeAccess, + postTicketsTicketCodeCheckin, + postTicketsTicketCodeResend, +} from "../client/sdk.gen"; +import { configureClient, unwrap } from "../lib/api"; +import { print } from "../lib/output"; + +/** + * `ft tickets` — door/access operations keyed by ticket code (the QR payload), + * not by numeric id. Kept separate from registerResource because the path + * param is `ticketCode`. + */ +export function registerTickets(program: Command): void { + const root = program + .command("tickets") + .description("Individual tickets: door check-in, access status, QR resend"); + + root + .command("access ") + .description("Read a ticket's access status without admitting it") + .option("--workspace ", "workspace override") + .option("--json", "raw JSON output") + .action(async (code, opts) => { + configureClient(opts.workspace); + const body = unwrap( + await getTicketsTicketCodeAccess({ path: { ticketCode: code } }), + ); + print(body.data ?? body, { json: opts.json }); + }); + + root + .command("checkin ") + .description( + "Admit a ticket at the door (idempotent, prevents double entry)", + ) + .option("--workspace ", "workspace override") + .option("--json", "raw JSON output") + .action(async (code, opts) => { + configureClient(opts.workspace); + const body = unwrap( + await postTicketsTicketCodeCheckin({ path: { ticketCode: code } }), + ); + print(body.data ?? body, { json: opts.json }); + }); + + root + .command("resend ") + .description("Resend the ticket's confirmation email (QR)") + .option("--workspace ", "workspace override") + .option("--json", "raw JSON output") + .action(async (code, opts) => { + configureClient(opts.workspace); + const body = unwrap( + await postTicketsTicketCodeResend({ path: { ticketCode: code } }), + ); + print(body.data ?? body, { json: opts.json }); + }); +} diff --git a/src/index.ts b/src/index.ts index 5279c66..926ea73 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,44 +2,56 @@ import { Command } from "commander"; // Version synced with package.json at build time (tsup injects it via import). import pkg from "../package.json" with { type: "json" }; import { + deleteDiscountsId, deleteEventsId, deleteEventsIdDatesDateId, deleteMembershipPlansId, deleteTicketTypesId, deleteVenuesId, + deleteWebhooksId, + getDiscounts, getEvents, getEventsId, getEventsIdDates, getMembershipPlans, getMembershipPlansId, + getMembershipPlansIdSubscribers, getSales, getSalesId, + getSalesIdTickets, getStaff, getTicketTypes, getTicketTypesId, getVenues, getVenuesId, + getWebhooks, + patchDiscountsId, patchEventsId, patchEventsIdDatesDateId, patchMembershipPlansId, patchStaffIdRole, patchTicketTypesId, patchVenuesId, + postDiscounts, postEvents, postEventsIdDates, postEventsIdPublish, postMembershipPlans, + postSales, postSalesIdCancel, postSalesIdRefund, postStaff, + postSubscriptionsIdCancel, postTicketTypes, postVenues, + postWebhooks, } from "./client/sdk.gen"; import { registerAdmin } from "./commands/admin"; import { registerAuth } from "./commands/auth"; import { registerEventDates } from "./commands/event-dates"; import { registerReports } from "./commands/reports"; import { registerResource } from "./commands/resource"; +import { registerTickets } from "./commands/tickets"; import { registerWorkspace } from "./commands/workspace"; import { banner } from "./lib/banner"; @@ -81,6 +93,7 @@ registerResource(program, { describe: "Sales", list: getSales, get: getSalesId, + create: postSales, actions: [ { name: "cancel", describe: "Cancel a sale", fn: postSalesIdCancel }, { @@ -89,10 +102,42 @@ registerResource(program, { fn: postSalesIdRefund, body: true, }, + { + name: "tickets", + describe: "List the individual tickets/attendees of a sale", + fn: getSalesIdTickets, + }, ], columns: ["id", "reference", "status", "total", "currency", "createdAt"], listFlags: [ { flag: "--status ", describe: "filter by status", query: "status" }, + { + flag: "--channel ", + describe: "filter by sales channel", + query: "channel", + }, + { flag: "--event ", describe: "filter by event", query: "event" }, + { + flag: "--event-date ", + describe: "filter by event date", + query: "eventDate", + }, + { + flag: "--reference ", + describe: "filter by reference", + query: "reference", + }, + { + flag: "--buyer ", + describe: "filter by buyer name/email", + query: "buyer", + }, + { + flag: "--from ", + describe: "created from (ISO 8601)", + query: "from", + }, + { flag: "--to ", describe: "created to (ISO 8601)", query: "to" }, ], }); @@ -122,9 +167,55 @@ registerResource(program, { create: postMembershipPlans, update: patchMembershipPlansId, del: deleteMembershipPlansId, + actions: [ + { + name: "subscribers", + describe: "List the subscribers/members of a plan", + fn: getMembershipPlansIdSubscribers, + }, + ], columns: ["id", "name", "price", "currency", "billingCycle"], }); +registerResource(program, { + name: "discounts", + describe: "Discount codes / coupons", + list: getDiscounts, + create: postDiscounts, + update: patchDiscountsId, + del: deleteDiscountsId, + columns: ["id", "code", "type", "value", "active", "uses", "maxUses"], + listFlags: [ + { flag: "--event ", describe: "filter by event", query: "event" }, + { + flag: "--active ", + describe: "filter by active (true/false)", + query: "active", + }, + ], +}); + +registerResource(program, { + name: "webhooks", + describe: "Webhook endpoints (HMAC-signed event delivery)", + list: getWebhooks, + create: postWebhooks, + del: deleteWebhooksId, + columns: ["id", "url", "events", "active", "createdAt"], +}); + +registerResource(program, { + name: "subscriptions", + describe: "Plan subscriptions", + actions: [ + { + name: "cancel", + describe: "Cancel a subscription", + fn: postSubscriptionsIdCancel, + }, + ], +}); + registerResource(program, { name: "venues", describe: "Venues", @@ -152,6 +243,7 @@ registerResource(program, { columns: ["id", "name", "email", "role"], }); +registerTickets(program); registerReports(program); registerAdmin(program);