Minimal full-stack restaurant order management scaffold.
npm run install:allnpm run devThis starts:
- Client: http://localhost:5173
- Server: http://localhost:3001
curl http://localhost:3001/healthExpected response:
{ "ok": true, "name": "mai-shan-yun", "time": "2026-01-24T..." }- Open http://localhost:5173
- Click Server to enter Server View
- You'll see a grid of 10 tables
Tables have 4 statuses:
| Status | Color | Description |
|---|---|---|
| Open | Gray | Table is available |
| Seated | Blue | Customers seated, items can be added |
| Served | Green | Food has been served, timer starts |
| Dirty | Amber | Customers left, needs cleaning |
- Click on any table (e.g., Table 1) to select it
- The right panel shows the selected table's current order
- Use the Add Item section at the bottom:
- Select a menu item from the dropdown (grouped by category)
- Set quantity (default: 1)
- Click Add
- The item appears in the order list
- Table status becomes "Seated"
- Use + / − buttons to adjust item quantities
- Reducing quantity to 0 removes the item
| Action | When Available | Effect |
|---|---|---|
| Mark Served | Seated status | Sets status to "Served", starts timer |
| Mark Dirty | Served status | Sets status to "Dirty" (customer left) |
| Mark Clear | Dirty status | Resets table to "Open", clears all items |
| Clear Table | Any except Dirty/Open | Emergency reset to Open |
When a table is marked "Served":
- A timer shows elapsed time since serving (mm:ss format)
- After 20 minutes, the table card turns red to alert servers
- Timer is synchronized with server time, consistent across all devices
- Multiple browser windows stay in sync via WebSocket
- The WebSocket status indicator shows connection state (top-right)
- "Synced" indicator shows server time synchronization status
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /api/time |
Server time for clock sync |
| GET | /api/menu |
Get full menu |
| GET | /api/tables |
Get all tables (summary) |
| GET | /api/tables/:id |
Get single table (full details) |
| POST | /api/tables/:id/items |
Add item to table |
| PATCH | /api/tables/:id/items/:menuId |
Update item quantity |
| POST | /api/tables/:id/served |
Mark table as served |
| POST | /api/tables/:id/dirty |
Mark table as dirty |
| POST | /api/tables/:id/clear |
Clear table (reset to open) |
| Event | Direction | Description |
|---|---|---|
hello |
Server → Client | Sent on connection (includes serverNow) |
tables:update |
Server → Client | Broadcast when any table changes |
table:update |
Server → Client | Broadcast with full table details |
tableUpdated |
Server → Client | New format with serverNow for timer sync |