73 lines
4.1 KiB
Markdown
73 lines
4.1 KiB
Markdown
# 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.
|