Multi-Location Restaurant Chain Reservation and Shift Infrastructure: Cross-Store Guest Routing and HQ Dashboards That Stop Full-House Leakage

Multi-Location Restaurant Chain Reservation and Shift Infrastructure: Cross-Store Guest Routing and HQ Dashboards That Stop Full-House Leakage
BLUF: The leak is isolated inventory, not a weak flagship
A Bangkok group with two or more shops does not lose Friday dinner because the flagship cannot attract guests. It loses because the reservation book and the shift sheet are closed per shop, so store 1 turns a four-top away at 20:00 while store 2, eight minutes on foot, sits with open four-tops and a full floor payroll. The loss is not “covers refused.” It is three stacked lines: (a) seat-hours that could have been sold inside the cluster, (b) overtime at the busy shop plus idle labor at the empty one, (c) an HQ daily report that arrives after Friday 20:00 is already over. A shift SaaS shows labor cost and has no table inventory. A reservation engine shows seats and has no help-shift PIN, floor map, or bonus rule. Cross-store routing dies less from a missing screen than from a store-manager bonus that counts only own-shop sales. Decide five things before you pick a logo: which screen is the vacancy master, how routed covers hit P&L, the corporate vs franchise read boundary, help-PIN lifetime, and the metric HQ actually looks at on Friday at 15:00.
1. Count unsold group seat-hours, not flagship occupancy
Use a four-site Japanese F&B group as the working model: two izakaya in Thong Lo and Phrom Phong, one entertaining room in Sriracha, one weekend room in Pattaya. Combined seats sit near 160. Dinner check is 2,050 THB. Average party is three. Friday-Saturday peak is eight nights a month. Weekday dinner is twelve nights. Store 1 (Thong Lo) fills from the book at Friday 20:00. At the same minute, store 2 eight minutes away has three open four-tops. If the tools are a paper diary per shop and a LINE group titled “who can help tonight,” the host sends the walk-in to a competitor. HQ learns this from an Excel daily the next morning.
Read four layers, not one occupancy percentage.
- Demand that left the brand. Friday-Saturday, the flagship refuses two parties of three. Eight nights × 2 parties × 3 covers × 2,050 THB = 98,400 THB. A weekday equivalent of one party a week adds about 22,000 THB. Flagship-only refusals are near 120,000 THB a month. Inside a 15-minute walk cluster, a one-tap route that recovers 60% is 72,000 THB a month, about 864,000 THB a year. The other 40% is distance refusal, menu mismatch, a private-room request, or a party that already holds another shop.
- Fixed labor at the empty shop. Store 2 still puts three floor staff on a normal roster. At 90 THB an hour for five hours that is 1,350 THB. Eight Friday-Saturday nights: 10,800 THB. If reservation density is visible, some of those nights drop to two on the floor.
- Overtime at the busy shop, plus help that fails. Store 1 keeps two people through close. The 1.5x overtime differential of 45 THB × 3 hours × 2 staff × 8 nights is 2,160 THB. The cash is small. The real cost is a helper who does not know store 2 table numbers or course stay times and collapses a private room. Two double-holds a month at 8,000 THB each is 16,000 THB.
- HQ action delay. Occupancy skew appears on the next-day report. The moves that still work at Friday 20:00 (route a party, send help, switch ads to the empty shop) are already gone. An HQ dashboard is not a prettier chart. It is knowing at Friday 15:00 that store 2 still has 20:00 inventory.
Add the four layers. Recoverable flagship overflow alone is on the order of 860,000 THB a year. Labor skew and seating accidents push the mismatch past 1,000,000 THB. A few thousand THB of monthly software delta does not explain that. Shared time-axis between seats and people does.
2. Floor notes, Reddit, and X describe the same multi-unit break
The shop failure and the public posts point at one structure.
On the floor. Friday 19:15, the Thong Lo host turns away a walk-in four-top with “we are full tonight.” Store 2 vacancy is supposed to be a phone call. Store 2 does not pick up at peak. The party walks to the Google Maps star next door. The same night, Sriracha fills private rooms with Japanese corporate entertaining, and Pattaya runs a weekday hall with surplus floor staff. The owner in a Bangkok condo watches four LINE groups at once. Routing ends as “they might have a table,” with no seat reserved.
On the operator side (Reddit). r/restaurantowners still surfaces “multi-unit owners with 5+ locations, how do you guys do it?” (2026, 27 comments). The reply spine is that HQ kept ordering and the shift master instead of handing store managers an SOP. The same community repeats, with different product names, that multi-unit control is scattered across POS, scheduling, chat, and spreadsheets. A parallel 2025 thread, “how are you managing multi unit operations today?”, lists POS extracts, vendor email, and per-shop workflows as the daily stack. r/KitchenConfidential and r/Serverlife keep the helper report: the moment you clock into another shop, POS, table numbers, and the allergy field are different, and the seating error happens in front of the guest. A shift tool alone cannot read destination-shop table inventory.
On the guest side (forums and X). r/Bangkok and r/ThailandTourism carry “they said full and never offered a sister shop” and “I was seated in a different building than the confirmation.” After TableCheck and Hungry Hub announced inventory sync in June 2024, X traffic from travelers was positive: Japanese-language booking of Thai rooms. The floor still has a separate accident in which package inventory and à la carte chairs sell twice. Guests are not angry at a brand name. They are angry that “full” is still a per-shop noun, and that the destination shop name never lands on the completion card.
The implication is narrow. Multi-unit failure is not “we need more software.” Seat master, people master, and bonus master are three different objects.
3. Feature, price, and cap comparison
“Multi-location” is a category label. Annual rank changes with whether vacancy can be searched across shops, whether headcount caps inflate per location, and which shop P&L receives a routed cover. FX below is 1 USD = 36 THB. 7shifts public bands are 2026 annual-prepaid list (month-to-month is about 10% higher).
| Dimension | Paper diary + LINE group + spreadsheet | Reservation engine only (TableCheck-class, per-site quote) | Shift SaaS only (7shifts-class, per-location billing) | Rezabo multi-site (seat master + routing + HQ view) |
|---|---|---|---|---|
| Vacancy master | Manager paper and memory. Phone check 2 to 5 minutes | Engine shop grid. Cross-shop search is a contract module | No table inventory. Labor and punches are master | Cluster vacancy referenced in the same event |
| Full-house routing | Verbal “they might be open.” Seat is not held | Guest-facing nearby-shop UX exists. Host one-tap transfer is separate | Out of scope | Atomic move of a booking to a sister shop inside a radius |
| Shift linked to reservations | None. Headcount added next morning after covers | Cover forecast inside the engine. Statutory time and social insurance sit elsewhere | Labor % from sales or POS. Daypart cover from the book often missing | Daypart cover on the HQ view as the help input. Not a payroll engine |
| Help shifts | Separate notebook per shop. Table numbers learned on the floor | Per-shop login. Floater accounts often extra licenses | Cross-location punch works. Destination floor map does not appear | Shared PIN loads destination map and booking rules |
| Same-day HQ watch | Next-morning daily. Friday-Saturday waits until Monday | Shop switch or senior role. Quote band set by site count | Labor and attendance same day. Occupancy invisible | All-shop covers, occupancy, and routing log on one dashboard |
| Guest data across shops | Cards and LINE. Handing it to a franchisee is a PDPA purpose failure | CRM inside the engine. Extract terms are contractual | Out of scope (employee data) | Corporate shops share VIP. Franchise cut at the tenant boundary |
| Published price | Software 0. Overflow and overtime are the body | Unpublished quote. Own-site path claims zero cover fee. OTA terms sit elsewhere | Comp free (1 location, 15 employees). Essentials USD 39.99 / location (30 staff), Pro 79.99 (60), Premium 134.99 (unlimited). Payroll: location 39.99 plus USD 6 per paid employee | Ledger 1,900 THB / month. No per-reservation usage |
| Headcount and site caps | Paper sheets and LINE group count | Quote stacks seats, modules, sites | Comp is 1 location only. Essentials 30 and Pro 60 are per location. Over cap you cannot add master records until you change plan | Unlimited reservation count. Sites are tenant config. No routing fee |
| 4-site software year (indicative) | 0 | Unpublished. Feature set can exceed a flat ledger | Pro only: 79.99 × 4 × 12 ≈ USD 3,840 (about 138,000 THB). Payroll plus tip tools can push toward USD 15,000 / year | 3,500 × 4 × 12 = 168,000 THB |
| Exit | Photos and re-key. Not auditable | Confirm term, extract fee, and format at quote time | Employee master exports. Reservation cover was never there | All-shop CSV is a standard export |
Read the table as a map of what you still cannot move. Paper is the cheapest invoice and leaves a 1,000,000 THB-class mismatch of seats and people. TableCheck can be a reservation master; list price is unpublished, and Hungry Hub package economics do not vanish. 7shifts is strong on multi-unit attendance. 2026 public annual bands run USD 39.99 to 134.99 per location per month, and employee caps travel with the plan. Comp is free only for one location and 15 people. Four sites still fail Pro if one shop exceeds 60. None of those products is a substitute for moving a chair to the next shop. Rezabo’s 1,900 THB is ledger rent. It does not replace payroll, social insurance, or cash tip split. PromptPay MDR and LINE Official Account message packs sit on other lines.
4. Pricing-plan traps and four-site annual TCO
A list-price glance ranks paper cheapest, shift SaaS in the middle, and the reservation engine as “ask for a quote.” Total cost of ownership reverses that order.
Assumptions: four sites. Flagship overflow Friday-Saturday 16 parties plus about four weekday parties. Recovery 0% versus 60%. Check 2,050 THB. Average party of three.
- Unrecovered overflow: 98,400 + 22,000 = 120,400 THB / month, 1,444,800 THB / year
- 60% recovered by one-tap routing: about 867,000 THB / year. Residual 40% is distance, private-room spec, or a party already held elsewhere
- Excess roster at the empty shop: about 10,800 THB / month on Friday-Saturday
- Seating accidents: about 16,000 THB / month
| Annual cost line | Paper + LINE + Excel | Reservation engine (quoted) + separate shift tool | 7shifts Pro, 4 sites + paper book | Rezabo, 4 sites |
|---|---|---|---|---|
| Software | 0 | Unpublished. Sites, IVR, analytics stack | About 138,000 THB (Pro only). Payroll (location 39.99 plus USD 6 / paid employee) and tip tools can push past 500,000 THB | 168,000 THB |
| Setup and training | Looks free. Manager shadow time is the body | Implementation project and per-shop RBAC | Location create plus re-contract when you hit the employee cap | Floor maps and routing role-play |
| Overflow sales | 1,444,800 THB stays out | Falls if the engine can search across shops. Stays if the bonus still counts only own-shop sales | No table inventory, so flagship refusals remain | 60% recovery returns about 867,000 THB in the model |
| Labor skew | Remains | Remains if book and attendance are two screens | Labor % is visible. Same-day help to the full shop is still a phone call | Cover forecast drives the help cut. Payroll calc stays elsewhere |
| Message packs, OTA, payments | LINE packs follow the OA plan | OTA prepaid packages are a separate contract | Out of scope | Flat ledger. OA packs and PromptPay MDR billed aside |
| Year-1 TCO shape | Overflow is the body, past 1,000,000 THB | Quote + OTA + bonus failure is the body | Shift cost is readable. Full-house leakage remains | Ledger 168,000 + OA actuals. The cut target is a 1,000,000 THB-class seat and labor mismatch |
Five traps sit under those rows.
First: 7shifts Comp is “1 location, 15 employees.” The second shop moves you into a paid band. Essentials at 30 and Pro at 60 are per location. 7shifts’ own KB states total employee limit = per-location cap × active locations, so a floater copied onto two shop masters consumes two slots and hits the cap early. Premium at USD 134.99 / location is about USD 6,480 a year for four sites (about 233,000 THB) before USD 6 per paid employee. Leave payroll outside and you pay “shift only, still expensive.” Month-to-month (Essentials 44.99, Pro 89.99, Premium 149.99) is about 10% above the annual table.
Second: TableCheck’s “zero cover fee” is a branded-demand claim. Hungry Hub fixed-price packages have their own cost of goods and stay time. Mix them onto the à la carte grid and Friday 20:00 private rooms fill twice. Add a multi-site dashboard to the quote and unpublished rows become the body. Free sync is a record statement. It is not a discount rate.
Third: four LINE Official Accounts multiply message packs by four. Thai OA free tiers sit in the hundreds of messages. Paid bands are pack-metered. Collapse to one group OA and LIFF must carry shop select plus inventory scope. If the Rich Menu reservation zone is a promo photo, the routing button does not exist. Route while keeping per-shop OAs and the guest stays friends with store 1; store 2’s day-before reminder never arrives.
Fourth: Japan HQ sometimes ships a Japanese attendance cloud to a Thai floor. The UI language and Thai working-hour buckets do not match the host’s Friday decision. Punches exist. Help at 15:00 does not. Keep statutory payroll where it is. Do not move the seat master into Japanese attendance.
Fifth: do not over-claim Rezabo. 1,900 THB is an unlimited-count ledger. Thai time-and-attendance, withholding, social insurance, cash tip split, and central-kitchen production planning are not in that fee. “No routing surcharge” is not “this is your payroll engine.”
5. Cross-store routing is an atomic inventory move, not a spoken suggestion
Routing dies on the floor when the host says “Phrom Phong might be open,” the party walks, and store 2’s door says “we have no reservation.” Fix the path to four steps.
- Threshold. When flagship occupancy crosses 90%, the host screen offers routing candidates. Do not end the UI on the word “full.”
- Cluster. Thong Lo and Phrom Phong are one trade area. Sriracha and Pattaya are not. Do not render a pair you cannot complete. A refused pair trains the host never to press the button again. Limit pairs to similar stay time and price band. Sending a course private room to a casual second shop is the X complaint.
- Atomic move. Release the hold at store 1, take a short exclusive lease (about 15 seconds) on store 2’s slot id, and return a new reservation id only to the terminal that won. Two store-1 hosts racing the last store-2 four-top at Friday 20:00, three seconds apart, is the same accident as a single-shop double-hold. A copy-paste leaves the same four-top on both books.
- Guest card. LINE Flex keeps store 2’s name, map, reservation id, and walk time. Bounce to an external browser and the LINE UID drops; arrival becomes a phone check of “whose booking is this.”
Revenue attribution stays on the reservation id: origin shop, destination shop, deposit present or not. Credit the origin shop with cover-equivalent points, scored outside monthly shop P&L. Routing without a deposit is scored as completed minus no-show. “Please go next door” has no attribution. “Do it for the group” with zero points does not survive Friday-Saturday.
6. The HQ dashboard is a Friday 15:00 decision device
Ten-second telemetry is not required. One-minute grain that lets a host decide a route, plus next-day cover forecast (shop × daypart × headcount) for prep, is enough. Lock the viewing clock.
Friday 15:00 (area manager). Four shops, daypart covers for Friday-Saturday, side by side. If the flagship is above 90% from 19:00 to 21:00, push store 2 vacancy to hosts as routing candidates. If the empty shop is rostered at three on the floor, cut one as flagship help. If that cut is impossible, send the store manager a two-person roster. Miss this clock and help does not arrive by Grab.
Saturday 10:00 (store manager). Friday routing completed, post-route no-shows, minutes from help clock-in to “can seat.” If no-show on routed books sits above ordinary books, the map or the id card is missing. If help takes 30 minutes, the PIN did not open the destination map.
Monday HQ (owner). Same table every week: parties refused, routing offer rate, routing completed, post-route no-show, help hours, occupancy gap across shops. A gap above 15 points moves ads to the empty shop and reopens cluster design. Only groups with a central kitchen pass next-day cover forecast into prep lots. Starting the conversation at purchase lots leaves full-house leakage untouched.
Split four roles. Store manager: own-shop grid and same-day help candidates. Area: cluster occupancy and routing log. HQ: all-shop KPI and bonus points. Franchise owner: vacancy inquiry on own unit only; other shops’ check and food cost stay dark. When HQ sits in Japan and shops sit in Bangkok, a UTC-cut dashboard paints Friday peak as Thursday. Fix the rollup key to Asia/Bangkok business day (example: 05:00 boundary).
7. API and infrastructure constraints to kill before legal signs
Sales decks say “real-time multi-site” and “open API.” Published and field limits disagree. Put the next table in the due-diligence pack.
| Constraint | Paper + LINE | TableCheck-class engine | 7shifts-class shift SaaS | Rezabo multi-site |
|---|---|---|---|---|
| Inventory object | Pencil row. No interval type | Hungry Hub refuses a book if the engine has no seat. Package stay time is not auto-split from à la carte | No table, course stay, or private-room lock in schema | One shop grid per tenant. Routing is a move, not a second master |
| Published rate limit | N/A | Public API notes cite 10,000 requests / 5 minutes per API component (limits do not pool) | REST for locations, shifts, punches. Poll cadence is a quote item | Webhook ingest burst control. Retries must be idempotent on reservation_id |
| Webhook semantics | Chat screenshots arrive twice | Create / change / cancel can land twice for one external id | Attendance webhooks are people events, not seat events | Paid / confirmed / released retry; same id consumes one seat |
| Naive multi-site poller | Hosts poll by phone | A 5-second refresh of every table across four shops 429s one component. Handle Retry-After. Do not retry create |
Forecast jobs sharing a window with punch sync starve one of them | Subscribe to events. Do not scrape occupancy |
| Phone / locale | Mixed 0 / +66 / spaces in chat | Mixed +66 / 0 plus tourist PANs | Employee phones, not guest join keys | Normalize to E.164 before CRM merge; +66 vs +81 is a join key |
| RBAC / PDPA | Franchisee sees whatever was forwarded in LINE | Confirm PII region and extract rights. Outbound transfer notice is the shop’s duty | Employee data. Guest PII is out of scope | Corporate VIP shared. Franchise tenant cut. Shop is controller |
| Help credential lifetime | PIN on a sticky note | Floater license often billed as a second seat | Punch works across locations. Map does not follow | PIN bound to staff id, location, and a time window |
| LINE / guest path | Four OA threads | Messaging API is not a LIFF seat picker on your Rich Menu | Out of scope | LIFF shop select plus seat hold, or webhook the booking number into talk |
Three traps sit inside that matrix.
Routing is not a record copy. Source release, destination exclusive lease, and new reservation id must be one transaction. A webhook that delivers create twice for one external id will occupy two chairs unless the ledger consumes each external id once.
A shift API does not know a chair. 7shifts REST handles locations, shifts, and attendance. Table inventory, course stay, and private-room lock are not in that schema. Labor % from POS sales and “how many floor staff are short at 20:00” from reservation cover are different pipelines. Wiring the first into a slide labeled “forecast AI” matches prep headcount and misses seated headcount. Connect daypart reservation cover only.
10,000 requests / 5 minutes per component is generous for one shop and tight for a four-site poller that refreshes every table every five seconds. Limits do not pool. A CRM extract that shares a window with a booking poller will 429 one of them.
8. Technical snippets: treat the move as one transaction
Name one inventory master on day one. If an engine is master, OTA may write only through that engine. If a LINE ledger is master, OTA is a residual pool with its own stay time. Paper plus chat as a third master turns every API into a contradiction detector.
type Channel = "line" | "walkin" | "phone" | "hungry_hub" | "engine";
interface RoutingRequest {
source_shop_id: string;
destination_shop_id: string;
source_reservation_id: string;
party_size: number;
start_at: string; // ISO-8601, Asia/Bangkok
stay_minutes: number;
phone_e164: string;
cluster_id: string;
}
interface RoutingResult {
status: "moved" | "lost_race" | "cluster_forbidden" | "duplicate";
new_reservation_id?: string;
}
const seenExternal = new Set<string>();
const WALKABLE = new Set(["thonglo_phromphong"]);
export function routeParty(req: RoutingRequest, destSlotId: string): RoutingResult {
const key = `${req.source_shop_id}:${req.source_reservation_id}`;
if (seenExternal.has(key)) return { status: "duplicate" };
if (!WALKABLE.has(req.cluster_id)) return { status: "cluster_forbidden" };
// BEGIN tx: release source hold, exclusive lease destSlotId (~15s), insert new id
const leased = tryLease(destSlotId, 15_000);
if (!leased) return { status: "lost_race" };
seenExternal.add(key);
const newId = insertReservation({ ...req, slot_id: destSlotId, routed_from: req.source_shop_id });
releaseHold(req.source_reservation_id);
return { status: "moved", new_reservation_id: newId };
}
export function normalizeThPhone(raw: string): string {
const digits = raw.replace(/\D/g, "");
if (digits.startsWith("66") && digits.length === 11) return `+${digits}`;
if (digits.startsWith("0") && digits.length === 10) return `+66${digits.slice(1)}`;
if (digits.startsWith("81")) return `+${digits}`;
throw new Error(`unjoinable phone: ${raw}`);
}
Persist the raw webhook body, then project stay time onto the grid. Do not infer 120 minutes because that is how the à la carte book works.
{
"id": "evt_route_19f3",
"type": "reservation.routed",
"data": {
"external_id": "THL-20260821-4412",
"source_shop_id": "thonglo_01",
"destination_shop_id": "phromphong_02",
"cluster_id": "thonglo_phromphong",
"party_size": 4,
"start_at": "2026-08-21T20:00:00+07:00",
"stay_minutes": 120,
"phone": "0812345678",
"deposit_satang": 0,
"origin_points": 3,
"status": "confirmed"
}
}
Collision detection is a SQL constraint, not a host habit. Overlapping intervals on the same chair, including a short routing lease, must fail closed.
/* Reject a second booking or routing lease that overlaps an occupied interval. */
CREATE EXTENSION IF NOT EXISTS btree_gist;
ALTER TABLE reservations
ADD CONSTRAINT reservations_no_overlap
EXCLUDE USING gist (
shop_id WITH =,
table_id WITH =,
tstzrange(
start_at,
start_at + (stay_minutes * INTERVAL '1 minute'),
'[)'
) WITH &&
)
WHERE (status IN ('held', 'confirmed', 'lease'));
INSERT INTO routing_log (
source_shop_id, dest_shop_id, source_res_id, dest_res_id, origin_points
) VALUES (
:src, :dst, :src_id, :dst_id, :party_size
);
Host iPad and LINE LIFF must read the same availability surface. Confirming a route must mutate the object the query just read. Fan-out to three vendors at tap time is how Friday 19:50 loses the last four-top.
query ClusterVacancy($clusterId: ID!, $from: DateTime!, $to: DateTime!) {
clusterAvailability(clusterId: $clusterId, from: $from, to: $to) {
shopId
tableId
stayMinutes
walkMinutesFromSource
routingAllowed
}
}
mutation RouteReservation($sourceReservationId: ID!, $destTableId: ID!) {
routeReservation(sourceReservationId: $sourceReservationId, destTableId: $destTableId) {
status
newReservationId
destShopName
guestCardUrl
}
}
Phone numbers arrive as 081-234-5678, 0812345678, +66812345678, and the occasional +81. Collapse to E.164 before CRM merge or one regular becomes three profiles and a store-1 no-show vanishes at store 2. Routed VIP recognition depends on that normalize step first.
LINE is the Thai completion surface. An email-first engine produces a second step: Thai hosts ask guests to screenshot a booking number into the OA. Budget LIFF shop select and seat hold, or webhook the number into talk, inside the implementation scope. Keep per-shop OAs and store 2’s reminder never sends.
If personal data lives in Japan or a third country, Thai PDPA outbound-transfer notice is the shop’s problem, not the vendor’s slide. Corporate four-shops under one legal entity may share VIP profiles. The moment a franchise unit is added, guest phone and allergy become another controller’s asset. Split routing-minimum fields (party size, time, allergy, reservation id) from marketing visit history. An HQ role that also sees franchise food cost fails franchise review.
Operational traps that do not appear on the pricing page
- Own-shop sales as the only bonus denominator. Routing then means giving covers to a neighbor. The screen exists; the host still says “full.” Credit origin-shop cover-equivalent points outside monthly shop P&L. Zero-point “for the group” does not survive Friday-Saturday.
- Cloud as a “reference screen” while paper stays master. Store 1’s iPad can show full while a pencil adds a four-top, and the routing engine has nothing to send. Input and floor master must be the same event.
- Rolling 7shifts to four sites without reading the employee cap. Comp is 1 location, 15 people. Essentials 30 and Pro 60 are per location. Dual-register floaters and you hit the cap first. After that, you cannot add master records until the plan changes.
- Giving franchise owners the HQ dashboard. They see other units’ check and occupancy. Stop it in contract and PDPA. The floor for routing is an API that returns vacancy yes/no, not a guest list.
- A hard-coded 3 km radius. Thong Lo to Phrom Phong is walkable. Sriracha to Pattaya is not. Cut clusters by trade area. Hide impossible pairs. A refused pair retires the button.
- A light LINE pack running four shops’ completion cards. Per-shop OAs hide the cap because it is split four ways. One group OA means confirm, day-before reminder, and broadcast share one pack. Month-end, only store 2’s routing confirms die, and the cause is OA add-on refusal, not the reservation engine.
- Hungry Hub package slots mixed into the vacancy test. Free sync does not equalize stay time (package 90 minutes, à la carte 120). Friday 20:00 private rooms fill twice. Do not treat package inventory as a routing candidate.
- Help PIN on a printed sheet. A leaver still deletes store 2 bookings next month. Bind PIN to staff id, destination location, and a time window. If punch lives in shift SaaS and seating lives in the ledger with no join, both the absence hole and the seat hole break at once.
9. A 90-day cutover that starts with bonus rules and floor maps
Handing out logins first trains the floor to treat the product as “a new daily report.” Fix the order.
- Weeks 1 to 2 (master and boundary). Load every shop’s table map, seat count, combinable sets, and private-room stay time into one master. Split corporate and franchise roles. Stop new rows on paper; keep paper only for power loss.
- Weeks 3 to 4 (routing ops). Occupancy threshold 90%. Host one-tap shows nearby vacancy; guest LINE keeps store 2 map and reservation id. Do not offer Sriracha-Pattaya. A lost race returns the next candidate.
- Weeks 5 to 8 (shifts and help). Store managers and area see daypart cover. When Friday-Saturday flagship crosses 90%, surplus at the empty shop becomes a help candidate. PIN opens destination map only. Statutory payroll may stay in the existing shift SaaS or payroll firm.
- Weeks 9 to 12 (bonus and HQ). Origin-shop points enter bonus calc. Monthly table: parties refused, routing completed, post-route no-show, help hours. Friday 15:00 becomes an area standing meeting. Only groups with a central kitchen pass next-day cover into prep.
Do not force every menu to match on day one. Routable pairs are the ones with similar stay time and price band.
10. Questions HQ and store managers actually ask
Q1. Can corporate and franchise shops share one guest list?
Corporate shops under one tenant may share. Franchise is vacancy inquiry and reservation-id handoff only. Bulk phone and visit-history reads are a contract and PDPA object.
Q2. Do we throw away 7shifts or the payroll firm?
No. Keep punches, overtime, and social insurance. Connect daypart reservation cover only. Do not move the seat master into shift SaaS.
Q3. How many hours to train a helper?
If map and booking rules load at the destination, fifteen minutes before peak to confirm table numbers and the allergy field is enough. A shop that still runs paper resets that fifteen minutes to zero every time.
Q4. How long to add a new shop?
Map, seat count, hours, cluster membership, and roles are enough to open a tenant the same day. What slips is the dual-run with the old paper book, and the store-manager bonus coefficient.
Q5. Who owns a no-show after a route to store 2?
Keep origin, destination, and deposit flag on the reservation id. Routing without a deposit is scored completed minus no-show. With a deposit, bind cash to store 2. Spoken “please go next door” cannot be attributed.
Q6. Is a phone enough for the HQ dashboard?
For Friday 15:00 occupancy and routing candidates, yes. Map edits and RBAC design stay on desktop. Ten-second refresh is unnecessary. One-minute grain plus next-day cover forecast is enough to decide.
11. Metrics to watch before and after
| Metric | Paper + LINE per shop | Post-integration target | Why you watch it |
|---|---|---|---|
| Flagship full-house refusals | Two-plus parties remain on Friday-Saturday | Routing offer rate above 80% of refusals | Hosts are pressing the button |
| Routing completed / month | A handful via phone | Walkable cluster 40 to 100 parties | Radius matches the trade area |
| Post-route no-show | Unmeasurable | In line with ordinary books. A spike means map or id card is missing | Guest recognized store 2 |
| Occupancy gap across shops | Flagship 85%, store 2 65% side by side | Gap inside 10 points | Ads and help are filling the empty shop |
| HQ delay to same-day occupancy | 12 to 24 hours | One-minute grain. Action possible at Friday 15:00 | The daily-report wait has stopped |
| Help clock-in to “can seat” | 30-plus minutes (map learning) | Under 5 minutes | PIN and map are alive |
| Why a store manager blocks routing | “My number falls” | Points sit in the bonus | Policy is stronger than the screen |
Closing
The first object to fix in a multi-location chain is not brand consistency or the next opening date. It is putting the four-top store 1 is refusing at Friday 20:00 onto store 2’s open slot and onto help that can reach that slot, on the same clock. A reservation engine alone does not move people. A shift SaaS alone does not move chairs. Paper plus a LINE group invoices at zero and exports 1,000,000 THB-class seat-hours out of the brand.
Decide five things first. One vacancy master. Routing as an atomic inventory move. Origin-shop points in the store-manager bonus. Corporate vs franchise lists split, and help PINs that expire. The metric HQ looks at on Friday at 15:00, locked. 7shifts location price and employee caps, TableCheck unpublished quotes and OTA terms, LINE pack add-on refusal: all of those are constraints separate from “a screen exists.” Rezabo’s ledger at 168,000 THB a year for four sites is not a payroll substitute. It is the master for seats and cover forecast. The difference is not dashboard color. It is whether Thong Lo being full became Phrom Phong’s sale.
If the four existing floor maps and bonus rules stay, and you want routing plus the HQ view run against that seat layout, the Bangkok team can walk the cluster on a demo.
Bangkok Restaurant No-Show Prevention Checklist (15 Rules)
An operational field guide for dining venues in Thailand: sync kitchen prep strictly with dynamic PromptPay QR deposits and automated LINE reminders to eliminate food waste.
- Strict synchronization of Friday 16:00 kitchen prep with paid bookings only
- Dynamic QR verification replacing static slip matching and slip forgery
- High-retention refund deadline rules and seamless tourist card routing
Delivered instantly via LINE Official Account (Instant 3-sec access)