# Data Model: Combat Conditions ## Entities ### ConditionId (new type) String literal union representing the 15 valid condition identifiers. ``` "blinded" | "charmed" | "deafened" | "exhaustion" | "frightened" | "grappled" | "incapacitated" | "invisible" | "paralyzed" | "petrified" | "poisoned" | "prone" | "restrained" | "stunned" | "unconscious" ``` - Order of literals in the union defines the canonical display order (FR-003). - Extensible: future conditions can be added to the union. ### ConditionDefinition (new type) Static metadata for each condition. | Field | Type | Description | | --------- | ----------- | ------------------------------------------------ | | id | ConditionId | Unique identifier | | label | string | Human-readable display name (e.g., "Blinded") | | iconName | string | Lucide icon component name (e.g., "EyeOff") | | color | string | Color category (e.g., "neutral", "pink", "amber") | - Registry: `CONDITION_DEFINITIONS` — a static readonly array of all 15 definitions, ordered by display priority. - No lifecycle/state transitions — definitions are immutable reference data. ### Combatant (modified) | Field | Type | Change | | ---------- | ----------------------------- | -------- | | id | CombatantId | existing | | name | string | existing | | initiative | number \| undefined | existing | | maxHp | number \| undefined | existing | | currentHp | number \| undefined | existing | | ac | number \| undefined | existing | | conditions | readonly ConditionId[] \| undefined | **new** | - `conditions` is optional; `undefined` means no conditions active. - When present, the array contains unique `ConditionId` values sorted in definition order. - Maximum cardinality: 15 (one of each condition). ## Relationships ``` Encounter 1──* Combatant Combatant 0──* ConditionId (from CONDITION_DEFINITIONS registry) ``` ## Validation Rules - A condition can appear at most once per combatant. - Only valid `ConditionId` values are accepted (unknown strings rejected). - The conditions array is always sorted in definition order after any mutation. - An empty conditions array is normalized to `undefined`. ## Domain Events ### ConditionAdded | Field | Type | | ----------- | ----------- | | type | "ConditionAdded" | | combatantId | CombatantId | | condition | ConditionId | Emitted when a condition is toggled on or explicitly added. ### ConditionRemoved | Field | Type | | ----------- | ----------- | | type | "ConditionRemoved" | | combatantId | CombatantId | | condition | ConditionId | Emitted when a condition is toggled off (via picker or tag click). ## Persistence - Serialization: `conditions` array serializes to JSON as `["blinded", "poisoned"]`. - Deserialization: Filter stored values through the `ConditionId` set; discard unknown strings. If resulting array is empty, set to `undefined`. - No schema migration required (field is optional with `undefined` default).