mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-01 15:53:27 +00:00
Add a minimal payment mock server for end-to-end testing
This commit is contained in:
@@ -139,3 +139,47 @@ cast past the type checker (`last-mile-invoice.service.ts:41`), while
|
||||
varchar with no constraint, so both spellings persist. Writes and reads agree
|
||||
within each module so billing works — but S39's "invoice source LASTMILE"
|
||||
assertion must match `'last_mile'`, not the enum value.
|
||||
|
||||
## Two engine changes the committed specs predate
|
||||
|
||||
Both were found by running the suite, and both broke EVERY scenario until
|
||||
fixed. They are recorded here because neither is visible from the scenario
|
||||
document — only from the API source.
|
||||
|
||||
**1. Every contract booking is born in the clearance gate.**
|
||||
`contract-booking.service.ts:211` — *"EVERY contract booking clears per booking
|
||||
now — both contract kinds, both paths, intercity included."* A booking is
|
||||
created in `AWAITING_DOCUMENTS` regardless of whether customs clearance is
|
||||
enabled, so `bookContainers` followed by `acceptOperation` always 409s with
|
||||
`Cannot perform this action on status "AWAITING_DOCUMENTS". Allowed:
|
||||
OPERATION_REQUEST_PENDING`.
|
||||
|
||||
The gate is upload → GL approve → finalize → customer proceeds with the day.
|
||||
`clearToOperationRequestPending` (import-utils) runs it; `bookAndClear`
|
||||
(g1-utils) wraps book + clear + accept and is what the g-specs use.
|
||||
|
||||
NOTE: the pre-existing corridor specs (e.g. `import_full_train.cy.ts`) still
|
||||
call `acceptOperation` directly and fail for this reason — 3 passing / 10
|
||||
failing when last run. They predate the gate and need the same treatment.
|
||||
|
||||
**2. An unpaid hold cannot expire without a reachable payment gateway.**
|
||||
Before expiring a reservation the engine asks the gateway whether a late
|
||||
payment landed (`booking-batch.service.ts:3484-3506`), and treats ANY error as
|
||||
`unverifiable: true` — deferring the expiry rather than risk expiring a
|
||||
customer who paid:
|
||||
|
||||
[BATCH] expire deferred for BK-… — settlement unverifiable at the
|
||||
gateway; retrying next settle tick
|
||||
|
||||
`PAYMENT_API_URL` defaults to the real `https://paymentcallback.triaplc.com`
|
||||
(`payment-client.service.ts:25`), unreachable from e2e, so every expiry
|
||||
deferred forever. Six scenarios turn on an expiry: G1·S1, G1·S5, G1·S6,
|
||||
G3·S16, G5·S22, G5·S24.
|
||||
|
||||
Fixed with a stand-in service — `e2e/freight/payment-mock/server.js`, wired as
|
||||
`payment-mock-e2e` in `docker-compose.e2e.yaml` with
|
||||
`PAYMENT_API_URL: http://payment-mock-e2e:4500`. It answers
|
||||
`POST /payments/reconcile` with `{paid:false, unverifiable:false}` so the
|
||||
engine gets a definite "no payment exists" and expires the hold as designed.
|
||||
A stack that does NOT point PAYMENT_API_URL at a reachable service will hang
|
||||
on every expiry assertion.
|
||||
|
||||
Reference in New Issue
Block a user