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

87 lines
3.3 KiB
Markdown

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