docs: define v1 requirements
23 requirements across 5 categories (Data Model, Constraints, Flattening, Drag, Persistence) 5 requirements deferred to v2 (Accessibility, External Drops)
This commit is contained in:
120
.planning/REQUIREMENTS.md
Normal file
120
.planning/REQUIREMENTS.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Requirements: Itinerary Editor
|
||||
|
||||
**Defined:** 2026-01-18
|
||||
**Core Value:** Drag-and-drop that operates on semantic positions (day + sortOrder), not row indices — so user intent is preserved across data reloads.
|
||||
|
||||
## v1 Requirements
|
||||
|
||||
Requirements for initial release. Each maps to roadmap phases.
|
||||
|
||||
### Data Model
|
||||
|
||||
- [ ] **DATA-01**: All movable items have semantic position `(day: Int, sortOrder: Double)`
|
||||
- [ ] **DATA-02**: Travel segments are positioned items with their own sortOrder, not structural day properties
|
||||
- [ ] **DATA-03**: Games are immovable anchors ordered by game time within each day
|
||||
- [ ] **DATA-04**: Custom items can be placed anywhere within any day (including between games)
|
||||
- [ ] **DATA-05**: Items always belong to exactly one day (no liminal "between days" state)
|
||||
|
||||
### Constraints
|
||||
|
||||
- [ ] **CONS-01**: Games cannot be moved (fixed by schedule)
|
||||
- [ ] **CONS-02**: Travel segments are constrained to valid day range (between last from-city game and first to-city game)
|
||||
- [ ] **CONS-03**: Travel segments must be positioned after from-city games and before to-city games on same day
|
||||
- [ ] **CONS-04**: Custom items have no constraints (any position within any day)
|
||||
|
||||
### Flattening
|
||||
|
||||
- [ ] **FLAT-01**: Visual flattening sorts by sortOrder within each day (not hard-coded order)
|
||||
- [ ] **FLAT-02**: Flattening is deterministic and stateless (same semantic state → same row order)
|
||||
- [ ] **FLAT-03**: sortOrder < 0 convention for "before games", sortOrder >= 0 for "after/between games"
|
||||
|
||||
### Drag Interaction
|
||||
|
||||
- [ ] **DRAG-01**: Lift animation on grab (shadow + slight scale)
|
||||
- [ ] **DRAG-02**: Insertion line appears between items showing exact drop target
|
||||
- [ ] **DRAG-03**: Items shuffle out of the way during drag (100ms animation)
|
||||
- [ ] **DRAG-04**: Magnetic snap on drop (item settles into position)
|
||||
- [ ] **DRAG-05**: Invalid drops rejected with snap-back animation
|
||||
- [ ] **DRAG-06**: Haptic feedback on grab (light) and drop (medium)
|
||||
- [ ] **DRAG-07**: Auto-scroll when dragging to viewport edge
|
||||
- [ ] **DRAG-08**: Slight tilt during drag (2-3 degrees, Trello-style)
|
||||
|
||||
### Persistence
|
||||
|
||||
- [ ] **PERS-01**: Semantic position survives data reloads from SwiftUI/SwiftData
|
||||
- [ ] **PERS-02**: No visual-only state; all positions are persisted semantically
|
||||
- [ ] **PERS-03**: Midpoint insertion for sortOrder (1.0, 2.0 → 1.5) enables unlimited insertions
|
||||
|
||||
## v2 Requirements
|
||||
|
||||
Deferred to future release. Tracked but not in current roadmap.
|
||||
|
||||
### Accessibility
|
||||
|
||||
- **ACC-01**: VoiceOver Move Up/Down actions for keyboard reordering
|
||||
- **ACC-02**: VoiceOver announcements on drag start/end
|
||||
- **ACC-03**: Focus management after reorder
|
||||
|
||||
### External Drops
|
||||
|
||||
- **EXT-01**: Accept drops from outside the table (UITableViewDropDelegate)
|
||||
- **EXT-02**: External items converted to semantic position on drop
|
||||
|
||||
### Polish
|
||||
|
||||
- **POL-01**: Undo toast after drop (5-second timeout)
|
||||
- **POL-02**: Drag handle visual affordance
|
||||
|
||||
## Out of Scope
|
||||
|
||||
Explicitly excluded. Documented to prevent scope creep.
|
||||
|
||||
| Feature | Reason |
|
||||
|---------|--------|
|
||||
| Reordering games | Games are fixed by schedule; core constraint |
|
||||
| Reordering day headers | Structural, one per day |
|
||||
| Multi-day travel segments | Complexity; travel belongs to exactly one day |
|
||||
| Multi-item drag | Overkill for itinerary; single item at a time |
|
||||
| Custom drag preview images | Unnecessary; default cell preview is fine |
|
||||
| Drag between screens | Overkill; all editing within single table |
|
||||
| Physics-based spring animations | Diminishing returns; standard easing is sufficient |
|
||||
| Zone-based drop highlighting | Using insertion lines for precision |
|
||||
|
||||
## Traceability
|
||||
|
||||
Which phases cover which requirements. Updated during roadmap creation.
|
||||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| DATA-01 | — | Pending |
|
||||
| DATA-02 | — | Pending |
|
||||
| DATA-03 | — | Pending |
|
||||
| DATA-04 | — | Pending |
|
||||
| DATA-05 | — | Pending |
|
||||
| CONS-01 | — | Pending |
|
||||
| CONS-02 | — | Pending |
|
||||
| CONS-03 | — | Pending |
|
||||
| CONS-04 | — | Pending |
|
||||
| FLAT-01 | — | Pending |
|
||||
| FLAT-02 | — | Pending |
|
||||
| FLAT-03 | — | Pending |
|
||||
| DRAG-01 | — | Pending |
|
||||
| DRAG-02 | — | Pending |
|
||||
| DRAG-03 | — | Pending |
|
||||
| DRAG-04 | — | Pending |
|
||||
| DRAG-05 | — | Pending |
|
||||
| DRAG-06 | — | Pending |
|
||||
| DRAG-07 | — | Pending |
|
||||
| DRAG-08 | — | Pending |
|
||||
| PERS-01 | — | Pending |
|
||||
| PERS-02 | — | Pending |
|
||||
| PERS-03 | — | Pending |
|
||||
|
||||
**Coverage:**
|
||||
- v1 requirements: 23 total
|
||||
- Mapped to phases: 0
|
||||
- Unmapped: 23 ⚠️
|
||||
|
||||
---
|
||||
*Requirements defined: 2026-01-18*
|
||||
*Last updated: 2026-01-18 after initial definition*
|
||||
Reference in New Issue
Block a user