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>
3.8 KiB
3.8 KiB
Contract: Problem Resolution
Agent-facing write routes are gated by fastify.authenticate (known limitation inherited from
002-008). Customer-facing routes are gated by fastify.authenticateProductIntegration +
fastify.checkIntegrationRateLimit (002's inbound trust boundary, research.md) and additionally
verify the caller's token identifies the same tenant/user as the ticket's own recorded
externalTenantId/externalUserId — a 403 if they don't match.
Investigation
POST /admin/problems/:problemId/investigations— body{ investigator, findings, evidence?, internalNotes?, status? }(statusdefaults toopen).404ifproblemIddoesn't exist.GET /admin/problems/:problemId/investigations— every investigation for the problem, newest first, includinginternalNotes(agent-facing).GET /problems/:problemId/investigations— customer/public-safe variant: same list, withinternalNotesalways omitted (FR-003).
Root Cause
POST /admin/problems/:problemId/root-causes— body{ type, description }.400iftypeisn't one of the five validated values.409if no investigation exists yet for the problem.
Solution
POST /admin/problems/:problemId/solutions— body{ proposed }.409if no root cause exists yet for the problem.PATCH /admin/solutions/:solutionId/approve— setsapproved: true.POST /admin/solutions/:solutionId/implementation— body{ notes?, implementedBy }.409if the solution isn't approved, or already has an implementation.POST /admin/solutions/:solutionId/verification— body{ method, result, evidence? }.400ifmethodisn't one of the four validated values.409if the solution has no implementation yet, or already has a verification.
Resolution
POST /admin/tickets/:ticketId/resolution— body{ outcome, resolvedBy }.409if the ticket's problem has no solution with a successful verification. Transitions the ticket toRESOLUTION_PENDING_CUSTOMERon success.POST /v1/support/tickets/:ticketId/confirm-resolution— customer-facing (trust boundary above).409if the ticket isn't inRESOLUTION_PENDING_CUSTOMER. Transitions toRESOLVED.
Reopen
POST /v1/support/tickets/:ticketId/reopen— customer-facing.409if the ticket isn'tRESOLVEDorCLOSED.POST /admin/tickets/:ticketId/reopen— agent-facing, same precondition.
Both reopen routes transition RESOLVED|CLOSED → REOPENED → IN_PROGRESS (research.md's two-hop
decision) and touch nothing else — no new SLARun, no mutation of any prior investigation/root-
cause/solution/verification/resolution record (FR-018, SC-005).
Guarantees (callable contract)
- Every investigation/root-cause/solution/implementation/verification/resolution record, once created, is retrievable exactly as given and is never silently overwritten by a later action in the same problem's lifecycle (SC-001).
internalNotesnever appears in a customer-facing investigation read, verified by a direct comparison against the agent-facing read of the same record (SC-002).- A
Resolutioncan never be recorded without a successfully verified solution already on file for the ticket's problem (SC-003). - A ticket in
RESOLUTION_PENDING_CUSTOMERwith no explicit confirmation reachesRESOLVEDwithin one auto-close job cycle of its configured waiting period elapsing (SC-004). - Reopening a ticket leaves every prior problem-resolution record and its
SLARun(008) untouched (SC-005). - A verification failure choosing escalation moves the ticket to
HUMAN_ESCALATIONthrough 003's existing state machine, and 007's orchestration re-runs automatically from that transition alone — no new escalation mechanism is introduced by this feature.