# Data Model: Bottom Bar Overhaul ## Existing Domain Entities (no changes) ### Combatant Already supports all fields needed for custom creature input: | Field | Type | Notes | |-------|------|-------| | id | CombatantId (branded string) | Auto-generated (c-1, c-2, ...) | | name | string | Required, non-empty | | initiative | number? | Optional — new: settable at add time for custom creatures | | maxHp | number? | Optional — new: settable at add time for custom creatures | | currentHp | number? | Optional — set equal to maxHp when provided | | ac | number? | Optional — new: settable at add time for custom creatures | | conditions | readonly ConditionId[]? | Not relevant to this feature | | isConcentrating | boolean? | Not relevant to this feature | | creatureId | CreatureId? | Set for bestiary creatures, absent for custom | ### SearchResult (BestiaryIndexEntry) | Field | Type | Notes | |-------|------|-------| | name | string | Creature name | | source | string | Source code (e.g., "srd") | | sourceDisplayName | string | Display name of sourcebook | | ac | number | Armor class | | hp | number | Average HP | | dex | number | Dexterity score | | cr | string | Challenge rating | | size | string | Size category | | type | string | Creature type | ## New UI-Only State (ephemeral, not persisted) ### QueuedCreature Transient state held in the action bar component representing a bestiary creature selected for batch-add. | Field | Type | Notes | |-------|------|-------| | result | SearchResult | The bestiary entry to add | | count | number | Number of copies to add (starts at 1, increments on re-click) | **Lifecycle**: Created on first click of a dropdown entry. Incremented on re-click of same entry. Replaced on click of different entry. Cleared on confirm, Escape, or when the queued creature leaves search results. ### CustomCreatureFields Transient state held in the action bar component for optional fields shown when no bestiary match exists. | Field | Type | Notes | |-------|------|-------| | initiative | string | Raw input (parsed to number on submit, empty = omit) | | ac | string | Raw input (parsed to number on submit, empty = omit) | | maxHp | string | Raw input (parsed to number on submit, empty = omit) | **Lifecycle**: Visible when search query yields no bestiary results. Cleared on submit or when bestiary results appear. ## State Transitions ``` [Empty input] → type 2+ chars with matches → [Dropdown with bestiary results] → type 2+ chars without matches → [Custom creature fields visible] [Dropdown with bestiary results] → click entry → [Queue: entry x1] → click same entry → [Queue: entry x(N+1)] → click different entry → [Queue: new entry x1] → click confirm / Enter → add N copies → [Empty input] → Escape → [Empty input] → change query (queued creature gone from results) → [Queue cleared] [Custom creature fields visible] → submit → add custom creature with optional fields → [Empty input] → type changes to match bestiary → [Dropdown with bestiary results] ```