# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a workout tracking iOS app built with Swift/SwiftUI, featuring both iPhone and Apple Watch companions. The app helps users manage workout splits, track exercise logs, and sync data across devices using CloudKit. ## Development Commands ### Building and Running - **Build the project**: Open `Workouts.xcodeproj` in Xcode and build (Cmd+B) - **Run on iOS Simulator**: Select the Workouts scheme and run (Cmd+R) - **Run on Apple Watch Simulator**: Select the "Workouts Watch App" scheme and run ## Architecture ### Data Layer - **CoreData**: Core persistence framework with CloudKit sync via `NSPersistentCloudKitContainer` - **CloudKit Container**: `iCloud.dev.rzen.indie.Workouts` - **PersistenceController**: Manages CoreData stack initialization, CloudKit configuration, and context access - **Models**: Located in `Models/` directory as NSManagedObject subclasses ### Core Models - **Split**: Workout routine templates with exercises, colors, and system images - **Exercise**: Individual exercises within splits (sets, reps, weight, load type) - **Workout**: Active workout sessions linked to splits - **WorkoutLog**: Historical exercise completion records - **WorkoutStatus**: Enum for tracking workout/exercise completion states ### Model Relationships ``` Split (1) ──cascade──> (many) Exercise Split (1) ──nullify──> (many) Workout Workout (1) ──cascade──> (many) WorkoutLog ``` ### App Structure - **Dual targets**: Main iOS app (`Workouts/`) and Watch companion (`Workouts Watch App/`) - **Shared components**: Both apps have similar structure with platform-specific implementations - **TabView navigation**: Main app uses tabs (Workouts, Logs, Reports, Achievements) ### CloudKit Integration - **Automatic sync**: Configured via `NSPersistentCloudKitContainerOptions` - **History tracking**: Enabled for CloudKit sync via `NSPersistentHistoryTrackingKey` - **Remote change notifications**: Enabled for real-time sync updates - **Cross-device sync**: Data syncs between iPhone and Apple Watch ### UI Patterns - **SwiftUI-first**: Modern declarative UI throughout - **Environment injection**: ManagedObjectContext passed via `.environment(\.managedObjectContext)` - **Navigation**: Uses NavigationStack for hierarchical navigation - **Form-based editing**: Consistent form patterns for data entry ### Key Directories - `Models/`: CoreData NSManagedObject subclasses - `Persistence/`: PersistenceController for CoreData stack management - `Views/`: UI components organized by feature (Splits, Exercises, Workouts, etc.) - `Utils/`: Shared utilities (date formatting, colors) - `*.xcdatamodeld`: CoreData model definition ### CoreData Guidelines - Each model gets its own file in `Models/` - Use `@NSManaged` for all persistent properties - Implement `fetchRequest()` class methods for type-safe fetching - Use `NSSet` for to-many relationships with convenience array accessors - Implement add/remove helper methods for relationship management - Use appropriate delete rules: cascade for owned children, nullify for references ### UI Guidelines - Tab-based root navigation with independent navigation stacks - Consistent form patterns for add/edit operations - Sheet presentations for modal operations - Swipe gestures for common actions (edit, complete, navigate) ### Development Notes - **Preview support**: `PersistenceController.preview` for SwiftUI previews - **Color system**: Custom color extensions for consistent theming (`Color.color(from:)`) - **Date formatting**: Extensions in `Date+Extensions.swift` ## Changelog `CHANGELOG.md` is shown in-app via IndieAbout, so it is written for end users, not developers: - Group entries by month; newest month first. - Write each entry as its own blank-line-separated paragraph — no bullet or dash markers, which the Apple inline-Markdown subset IndieAbout renders doesn't style. - Derive entries from the git log, but rewrite (don't copy) each into a concise one-liner describing the crux of the change in end-user-understandable terms. - Include only changes significant to an end user; skip internal/tooling/refactor-only commits. - When one commit holds several user-facing changes, break them into separate paragraphs. - When several commits address the same user-facing change, collapse them into one paragraph.