# Assignment

## Description

Assignment is the **effective-dated placement of an employment into an organizational post** — it links a `WorkerEmployment` to a `Position` (which in turn resolves the Department, Site, and JobProfile). This is the Oracle "Assignment" tier (issue #7): the concrete "which post, from when" layer beneath the employment relationship.

A transfer is not an overwrite; it is a new Assignment generation for the same `versionOf` with a later `effectiveStart`, while the prior generation is closed (ADR-013). Concurrent posts are represented by multiple simultaneously-open Assignments for one employment, exactly one of which is flagged primary. Because Assignment is the join between people and posts over time, it — together with `AppointmentHistory` — is what makes "the org chart as of any date" reconstructable.

Downstream attendance modules resolve **"whose"** through an Assignment: a time punch, a scheduled shift, and a leave request all reference the Assignment effective on their date, which is how support and multi-post work become representable (issues #14, #16).

## Domain Model Definitions

### Model type

Standard

### Command Definitions

Command docs are out of scope for this design phase (ADR-011). Anticipated commands:

- createAssignment — assign an employment to a Position (initial generation)
- transferAssignment — record a transfer as a new effective-dated generation (closes prior generation)
- endAssignment — close the current generation (e.g. on termination or post abolition)

### Query Definitions

- getAssignment — retrieve a single assignment generation by id
- listAssignmentsByWorker — assignment history for a Worker (across employments), paginated
- listAssignmentsByPosition — who has occupied a Position over time, paginated
### Models

- Assignment

### Invariants

- Effective-dated per ADR-013: `effectiveStart`, nullable `effectiveEnd`, `versionOf`; generations sharing a `versionOf` must not overlap
- Every Assignment references exactly one WorkerEmployment and exactly one Position
- At any given date, an employment has at most one **primary** open Assignment; concurrent assignments are non-primary
- An Assignment's effective range must fall within its WorkerEmployment's effective range (you cannot be posted before you are employed or after termination)
- A transfer preserves history: the prior post's Assignment generation is closed, not deleted or mutated
- The Position referenced must be effective on the Assignment's effective date (no assignment to a not-yet-existing or abolished post)

### Relationships

- **Belongs to WorkerEmployment**: `workerEmploymentId` references the employment being posted
- **References Position**: `positionId` references the post occupied (which resolves Department, Site, JobProfile)
- **Referenced by AppointmentHistory**: each appointment event references the Assignment it created or changed
- **Referenced downstream**: time-tracking TimeClockEvent / scheduling Shift / leave requests reference the Assignment effective on their date to establish "whose"
