Assignments Data Model
1. Executive Summary
Purpose
The assignments domain provides a unified framework for tracking two structurally related but behaviorally distinct concepts within the financial workflow. Task assignments are one-off work items attached to transactional entities such as cash receipts, cash receipt splits, and outbound payments; they represent specific actions a user must complete (e.g., "Resolve unmatched deposit," "Follow up on held payment"), support multiple assignees per entity, and progress through a forward-only status lifecycle. Responsibility assignments are long-lived ownership records that associate a single accountable person with a business entity at any level of the organizational hierarchy — department, client, buyer, deal, meta-data pair, sales item, or payment term. Exactly one active responsibility exists per entity at any time; when ownership changes, the system deactivates the old record and creates a new one, preserving a full transfer audit trail in assignment_history.
Responsibility assignments also participate in a four-level hierarchy resolution mechanism. When a downstream entity has no direct responsibility assignment, the system walks up the hierarchy to find the responsible person at a broader level: Sales Item / Payment Term (Level 4) → Deal / Meta-Data Pair (Level 3) → Client / Buyer (Level 2) → Department (Level 1).
Scope
Covered:
assignment— Primary record for both task and responsibility assignments. Uses a polymorphic entity reference pattern to associate with any supported entity type.assignment_history— Immutable append-only audit log recording every creation, transfer, status change, deactivation, and cancellation event against an assignment.
Not covered (documented separately):
- Cash receipts, splits, and payment items that assignments reference as entity targets — see Cash Receipts Data Model, Worksheets Data Model, and Settlements Data Model.
- Parties, departments, deals, and sales items that form the responsibility hierarchy — see Parties Data Model and Deals, Sales Items & Payment Terms Data Model.
2. Data Model
2.1 Entity-Relationship Diagram
erDiagram
users {
int user_id PK
varchar email
varchar first_name
varchar last_name
}
assignment {
uuid assignment_id PK
varchar assignment_type_cd
varchar entity_type_cd
int entity_id
varchar entity_reference
varchar meta_data_type_cd
varchar meta_data_value
date meta_data_date_value
int assigned_to_user_id FK
varchar task_status_cd
varchar task_title
date start_dt
date end_dt
boolean is_active_ind
}
assignment_history {
uuid assignment_history_id PK
uuid assignment_id FK
varchar action_cd
int from_user_id FK
int to_user_id FK
varchar from_status_cd
varchar to_status_cd
text comment_text
int action_by_user_id FK
timestamp action_dt
}
assignment ||--o{ assignment_history : "has history"
users ||--o{ assignment : "assigned to"
users ||--o{ assignment_history : "from user"
users ||--o{ assignment_history : "to user"
users ||--o{ assignment_history : "action by"The assignment table does not carry database-enforced foreign keys to the entities it references. Instead it uses a polymorphic pattern where entity_type_cd declares the entity type and entity_id or entity_reference holds the identifier. The following diagram illustrates the logical (non-enforced) associations:
erDiagram
assignment {
varchar entity_type_cd
int entity_id
varchar entity_reference
}
department { int department_id PK }
party_client { int party_id PK }
party_buyer { int party_id PK }
deal { varchar deal_reference PK }
sales_item { varchar sales_item_reference PK }
payment_term { varchar payment_term_reference PK }
cash_receipt { int cash_receipt_id PK }
cash_receipt_split { int cash_receipt_split_id PK }
payment_item { int payment_item_id PK }
assignment }o..|| department : "DEPARTMENT"
assignment }o..|| party_client : "CLIENT"
assignment }o..|| party_buyer : "BUYER"
assignment }o..|| deal : "DEAL"
assignment }o..|| sales_item : "SALES_ITEM"
assignment }o..|| payment_term : "PAYMENT_TERM"
assignment }o..|| cash_receipt : "CASH_RECEIPT"
assignment }o..|| cash_receipt_split : "CASH_RECEIPT_SPLIT"
assignment }o..|| payment_item : "PAYMENT"NOTE
These are logical associations, not database-enforced foreign keys. The polymorphic pattern trades referential integrity enforcement for the flexibility to associate assignments with a wide variety of entity types without requiring one join table per type.
2.2 assignment
The primary record for both task and responsibility assignments. A single assignment_type_cd discriminator (TASK or RESPONSIBILITY) determines which fields are relevant and which business rules apply.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
assignment_id | uuid | Yes | Random UUID | Primary key. |
assignment_type_cd | varchar(20) | Yes | — | Discriminator: TASK or RESPONSIBILITY. See Section 5.1. |
entity_type_cd | varchar(50) | Yes | — | The kind of entity this assignment targets. See Section 5.2. |
entity_id | integer | No | — | FK to the entity when it uses an integer primary key (department, client, buyer, cash receipt, cash receipt split, payment item). Mutually exclusive with entity_reference for most entity types. |
entity_reference | varchar(500) | No | — | String-based reference for entities that use non-integer identifiers (deal reference, sales item reference, payment term reference). Mutually exclusive with entity_id for most entity types. |
meta_data_type_cd | varchar(50) | No | — | Only populated when entity_type_cd = META_DATA_PAIR. Identifies the meta-data attribute type (e.g., genre, territory, show type). |
meta_data_value | varchar(500) | No | — | Only populated when entity_type_cd = META_DATA_PAIR. The value of the meta-data attribute. |
meta_data_date_value | date | No | — | Only populated when entity_type_cd = META_DATA_PAIR. An optional date associated with the meta-data pair. |
assigned_to_user_id | integer | Yes | — | FK to users.user_id. The person currently assigned. For responsibilities, this is the single accountable owner. For tasks, this is one of potentially many assignees. |
task_status_cd | varchar(20) | No | — | Current status of a task assignment. Null for RESPONSIBILITY type. Required for TASK type; initialized to OPEN on creation. See Section 3.1. |
task_title | varchar(500) | No | — | Short description of the task. Required for TASK type; null for RESPONSIBILITY type. |
start_dt | date | No | — | Optional start date for task assignments. Not used for responsibilities. |
end_dt | date | No | — | Optional due date for task assignments. Not used for responsibilities. |
is_active_ind | boolean | Yes | true | Active indicator. For RESPONSIBILITY type: set to false when the responsibility is transferred (deactivated in favor of a new record). For TASK type: always true; lifecycle is managed via task_status_cd instead. |
NOTE
Pure audit columns (created_by, created_dt, updated_by, updated_dt) are present on this table. They are omitted from the table above because they carry no business meaning beyond standard audit tracking.
Indexes:
| Index Name | Columns | Purpose |
|---|---|---|
assignment_assigned_to_user_id_idx | assigned_to_user_id | Look up all assignments for a given user. |
assignment_entity_type_id_idx | entity_type_cd, entity_id | Responsibility resolution and entity lookups for integer-keyed entities. |
assignment_entity_type_ref_idx | entity_type_cd, entity_reference | Responsibility resolution and entity lookups for string-referenced entities. |
assignment_type_active_idx | assignment_type_cd, is_active_ind | Filter active responsibilities efficiently. |
assignment_task_status_idx | task_status_cd | Filter tasks by status (e.g., find all open tasks). |
assignment_meta_data_idx | meta_data_type_cd, meta_data_value | Look up assignments for meta-data pair entities. |
2.3 assignment_history
An immutable append-only audit trail. Every change to an assignment — creation, transfer, status transition, deactivation, or cancellation — produces exactly one history record. Records are never updated or deleted.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
assignment_history_id | uuid | Yes | Random UUID | Primary key. |
assignment_id | uuid | Yes | — | FK to assignment.assignment_id. Cascades on delete. Identifies which assignment this history entry belongs to. |
action_cd | varchar(50) | Yes | — | The type of action recorded. See Section 5.4. Valid values: ASSIGNED, REASSIGNED, STATUS_CHANGED, DEACTIVATED, CANCELLED. |
from_user_id | integer | No | — | FK to users.user_id. The previous assignee. Populated for REASSIGNED and DEACTIVATED actions; null for initial ASSIGNED actions. |
to_user_id | integer | No | — | FK to users.user_id. The new assignee. Populated for ASSIGNED and REASSIGNED actions. |
from_status_cd | varchar(20) | No | — | Previous task status. Populated for STATUS_CHANGED and CANCELLED actions. |
to_status_cd | varchar(20) | No | — | New task status. Populated for STATUS_CHANGED and CANCELLED actions. |
comment_text | text | No | — | Free-text reason or context for the change. Used for transfer justifications, cancellation reasons, or general notes. |
action_by_user_id | integer | Yes | — | FK to users.user_id. The user who performed the action (not necessarily the assignee). Always populated. |
action_dt | timestamp | Yes | Current timestamp | When the action occurred. |
3. Status Lifecycle
3.1 Task Status
Task assignments follow a forward-only status progression. Once a task reaches a terminal state (COMPLETE or CANCELLED), no further transitions are permitted.
| Status | Code | Description | Allowed Transitions |
|---|---|---|---|
| Open | OPEN | Task has been created and assigned but work has not begun. | → Working (WORKING), → Cancelled (CANCELLED) |
| Working | WORKING | The assignee is actively working on the task. | → Waiting (WAITING), → Complete (COMPLETE), → Cancelled (CANCELLED) |
| Waiting | WAITING | The task is paused, pending external input or a dependency. | → Working (WORKING), → Cancelled (CANCELLED) |
| Complete | COMPLETE | The task has been successfully finished. Terminal state. | — |
| Cancelled | CANCELLED | The task has been abandoned, superseded, or cancelled due to sibling completion. Terminal state. | — |
stateDiagram-v2
[*] --> OPEN : Task created
OPEN --> WORKING : Begin work
OPEN --> CANCELLED : Cancel before starting
WORKING --> WAITING : Blocked on dependency
WORKING --> COMPLETE : Finish
WORKING --> CANCELLED : Abandon
WAITING --> WORKING : Unblocked
WAITING --> CANCELLED : AbandonTransition: OPEN → WORKING
- Trigger: Assignee begins work on the task.
- Preconditions: Task must be in
OPENstatus. - Side-effects:
assignment_historyrow inserted withaction_cd=STATUS_CHANGED,from_status_cd=OPEN,to_status_cd=WORKING.
Transition: OPEN → CANCELLED
- Trigger: User cancels the task before work begins, or sibling task is completed (see Sibling Cancellation below).
- Preconditions: Task must be in
OPENstatus. - Side-effects:
assignment_historyrow inserted withaction_cd=CANCELLED,from_status_cd=OPEN,to_status_cd=CANCELLED.
Transition: WORKING → WAITING
- Trigger: Assignee marks the task as blocked pending external input.
- Preconditions: Task must be in
WORKINGstatus. - Side-effects:
assignment_historyrow inserted withaction_cd=STATUS_CHANGED,from_status_cd=WORKING,to_status_cd=WAITING.
Transition: WORKING → COMPLETE
- Trigger: Assignee marks the task as finished.
- Preconditions: Task must be in
WORKINGstatus. - Side-effects:
assignment_historyrow inserted withaction_cd=STATUS_CHANGED,from_status_cd=WORKING,to_status_cd=COMPLETE. Optionally triggers sibling cancellation (see below).
Transition: WORKING → CANCELLED
- Trigger: User abandons the task, or sibling task is completed.
- Preconditions: Task must be in
WORKINGstatus. - Side-effects:
assignment_historyrow inserted withaction_cd=CANCELLED,from_status_cd=WORKING,to_status_cd=CANCELLED.
Transition: WAITING → WORKING
- Trigger: Blocking dependency is resolved; assignee resumes work.
- Preconditions: Task must be in
WAITINGstatus. - Side-effects:
assignment_historyrow inserted withaction_cd=STATUS_CHANGED,from_status_cd=WAITING,to_status_cd=WORKING.
Transition: WAITING → CANCELLED
- Trigger: User abandons the blocked task, or sibling task is completed.
- Preconditions: Task must be in
WAITINGstatus. - Side-effects:
assignment_historyrow inserted withaction_cd=CANCELLED,from_status_cd=WAITING,to_status_cd=CANCELLED.
NOTE
Sibling Cancellation: When a task reaches COMPLETE, the system can optionally cancel all sibling tasks for the same entity. Sibling tasks are defined as other TASK-type assignments with the same entity_type_cd and entity key (entity_id or entity_reference) that are not yet in a terminal state. Only tasks whose current status permits a transition to CANCELLED are affected; tasks already in COMPLETE or CANCELLED are skipped. This prevents duplicate work when multiple users hold the same task and one finishes first.
3.2 Responsibility Lifecycle
Responsibility assignments do not use task_status_cd. Their lifecycle is governed entirely by is_active_ind.
| Status | is_active_ind | Description | Allowed Transitions |
|---|---|---|---|
| Active | true | Current responsibility holder for the entity. Exactly one active responsibility exists per entity at any given time. | → Inactive (via transfer) |
| Inactive | false | Responsibility has been superseded by a transfer. Record is preserved for audit purposes with original data intact. | — |
stateDiagram-v2
[*] --> Active : Responsibility created
Active --> Inactive : Transfer to new personTransition: Active → Inactive (Responsibility Transfer)
- Trigger: User transfers responsibility to a different person.
- Preconditions: The assignment must be in
RESPONSIBILITYtype andis_active_ind=true. The new assignee must differ from the current assignee. - Side-effects:
- Existing
assignmentrecord:is_active_indset tofalse. assignment_historyrow inserted against the old assignment withaction_cd=DEACTIVATED,from_user_id= previous owner, optionalcomment_textwith transfer reason.- New
assignmentrow created withis_active_ind=true,assigned_to_user_id= new owner, all entity key fields copied from the old record. assignment_historyrow inserted against the new assignment withaction_cd=REASSIGNED,from_user_id= previous owner,to_user_id= new owner, optionalcomment_text.
- Existing
4. Validation & Database Constraints
Unique Constraints
| Table | Constraint | Columns | Business Rule |
|---|---|---|---|
assignment | Application-layer only | assignment_type_cd, entity_type_cd, entity key, is_active_ind | Exactly one active RESPONSIBILITY assignment may exist per (entity_type_cd + entity key) combination at any time. The entity key is entity_id for integer-keyed types, entity_reference for string-referenced types, or meta_data_type_cd + meta_data_value for META_DATA_PAIR. |
IMPORTANT
The responsibility uniqueness constraint is enforced at the application layer, not as a database unique index, because the composite key varies by entity type. The service layer checks for an existing active responsibility before creating a new one and rejects the operation if a duplicate would result. Transfers are the correct mechanism for changing ownership — direct creation of a second active responsibility is not permitted.
Business Validation
- Task multiplicity allowed: Multiple
TASK-type assignments are explicitly permitted for the same entity. This supports scenarios where several users are independently assigned to work on the same cash receipt, split, or payment. - Assignment type discriminator:
assignment_type_cdmust beTASKorRESPONSIBILITY. Only these two values are recognized. - Entity type codes:
entity_type_cdmust match one of the ten defined entity type codes. See Section 5.2. - Task status required for tasks:
task_status_cdis required whenassignment_type_cd=TASK. Initialized toOPENon creation. - Task title required for tasks:
task_titleis required whenassignment_type_cd=TASK(minimum length 1). - Task status null for responsibilities:
task_status_cdmust be null whenassignment_type_cd=RESPONSIBILITY. - Meta-data pair fields required for meta-data entities:
meta_data_type_cdandmeta_data_valuemust be populated whenentity_type_cd=META_DATA_PAIR. - Entity key required: At least one of
entity_id,entity_reference, or (meta_data_type_cd+meta_data_value) must be populated. Assignments must reference a specific entity. - Task status transitions are forward-only: Invalid transitions (e.g.,
COMPLETE→OPEN) are rejected by the service layer. See Section 3.1 for the allowed state machine. - Transfer only applies to active responsibilities: Transferring an inactive (already superseded) responsibility is rejected.
- Self-transfer rejected: The new assignee on a transfer must differ from the current assignee.
Referential Integrity
| FK Column | References | On Delete | Notes |
|---|---|---|---|
assignment.assigned_to_user_id | users.user_id | Restrict | Every assignment must have a valid assignee. |
assignment_history.assignment_id | assignment.assignment_id | Cascade | Deleting an assignment removes its history. In practice, assignments are not deleted — they are deactivated or reach terminal status. |
assignment_history.from_user_id | users.user_id | Restrict | Optional reference to the previous assignee. |
assignment_history.to_user_id | users.user_id | Restrict | Optional reference to the new assignee. |
assignment_history.action_by_user_id | users.user_id | Restrict | The user who performed the action. Always populated. |
IMPORTANT
The assignment_history table is append-only. Records are never updated or deleted through normal operations. The cascade delete on assignment_history.assignment_id exists as a safety mechanism but is not exercised in standard workflows. This design guarantees a complete and tamper-resistant audit trail.
5. Code Master Values
5.1 assignment_type_cd
Used by assignment.assignment_type_cd. Values are application-defined constants, not stored in code_master.
| Code | Description | Behavior / When Used |
|---|---|---|
TASK | A one-off work item tied to a transactional entity. Has a status lifecycle. Multiple tasks can exist per entity simultaneously. | Cash receipt processing tasks, payment follow-ups, split review tasks. Initialized with task_status_cd = OPEN. |
RESPONSIBILITY | Long-lived ownership of a business entity at any hierarchy level. No status lifecycle; governed by is_active_ind only. Exactly one active responsibility exists per entity at any time. | Department ownership, client account responsibility, deal ownership, buyer relationship management. |
Default on creation: Must be explicitly specified; no system default.
5.2 entity_type_cd
Used by assignment.entity_type_cd. Values are application-defined constants, not stored in code_master.
| Code | Hierarchy Level | Key Field | Description |
|---|---|---|---|
DEPARTMENT | Level 1 (broadest) | entity_id | A UTA organizational department. The broadest catch-all in the responsibility resolution chain. |
CLIENT | Level 2 | entity_id | A client (talent/artist) represented by UTA. References the party table where party type = Client. |
BUYER | Level 2 | entity_id | A buyer (studio, brand, network, platform) that pays for client services. References the party table where party type = Buyer. |
DEAL | Level 3 | entity_reference | A specific deal/engagement/booking between a client and buyer. Referenced by deal identifier string. |
META_DATA_PAIR | Level 3 | meta_data_type_cd + meta_data_value | A meta-data attribute pair (e.g., genre, territory, show type) used for fine-grained assignment routing. Uses the meta_data_type_cd and meta_data_value fields instead of entity_id or entity_reference. |
SALES_ITEM | Level 4 (most specific) | entity_reference | A specific sales item within a deal. The most granular level of the responsibility hierarchy. |
PAYMENT_TERM | Level 4 (most specific) | entity_reference | A specific payment term within a deal. Equally granular as SALES_ITEM. |
CASH_RECEIPT | Task-only (no hierarchy) | entity_id | An incoming cash receipt. Used only for task assignments; does not participate in the responsibility hierarchy. |
CASH_RECEIPT_SPLIT | Task-only (no hierarchy) | entity_id | A split portion of a cash receipt. Used only for task assignments. |
PAYMENT | Task-only (no hierarchy) | entity_id | An outbound payment item. Used only for task assignments. |
Default on creation: Must be explicitly specified; no system default.
5.3 task_status_cd
Used by assignment.task_status_cd. Values are application-defined constants, not stored in code_master.
| Code | Description | Behavior / When Used |
|---|---|---|
OPEN | Task has been created and assigned but work has not begun. | Assigned automatically on task creation. |
WORKING | The assignee is actively working on the task. | Set when the assignee begins work. |
WAITING | The task is paused, pending external input or a dependency. | Set when the assignee is blocked. |
COMPLETE | The task has been successfully finished. Terminal state. | Set when the assignee finishes the work. Optionally triggers sibling cancellation. |
CANCELLED | The task has been abandoned, superseded, or cancelled due to sibling completion. Terminal state. | Set on explicit cancellation or sibling cancellation. |
Default on creation: OPEN
5.4 action_cd
Used by assignment_history.action_cd. Values are application-defined constants, not stored in code_master.
| Code | Description | Behavior / When Used |
|---|---|---|
ASSIGNED | Initial creation of either assignment type. | Recorded when a task or responsibility is first created. from_user_id is null; to_user_id is the initial assignee. |
REASSIGNED | Responsibility transferred to a new person, or task reassigned via edit. | For responsibilities: recorded on the new assignment when a transfer occurs — from_user_id = previous owner, to_user_id = new owner. For tasks: recorded on the existing assignment when the assignee is changed via edit. |
STATUS_CHANGED | Task status transition between non-terminal states. | Recorded when a task moves between statuses (e.g., OPEN to WORKING). from_status_cd and to_status_cd capture the transition. |
DEACTIVATED | Responsibility deactivated as part of a transfer. | Recorded on the old assignment when it is deactivated. from_user_id = previous owner; to_user_id is null. |
CANCELLED | Task cancelled, either directly or as a sibling cancellation. | Recorded when a task moves to CANCELLED. from_status_cd = previous status; to_status_cd = CANCELLED. |
Default on creation: Must be explicitly specified; set by the operation that triggers the history entry.
6. Cross-References
| Document | Relationship |
|---|---|
| Cash Receipts Data Model | assignment.entity_id → cash_receipt.cash_receipt_id when entity_type_cd = CASH_RECEIPT. Task assignments on receipts track review, matching, and follow-up work items. |
| Cash Receipts Data Model | assignment.entity_id → cash_receipt_split.cash_receipt_split_id when entity_type_cd = CASH_RECEIPT_SPLIT. Splits requiring manual review generate task assignments for the responsible user. |
| Settlements Data Model | assignment.entity_id → payment_item.payment_item_id when entity_type_cd = PAYMENT. Payment holds, failures, and follow-up actions generate task assignments routed to the responsible user. |
| Parties Data Model | assignment.entity_id → party.party_id when entity_type_cd = CLIENT or BUYER. Responsibility assignments at these levels determine who owns the relationship with a given client or buyer. assigned_to_user_id references users (internal UTA staff), not external parties. |
| Deals, Sales Items & Payment Terms Data Model | assignment.entity_reference → deal reference string when entity_type_cd = DEAL. Responsibility assignments at the deal level determine who owns a specific engagement. entity_reference → sales_item reference when entity_type_cd = SALES_ITEM. entity_reference → payment_term reference when entity_type_cd = PAYMENT_TERM. |