Adds competitive analysis document comparing PlantGuide against major plant identification apps (PlantIn, PictureThis, Planta, etc.) and CLAUDE.md to help future Claude Code instances navigate the codebase. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.3 KiB
3.3 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build & Test Commands
# 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 viaLazyService<T>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:
PlantClassificationServiceand Core Data access use actors for thread safety - ViewModels:
@MainActor @Observableclasses, created viaDIContainer.makeXxxViewModel()
Data Flow Example
CameraView → IdentificationViewModel → HybridIdentificationUseCase
→ PlantClassificationService (on-device ML)
→ PlantNetAPIService (online fallback)
→ IdentificationView (results)
Directory Structure
App/- Entry point, configuration, API keysCore/DI/- DIContainer and LazyServiceDomain/- Business logic: Entities, UseCases, RepositoryInterfacesData/- Persistence: CoreData, Repositories, API services, MappersML/- Core ML inference service and image preprocessingPresentation/- 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:
InMemoryPlantRepositorydoesn't conform toPlantRepositoryProtocolCoreDataStacklazy var initialization isn't thread-safeDIContainerusesunowned selfin closures (crash risk)- SwiftData initialized but unused (Core Data is the actual persistence layer)
Testing
- Unit tests in
PlantGuideTests/with mock implementations inMocks/ - Test fixtures available for
Plant,CareTask,PlantCareSchedule - Mock services:
MockPlantCollectionRepository,MockNetworkService, etc.