Documentation Index
Fetch the complete documentation index at: https://docs.laportenard.com/llms.txt
Use this file to discover all available pages before exploring further.
Package
nu_pos_sync_protocol/ — Shared TypeScript package consumed by the hub (@nu/sync-protocol).
Message types
All WebSocket communication uses JSON-encoded messages with atype discriminator field.
Terminal to hub (13 message types)
| Type | Purpose | Key fields |
|---|---|---|
AUTH | Authenticate on connect | token, deviceId |
LEASE_ACQUIRE | Request exclusive edit rights | posReference, baseVersion, force? |
LEASE_RELEASE | Release edit rights | posReference, finalSnapshot? |
LEASE_HEARTBEAT | Keep lease alive | posReference |
ORDER_SNAPSHOT | Send full order state | posReference, baseVersion, snapshot |
ORDER_FINALIZE | Finalize order through hub | posReference, snapshot, configId |
TABLE_UPDATE | Update table status | tableId, status, posReference? |
TABLE_LOCK_ACQUIRE | Request table lock | tableId |
TABLE_LOCK_RELEASE | Release table lock | tableId |
TABLE_LOCK_HEARTBEAT | Keep table lock alive | tableId |
TABLE_LOCK_FORCE_ACQUIRE | Manager table lock override | tableId |
TICKET_NUMBER_REQUEST | Request sequential ticket number | orderType ("takeout" or "delivery") |
FLOOR_PLAN_UPDATE | Broadcast floor plan changes | floorId, tables, layoutMode? |
Hub to terminal (19 message types)
| Type | Purpose | Key fields |
|---|---|---|
AUTH_OK | Authentication success | terminalId, role |
AUTH_FAIL | Authentication failure | reason |
LEASE_GRANTED | Lease acquired | posReference, version, expiresAt |
LEASE_DENIED | Lease rejected | posReference, holder, reason |
LEASE_REVOKED | Lease taken away | posReference, reason, snapshot? |
ORDER_UPDATED | Order changed by another terminal | posReference, version, snapshot, sourceTerminal |
ORDER_FINALIZED | Order finalization success | posReference, orderId, lineIdMap, fiscal? |
ORDER_FINALIZE_ERROR | Order finalization failure | posReference, error, retryable |
SYNC_INIT | Full order state on connect | orders: [{ posReference, version, snapshot }] |
TABLE_UPDATED | Table status changed | tableId, status, posReference? |
CONFLICT | Version conflict detected | posReference, hubVersion, hubSnapshot |
SYNC_STATUS | Periodic hub health broadcast | connectedTerminals, pendingForward, lastOdooSync |
TABLE_LOCK_GRANTED | Table lock acquired | tableId |
TABLE_LOCK_DENIED | Table lock rejected | tableId, lockedBy: { userId, userName } |
TABLE_LOCK_RELEASED | Table lock released | tableId |
TABLE_LOCK_REVOKED | Table lock taken away | tableId, reason |
TABLE_LOCKS_STATE | Full table lock snapshot | locks: [{ tableId, terminalId, userId, userName }] |
TICKET_NUMBER_RESPONSE | Ticket number assigned | ticketNumber, orderType |
TICKET_NUMBER_ERROR | Ticket number failure | reason, orderType? |
FLOOR_PLAN_CHANGED | Floor plan changed by another terminal | floorId, tables, layoutMode?, sourceTerminal |
OrderSnapshot
The canonical representation of an order’s state, transmitted inORDER_SNAPSHOT, ORDER_UPDATED, CONFLICT, and LEASE_REVOKED messages.
OrderLineSnapshot
Voided lines (
isVoided: true) are included in snapshots for audit purposes but filtered out before forwarding to Odoo.FiscalData
Returned inORDER_FINALIZED messages for Dominican tax (NCF/DGII) integration:
Protocol constants
Defined innu_pos_sync_protocol/src/constants.ts:
| Constant | Value | Purpose |
|---|---|---|
PROTOCOL_VERSION | 1 | Bump on breaking wire format changes |
LEASE_TTL_MS | 60,000 (60s) | Lease validity without heartbeat |
HEARTBEAT_MS | 20,000 (20s) | Terminal heartbeat frequency |
GRACE_MS | 10,000 (10s) | Grace period after disconnect before lease revocation |
FORWARD_INTERVAL_MS | 5,000 (5s) | Hub event drain to Odoo interval |
FORWARD_BATCH_SIZE | 20 | Max events per drain batch |
RECONNECT_BASE_MS | 1,000 (1s) | Reconnect backoff base (doubles each attempt) |
RECONNECT_MAX_MS | 30,000 (30s) | Max reconnect delay |
TABLE_LOCK_TTL_MS | 45,000 (45s) | Table lock validity without heartbeat |
TABLE_LOCK_HEARTBEAT_MS | 15,000 (15s) | Table lock heartbeat frequency |
Validation
Every message is validated at runtime using Zod schemas (validators.ts). The hub validates incoming terminal messages before routing; the frontend can optionally validate hub messages.
z.discriminatedUnion on the type field for efficient runtime dispatch.