README docs frontend-handout/05-DINE-ORDERS.md

05 — Dine orders (floor plan + active dine-in)

List floor-plan tables with their open / done dine-in invoices.

Each invoice in dinerOrderDetail uses the same sync payload shape as history/KDS (06-PAYLOAD-REFERENCE.md) plus optional order_type_icon.


Endpoint

GET /v1/dine-orders
Authorization: Bearer <jwt>

Legacy: GET /dine-ordersGET /v1/dine-orders


Query parameters

Param Type Default Description
table_id number Filter to one floor-plan table (tables.id)
brand_id number Filter invoices by brand_id
app_version string Affects items[].qty typing
build_number number | string With app_version for qty typing
icon_pixel_size number 24 1–512 for order_type_icon
icon_format string png png | jpg | jpeg | webp | gif
icon_url_format string Alias of icon_format

Invalid query → 400.

Tenant from JWT only.


Selection rules

Tables

  • Match JWT customer_id + location_id
  • Optional table_id filter
  • Sorted by tables.id ascending

Invoices per table

  • Same tenant
  • table_id matches returned table
  • Invoice status in open, done
  • Optional brand_id
  • Sorted created_at DESC (newest first)
  • Only non-deleted line items (is_deleted = 0)

Inclusion in dinerOrderDetail

Condition Result
No open/done invoices dinerOrderDetail: null
Invoices exist but none have items dinerOrderDetail: []
One or more invoices with items Array of sync-shaped invoices

Only invoices with at least one non-deleted line item are included. Those UUIDs are listed in table uuid[].

plate_number on the table row comes from the latest open/done invoice for that table (created_at DESC), not from tables.plate_number.


Success response

HTTP 200plain JSON array of table objects (no envelope, no pagination).

No tables → [].

[
  {
    "floor_id": 606,
    "id": 5935,
    "name": "Table A5",
    "customer_id": 437,
    "location_id": 907,
    "x": 72,
    "y": 49,
    "is_rounded": 0,
    "rotation": 0,
    "height": 30,
    "width": 30,
    "people_size": 0,
    "attended_by": null,
    "unavailable": 1,
    "is_plate": 1,
    "plate_number": null,
    "uuid": [
      "AA792674-95CA-4C2E-AED4-BDB68314CA83"
    ],
    "dinerOrderDetail": [
      {
        "uuid": "AA792674-95CA-4C2E-AED4-BDB68314CA83",
        "status": "open",
        "customer_id": 437,
        "location_id": 907,
        "order_no": 2,
        "customer_invoice_id": 234972,
        "table_id": 5935,
        "order_type": "dine-in",
        "order_type_icon_key": "",
        "order_type_icon": null,
        "payments": null,
        "items": [
          {
            "name": "Mocha",
            "product_id": 257508,
            "qty": 1,
            "price": 10,
            "subtotal": 10,
            "modifiers": [],
            "addons": null
          }
        ]
      }
    ]
  }
]

Table-level fields

Field Type Description
floor_id number | null Floor reference
id number Table PK
name string | null Display name
customer_id number Tenant
location_id number Location
x, y number | null Floor-plan coords
is_rounded 0 | 1 | null Shape
rotation number | null Degrees
height, width number | null Dimensions
people_size number | null Capacity config
attended_by string | null Attendant
unavailable 0 | 1 | null Blocked table
is_plate 0 | 1 | null Plate-order table
plate_number string | null From latest open/done invoice
uuid string[] Invoice UUIDs in dinerOrderDetail
dinerOrderDetail array | null Sync-shaped invoices

Not returned (legacy columns unused here): x_pos, y_pos, guest_name, current_status, capacity, qr_code_link, etc. floors table is not joined — only floor_id is present.


Invoice objects in dinerOrderDetail

Same rules as KDS/history:

Concern Rule
Timestamps Unix seconds
Flags 0 / 1
payments { payment_method, amount, tip_amount }[] or null
items Nested addons; flat modifiers
notes String array
order_type_icon URL or null

Full fields: 06-PAYLOAD-REFERENCE.md.


Legacy v3 differences (migration)

Legacy TRACK / v3 This service
order_items items
payment_method: [{ "cash": 50 }] payments: [{ payment_method, amount, tip_amount }]
modifier string modifiers array
Flat addons Nested addons
Product image / type on line Not included

Mobile integration tips

  1. Floor-plan UI: GET /v1/dine-orders once (or poll); plot by x/y/rotation/width/height.
  2. Table badge/count: length of uuid / dinerOrderDetail (null vs empty vs array).
  3. Open a ticket: navigate with invoice from dinerOrderDetail[i] (same model as sync).
  4. Create/update order: still POST /v1/invoices/sync with table_id + order_type dine-in.
  5. Single table refresh: ?table_id={id}.
  6. Brand filter: ?brand_id= when multi-brand locations.

Semantics of dinerOrderDetail

null  → no matching invoices (table free of open/done tickets)
[]    → invoices existed but none with items (treat as empty for UI)
[…]   → show tickets

Errors

Case HTTP Body
Bad JWT 401 Auth error
Missing claims 400 Authentication must include customer_id and location_id
Bad query 400 Validation message
Success 200 [] or table array

Related workflows

Goal Call
Place / update dine-in order POST /v1/invoices/sync with table_id
Cancel table order PUT /v1/invoices/:uuid/cancel
Kitchen view of same day GET /v1/kds-orders
Past orders GET /v1/invoices/history