# 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*