Skip to content

Domain Specification: Case Management

Validated against PRD v1.0 — All FR-CM-* requirements implemented here. See Traceability Matrix.


1. Context Overview

Bounded Context: casemanagement
Responsibility: Manage investigation cases — lifecycle, assignment, evidence, notes, escalation, decisions. Single-pane analyst workspace.
Owns: Case aggregate root.
Depends On: Workflow Orchestration (case creation, state sync), RBAC (role-based access), Notification (alerts), Audit (logging).
Events Published: CaseCreated, CaseAssigned, NoteAdded, EvidenceAttached, DecisionMade, CaseClosed.


2. Case Lifecycle

stateDiagram-v2
    [*] --> CREATED
    CREATED --> ASSIGNED : auto/supervisor assigns
    ASSIGNED --> IN_PROGRESS : analyst starts work
    IN_PROGRESS --> PENDING_REVIEW : analyst submits
    IN_PROGRESS --> ESCALATED : risk/sanctions/PEP trigger
    IN_PROGRESS --> WAITING_EXTERNAL : document requested
    PENDING_REVIEW --> DECIDED : reviewer decides
    DECIDED --> CLOSED : audit check
    ESCALATED --> IN_PROGRESS : escalation handled
    WAITING_EXTERNAL --> IN_PROGRESS : docs received
From To Trigger Actor
CREATED ASSIGNED Case auto-assigned or supervisor assigns System / Supervisor
ASSIGNED IN_PROGRESS Analyst opens and starts work Analyst
IN_PROGRESS PENDING_REVIEW Analyst submits for review Analyst
IN_PROGRESS ESCALATED Escalation triggered (risk score, sanctions hit, PEP) System
PENDING_REVIEW DECIDED Reviewer makes decision Reviewer
DECIDED CLOSED Final audit check complete System
Any WAITING_EXTERNAL Document requested from customer Analyst

3. API Contracts

3.1 Get Analyst Queue

GET /api/v1/cases?status=ASSIGNED,IN_PROGRESS&assignedTo={userId}&page=1&limit=20
Authorization: Bearer <jwt>

Response 200:
{
  "items": [
    {
      "caseId": "uuid",
      "caseType": "ONBOARDING_REVIEW",
      "customerName": "ACME Holdings B.V.",
      "customerType": "CORPORATE",
      "riskBand": "MEDIUM",
      "state": "ASSIGNED",
      "priority": "MEDIUM",
      "escalationLevel": 0,
      "slaDeadline": "2025-06-02T12:00:00Z",
      "slaRemaining": "18h 30m",
      "createdAt": "2025-06-01T10:00:00Z",
      "tags": ["PEP_EXPOSURE"]
    }
  ],
  "total": 12,
  "page": 1
}

3.2 Get Case Detail (Analyst Workspace)

GET /api/v1/cases/{caseId}
Authorization: Bearer <jwt>

Response 200:
{
  "caseId": "uuid",
  "caseType": "ONBOARDING_REVIEW",
  "state": "IN_PROGRESS",
  "customer": { /* full customer profile */ },
  "riskAssessment": { /* current risk rating */ },
  "screeningResults": [ /* all screening results */ ],
  "ownershipGraph": { /* network analysis output */ },
  "documents": [ /* all uploaded documents */ ],
  "notes": [
    { "noteId": "uuid", "author": "KYC Analyst", "content": "...", "createdAt": "..." }
  ],
  "decisions": [ /* decisions made so far */ ],
  "auditTrail": [ /* recent audit events */ ],
  "availableActions": ["ADD_NOTE", "REQUEST_DOCUMENT", "APPROVE", "REJECT", "ESCALATE"]
}

3.3 Add Case Note

POST /api/v1/cases/{caseId}/notes
Authorization: Bearer <jwt>

Request: { "content": "Verified UBO structure. All beneficial owners identified. Ownership chain matches corporate registry." }
Response 201: { "noteId": "uuid", "createdAt": "2025-06-01T13:00:00Z" }

3.4 Reassign Case

PATCH /api/v1/cases/{caseId}
Authorization: Bearer <jwt> (SUPERVISOR role required)

Request: { "assignedTo": "user-uuid", "reason": "Workload balancing — Analyst A has 15 cases, Analyst B has 5" }
Response 200: { "caseId": "uuid", "assignedTo": "user-uuid", "reassignedAt": "2025-06-01T14:00:00Z" }

3.5 Make Decision

POST /api/v1/cases/{caseId}/decisions
Authorization: Bearer <jwt>
Idempotency-Key: <uuid>

Request:
{
  "decisionType": "APPROVED",
  "rationale": "All KYC checks passed. Screening clear. Risk MEDIUM — acceptable for lending product."
}
Response 201: { "decisionId": "uuid", "caseState": "DECIDED" }

3.6 Supervisor Dashboard

GET /api/v1/cases/summary?supervisorId={userId}
Authorization: Bearer <jwt>

Response 200:
{
  "teamStats": [
    { "analystId": "uuid", "name": "Jane Doe", "activeCases": 8, "avgAgeHours": 12.5, "slaBreachRisk": 1 },
    { "analystId": "uuid", "name": "John Smith", "activeCases": 15, "avgAgeHours": 28.3, "slaBreachRisk": 3 }
  ],
  "totalCases": 23,
  "byState": { "ASSIGNED": 5, "IN_PROGRESS": 12, "PENDING_REVIEW": 4, "ESCALATED": 2 },
  "slaAtRisk": 4,
  "slaBreached": 1
}

4. Escalation Model

Level Role Trigger Examples SLA
L1 KYC Analyst Standard review, document validation 24h
L2 Senior Analyst Ownership complexity >3 levels, identity mismatch, analyst uncertainty 12h
L3 EDD Analyst HIGH risk band, PEP exposure, sanctions POTENTIAL_MATCH 48h
L4 FCC Reviewer Policy exception, sanctions CONFIRMED_MATCH, prohibited jurisdiction 24h
L5 Executive / Legal Critical sanctions, law enforcement request, executive override 8h

Escalation chain preserved in audit trail. Each escalation level records: who escalated, to whom, timestamp, reason.


5. Error Handling

Scenario Behavior
Reassign to self 400 Bad Request. "Cannot reassign case to yourself."
Approve own escalation (SoD) 403 Forbidden. "Analyst who investigated cannot approve. Escalate to FCC Reviewer."
Close without decision 422 Unprocessable. "Case must have at least one decision before closing."
SLA breached without action Auto-escalates to supervisor queue. Notification sent.
Case not found 404. "Case {id} not found or you do not have access."

Spec validated against PRD v1.0 requirements FR-CM-01 through FR-CM-05.