Files
kooltab-backoffice/docs/api.md
T
2026-10-08 04:11:44 +02:00

93 lines
3.4 KiB
Markdown

# API Documentation
Base URL: `http://localhost:3001/api/v1`
Swagger UI: `http://localhost:3001/api/docs`
## Authentication
### Dashboard Users
- Login to receive JWT access token (24h) + refresh token (30 days)
- Include access token in `Authorization: Bearer <token>` header
### Devices
- Register to receive device bearer token (90 days)
- Include device token in `Authorization: Bearer <token>` header
- Device ID must match URL parameter
## Endpoints
### Health
`GET /health` - Server health check (503 when the database is unreachable)
### Auth
`POST /auth/login` - Login with email/password
`POST /auth/refresh` - Refresh access token
`POST /auth/logout` - Logout and revoke refresh token
### Venues
`GET /venues` - List venues
`GET /venues/:venueId` - Get venue details
`GET /venues/:venueId/devices` - List devices in venue
### Devices
`POST /devices/register` - Register a new device
`POST /devices/:deviceId/sync` - Sync device state (device auth)
`POST /devices/:deviceId/commands/:commandId/ack` - Acknowledge command (device auth)
`GET /devices/generation-code` - Generate registration code (admin)
Sync semantics:
- `openTabs` must be the device's **complete** list of open tabs. Tabs it no longer reports
(e.g. deleted on the terminal) are removed from the dashboard. Settling a tab on the terminal
keeps the tab open under the same name with a zero balance, so the name stays listed.
- Every sync returns **all** pending commands for the device; `cursor` is still returned but no longer
filters. Devices dedupe by command id and re-send the ack for commands they already processed.
- The first ack for a command wins; later acks are accepted as no-ops.
- `plannedTabNames` only contains planned customers the device has not opened a tab for yet. Once a sync
reports an open tab with exactly that name, the customer is marked delivered and no longer sent.
The customer (and their email, used for reminders) is kept.
### Tabs
`GET /venues/:venueId/tabs` - List open tabs
### Planned Tabs (customer list)
`GET /venues/:venueId/planned-tabs` - List planned customers
`POST /venues/:venueId/planned-tabs` - Add a customer (admin)
`POST /venues/:venueId/planned-tabs/import` - Bulk import `{ entries: [{ customerName, email? }], mode: 'merge' | 'replace' }` (admin).
Names match case-insensitively and keep their existing spelling; `replace` also removes customers missing from the import.
`PUT /venues/:venueId/planned-tabs/:id` - Rename a customer / set email (admin)
`DELETE /venues/:venueId/planned-tabs/:id` - Remove a customer (admin)
### Reminders
`GET /venues/:venueId/reminders/candidates` - Customers with an unpaid balance and email, not reminded in the last 7 days
`POST /venues/:venueId/reminders/send` - Send payment reminders
`GET /venues/:venueId/reminders` - Reminder history
`POST /venues/:venueId/reminders/test/:plannedTabId` - Send a test email (admin)
### Commands
`POST /venues/:venueId/commands` - Create a command
`GET /venues/:venueId/commands` - List command history
`POST /venues/:venueId/commands/devices/:deviceId/revoke` - Revoke device (admin)
All `/venues/:venueId/...` routes return `403 venue_forbidden` unless the user belongs to that venue.
## Error Format
```json
{
"error": {
"code": "error_code",
"message": "Human-readable message"
}
}
```
## HTTP Status Codes
- 200 Success
- 201 Created
- 400 Bad Request
- 401 Unauthorized
- 403 Forbidden
- 404 Not Found
- 409 Conflict
- 429 Too Many Requests