Phase 0 research resolves module placement (problem-management/problems confirmed dead/unwired, left untouched), Investigation's version-row-per- attempt shape, the strict investigation->root-cause->solution-> implementation->verification existence chain, why Resolution has no solutionId FK (matches doc06 exactly), why verification-failure escalation reuses 003/007's plain HUMAN_ESCALATION transition instead of adding an eleventh trigger type to 008's already-shipped escalation rules, the customer-facing route design (reusing 002's inbound trust boundary rather than fastify.authenticate), and the auto-close sweep design (the already-defined-but-unused CLEANUP queue, mirroring 008's breach-detection job). Phase 1 adds data-model.md, the admin/customer-facing contract, and six quickstart scenarios covering the full sequential workflow through customer confirmation, auto-close, and reopen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.1 KiB
4.1 KiB
Quickstart: Validating Problem Resolution
Prerequisites: migrations applied; a ticket created per 003-ticketing's own quickstart (this
feature works against its problemId).
Scenario 1 — structured investigation, preserved across attempts (User Story 1)
POST /admin/problems/:problemId/investigationswith findings/evidence/internalNotes. Expected:201, retrievable viaGET /admin/problems/:problemId/investigationswith every field intact.GET /problems/:problemId/investigations(customer-safe variant). Expected: same rows,internalNotesabsent from every one.- Record a second investigation for the same problem. Expected: both rows remain, in order — the first is never overwritten.
Scenario 2 — root cause requires an investigation on file (User Story 2)
POST /admin/problems/:problemId/root-causesfor a problem with no investigation. Expected:409.- Repeat after Scenario 1's investigation exists. Expected:
201,typeone of the five validated values. - Repeat with an invalid
type. Expected:400.
Scenario 3 — solution proposed, approved, implemented as distinct states (User Story 3)
POST /admin/problems/:problemId/solutionsbefore any root cause exists. Expected:409.- Repeat after Scenario 2's root cause exists. Expected:
201,approved: false. POST /admin/solutions/:solutionId/implementationbefore approval. Expected:409.PATCH /admin/solutions/:solutionId/approve, then repeat step 3. Expected:201.- Repeat step 3 again (a second implementation). Expected:
409.
Scenario 4 — verification, and what happens on failure (User Story 4)
POST /admin/solutions/:solutionId/verificationwithresult: success. Expected:201.- On a different solution (Scenario 3 repeated for a fresh problem), verify with
result: failed. Expected:201, but noResolutioncan be recorded referencing it (Scenario 5, step 1). - On the failed-verification path, request a fresh investigation. Expected: a new
Investigationrow for the same problem, the original untouched. - On the failed-verification path, request escalation instead. Expected: the ticket
transitions to
HUMAN_ESCALATION, and (007) is automatically assigned from that transition alone — no separate escalation call needed.
Scenario 5 — resolution, customer confirmation, and auto-close (User Story 5)
POST /admin/tickets/:ticketId/resolutionfor a ticket whose problem has no successfully verified solution. Expected:409.- Repeat once Scenario 4 step 1's successful verification exists. Expected:
201, ticket status becomesRESOLUTION_PENDING_CUSTOMER. POST /v1/support/tickets/:ticketId/confirm-resolutionwith the customer's own token. Expected:200, ticket status becomesRESOLVED.- Repeat steps 1-2 for a second ticket; instead of confirming, directly age the ticket's
updatedAtpast the configured waiting period and run the auto-close sweep. Expected: ticket status becomesRESOLVEDwithout any explicit confirmation call.
Scenario 6 — reopen (User Story 6)
POST /v1/support/tickets/:ticketId/reopenon theRESOLVEDticket from Scenario 5. Expected:200, ticket status becomesIN_PROGRESS(viaREOPENED).GET /tickets/:ticketId/resolution(or the admin equivalent). Expected: the originalResolutionrecord is still present, unchanged.- If the ticket has an
SLARun(008) from its original assignment, Expected: it is unchanged — no new run created, its status exactly what it was before the reopen. POST /admin/tickets/:ticketId/reopenon aCLOSEDticket, as an agent. Expected: sameREOPENED → IN_PROGRESSresult, this time attributed to the agent, not"customer".
What "done" looks like
All six scenarios pass, together demonstrating every functional requirement and success
criterion in spec.md — including SC-004's auto-close job cycle and SC-005's "reopen touches
nothing else" guarantee, both of which need direct-DB-state manipulation (not just waiting) to
verify without a multi-hour real-time test run.