Skip to content

fix(server-app): preserve drafts during send - #1151

Merged
khaira777 merged 6 commits into
mainfrom
codex/server-app-send-race
Oct 15, 2026
Merged

khaira777 merged 6 commits into
mainfrom
codex/server-app-send-race

Conversation

@khaira777

@khaira777 khaira777 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Intent

PR 4 - Prevent Server App draft loss during send (Fixes #1140)
Branch: codex/server-app-send-race
Title: fix(server-app): preserve drafts during send

Choose the minimal freeze-during-send approach:

  • Capture one immutable submission snapshot.
  • While sending, disable draft add/remove/edit/quantity controls, notes/customer edits, table switching and refresh actions that could replace this snapshot.
  • Guard their handlers with the existing synchronous in-flight ref; disabled styling alone is insufficient.
  • Guard customizer callbacks opened before Send so they cannot mutate the draft afterward.
  • On success, clear only the acknowledged submission's state.
  • On failure or uncertain response, retain the draft and existing retry key. Re-enable editing only under the established retry rules.
  • Keep background printing from blocking Send, and preserve append-only KOT behaviour.

Acceptance: a delayed send cannot silently lose a second item; double Send creates one mutation; failed sends retain their draft; table changes cannot display a response against the wrong table.

What Changed

  • Capture an immutable SendSnapshot in frontend/src/app/server-standalone/page.tsx paired with the idempotency nonce, gate sendDraft until the active table's order lookup finishes, and subtract only acknowledged line quantities and matching notes on success while preserving the snapshot and retry key across failed sends.
  • Disable and guard draft line mutations, ProductGrid interactions, pre-send addon/edit customizer callbacks, customer and order-note inputs, table switching, and refresh handlers via sendInFlightRef and send sequence tracking while a submission is in flight, while running post-send KOT printing and background refresh from the snapshot without blocking completion.
  • Add E2E regression tests in frontend/e2e/server-app-ordering.spec.ts verifying draft freeze during delayed sends, rejection of stale customizer modal submissions, draft and idempotency-key retention after failed sends and table switches, and non-blocking KOT printing.

Risk Assessment

✅ Low: The change cleanly freezes Server App draft and table controls during an in-flight send using an immutable submission snapshot, synchronous ref guards, sequence-guarded customizer callbacks, and table-lookup gating, with comprehensive E2E test coverage.

Testing

Built the backend and static frontend, ran the full 6-test Playwright E2E suite in frontend/e2e/server-app-ordering.spec.ts and npm run test:server-app-server-role against isolated disposable server instances, and captured three live browser screenshots in the evidence directory verifying the frozen in-flight controls, post-send append behavior, and retained draft state after a failed send.

  • Live validation: ✅ go - 5 of 5 scenarios driven live against the product
Scenario Result Live Evidence
While a Server App order Send is in flight, draft add/remove/edit/quantity controls, customer and notes inputs, table switching, and refresh are disabled in the UI and synchronously blocked by the in-… ✅ pass live ~/.no-mistakes/evidence/01M4YM7VD0QTC7H9WG5N18J4R7/server-app-sending-frozen.png and frontend/e2e/server-app-ordering.spec.ts ("freezes draft controls, pre-opened customizer, and t…
When a delayed Send completes while KOT printing is still in flight, the acknowledged submission clears only its own snapshot state without waiting on printing, and a subsequent item added and sent ap… ✅ pass live ~/.no-mistakes/evidence/01M4YM7VD0QTC7H9WG5N18J4R7/server-app-order-sent-append.png and frontend/e2e/server-app-ordering.spec.ts ("freezes draft controls, pre-opened customizer, an…
Clicking Send twice in the same synchronous tick dispatches only a single POST /api/orders request and creates one order item mutation ✅ pass live frontend/e2e/server-app-ordering.spec.ts ("double Send in the same tick creates only one order mutation")
When a Send fails (including after backend commit with a lost response), the Server App retains the draft items, order notes, and frozen submission snapshot/idempotency key so retrying replays the ori… ✅ pass live ~/.no-mistakes/evidence/01M4YM7VD0QTC7H9WG5N18J4R7/server-app-failed-send-retained-draft.png and frontend/e2e/server-app-ordering.spec.ts ("retains draft and idempotency retry key…
Switching tables while a table order lookup is in flight ignores stale responses for the previous table, and a failed order lookup on an occupied table keeps Send disabled until the table's order look… ✅ pass live frontend/e2e/server-app-ordering.spec.ts ("retains draft and idempotency retry key after a failed send, and ignores stale table order responses")

Server App frozen state during in-flight Send (Sending... button disabled, product grid/draft/notes/customer/table/refresh controls disabled)
Server App after first Send completes and a second item is appended via Add to order
Server App retaining draft items and order notes with controls re-enabled after a failed Send

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.

  • Live validation: ✅ go - 5 of 5 scenarios driven live against the product
Scenario Result Live Evidence
While a Server App order Send is in flight, draft add/remove/edit/quantity controls, customer and notes inputs, table switching, and refresh are disabled in the UI and synchronously blocked by the in-… ✅ pass live ~/.no-mistakes/evidence/01M4YM7VD0QTC7H9WG5N18J4R7/server-app-sending-frozen.png and frontend/e2e/server-app-ordering.spec.ts ("freezes draft controls, pre-opened customizer, and t…
When a delayed Send completes while KOT printing is still in flight, the acknowledged submission clears only its own snapshot state without waiting on printing, and a subsequent item added and sent ap… ✅ pass live ~/.no-mistakes/evidence/01M4YM7VD0QTC7H9WG5N18J4R7/server-app-order-sent-append.png and frontend/e2e/server-app-ordering.spec.ts ("freezes draft controls, pre-opened customizer, an…
Clicking Send twice in the same synchronous tick dispatches only a single POST /api/orders request and creates one order item mutation ✅ pass live frontend/e2e/server-app-ordering.spec.ts ("double Send in the same tick creates only one order mutation")
When a Send fails (including after backend commit with a lost response), the Server App retains the draft items, order notes, and frozen submission snapshot/idempotency key so retrying replays the ori… ✅ pass live ~/.no-mistakes/evidence/01M4YM7VD0QTC7H9WG5N18J4R7/server-app-failed-send-retained-draft.png and frontend/e2e/server-app-ordering.spec.ts ("retains draft and idempotency retry key…
Switching tables while a table order lookup is in flight ignores stale responses for the previous table, and a failed order lookup on an occupied table keeps Send disabled until the table's order look… ✅ pass live frontend/e2e/server-app-ordering.spec.ts ("retains draft and idempotency retry key after a failed send, and ignores stale table order responses")
  • npm run build && npm run build:frontend
  • E2E_BASE_URL=http://127.0.0.1:43001 E2E_KDS_BASE_URL=http://127.0.0.1:43002 E2E_SERVER_APP_BASE_URL=http://127.0.0.1:43003 npx --prefix frontend playwright test --config=frontend/playwright.config.ts --project=chromium frontend/e2e/server-app-ordering.spec.ts
  • npm run test:server-app-server-role
  • Live Playwright browser capture against tests/e2e-server.cjs producing server-app-sending-frozen.png, server-app-order-sent-append.png, and server-app-failed-send-retained-draft.png
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

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.

⚙️ Run configuration
  • Configuration used: Repository: FreeOpenSourcePOS/FloCafe/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a97ebb86-4e3d-4ad1-97a6-d2c1fd9c691f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@khaira777

Copy link
Copy Markdown
Contributor Author

@greptile review

@greptile-apps

greptile-apps Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] Adds draft preservation logic during order send.

The PR needs a retry fix before merging because saving an unchanged edit can duplicate an order.

Findings

  1. P1 Unchanged edits duplicate orders ▶

Summary

The PR freezes draft controls during Send and keeps a snapshot of the submitted items, table, customer, and notes.

  • The Server App sends one saved draft and keeps it for a retry.
  • Draft controls stop changing the ticket while an order is sending.
  • Late order and login responses stay tied to the request that started them.

Reviews (5) · Last reviewed commit: "fix(server-app): preserve retry target a..." · Reviewed by Greptile

Comment thread frontend/src/app/server-standalone/page.tsx Outdated
Comment thread frontend/src/app/server-standalone/page.tsx
Comment thread frontend/e2e/server-app-ordering.spec.ts
@khaira777

Copy link
Copy Markdown
Contributor Author

@greptileai review

@khaira777
khaira777 force-pushed the codex/server-app-send-race branch from bf0f5e9 to dc3c78a Compare October 15, 2026 01:28
@khaira777

Copy link
Copy Markdown
Contributor Author

@greptileai review

1 similar comment
@khaira777

Copy link
Copy Markdown
Contributor Author

@greptileai review

@khaira777
khaira777 force-pushed the codex/server-app-send-race branch from dc3c78a to 7a2a2e2 Compare October 15, 2026 02:14
@khaira777

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread frontend/src/app/server-standalone/page.tsx Outdated
@khaira777

Copy link
Copy Markdown
Contributor Author

Greptile P1 addressed in ac92516: removed the eager sendAttemptRef.current = null clears from the draft/customer/notes mutation handlers. The pending attempt is now kept when the submitted content is unchanged; the signature comparison at the send path (page.tsx:819) decides when to replace it, and the attempt is cleared on a matched-signature success (page.tsx:870). Marking the thread resolved.

@khaira777
khaira777 merged commit 7dc3e8b into main Oct 15, 2026
23 checks passed
@khaira777
khaira777 deleted the codex/server-app-send-race branch October 15, 2026 05:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(server-app): freeze draft state during in-flight send to prevent item loss

1 participant