docs
/
Appmint Mobile

Locations and service points

Business locations, the service points inside them, their statuses, and which part of the platform is allowed to change each one.

Almost everything operational in the app is scoped to a location: the floor, the check-in queue, open tabs, the day-part menu and the 86 list all change when the picker in the header changes. Inside a location, the things you seat people at and sell from are service points.

Locations

A location is a location record. The app lists them with POST /repository/find/location and remembers the choice per device (location_selected_id).

Queries use the location's name, not its id

When the app asks for open tabs, the queue or service points it passes the location's data.name slug — for example garden-bar-brooklyn — as businessLocationId, because that is what the server records point at. Renaming a location in a way that changes its slug orphans every record that references the old one.

A location with no service points is not broken; the Floor screen simply reports "No service points configured". A location with no open tabs shows an empty Tabs list. Both are normal for a new site.

Service points

A service point is one thing a party can be assigned to: a table, a seat, a booth, a bay, a room, a counter. They form a tree, so a floor can contain sections, a section tables, and a table seats.

FieldMeaning
nameThe unique key. Orders and tabs reference a service point by this name, not by record id.
displayNameWhat staff see — "Seat 8", "Patio 2".
kindFree text: seat, table, booth, bay, room, section, chair… The app offers a curated list but accepts anything.
businessLocationIdThe location slug it belongs to.
parentNameThe service point above it in the tree (floor → section → table → seat).
level, sortOrderDepth and ordering within a parent.
capacity, minCapacity, maxCapacityParty sizes it suits.
x, y, width, height, rotation, color, shape, backgroundImageGeometry for the floor plan.
bookableWhether reservations may target it. Default true.
isActiveWhether it is in service. Default true.
features[], images[]Descriptive extras.

Live state lives on the same record and is written by the flows below: status, currentReservationId, currentTabId, currentServerId, currentPartySize, seatedAt, estimatedEndTime, lastStatusChangeAt, lastStatusReason.

Creating and editing from the app

Floor → + opens the service point form. It covers name, display name, kind (chips plus free text), parent, capacity, the Bookable and Active toggles, and geometry. The form preserves the live fields on edit so a rename does not detach a seated party.

GET/crm/reservations/service-point/get/:id?CUSTOMER
POST/crm/reservations/service-point/createCUSTOMER
POST/crm/reservations/service-point/updateCUSTOMER
DELETE/crm/reservations/service-point/delete/:idCUSTOMER

The floor plan itself is read-only on mobile: it draws points at their authored x/y and lets you pan and zoom. Points without geometry appear in a row underneath. Dragging and resizing is done in the desktop floor editor.

Statuses and who sets them

The status vocabulary in the schema is:

StatusMeaning
availableFree to seat. Default.
occupiedA party is at it.
reservedHeld for an upcoming booking.
dirtyNeeds turning before the next party.
blockedTaken out of service by staff.
closedNot in service today.

Three different flows write it, and it matters which one you use:

FlowWhat it writesEndpoint
Check-in → Assignoccupied, plus currentReservationId, currentPartySize, seatedAt; the reservation becomes usedPOST /checkin/:taskId/assign
POS → assign a tabLinks currentTabId; can mark occupied; several tabs may share a point (joined parties)POST /storefront/pos/tab/:id/assign-service-point
POS → release a tabdirty by default, available if asked; clears the occupant only if that tab owned itPOST /storefront/pos/tab/:id/release-service-point
Check-in → Cleardirty or availablePOST /checkin/service-point/:spId/clear
Floor → long-pressA manual status — dirty, clear, blockedPOST /storefront/service-point/:id/status

The manual status call is deliberate: it changes status and lastStatusReason only, and never touches currentTabId or currentReservationId. An earlier build wrote the whole record and erased the table-to-tab link; that is why the app uses the dedicated endpoint.

Status is stored as free text, and only check-in enforces it

The manual status endpoint accepts any string — the operator owns the vocabulary. Check-in's Assign is the one place that refuses a point, and it refuses exactly occupied and reserved. A custom status such as taken would slip past that guard, so keep to the six values above unless you have a reason not to.

Seating rules worth knowing

  • Assign from the check-in queue rejects a point that is occupied or reserved, and rejects a task that is already done.
  • Assigning a tab to a point does not reject occupied points. That is how a second tab joins an existing party. If the tab has no customer and the point has a seated reservation, the tab inherits that guest, so their spend lands on their record.
  • A tab cannot be assigned across locations, and a finalized order (paid, completed, cancelled, refunded, returned) cannot be moved.
  • Releasing a tab marks the point dirty unless the release says otherwise. Someone has to clear it before the queue will seat there again.