You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
test(server-app): e2e multi-station KOT routing - #1388
Implement and verify issue #1348 (test(server-app): end-to-end multi-station KOT routing from the waiter app) and open a PR targeting main without merging it:
Users asked whether orders sent from the waiter app (Server App) print to the right kitchen station printers.
In code:
frontend/src/app/server-standalone/page.tsx calls printKotForOrder after Send, which posts /api/printers/print-kot with no stationName (~L770-777, L959-963). It is proxied by main/server-app.ts ~L432.
main/routes/printers.ts ~L1226-1320: with no station, routeItemsToStations (~L1166) groups items by category station printer. Unmatched items go to the default Kitchen ticket.
However, nothing tests this end to end (frontend/e2e/server-app-ordering.spec.ts mocks print-kot, and tests/issue-134-station-routing.test.ts tests only the routing function).
Task & Acceptance Criteria:
Add an integration test that sends an order through the Server App path (main/server-app.tsPOST /api/printers/print-kot -> forwardToMainApi -> main/routes/printers.ts), with two categories mapped to two station printers, plus unmatched items that fall back to the default Kitchen ticket, and asserts that separate KOT dispatches happen with the right items each.
Stub the physical printer dispatch layer (main/printers/thermal.ts / network send), NOT the route or forwarding layer.
The test fails if routing is bypassed (for example, everything goes to one ticket).
It is wired into package.json so npm run test:script-coverage passes.
Do not change production code unless the test exposes an actual bug in the requested flow.
What Changed
Added tests/server-app-station-routing.test.ts to verify end-to-end KOT printing through the Server App loopback proxy (POST /api/printers/print-kot -> forwardToMainApi -> main/routes/printers.ts) while stubbing only the physical network socket connection (net.Socket.prototype.connect) for configured printer IPs.
Asserted multi-station ESC/POS dispatch across mapped category station printers (Grill and Bar) and default Kitchen fallback for unmapped items, orderId-only reprints, delta item appends, inactive station fallback to the default Kitchen printer, and negative checks against single-ticket or cross-station routing leaks.
Added the test:server-app-station-routing script to package.json and wired it into the npm test execution chain.
Risk Assessment
✅ Low: Test-only change adding an end-to-end Server App multi-station KOT routing integration test and wiring it into package.json without touching production code.
Testing
Executed npm run test:server-app-station-routing, npm run test:script-coverage, npm run test:issue-134-routing, npm run test:issue-134-mgmt, and npm run test:server-app-maintenance-handoff, and stood up an isolated live instance of the Server App, Main API, KDS Server, and three local TCP raw-printer socket listeners to drive all five multi-station KOT routing scenarios end-to-end without route or socket stubs. Captured the decoded ESC/POS thermal tickets and test outputs as evidence artifacts; no visual screenshot artifact was captured because this change adds a backend/transport integration test with no UI/HTML/CSS changes, and all scenarios passed.
Live validation: ✅ go - 5 of 5 scenarios driven live against the product
Scenario
Result
Live
Evidence
Waiter logs into the Server App, creates a multi-category dine-in order (Grill, Bar, and unmapped Desserts), and posts /api/printers/print-kot with { orderId, items } and no stationName; the Server Ap…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario1_sendOrderWithItems) and npm run test:server-app-station-routing
Waiter triggers Server App POST /api/printers/print-kot with { orderId } only (omitting items and stationName); persisted pending order items are loaded from SQLite and routed into 3 separate ESC/POS…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario2_orderIdOnly) and npm run test:server-app-station-routing
Waiter appends a Bar item and an unmapped Dessert item to an existing order via Server App POST /api/orders/:id/items and calls POST /api/printers/print-kot with only the newly added items delta; only…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario3_appendItemsDelta) and npm run test:server-app-station-routing
When the Bar kitchen station is deactivated (is_active = 0), posting /api/printers/print-kot through the Server App routes Grill items to the Grill Station Printer, sends zero dispatches to the inacti…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario4_inactiveStationFallback) and npm run test:server-app-station-routing
Adversarial bypass check: passing an explicit stationName ("Kitchen") to POST /api/printers/print-kot bypasses per-station routing into a single combined ticket on the Default Kitchen Printer, and the…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario5_explicitStationBypass) and npm run test:server-app-station-routing
Evidence: Live Server App multi-station TCP ESC/POS KOT dispatch transcript
Evidence: Server App station routing integration test and script-coverage output
✓ Waiter App print-kot (with items, no stationName) routed to Grill, Bar, and fallback Kitchen printers
✓ Waiter App print-kot (orderId only, no stationName) routed DB items to Grill, Bar, and fallback Kitchen printers
✓ Waiter App append-items print-kot routed only touched stations (Bar + fallback Kitchen)
✓ Inactive station (stn-bar) items fell back to Default Kitchen printer while Grill routed normally
✓ Routing assertion rejects bypassed single-ticket and cross-station dispatches
ALL PASSED
Test script coverage OK: 267 reachable, 8 explicitly excluded.
Test file coverage OK: 327 run by the default suite, 1 excluded with a stated reason.
> flo-desktop@3.13.14 test:server-app-station-routing
> node tests/run-electron-node-test.cjs tests/server-app-station-routing.test.ts
Integration Test: Server App end-to-end multi-station KOT routing (#1348)
==========================================================================
[DB] Opening database at: /var/folders/y_/1ltcxtwj0zd_w1dg9jv4jl580000gn/T/flo-server-app-station-routing-ik2yxP/flo.db
[DB] Schema: v0 → v118
[DB] Triggering auto-backup before migrating v0 → v118...
[DB] Auto-backup before migrating v0 → v118 created at /var/folders/y_/1ltcxtwj0zd_w1dg9jv4jl580000gn/T/flo-server-app-station-routing-ik2yxP/backups/flo-backup-2026-10-28T20-58-10-744Z-pre-v0-to-v118.db
[DB] Install defaults loaded; first-run setup pending
[MIGRATION v23] normalized: 0, unparseable: 0
[MIGRATION v23] merged 0 duplicate customer(s)
[MIGRATION v23] verification: 0 customers, 0 still non-E.164
[MIGRATION v24] normalized: 0, unparseable: 0
[MIGRATION v25] backfilled addons for 0 order items (0 unparseable, skipped)
[MIGRATION v30] backfilled 0 order_item(s) still missing a normalized addons snapshot
[MIGRATION v30] Dropped order_items.addons — order_item_addons is now the only place selected addons live.
[MIGRATION v73] normalized 0 merchant template payload(s); 0 already canonical or left untouched
[DB] integrity_check: ok
[DB] foreign_key_check: clean
[Server] Frontend build not found. Run `npm run build:frontend` first.
[Server] HTTP server running on http://localhost:50554
[KDS] WebSocket server setup complete
[Server] KDS WebSocket running on ws://localhost:50554/kds
[WhatsApp] {"event":"startup_init","enabled":false,"hasCredentials":false,"connectedPhone":null}
[KDS Server] Static build not found. Run `npm run build:frontend` first.
[KDS Server] HTTP server running on http://localhost:50555
[KDS] WebSocket server setup complete
[KDS Server] WebSocket running on ws://localhost:50555/kds
[Server App] Static build not found. Run `npm run build:frontend` first.
[Server App] HTTP server running on http://localhost:50556
[Auth] Generated new JWT secret for this install
[Printer] printKOT called, items count: 2 useUnicode: false station: Grill
[Printer] Using printer: Grill Station Printer network
[Printer] KOT data length: 335 bytes
[Printer] printKOT called, items count: 1 useUnicode: false station: Bar
[Printer] Using printer: Bar Station Printer network
[Printer] KOT data length: 303 bytes
[Printer] printKOT called, items count: 1 useUnicode: false station: Kitchen
[Printer] Using printer: Main Kitchen Printer network
[Printer] KOT data length: 310 bytes
✓ Waiter App print-kot (with items, no stationName) routed to Grill, Bar, and fallback Kitchen printers
[Printer] printKOT called, items count: 2 useUnicode: false station: Grill
[Printer] Using printer: Grill Station Printer network
[Printer] KOT data length: 335 bytes
[Printer] printKOT called, items count: 1 useUnicode: false station: Bar
[Printer] Using printer: Bar Station Printer network
[Printer] KOT data length: 303 bytes
[Printer] printKOT called, items count: 1 useUnicode: false station: Kitchen
[Printer] Using printer: Main Kitchen Printer network
[Printer] KOT data length: 310 bytes
✓ Waiter App print-kot (orderId only, no stationName) routed DB items to Grill, Bar, and fallback Kitchen printers
[Printer] printKOT called, items count: 1 useUnicode: false station: Bar
[Printer] Using printer: Bar Station Printer network
[Printer] KOT data length: 303 bytes
[Printer] printKOT called, items count: 1 useUnicode: false station: Kitchen
[Printer] Using printer: Main Kitchen Printer network
[Printer] KOT data length: 310 bytes
✓ Waiter App append-items print-kot routed only touched stations (Bar + fallback Kitchen)
[Printer] printKOT called, items count: 2 useUnicode: false station: Grill
[Printer] Using printer: Grill Station Printer network
[Printer] KOT data length: 335 bytes
[Printer] printKOT called, items count: 2 useUnicode: false station: Kitchen
[Printer] Using printer: Main Kitchen Printer network
[Printer] KOT data length: 338 bytes
✓ Inactive station (stn-bar) items fell back to Default Kitchen printer while Grill routed normally
[Printer] printKOT called, items count: 4 useUnicode: false station: Kitchen
[Printer] Using printer: Main Kitchen Printer network
[Printer] KOT data length: 396 bytes
✓ Routing assertion rejects bypassed single-ticket and cross-station dispatches
[Server App] HTTP server stopped
[KDS Server] HTTP/WebSocket server stopped
[Server] HTTP/WebSocket server stopped
[DB] Database closed
ALL PASSED
> flo-desktop@3.13.14 test:script-coverage
> node scripts/ci/validate-test-script-coverage.cjs && node tests/test-script-coverage.test.cjs && ts-node --transpile-only -P tests/tsconfig.json tests/test-harness-assertions.test.ts
Test script coverage OK: 267 reachable, 8 explicitly excluded.
Test file coverage OK: 327 run by the default suite, 1 excluded with a stated reason.
Test-script command parsing verified.
Test harness assertion contract
✗ deliberate counting failure
✗ deliberate counting failure — expected 2, got 1
✗ deliberate counting failure — "abc" does not contain "z"
✗ deliberate counting failure — expected > 2, got 1
✗ deliberate throwing failure
✗ deliberate throwing failure — expected 2, got 1
✗ deliberate throwing failure — "abc" does not contain "z"
✗ deliberate throwing failure — expected > 2, got 1
✓ harness contract verified
Live validation: ✅ go - 5 of 5 scenarios driven live against the product
Scenario
Result
Live
Evidence
Waiter logs into the Server App, creates a multi-category dine-in order (Grill, Bar, and unmapped Desserts), and posts /api/printers/print-kot with { orderId, items } and no stationName; the Server Ap…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario1_sendOrderWithItems) and npm run test:server-app-station-routing
Waiter triggers Server App POST /api/printers/print-kot with { orderId } only (omitting items and stationName); persisted pending order items are loaded from SQLite and routed into 3 separate ESC/POS…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario2_orderIdOnly) and npm run test:server-app-station-routing
Waiter appends a Bar item and an unmapped Dessert item to an existing order via Server App POST /api/orders/:id/items and calls POST /api/printers/print-kot with only the newly added items delta; only…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario3_appendItemsDelta) and npm run test:server-app-station-routing
When the Bar kitchen station is deactivated (is_active = 0), posting /api/printers/print-kot through the Server App routes Grill items to the Grill Station Printer, sends zero dispatches to the inacti…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario4_inactiveStationFallback) and npm run test:server-app-station-routing
Adversarial bypass check: passing an explicit stationName ("Kitchen") to POST /api/printers/print-kot bypasses per-station routing into a single combined ticket on the Default Kitchen Printer, and the…
✅ pass
live
~/.no-mistakes/evidence/01M624FYP5RKN5ZT9N6Y4Y0JE5/server-app-station-routing-live-transcript.json (scenario5_explicitStationBypass) and npm run test:server-app-station-routing
npm run test:server-app-station-routing
npm run test:script-coverage
npm run test:issue-134-routing
npm run test:issue-134-mgmt
npm run test:server-app-maintenance-handoff
Live end-to-end Server App + Main API + KDS Server + 3 TCP raw-printer listeners harness (node tests/run-electron-node-test.cjs -e ...)
Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.
Test Server App KOT routing across kitchen stations
🧪 Tests⚙️ Configuration changes🕐 20-40 Minutes
AI Description
• Add an HTTP integration test for waiter orders routed through the Server App to station printers.
• Verify Grill and Bar receive separate KOTs while unmapped desserts reach the default Kitchen
printer.
• Cover initial and appended items, and run the test in the standard suite.
Diagram
sequenceDiagram
actor Test as Waiter test
participant App as Server App
participant API as Main API
participant DB as Test database
participant Route as Station routing
participant Thermal as Thermal printing
participant Socket as Socket stub
Test->>App: Create order and request KOT
App->>API: Forward authenticated requests
API->>DB: Load order and printer mappings
API->>Route: Group pending items
Route-->>API: Grill, Bar, Kitchen groups
loop Each nonempty group
API->>Thermal: Print station KOT
Thermal->>Socket: Send ESC/POS bytes
end
Socket-->>Test: Recorded dispatches
Loading
High-Level Assessment
The HTTP integration test is well matched to the missing coverage: it exercises forwarding and routing together while stubbing only physical printer connections. A routing unit test would miss forwarding regressions, while browser-driven testing would add setup and UI dependencies without improving verification of printer dispatch.
• Adds a dedicated Electron-node test command and includes it in the standard test script, making the new test discoverable by script-coverage validation.
server-app-station-routing.test.tsVerify Server App KOT dispatch to mapped and fallback printers+554/-0
Verify Server App KOT dispatch to mapped and fallback printers
• Creates a waiter order through the Server App and checks that Grill, Bar, and unmapped Dessert items print on separate station-specific KOTs. Also covers order-ID-only printing, appended-item printing, and assertions that reject single-ticket routing or cross-station item leakage; physical printer sockets are stubbed while HTTP forwarding remains live.
1. Appended tickets can use the wrong port✓ Resolved
Description
The append-flow assertions identify the Bar and Kitchen dispatches by IP address but never check
their recorded ports. If an appended ticket is sent to the right IP on the wrong port, this scenario
still passes even though the ticket has not reached its configured printer endpoint.
ⓘ Recommendations generated based on similar findings in past PRs
Evidence
The socket stub records each dispatch's actual port, and the printer fixtures define expected ports.
Unlike the initial-order assertions, the append-flow lookup uses only IP, so its content checks
cannot detect a wrong-port dispatch.
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution
## Issue description
The append-flow test accepts dispatches to the expected IP even when they use the wrong printer port.
## Fix Focus Areas
- tests/server-app-station-routing.test.ts[467-479]
## Recommended Fix
Match both IP and configured port for the appended Bar and Kitchen tickets, and assert that neither printer receives an extra dispatch.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Context sources
⚠️ Tickets: not configured — No jira, linear integration is connected for the linked tickets
khaira777
changed the title
test: verify end-to-end multi-station KOT routing from the Server App
test(server-app): e2e multi-station KOT routing
Oct 27, 2026
khaira777
changed the title
test(server-app): e2e multi-station KOT routing
test(server-app): end-to-end multi-station KOT routing
Oct 28, 2026
khaira777
changed the title
test(server-app): end-to-end multi-station KOT routing
test(server-app): e2e multi-station KOT routing
Oct 28, 2026
khaira777
changed the title
test(server-app): e2e multi-station KOT routing
test(server-app): end-to-end multi-station KOT routing from the waiter app
Oct 28, 2026
khaira777
changed the title
test(server-app): end-to-end multi-station KOT routing from the waiter app
test(server-app): e2e multi-station KOT routing
Oct 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1348
Intent
Implement and verify issue #1348 (
test(server-app): end-to-end multi-station KOT routing from the waiter app) and open a PR targetingmainwithout merging it:frontend/src/app/server-standalone/page.tsxcallsprintKotForOrderafter Send, which posts/api/printers/print-kotwith nostationName(~L770-777, L959-963). It is proxied bymain/server-app.ts~L432.main/routes/printers.ts~L1226-1320: with no station,routeItemsToStations(~L1166) groups items by category station printer. Unmatched items go to the default Kitchen ticket.frontend/e2e/server-app-ordering.spec.tsmocksprint-kot, andtests/issue-134-station-routing.test.tstests only the routing function).main/server-app.tsPOST /api/printers/print-kot->forwardToMainApi->main/routes/printers.ts), with two categories mapped to two station printers, plus unmatched items that fall back to the default Kitchen ticket, and asserts that separate KOT dispatches happen with the right items each.main/printers/thermal.ts/ network send), NOT the route or forwarding layer.package.jsonsonpm run test:script-coveragepasses.What Changed
tests/server-app-station-routing.test.tsto verify end-to-end KOT printing through the Server App loopback proxy (POST /api/printers/print-kot->forwardToMainApi->main/routes/printers.ts) while stubbing only the physical network socket connection (net.Socket.prototype.connect) for configured printer IPs.orderId-only reprints, delta item appends, inactive station fallback to the default Kitchen printer, and negative checks against single-ticket or cross-station routing leaks.test:server-app-station-routingscript topackage.jsonand wired it into thenpm testexecution chain.Risk Assessment
✅ Low: Test-only change adding an end-to-end Server App multi-station KOT routing integration test and wiring it into package.json without touching production code.
Testing
Executed
npm run test:server-app-station-routing,npm run test:script-coverage,npm run test:issue-134-routing,npm run test:issue-134-mgmt, andnpm run test:server-app-maintenance-handoff, and stood up an isolated live instance of the Server App, Main API, KDS Server, and three local TCP raw-printer socket listeners to drive all five multi-station KOT routing scenarios end-to-end without route or socket stubs. Captured the decoded ESC/POS thermal tickets and test outputs as evidence artifacts; no visual screenshot artifact was captured because this change adds a backend/transport integration test with no UI/HTML/CSS changes, and all scenarios passed.npm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:server-app-station-routingEvidence: Live Server App multi-station TCP ESC/POS KOT dispatch transcript
Station: Grill (335 bytes) -> 2x Ribeye Steak, 1x Charbroiled Burger Station: Bar (303 bytes) -> 3x Classic Mojito Station: Kitchen (310 bytes) -> 1x Basque CheesecakeEvidence: Server App station routing integration test and script-coverage output
✓ Waiter App print-kot (with items, no stationName) routed to Grill, Bar, and fallback Kitchen printers ✓ Waiter App print-kot (orderId only, no stationName) routed DB items to Grill, Bar, and fallback Kitchen printers ✓ Waiter App append-items print-kot routed only touched stations (Bar + fallback Kitchen) ✓ Inactive station (stn-bar) items fell back to Default Kitchen printer while Grill routed normally ✓ Routing assertion rejects bypassed single-ticket and cross-station dispatches ALL PASSED Test script coverage OK: 267 reachable, 8 explicitly excluded. Test file coverage OK: 327 run by the default suite, 1 excluded with a stated reason.Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
npm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:server-app-station-routingnpm run test:script-coveragenpm run test:issue-134-routingnpm run test:issue-134-mgmtnpm run test:server-app-maintenance-handoffLive end-to-end Server App + Main API + KDS Server + 3 TCP raw-printer listeners harness (node tests/run-electron-node-test.cjs -e ...)✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.