Commit Graph
8 Commits
Author SHA1 Message Date
lukasandClaude Sonnet 5 b7fdbd4779 Don't let a compensating payment call swallow the original error
Both placeOrder and cancelOrderItem call a compensating payment action
(refund / re-charge) after catching a failure, then rethrow. If that
compensating call itself threw, its error replaced the original one,
hiding the actual root cause behind whatever the payment provider
happened to fail with on the second attempt. Wrap each compensation in
its own try/catch, log the compensation failure, and always rethrow
the original error.

Also fixes a stale comment left over from renaming
createFirstStepForOrderItem to initializeOrderItemRecipe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 20:07:14 +02:00
lukasandClaude Sonnet 5 506319ce4f Refund before cancelling, not after, with compensation on failure
cancelOrderItem committed the cancellation (freeing the Machine slot,
marking the item cancelled) before calling the payment provider's
refund — so a refund failure (gateway timeout, provider outage) left
the item cancelled with no refund ever issued, and no record that one
was owed. placeOrder already avoids the equivalent problem by charging
before its DB transaction and refunding if the transaction then fails;
apply the same pattern here for consistency.

Refund now happens first; the DB transaction's atomic queued-status
check (added for the earlier cancellation race) doubles as the signal
that the refund needs to be undone if this transaction loses the race
or otherwise fails, so the catch block re-charges to compensate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 20:01:55 +02:00
lukasandClaude Sonnet 5 9c3ad51686 Freeze an Order Item's Recipe at order time
Price was already snapshotted per Order Item so later menu changes
don't rewrite history, but the Recipe (Step list) wasn't: advancing an
Order Item looked up its next Step from the live menuItemSteps table,
so an operator editing a Menu Item's Recipe mid-cook could silently
reshape an Order already in flight (different Machine Tag, duration,
or Step order than what the customer paid for).

Adds order_item_steps as a per-Order-Item copy of the Recipe, taken at
placement time; placeOrder, advanceOrderItemStep, and getOrderStatus
now all read from that snapshot instead of the live menu. Recorded as
docs/adr/0005 and added Recipe as a formal CONTEXT.md term.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 19:55:05 +02:00
lukasandClaude Sonnet 5 d291312139 Sharpen ordering domain model and close a cancellation race
CONTEXT.md described Order Item cancellability and Order completion
in ways the code didn't actually implement (cancellability only
covered the first Preparation Step; completion required pickup, not
any terminal state). Corrected the glossary to match intended
behavior, added Guest Access Token and Charge as formal terms, and
recorded the single-Charge-per-Order design as an ADR.

Also closes a real race in cancelOrderItem: a Machine could claim a
queued Step between the cancellability check and the delete, letting
an already-cooking item get cancelled and refunded. The delete now
atomically re-checks status = 'queued'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 19:48:04 +02:00
lukasandClaude Sonnet 5 456c3acda5 Implement ordering MVP domain layer per spec (issue #1)
Scaffolds the TanStack Start + Drizzle/Postgres + Better Auth app and
implements the core ordering domain: menu browsing, guest/account order
placement with online payment, per-Order-Item independent cooking and
cancellation, dynamic Machine-Tag pool assignment, and multi-step recipes
(see docs/adr/0001-0003). Adds a guest-access-token / session-based
ownership check on every read/mutation so an order can't be viewed,
cancelled, or picked up by anyone but its owner.

Covered by 14 tests running the domain layer directly against a real,
ephemeral Postgres (testcontainers) — createServerFn couldn't be called
outside a real request context, so tests exercise the domain functions the
server functions thinly wrap instead of the server functions themselves.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 18:46:58 +02:00
lukas e532a95f0b Merge pull request '🔧 update docs' (#2) from feat/update-docs into master
Reviewed-on: #2
2026-09-09 18:12:51 +02:00
lukas d2806818d2 🔧 update docs 2026-09-09 18:11:50 +02:00
lukas 9dee2a4013 🎉 initial commit 2026-09-09 17:49:49 +02:00