Files
PlantGuide/CLAUDE.md
Trey t 136b327093 Add project documentation and CLAUDE.md
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>
2026-01-23 13:55:56 -06:00

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 via LazyService<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: 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.