Files
SportstimeAPI/.planning/phases/01-semantic-position-model/01-01-PLAN.md
Trey t a7d0e7f049 fix(01): revise plans based on checker feedback
- 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>
2026-01-18 13:47:12 -06:00

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
SportsTime/Core/Models/Domain/SortOrderProvider.swift
SportsTime/Core/Models/Domain/Trip.swift
true
truths artifacts key_links
Games sort by schedule time within each day
Items can be inserted at any position (before, between, after existing items)
Items can be assigned to any trip day by date calculation
path provides exports
SportsTime/Core/Models/Domain/SortOrderProvider.swift sortOrder calculation utilities
initialSortOrder(forGameTime:)
sortOrderBetween(_:_:)
sortOrderBefore(_:)
sortOrderAfter(_:)
needsNormalization(_:)
normalize(_:)
path provides contains
SportsTime/Core/Models/Domain/Trip.swift Day derivation methods func dayNumber(for date: Date) -> Int
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.

<execution_context> @/.claude/get-shit-done/workflows/execute-plan.md @/.claude/get-shit-done/templates/summary.md </execution_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

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):

  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. 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
SortOrderProvider.swift exists with all 6 static methods, project builds without errors Task 2: Add day derivation methods to Trip SportsTime/Core/Models/Domain/Trip.swift 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. 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
Trip.swift has dayNumber(for:) and date(forDay:) methods, project builds without errors 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

<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>
After completion, create `.planning/phases/01-semantic-position-model/01-01-SUMMARY.md`