Hospitality engine

List a furniture-set piece's configured combos

get/api/furniture-set-combos

Every staff-configured subset of one piece's real member rows that MAY combine into one reservation (book_furniture_set_combos + ...combo_members, 2026-09-11). By default a furniture-set piece's members never auto-combine (see reservation-slots.ts's own comment), so an empty list here means every member of that piece is bookable only on its own until staff configure one.

Authorization

sessionCookie
sb-qxrvgfkjyvbngipqvslu-auth-token<token>

The dashboard's Supabase Auth session cookie, set at sign-in. Large sessions are split across numbered chunks (…auth-token.0, .1), so treat this as a cookie family rather than one name.

Every request re-validates it against the Auth server (getUser()), never by decoding the cookie locally: a JWT nothing has checked is not a credential. Tenancy is then read from the verified app_metadata.company_id claim and enforced by row-level security; it is never read from request input, on any route, ever.

role (admin / staff) is deliberately not in RLS. It gates specific actions in route code, the operations marked admin below, so hiding a button in the UI is cosmetic only, and a route's own check is the enforcement.

In: cookie

Query Parameters

linkGroupId*string

The furniture-set piece's own book_table_link_groups id.

Formatuuid

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/furniture-set-combos?linkGroupId=497f6eca-6276-4993-bfeb-53cbbbba6f08"
{  "combos": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "name": "string",      "tableIds": [        "0f15e971-bb89-4712-9d06-bc444ed39ebe"      ]    }  ]}

Place a furniture-set piece (a bar, a multi-tabletop banquette) POST

Independent booking (2026-09-10): a piece that renders as ONE object on the floor plan but is backed by N real, separately-bookable rows: one per bar stool, or one per banquette tabletop. Creates a new book_table_link_groups row (`kind='furniture_set'`) and N book_tables rows in one atomic insert; the first row's id is deliberately set equal to the group's own id (the anchor, the only member that ever carries real geometry; see that row's own comment for why no extra column was needed to mark it). Deliberately its own route, not a branch inside POST /api/link-groups: that route gates on the Venue Pro `table_combining` feature, and a furniture-set piece must be placeable on every plan tier. A separate route makes that impossible to leak in by accident. `MAX_COMBINED_TABLES` (the ordinary combine cap) does not apply to this group's kind either, so a whole 12-seat bar can still be booked as one party.

Configure a combo for a furniture-set piece POST

Names a subset of one furniture-set piece's real member rows (at least 2) that the allocator may combine into one reservation: the explicit, staff-driven replacement for the automatic uncapped combining this feature used to do (removed 2026-09-11, no adjacency awareness, could combine stool 2 with stool 7). Deliberately its own route, not a branch inside POST /api/link-groups: that route gates on the Venue Pro `table_combining` feature, which furniture-set pieces were built to avoid, and repointing a member's single `link_group_id` into an ordinary combine group would strip its furniture-set identity. Every `tableId` is verified server-side to actually belong to `linkGroupId`, and that group's own `kind` must be `furniture_set`.