Files
support_backend/specs/007-orchestration-assignment/data-model.md
T
saqib mirandClaude Sonnet 5 846b9e8dca docs: plan and design artifacts for orchestration and assignment feature
Maps the feature onto the three existing orchestration/{routing,
assignments,orchestration} scaffold stubs. Key decisions: Assignment
refined as a version-row-per-period model (paired with a separate
append-only AssignmentHistory event log), round-robin concurrency
safety via atomic Redis INCR (reusing existing infra, not a new one),
LEAST_LOADED/SKILL_BASED tie-breaks falling back to that same cursor,
currentLoad read but never mutated by this feature, and the escalation
trigger reusing 005's existing domain-event bus rather than a new
notification path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 11:30:23 +05:30

2.8 KiB

Phase 1 Data Model: Orchestration and Assignment

All new models use cuid() ids. Refines docs/06-database-schema.md's conceptual Assignment/ AssignmentHistory shapes (research.md).

Assignment

Field Type Notes
id String @id @default(cuid())
ticketId String FK → Ticket. Not unique — one row per assignment period (research.md)
agentId String FK → Agent
strategy String ROUND_ROBIN | LEAST_LOADED | SKILL_BASED | MANUAL | DIRECT
reason String? Free text — required-in-practice for MANUAL/DIRECT, optional for automatic strategies
isCurrent Boolean @default(true) Exactly one true row per ticketId at a time — set false when superseded
assignedAt DateTime @default(now())
unassignedAt DateTime? Set when superseded by a later assignment

Constraints: Index on (ticketId, isCurrent) — the exact shape "the current assignment for this ticket" queries on. No DB-level unique on (ticketId, isCurrent: true) (Postgres partial unique indexes aren't expressed directly in this Prisma version's schema syntax used elsewhere in this codebase) — enforced instead by the repository's single transaction that supersedes the prior row and inserts the new one together (same class of guarantee as 004's conditional-update-then-insert).

AssignmentHistory

Field Type Notes
id String @id @default(cuid())
ticketId String FK → Ticket
agentId String? Null for a no eligible agent outcome (FR-008)
action String assigned | reassigned | unassigned
strategy String Same value set as Assignment.strategy
reason String?
actor String system (automatic orchestration) or an admin/agent identifier (manual)
createdAt DateTime @default(now())

Never updated or deleted — this is the append-only audit trail FR-009/SC-003/SC-004 require. Written in the same transaction as the Assignment row it corresponds to (or on its own, for a "no eligible agent" outcome that produces no Assignment row at all).

Ticket / Agent (relations added by this feature)

Ticket.assignments Assignment[], Ticket.assignmentHistory AssignmentHistory[], Agent.assignments Assignment[] — forward relations doc 06 already implied but that couldn't be added until these models existed (same pattern every prior feature has used for its own new back-relations).

No new fields on HierarchyNode or AgentAvailability

Round-robin's cursor lives in Redis, not Postgres (research.md) — no schema change to either model 006-support-organization already shipped. AgentAvailability.currentLoad is read, never written, by this feature (research.md) — no new mutation path added to it here.