- 01-01: Reframe must_haves.truths to user-observable behaviors - 01-01: Remove unimplemented key_link (wiring happens in later phases) - 01-02: Add test case for DATA-04 (custom items at any position) - 01-02: Add must_haves.truths entry for custom item flexibility - 01-02: Document LocalItineraryItem is standalone (no sibling models needed) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.4 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | |||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-semantic-position-model | 01 | execute | 1 |
|
true |
|
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.
<execution_context>
@/.claude/get-shit-done/workflows/execute-plan.md
@/.claude/get-shit-done/templates/summary.md
</execution_context>
Existing source files
@SportsTime/Core/Models/Domain/ItineraryItem.swift @SportsTime/Core/Models/Domain/Trip.swift
Task 1: Create SortOrderProvider utility SportsTime/Core/Models/Domain/SortOrderProvider.swift Create a new file `SortOrderProvider.swift` with an enum containing static methods for sortOrder calculation.Include these methods (as specified in 01-RESEARCH.md):
-
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
-
sortOrderBetween(_ above: Double, _ below: Double) -> Double- Return (above + below) / 2.0
- Simple midpoint calculation
-
sortOrderBefore(_ first: Double) -> Double- Return first - 1.0
- Creates space before the first item
-
sortOrderAfter(_ last: Double) -> Double- Return last + 1.0
- Creates space after the last item
-
needsNormalization(_ items: [ItineraryItem]) -> Bool- Sort items by sortOrder
- Check if any adjacent gap is less than 1e-10
- Return true if normalization needed
-
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.
File exists at SportsTime/Core/Models/Domain/SortOrderProvider.swift with all 6 methods. Build succeeds:
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' build 2>&1 | tail -20
Add these methods:
-
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)
-
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.
Build succeeds and new methods are callable:
xcodebuild -project SportsTime.xcodeproj -scheme SportsTime -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' build 2>&1 | tail -20
<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>