docs(01): create phase 1 plans
Phase 01: Semantic Position Model - 2 plans in 2 waves - Wave 1: SortOrderProvider + Trip day derivation (parallel-ready) - Wave 2: Tests verifying persistence behavior Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
155
.planning/phases/01-semantic-position-model/01-01-PLAN.md
Normal file
155
.planning/phases/01-semantic-position-model/01-01-PLAN.md
Normal file
@@ -0,0 +1,155 @@
|
||||
---
|
||||
phase: 01-semantic-position-model
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- SportsTime/Core/Models/Domain/SortOrderProvider.swift
|
||||
- SportsTime/Core/Models/Domain/Trip.swift
|
||||
autonomous: true
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "Games get sortOrder derived from game time (minutes since midnight + offset)"
|
||||
- "Inserting between two items produces midpoint sortOrder"
|
||||
- "Day number can be calculated from any date given trip start date"
|
||||
artifacts:
|
||||
- path: "SportsTime/Core/Models/Domain/SortOrderProvider.swift"
|
||||
provides: "sortOrder calculation utilities"
|
||||
exports: ["initialSortOrder(forGameTime:)", "sortOrderBetween(_:_:)", "sortOrderBefore(_:)", "sortOrderAfter(_:)", "needsNormalization(_:)", "normalize(_:)"]
|
||||
- path: "SportsTime/Core/Models/Domain/Trip.swift"
|
||||
provides: "Day derivation methods"
|
||||
contains: "func dayNumber(for date: Date) -> Int"
|
||||
key_links:
|
||||
- from: "SortOrderProvider"
|
||||
to: "ItineraryItem.sortOrder"
|
||||
via: "Utilities compute values assigned to sortOrder property"
|
||||
pattern: "sortOrder.*=.*SortOrderProvider"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Create the sortOrder calculation utilities and day derivation methods that Phase 1 depends on.
|
||||
|
||||
Purpose: Establish the foundational utilities for semantic position assignment. Games need sortOrder derived from time, travel/custom items need midpoint insertion, and items need day derivation from trip dates.
|
||||
|
||||
Output: `SortOrderProvider.swift` with all sortOrder utilities, `Trip.swift` extended with day derivation methods.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/01-semantic-position-model/01-RESEARCH.md
|
||||
|
||||
# Existing source files
|
||||
@SportsTime/Core/Models/Domain/ItineraryItem.swift
|
||||
@SportsTime/Core/Models/Domain/Trip.swift
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create SortOrderProvider utility</name>
|
||||
<files>SportsTime/Core/Models/Domain/SortOrderProvider.swift</files>
|
||||
<action>
|
||||
Create a new file `SortOrderProvider.swift` with an enum containing static methods for sortOrder calculation.
|
||||
|
||||
Include these methods (as specified in 01-RESEARCH.md):
|
||||
|
||||
1. `initialSortOrder(forGameTime: Date) -> Double`
|
||||
- Extract hour and minute from game time
|
||||
- Calculate minutes since midnight
|
||||
- Return 100.0 + minutesSinceMidnight (range: 100-1540)
|
||||
- This ensures games sort by time and leaves room for negative sortOrder items
|
||||
|
||||
2. `sortOrderBetween(_ above: Double, _ below: Double) -> Double`
|
||||
- Return (above + below) / 2.0
|
||||
- Simple midpoint calculation
|
||||
|
||||
3. `sortOrderBefore(_ first: Double) -> Double`
|
||||
- Return first - 1.0
|
||||
- Creates space before the first item
|
||||
|
||||
4. `sortOrderAfter(_ last: Double) -> Double`
|
||||
- Return last + 1.0
|
||||
- Creates space after the last item
|
||||
|
||||
5. `needsNormalization(_ items: [ItineraryItem]) -> Bool`
|
||||
- Sort items by sortOrder
|
||||
- Check if any adjacent gap is less than 1e-10
|
||||
- Return true if normalization needed
|
||||
|
||||
6. `normalize(_ items: inout [ItineraryItem])`
|
||||
- Sort by current sortOrder
|
||||
- Reassign sortOrder as 1.0, 2.0, 3.0... (integer spacing)
|
||||
- Updates items in place
|
||||
|
||||
Use `Calendar.current` for date component extraction. Import Foundation only.
|
||||
</action>
|
||||
<verify>
|
||||
File exists at `SportsTime/Core/Models/Domain/SortOrderProvider.swift` with all 6 methods. Build succeeds:
|
||||
```bash
|
||||
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' build 2>&1 | tail -20
|
||||
```
|
||||
</verify>
|
||||
<done>SortOrderProvider.swift exists with all 6 static methods, project builds without errors</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Add day derivation methods to Trip</name>
|
||||
<files>SportsTime/Core/Models/Domain/Trip.swift</files>
|
||||
<action>
|
||||
Extend the existing Trip struct with day derivation methods in a new extension at the bottom of the file.
|
||||
|
||||
Add these methods:
|
||||
|
||||
1. `func dayNumber(for date: Date) -> Int`
|
||||
- Use Calendar.current to get startOfDay for both startDate and target date
|
||||
- Calculate days between using dateComponents([.day], from:to:)
|
||||
- Return days + 1 (1-indexed)
|
||||
|
||||
2. `func date(forDay dayNumber: Int) -> Date?`
|
||||
- Use Calendar.current to add (dayNumber - 1) days to startDate
|
||||
- Return the resulting date
|
||||
|
||||
Add a comment block explaining:
|
||||
- Day 1 = trip.startDate
|
||||
- Day 2 = startDate + 1 calendar day
|
||||
- Games belong to their start date (even if running past midnight)
|
||||
|
||||
These methods complement the existing `itineraryDays()` method but work with raw Date values rather than the Trip's stops structure.
|
||||
</action>
|
||||
<verify>
|
||||
Build succeeds and new methods are callable:
|
||||
```bash
|
||||
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' build 2>&1 | tail -20
|
||||
```
|
||||
</verify>
|
||||
<done>Trip.swift has dayNumber(for:) and date(forDay:) methods, project builds without errors</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
1. Both files exist and contain expected methods
|
||||
2. `xcodebuild build` succeeds with no errors
|
||||
3. SortOrderProvider methods are static and accessible as `SortOrderProvider.methodName()`
|
||||
4. Trip extension methods are instance methods callable on any Trip value
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- SortOrderProvider.swift exists with 6 static methods for sortOrder calculation
|
||||
- Trip.swift extended with dayNumber(for:) and date(forDay:) methods
|
||||
- Project builds successfully
|
||||
- No changes to existing ItineraryItem.swift (model already has correct fields)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-semantic-position-model/01-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user