Implement the 004-edit-combatant feature that adds the possibility to change a combatants name
This commit is contained in:
77
specs/004-edit-combatant/spec.md
Normal file
77
specs/004-edit-combatant/spec.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Feature Specification: Edit Combatant
|
||||
|
||||
**Feature Branch**: `004-edit-combatant`
|
||||
**Created**: 2026-03-03
|
||||
**Status**: Draft
|
||||
**Input**: User description: "EditCombatant: allow updating a combatant's name by id in Encounter (emit CombatantUpdated, error if id not found) and wire through application + minimal UI."
|
||||
|
||||
## User Scenarios & Testing *(mandatory)*
|
||||
|
||||
### User Story 1 - Rename a Combatant (Priority: P1)
|
||||
|
||||
A user running an encounter realizes a combatant's name is misspelled or wants to change it. They select the combatant by its identity, provide a new name, and the system updates the combatant in-place while preserving turn order and round state.
|
||||
|
||||
**Why this priority**: Core feature — without the ability to rename, the entire edit-combatant feature has no value.
|
||||
|
||||
**Independent Test**: Can be fully tested by creating an encounter with combatants, editing one combatant's name, and verifying the name is updated while all other encounter state remains unchanged.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** an encounter with combatants [Alice, Bob], **When** the user updates Bob's name to "Robert", **Then** the encounter contains [Alice, Robert] and a `CombatantUpdated` event is emitted with the combatant's id, old name, and new name.
|
||||
2. **Given** an encounter with combatants [Alice, Bob] where Bob is the active combatant, **When** the user updates Bob's name to "Robert", **Then** Bob remains the active combatant (active index unchanged) and the round number is preserved.
|
||||
|
||||
---
|
||||
|
||||
### User Story 2 - Error Feedback on Invalid Edit (Priority: P2)
|
||||
|
||||
A user attempts to edit a combatant that no longer exists (e.g., removed in another action) or provides an invalid name. The system returns a clear error without modifying the encounter.
|
||||
|
||||
**Why this priority**: Error handling ensures data integrity and provides a usable experience when things go wrong.
|
||||
|
||||
**Independent Test**: Can be tested by attempting to edit a non-existent combatant id and verifying an error is returned with no state change.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** an encounter with combatants [Alice, Bob], **When** the user attempts to update a combatant with a non-existent id, **Then** the system returns a "combatant not found" error and the encounter is unchanged.
|
||||
2. **Given** an encounter with combatants [Alice, Bob], **When** the user attempts to update Alice's name to an empty string, **Then** the system returns an "invalid name" error and the encounter is unchanged.
|
||||
3. **Given** an encounter with combatants [Alice, Bob], **When** the user attempts to update Alice's name to a whitespace-only string, **Then** the system returns an "invalid name" error and the encounter is unchanged.
|
||||
|
||||
---
|
||||
|
||||
### Edge Cases
|
||||
|
||||
- What happens when the user sets a combatant's name to the same value it already has? The system treats it as a valid update — the encounter state is unchanged but a `CombatantUpdated` event is still emitted.
|
||||
- What happens when the encounter has no combatants? Editing any id returns a "combatant not found" error.
|
||||
|
||||
## Requirements *(mandatory)*
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
- **FR-001**: System MUST allow updating a combatant's name by providing the combatant's id and a new name.
|
||||
- **FR-002**: System MUST emit a `CombatantUpdated` event containing the combatant id, old name, and new name upon successful update.
|
||||
- **FR-003**: System MUST return a "combatant not found" error when the provided id does not match any combatant in the encounter.
|
||||
- **FR-004**: System MUST return an "invalid name" error when the new name is empty or whitespace-only.
|
||||
- **FR-005**: System MUST preserve turn order (active index) and round number when a combatant is renamed.
|
||||
- **FR-006**: System MUST preserve the combatant's position in the combatant list (no reordering).
|
||||
- **FR-007**: The user interface MUST provide a way to trigger a name edit for each combatant in the encounter.
|
||||
|
||||
### Key Entities
|
||||
|
||||
- **Combatant**: Identified by a unique id; has a mutable name. Editing updates only the name, preserving identity and list position.
|
||||
- **CombatantUpdated (event)**: Records that a combatant's name changed. Contains combatant id, old name, and new name.
|
||||
|
||||
## Success Criteria *(mandatory)*
|
||||
|
||||
### Measurable Outcomes
|
||||
|
||||
- **SC-001**: Users can rename any combatant in the encounter in a single action.
|
||||
- **SC-002**: Renaming a combatant never disrupts turn order, active combatant, or round number.
|
||||
- **SC-003**: Invalid edit attempts (missing combatant, empty name) produce a clear, actionable error message with no side effects.
|
||||
- **SC-004**: The combatant's updated name is immediately visible in the encounter UI after editing.
|
||||
|
||||
## Assumptions
|
||||
|
||||
- Name validation follows the same rules as adding a combatant (reject empty and whitespace-only names).
|
||||
- No uniqueness constraint on combatant names — multiple combatants may share the same name.
|
||||
- MVP baseline does not include editing other combatant attributes (e.g., initiative score, HP). Only name editing is in scope.
|
||||
- MVP baseline uses inline editing (click-to-edit input field) as the name editing mechanism. More complex UX (e.g., modal dialogs, undo/redo) is not in the MVP baseline.
|
||||
Reference in New Issue
Block a user