Files
Sportstime/.planning/codebase/CONVENTIONS.md
Trey t 60b450d869 docs: add Phase 1 plans and codebase documentation
- 01-01-PLAN.md: core.py + mlb.py (executed)
- 01-02-PLAN.md: nba.py + nhl.py
- 01-03-PLAN.md: nfl.py + orchestrator refactor
- Codebase documentation for planning context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:00:45 -06:00

151 lines
4.2 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Coding Conventions
**Analysis Date:** 2026-01-09
## Naming Patterns
**Files:**
- PascalCase for all Swift files: `TripDetailView.swift`, `DataProvider.swift`
- Views: `*View.swift` (e.g., `HomeView.swift`, `TripCreationView.swift`)
- ViewModels: `*ViewModel.swift` (e.g., `TripCreationViewModel.swift`)
- Services: `*Service.swift` (e.g., `LocationService.swift`)
- Tests: `*Tests.swift` (e.g., `TravelEstimatorTests.swift`)
**Functions:**
- camelCase for all functions: `loadInitialData()`, `planItineraries()`
- No special prefix for async functions
- Handlers: `handle*` pattern not heavily used; actions named directly
**Variables:**
- camelCase: `selectedSports`, `startDate`, `gamesOnThisDay`
- No underscore prefix for private (Swift convention)
- Constants: camelCase (no UPPER_SNAKE_CASE)
**Types:**
- PascalCase for all types: `Stadium`, `TripPreferences`, `PlanningRequest`
- No I prefix for protocols: `ScenarioPlanner` (not `IScenarioPlanner`)
- Enums: PascalCase name, camelCase cases: `Sport.mlb`, `FailureReason.noGamesFound`
## Code Style
**Formatting:**
- 4-space indentation (inferred from code)
- No SwiftLint or SwiftFormat configuration
- Follows standard Swift conventions organically
**Section Organization:**
- `// MARK: -` for major sections (560 occurrences across codebase)
- Pattern: `// MARK: - Section Name`
- Example sections: `// MARK: - Properties`, `// MARK: - Public API`, `// MARK: - Private`
**File Headers:**
```swift
//
// FileName.swift
// SportsTime
//
// Optional description line.
//
```
## Import Organization
**Order:**
1. Foundation/Swift standard library
2. Apple frameworks (SwiftUI, SwiftData, MapKit)
3. Project imports (`@testable import SportsTime` in tests)
**Grouping:**
- No blank lines between import groups
- Alphabetical not enforced
**Path Aliases:**
- None used (no module aliasing)
## Error Handling
**Patterns:**
- Explicit result types: `ItineraryResult` enum with `.success` / `.failure`
- `throws` for recoverable service errors
- Async functions use `async throws`
**Error Types:**
- `PlanningFailure` with `FailureReason` enum and user message
- `ConstraintViolation` for planning constraint issues
- SwiftData errors propagated via `try`
**Async:**
- `async/await` throughout (no completion handlers)
- `try await` pattern for async throwing functions
## Logging
**Framework:**
- `print()` with emoji prefixes for debugging
- No production logging framework (Sentry, etc.)
**Patterns:**
- Warning: `print("⚠️ Warning message")`
- Info: `print(" Info message")`
- Error: `print("❌ Error: \(error)")`
- Debug only; no structured logging
## Comments
**When to Comment:**
- Explain why, not what
- Document business logic and edge cases
- Complex algorithms get explanatory comments
**Documentation Comments:**
- Triple-slash `///` for public APIs (487 occurrences)
- Example:
```swift
/// Main entry point for trip planning.
/// - Parameter request: The planning request containing all inputs
/// - Returns: Ranked itineraries on success, or explicit failure
func planItineraries(request: PlanningRequest) -> ItineraryResult
```
**TODO Comments:**
- Format: `// TODO: description`
- Currently only 1 TODO in codebase: `RouteDescriptionGenerator.swift:30`
## Function Design
**Size:**
- No strict line limit enforced
- Large files exist (800+ lines in some services)
- Complex logic extracted to private helpers
**Parameters:**
- Default parameters used extensively
- Options objects for complex configuration: `PlanningRequest`, `TripPreferences`
**Return Values:**
- Explicit returns
- Result types for operations that can fail
- Optional for lookups that may not find data
## Module Design
**Exports:**
- No barrel files (Swift doesn't use this pattern)
- Public API via `public`/`internal` access control
**Access Control:**
- `private` for implementation details
- `internal` (default) for module-internal
- `public` for Codable conformances and cross-module APIs
**Property Wrappers:**
- `@Observable` for ViewModels (modern pattern)
- `@Model` for SwiftData entities
- `@MainActor` for UI-bound services
- `@Query` for SwiftData queries in views
---
*Convention analysis: 2026-01-09*
*Update when patterns change*