# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Build & Test Commands ```bash # Build xcodebuild -project PlantGuide.xcodeproj -scheme PlantGuide -configuration Debug # Run all tests xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 16' # Run a single test class xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 16' -only-testing:PlantGuideTests/HybridIdentificationUseCaseTests # Run a single test method xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 16' -only-testing:PlantGuideTests/SavePlantUseCaseTests/testSavePlant_Success ``` ## Architecture **Clean Architecture + MVVM** with three main layers: ``` Presentation (SwiftUI Views + ViewModels) ↓ Domain (Use Cases + Entities + Repository Protocols) ↓ Data (Repository Implementations + Data Sources) ``` ### Key Patterns - **Dependency Injection**: `DIContainer` (singleton) provides all dependencies via `LazyService` wrappers - **Use Cases**: Each user action is a separate use case class (e.g., `SavePlantUseCase`, `HybridIdentificationUseCase`) - **Repository Pattern**: Protocols in Domain layer, implementations in Data layer - **Actor-based Concurrency**: `PlantClassificationService` and Core Data access use actors for thread safety - **ViewModels**: `@MainActor @Observable` classes, created via `DIContainer.makeXxxViewModel()` ### Data Flow Example ``` CameraView → IdentificationViewModel → HybridIdentificationUseCase → PlantClassificationService (on-device ML) → PlantNetAPIService (online fallback) → IdentificationView (results) ``` ### Directory Structure - `App/` - Entry point, configuration, API keys - `Core/DI/` - DIContainer and LazyService - `Domain/` - Business logic: Entities, UseCases, RepositoryInterfaces - `Data/` - Persistence: CoreData, Repositories, API services, Mappers - `ML/` - Core ML inference service and image preprocessing - `Presentation/` - SwiftUI views, ViewModels, navigation ## External Services - **PlantNet API** (`my.plantnet.org`) - Plant identification via image upload (500 free/day) - **Trefle API** (`trefle.io`) - Botanical care data (400K+ species) - **Local Database** - `Resources/houseplants_list.json` (2,278 species) API keys configured in `App/Configuration/APIKeys.swift` via environment variables. ## ML Model PlantNet-300K ResNet50 for on-device plant classification: - Input: 224x224 RGB image with ImageNet normalization - Output: 1,081 plant species probabilities - Conversion scripts in `scripts/` directory ## Known Issues See `Docs/ARCHITECTURE_REMEDIATION_PLAN.md` for pre-production fixes: - `InMemoryPlantRepository` doesn't conform to `PlantRepositoryProtocol` - `CoreDataStack` lazy var initialization isn't thread-safe - `DIContainer` uses `unowned self` in closures (crash risk) - SwiftData initialized but unused (Core Data is the actual persistence layer) ## Testing - Unit tests in `PlantGuideTests/` with mock implementations in `Mocks/` - Test fixtures available for `Plant`, `CareTask`, `PlantCareSchedule` - Mock services: `MockPlantCollectionRepository`, `MockNetworkService`, etc.