# Data Model: Problem Resolution Every model below matches `docs/06-database-schema.md` "Domain: Problem Resolution" field-for- field — no new columns invented (research.md explains the two places this was deliberately considered and rejected: `Resolution.solutionId`, `Investigation.isCurrent`). ## Investigation | Field | Type | Notes | |---|---|---| | `id` | `String @id @default(cuid())` | | | `problemId` | `String` | FK to `Problem.id` (the existing `ticketing/tickets` one) | | `investigator` | `String` | agentId — same non-FK free-text convention as `TicketMessage.authorRef` | | `findings` | `Json` | structured, not free text (doc 04 §4) | | `evidence` | `Json?` | | | `internalNotes` | `String?` | never exposed on any customer-facing read (FR-003) | | `status` | `String` | `open \| complete` | | `createdAt` | `DateTime @default(now())` | ordering field for "most recent investigation" (research.md — no `isCurrent` flag) | ## RootCause | Field | Type | Notes | |---|---|---| | `id` | `String @id @default(cuid())` | | | `problemId` | `String` | FK to `Problem.id` | | `type` | `String` | `technical \| configuration \| external_dependency \| business \| contributing_factor` — validated, not free text (FR-005) | | `description` | `String` | | | `createdAt` | `DateTime @default(now())` | | ## Solution | Field | Type | Notes | |---|---|---| | `id` | `String @id @default(cuid())` | | | `problemId` | `String` | FK to `Problem.id` | | `proposed` | `String` | | | `approved` | `Boolean @default(false)` | explicit approval action (FR-007) | | `createdAt` | `DateTime @default(now())` | | | `implementation` | `SolutionImplementation?` | inverse of the 1:1 below | | `verification` | `SolutionVerification?` | inverse of the 1:1 below | ## SolutionImplementation | Field | Type | Notes | |---|---|---| | `id` | `String @id @default(cuid())` | | | `solutionId` | `String @unique` | 1:1 with `Solution` — a second implementation attempt is rejected (FR-007 Edge Cases), not overwritten | | `notes` | `String?` | | | `implementedBy` | `String` | agentId | | `implementedAt` | `DateTime @default(now())` | | ## SolutionVerification | Field | Type | Notes | |---|---|---| | `id` | `String @id @default(cuid())` | | | `solutionId` | `String @unique` | 1:1 with `Solution` — at most one verification per solution (data-model note in Edge Cases) | | `method` | `String` | `automated \| technical_test \| customer_confirmation \| agent_confirmation` — validated (FR-011) | | `result` | `String` | `success \| failed` | | `evidence` | `Json?` | | | `verifiedAt` | `DateTime @default(now())` | | ## Resolution | Field | Type | Notes | |---|---|---| | `id` | `String @id @default(cuid())` | | | `ticketId` | `String @unique` | one resolution per ticket | | `outcome` | `String` | | | `resolvedBy` | `String` | `"ai"` or agentId | | `resolvedAt` | `DateTime @default(now())` | | No `solutionId` FK here (research.md) — the "a successfully verified solution exists for this ticket's problem" precondition (FR-014) is enforced by the service layer at write time via a join through `Ticket.problemId → Solution.problemId → Solution.verification.result`, not stored. ## Relations added to existing models - `Problem.investigations Investigation[]`, `Problem.rootCauses RootCause[]`, `Problem.solutions Solution[]` (all on the existing `ticketing/tickets`-owned `Problem` model) - `Ticket.resolution Resolution?` (inverse of `Resolution.ticketId @unique`) ## Validation chain (service layer, not DB constraints — matches 003's own state-machine convention) 1. `RootCause` create → `Problem` must have at least one `Investigation` (FR-006). 2. `Solution` create → `Problem` must have at least one `RootCause` (FR-009). 3. `SolutionImplementation` create → the `Solution` must have `approved: true` (FR-008), and must not already have an implementation (unique constraint surfaces this as a conflict). 4. `SolutionVerification` create → the `Solution` must already have a `SolutionImplementation` (verification is of something implemented, doc 04 §7). 5. `Resolution` create → the `Ticket`'s `Problem` must have at least one `Solution` whose `verification.result === 'success'` (FR-014). ## Out of scope for this data model (per spec.md Assumptions) - No new `EscalationRule.triggerType` value for verification failure (research.md — reuses the plain `HUMAN_ESCALATION` status transition instead). - No `ResolutionPolicy`/scoped auto-close configuration entity — one system-wide config value (research.md).