Fix Core Data CloudKit compatibility and update CLAUDE.md
- Make all Core Data attributes CloudKit-compatible (optional or with defaults) - Fix CoreDataStack to wait for persistent store loading before operations - Add AccentColor to asset catalog (green theme color) - Remove Browse tab from navigation (keep underlying code) - Update CLAUDE.md with current features, architecture, and tab structure Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
41
CLAUDE.md
41
CLAUDE.md
@@ -18,6 +18,22 @@ xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'p
|
||||
xcodebuild test -project PlantGuide.xcodeproj -scheme PlantGuide -destination 'platform=iOS Simulator,name=iPhone 16' -only-testing:PlantGuideTests/SavePlantUseCaseTests/testSavePlant_Success
|
||||
```
|
||||
|
||||
## App Structure
|
||||
|
||||
**Tab Navigation**: Camera | Collection | Today | Settings
|
||||
|
||||
### Implemented Features
|
||||
|
||||
- **Plant Identification** - Camera-based plant ID using on-device ML + PlantNet API fallback
|
||||
- **Plant Collection** - Save identified plants with care schedules
|
||||
- **Plant Rooms/Zones** - Organize plants by room (Kitchen, Living Room, Bedroom, etc.)
|
||||
- **Today View** - Dashboard showing overdue + today's care tasks grouped by room
|
||||
- **Progress Photos** - Capture growth photos with time-lapse playback and photo reminders
|
||||
- **Care Scheduling** - Watering, fertilizing, repotting, pruning, pest control tasks
|
||||
- **Notifications** - Local notifications for care reminders and photo reminders
|
||||
- **CloudKit Sync** - iCloud sync via NSPersistentCloudKitContainer
|
||||
- **Dark Mode** - System-following color scheme with semantic color tokens
|
||||
|
||||
## Architecture
|
||||
|
||||
**Clean Architecture + MVVM** with three main layers:
|
||||
@@ -35,8 +51,9 @@ Data (Repository Implementations + Data Sources)
|
||||
- **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
|
||||
- **Actor-based Concurrency**: `PlantClassificationService`, `NotificationService`, and Core Data background tasks use actors
|
||||
- **ViewModels**: `@MainActor @Observable` classes, created via `DIContainer.makeXxxViewModel()`
|
||||
- **Core Data + CloudKit**: `NSPersistentCloudKitContainer` with async store loading and `waitForStoreLoaded()` pattern
|
||||
|
||||
### Data Flow Example
|
||||
|
||||
@@ -51,16 +68,20 @@ CameraView → IdentificationViewModel → HybridIdentificationUseCase
|
||||
|
||||
- `App/` - Entry point, configuration, API keys
|
||||
- `Core/DI/` - DIContainer and LazyService
|
||||
- `Core/DesignSystem/` - Color tokens, animations, appearance management
|
||||
- `Core/Services/` - NotificationService
|
||||
- `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
|
||||
- `Scenes/` - Feature-specific views (Camera, Collection, Today, Settings, ProgressPhotos, Rooms)
|
||||
- `Common/` - Shared components and modifiers
|
||||
|
||||
## 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)
|
||||
- **CloudKit** - iCloud sync for plants, rooms, care tasks, and progress photos
|
||||
|
||||
API keys configured in `App/Configuration/APIKeys.swift` via environment variables.
|
||||
|
||||
@@ -71,16 +92,20 @@ PlantNet-300K ResNet50 for on-device plant classification:
|
||||
- Output: 1,081 plant species probabilities
|
||||
- Conversion scripts in `scripts/` directory
|
||||
|
||||
## Known Issues
|
||||
## Core Data Model
|
||||
|
||||
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)
|
||||
Entities (all CloudKit-compatible with optional attributes):
|
||||
- `PlantMO` - Plant records with identification data
|
||||
- `RoomMO` - User-created rooms/zones
|
||||
- `CareScheduleMO` - Care schedule configuration per plant
|
||||
- `CareTaskMO` - Individual care tasks (watering, fertilizing, etc.)
|
||||
- `ProgressPhotoMO` - Progress photos with thumbnails
|
||||
- `IdentificationMO` - Plant identification history
|
||||
- `PlantCareInfoMO` - Cached care information from APIs
|
||||
|
||||
## Testing
|
||||
|
||||
- Unit tests in `PlantGuideTests/` with mock implementations in `Mocks/`
|
||||
- Test fixtures available for `Plant`, `CareTask`, `PlantCareSchedule`
|
||||
- Mock services: `MockPlantCollectionRepository`, `MockNetworkService`, etc.
|
||||
- In-memory Core Data stack for test isolation: `CoreDataStack(inMemory: true)`
|
||||
|
||||
Reference in New Issue
Block a user