From 36544b86d0b16e861af4fc8ac284178c675c94f9 Mon Sep 17 00:00:00 2001 From: Trey t Date: Sun, 18 Jan 2026 13:24:27 -0600 Subject: [PATCH] docs: create roadmap (4 phases) Phases: 1. Semantic Position Model: DATA-*, PERS-* (foundation) 2. Constraint Validation: CONS-* (rules engine) 3. Visual Flattening: FLAT-* (display bridge) 4. Drag Interaction: DRAG-* (UI layer) All 23 v1 requirements mapped to phases. --- .planning/REQUIREMENTS.md | 52 +++++++++--------- .planning/ROADMAP.md | 109 ++++++++++++++++++++++++++++++++++++++ .planning/STATE.md | 68 ++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 26 deletions(-) create mode 100644 .planning/ROADMAP.md create mode 100644 .planning/STATE.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 5f86329..334ae4e 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -86,35 +86,35 @@ 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 | +| DATA-01 | Phase 1 | Pending | +| DATA-02 | Phase 1 | Pending | +| DATA-03 | Phase 1 | Pending | +| DATA-04 | Phase 1 | Pending | +| DATA-05 | Phase 1 | Pending | +| CONS-01 | Phase 2 | Pending | +| CONS-02 | Phase 2 | Pending | +| CONS-03 | Phase 2 | Pending | +| CONS-04 | Phase 2 | Pending | +| FLAT-01 | Phase 3 | Pending | +| FLAT-02 | Phase 3 | Pending | +| FLAT-03 | Phase 3 | Pending | +| DRAG-01 | Phase 4 | Pending | +| DRAG-02 | Phase 4 | Pending | +| DRAG-03 | Phase 4 | Pending | +| DRAG-04 | Phase 4 | Pending | +| DRAG-05 | Phase 4 | Pending | +| DRAG-06 | Phase 4 | Pending | +| DRAG-07 | Phase 4 | Pending | +| DRAG-08 | Phase 4 | Pending | +| PERS-01 | Phase 1 | Pending | +| PERS-02 | Phase 1 | Pending | +| PERS-03 | Phase 1 | Pending | **Coverage:** - v1 requirements: 23 total -- Mapped to phases: 0 -- Unmapped: 23 ⚠️ +- Mapped to phases: 23 +- Unmapped: 0 --- *Requirements defined: 2026-01-18* -*Last updated: 2026-01-18 after initial definition* +*Last updated: 2026-01-18 after roadmap creation* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md new file mode 100644 index 0000000..b69a4ae --- /dev/null +++ b/.planning/ROADMAP.md @@ -0,0 +1,109 @@ +# Roadmap: Itinerary Editor + +## Overview + +Build a drag-and-drop itinerary editor for SportsTime using UITableView bridged into SwiftUI. The core insight is that semantic positions (day, sortOrder) are truth while row indices are ephemeral display concerns. Four phases establish the data model, constraints, flattening, and interaction layer - each building on the previous. + +## Phases + +### Phase 1: Semantic Position Model + +**Goal:** All movable items have a persistent semantic position that survives data reloads. + +**Dependencies:** None (foundation phase) + +**Requirements:** +- DATA-01: All movable items have semantic position `(day: Int, sortOrder: Double)` +- DATA-02: Travel segments are positioned items with their own sortOrder +- DATA-03: Games are immovable anchors ordered by game time within each day +- DATA-04: Custom items can be placed anywhere within any day +- DATA-05: Items always belong to exactly one day +- 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 enables unlimited insertions + +**Success Criteria:** +1. User can persist an item's position, reload the app, and find it in the same location +2. Moving travel segment to different day updates its `day` property (verifiable in debugger/logs) +3. Inserting between two items gets sortOrder between their values (e.g., 1.0 and 2.0 -> 1.5) +4. Games remain fixed at their schedule-determined positions regardless of other changes + +--- + +### Phase 2: Constraint Validation + +**Goal:** The system prevents invalid positions and enforces item-specific rules. + +**Dependencies:** Phase 1 (semantic position model) + +**Requirements:** +- CONS-01: Games cannot be moved (fixed by schedule) +- CONS-02: Travel segments constrained to valid day range +- CONS-03: Travel segments must be after from-city games, before to-city games on same day +- CONS-04: Custom items have no constraints (any position within any day) + +**Success Criteria:** +1. Attempting to drag a game row shows no drag interaction (game is not draggable) +2. Travel segment between Chicago and Boston cannot be placed on Day 1 if Chicago games extend through Day 2 +3. Custom note item can be placed before, between, or after games on any day +4. Invalid position attempt returns rejection (constraint checker returns false) + +--- + +### Phase 3: Visual Flattening + +**Goal:** Semantic items flatten to display rows deterministically, sorted by sortOrder. + +**Dependencies:** Phase 2 (constraints inform what items exist per day) + +**Requirements:** +- FLAT-01: Visual flattening sorts by sortOrder within each day +- FLAT-02: Flattening is deterministic and stateless +- FLAT-03: sortOrder < 0 for "before games", sortOrder >= 0 for "after/between games" + +**Success Criteria:** +1. Item with sortOrder -1.0 appears before all games in that day's section +2. Same semantic state always produces identical row order (test with snapshot comparison) +3. Reordering items and re-flattening preserves the new order (no reversion to "default") + +--- + +### Phase 4: Drag Interaction + +**Goal:** User can drag items with proper feedback, animation, and constraint enforcement. + +**Dependencies:** Phase 3 (flattening provides row-to-semantic translation) + +**Requirements:** +- DRAG-01: Lift animation on grab (shadow + slight scale) +- DRAG-02: Insertion line appears between items showing drop target +- DRAG-03: Items shuffle out of the way during drag (100ms animation) +- DRAG-04: Magnetic snap on drop +- 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) + +**Success Criteria:** +1. User sees clear insertion line indicating where item will land during drag +2. Dropping on invalid target snaps item back to original position with haptic feedback +3. Dragging to bottom of visible area auto-scrolls to reveal more content +4. Complete drag-drop cycle feels responsive with visible lift, shuffle, and settle animations +5. Haptic pulses on both grab and drop (verifiable on physical device) + +--- + +## Progress + +| Phase | Status | Requirements | Completed | +|-------|--------|--------------|-----------| +| 1 - Semantic Position Model | Not Started | 8 | 0 | +| 2 - Constraint Validation | Not Started | 4 | 0 | +| 3 - Visual Flattening | Not Started | 3 | 0 | +| 4 - Drag Interaction | Not Started | 8 | 0 | + +**Total:** 0/23 requirements completed + +--- +*Roadmap created: 2026-01-18* +*Depth: quick (4 phases)* diff --git a/.planning/STATE.md b/.planning/STATE.md new file mode 100644 index 0000000..d9ee15c --- /dev/null +++ b/.planning/STATE.md @@ -0,0 +1,68 @@ +# Project State: Itinerary Editor + +## Project Reference + +**Core Value:** Drag-and-drop that operates on semantic positions (day + sortOrder), not row indices - so user intent is preserved across data reloads. + +**Current Focus:** Beginning Phase 1 - Semantic Position Model + +## Current Position + +**Phase:** 1 - Semantic Position Model +**Plan:** Not yet created +**Status:** Awaiting plan creation + +``` +Progress: [----------] 0% +Phase 1: [----------] Not Started +Phase 2: [----------] Not Started +Phase 3: [----------] Not Started +Phase 4: [----------] Not Started +``` + +## Performance Metrics + +| Metric | Value | +|--------|-------| +| Total Requirements | 23 | +| Completed | 0 | +| Current Phase | 1 | +| Plans Executed | 0 | + +## Accumulated Context + +### Key Decisions + +| Decision | Rationale | Phase | +|----------|-----------|-------| +| UITableView over SwiftUI List | SwiftUI drag-drop lacks insertion line precision | Pre-planning | +| (day, sortOrder) position model | Row indices break on reload; semantic position is stable | Pre-planning | +| Insertion lines (not zones) | User wants precise feedback on exact drop location | Pre-planning | +| Invalid drops rejected (snap back) | Cleaner than auto-clamping; user knows what happened | Pre-planning | + +### Learned + +- Previous attempts failed due to row-based thinking instead of semantic positioning +- Travel was incorrectly treated as structural ("travelBefore") instead of positional +- Hard-coded flatten order ignoring sortOrder caused reload issues + +### TODOs + +None yet - awaiting Phase 1 planning. + +### Blockers + +None currently. + +## Session Continuity + +**Last Session:** Project initialized, roadmap created +**Next Action:** Create plan for Phase 1 + +### Context for Next Session + +Starting fresh. Phase 1 establishes the semantic position model that everything else depends on. Requirements DATA-01 through DATA-05 define the model structure, PERS-01 through PERS-03 define persistence behavior. The key insight from research: row indices are lies, semantic positions are truth. + +--- +*State initialized: 2026-01-18* +*Last updated: 2026-01-18*