Files
support_backend/specs/009-problem-resolution/quickstart.md
T
saqib mirandClaude Sonnet 5 9ce34d8ca4 plan: design for problem resolution feature (009)
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>
2026-09-03 14:37:42 +05:30

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)

  1. POST /admin/problems/:problemId/investigations with findings/evidence/internalNotes. Expected: 201, retrievable via GET /admin/problems/:problemId/investigations with every field intact.
  2. GET /problems/:problemId/investigations (customer-safe variant). Expected: same rows, internalNotes absent from every one.
  3. 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)

  1. POST /admin/problems/:problemId/root-causes for a problem with no investigation. Expected: 409.
  2. Repeat after Scenario 1's investigation exists. Expected: 201, type one of the five validated values.
  3. Repeat with an invalid type. Expected: 400.

Scenario 3 — solution proposed, approved, implemented as distinct states (User Story 3)

  1. POST /admin/problems/:problemId/solutions before any root cause exists. Expected: 409.
  2. Repeat after Scenario 2's root cause exists. Expected: 201, approved: false.
  3. POST /admin/solutions/:solutionId/implementation before approval. Expected: 409.
  4. PATCH /admin/solutions/:solutionId/approve, then repeat step 3. Expected: 201.
  5. Repeat step 3 again (a second implementation). Expected: 409.

Scenario 4 — verification, and what happens on failure (User Story 4)

  1. POST /admin/solutions/:solutionId/verification with result: success. Expected: 201.
  2. On a different solution (Scenario 3 repeated for a fresh problem), verify with result: failed. Expected: 201, but no Resolution can be recorded referencing it (Scenario 5, step 1).
  3. On the failed-verification path, request a fresh investigation. Expected: a new Investigation row for the same problem, the original untouched.
  4. 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)

  1. POST /admin/tickets/:ticketId/resolution for a ticket whose problem has no successfully verified solution. Expected: 409.
  2. Repeat once Scenario 4 step 1's successful verification exists. Expected: 201, ticket status becomes RESOLUTION_PENDING_CUSTOMER.
  3. POST /v1/support/tickets/:ticketId/confirm-resolution with the customer's own token. Expected: 200, ticket status becomes RESOLVED.
  4. Repeat steps 1-2 for a second ticket; instead of confirming, directly age the ticket's updatedAt past the configured waiting period and run the auto-close sweep. Expected: ticket status becomes RESOLVED without any explicit confirmation call.

Scenario 6 — reopen (User Story 6)

  1. POST /v1/support/tickets/:ticketId/reopen on the RESOLVED ticket from Scenario 5. Expected: 200, ticket status becomes IN_PROGRESS (via REOPENED).
  2. GET /tickets/:ticketId/resolution (or the admin equivalent). Expected: the original Resolution record is still present, unchanged.
  3. 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.
  4. POST /admin/tickets/:ticketId/reopen on a CLOSED ticket, as an agent. Expected: same REOPENED → IN_PROGRESS result, 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.