Advance a test case to a known lifecycle state.
POST/test/cases/:id/advance
Drives a test case to a well-known lifecycle state in a single call.
Purpose: Enables CI pipelines and integrators to exercise the full collection lifecycle — including real webhooks and events — without manual intervention.
Target States:
Active— Activates the case from PendingVerification or PendingVerificationInternal. No-op if already Active or Closed.Closed:Paid— Records a payment foramountand closes the case as Paid. Activates the case first if needed.amountis required.Closed:NoPayment— Closes the case with PreLegalExhaustedNoPayment. Activates the case first if needed.
Guards:
- Returns 400 if the case is not a test case (Classification != Test).
- Returns 400 if
amountis missing whentoisClosed:Paid. - Returns 400 if
tois not one of the valid values. - Returns 400 if the case is already closed with a different close code (e.g. already Closed:NoPayment when requesting Closed:Paid).
- Returns 404 if the case is not found or not owned by the calling creditor.
No-op behaviour:
If the case is already at the requested state, the call returns 200 with advanced: false and the current state — no changes are made.
Webhooks: Transitions use the real internal service pipeline. Webhook delivery per target:
→ Active: firescase.updatedto Creditor subscriptions.→ Closed:Paid: firespayment.createdandcase.updatedandcase.closedto Creditor subscriptions.→ Closed:NoPayment: firescase.updatedandcase.closedto Creditor subscriptions.
All events carry classification: test and are only delivered to webhook subscriptions registered with classification: test.
How to Test:
-
Create a test case —
POST /caseswithisTest: trueandtag: suite-run-{uuid}. Note the returnedid. -
Register a test webhook subscription — subscribe to the events you want to assert on (
case.updated,payment.created,case.closed) withclassification: testand point the URL to your test receiver (e.g. a local ngrok tunnel or a CI webhook sink). -
Advance to Active —
POST /test/cases/{id}/advancewith{ "to": "Active" }. Expect{ advanced: true, state: "Active" }and acase.updatedevent on your Creditor subscription. -
Advance to Closed:Paid —
POST /test/cases/{id}/advancewith{ "to": "Closed:Paid", "amount": 1000.00 }. Expect{ advanced: true, state: "Closed:Paid" }and apayment.createdevent on your Creditor subscription. -
Verify final state —
GET /cases/{id}and assertlifecycle: ClosedandcloseCode: Paid. -
Test no-op — Call the same advance again. Expect
{ advanced: false, state: "Closed:Paid" }and no new webhook events. -
Test mismatch error — With the case closed as Paid, call
{ "to": "Closed:NoPayment" }. Expect 400 with a message describing the conflict. -
Assert webhooks —
GET /webhooks/events?caseId={id}to verify which events fired. -
Reset between runs —
DELETE /test/cases?tag=suite-run-{uuid}to clean up all cases created in this run.
Request
Responses
- 200
- 400
- 404
- 500
Advance result (advanced=true if state changed, advanced=false if already there)
Validation error — non-test case, missing amount, or unknown target state
Case not found or not owned by this creditor
Internal server error