- Implement camera capture and plant identification workflow - Add Core Data persistence for plants, care schedules, and cached API data - Create collection view with grid/list layouts and filtering - Build plant detail views with care information display - Integrate Trefle botanical API for plant care data - Add local image storage for captured plant photos - Implement dependency injection container for testability - Include accessibility support throughout the app Bug fixes in this commit: - Fix Trefle API decoding by removing duplicate CodingKeys - Fix LocalCachedImage to load from correct PlantImages directory - Set dateAdded when saving plants for proper collection sorting Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
186 lines
7.2 KiB
Markdown
186 lines
7.2 KiB
Markdown
# Plant Detail Auto-Add Care Items with Notifications
|
|
|
|
## Summary
|
|
Add an "Auto-Add Care Items" feature to the plant detail screen that:
|
|
1. Creates recurring care tasks (watering, fertilizing) based on Trefle API data
|
|
2. Allows per-task-type notification toggles
|
|
3. Sends local notifications at user-configured time
|
|
4. Adds "Notify Me Time" setting in Settings
|
|
|
|
## Current State Analysis
|
|
|
|
**What Already Exists:**
|
|
- `PlantDetailView` shows plant info, care requirements, and upcoming tasks
|
|
- `PlantDetailViewModel` has `loadCareInfo()` and `createSchedule()` methods
|
|
- `FetchPlantCareUseCase` fetches care info from Trefle API
|
|
- `CreateCareScheduleUseCase` generates watering/fertilizer tasks for 30 days
|
|
- `CoreDataCareScheduleStorage` persists care schedules to CoreData
|
|
- `NotificationService` exists with notification scheduling capabilities
|
|
- `CarePreferences` has `preferredWateringHour` and `preferredWateringMinute`
|
|
|
|
**Gap Analysis:**
|
|
1. No UI to trigger schedule creation
|
|
2. Schedules not persisted to CoreData
|
|
3. No notification toggles per task type
|
|
4. No "Notify Me Time" setting in Settings UI
|
|
5. No local notification scheduling when tasks are created
|
|
|
|
## Implementation Steps
|
|
|
|
### Step 1: Add Notification Time Setting to Settings
|
|
**Files:**
|
|
- `PlantGuide/Presentation/Scenes/Settings/SettingsView.swift`
|
|
- `PlantGuide/Presentation/Scenes/Settings/SettingsViewModel.swift`
|
|
|
|
Add:
|
|
- "Notify Me Time" DatePicker (time only) in Settings
|
|
- Store in UserDefaults: `settings_notification_time_hour`, `settings_notification_time_minute`
|
|
- Default to 8:00 AM
|
|
|
|
### Step 2: Create CareNotificationPreferences Model
|
|
**File (new):** `PlantGuide/Domain/Entities/CareNotificationPreferences.swift`
|
|
|
|
```swift
|
|
struct CareNotificationPreferences: Codable, Sendable, Equatable {
|
|
var wateringEnabled: Bool = true
|
|
var fertilizingEnabled: Bool = true
|
|
var repottingEnabled: Bool = false
|
|
var pruningEnabled: Bool = false
|
|
}
|
|
```
|
|
|
|
### Step 3: Update PlantDetailViewModel
|
|
**File:** `PlantGuide/Presentation/Scenes/PlantDetail/PlantDetailViewModel.swift`
|
|
|
|
Add:
|
|
- Dependency on `CareScheduleRepositoryProtocol`
|
|
- Dependency on `NotificationService`
|
|
- `notificationPreferences: CareNotificationPreferences` (per plant, stored in UserDefaults by plantID)
|
|
- `hasExistingSchedule: Bool`
|
|
- `isCreatingSchedule: Bool`
|
|
- Load existing schedule on `loadCareInfo()`
|
|
- `createSchedule()` → persist schedule + schedule notifications
|
|
- `updateNotificationPreference(for:enabled:)` → update toggles + reschedule
|
|
|
|
### Step 4: Update PlantDetailView UI
|
|
**File:** `PlantGuide/Presentation/Scenes/PlantDetail/PlantDetailView.swift`
|
|
|
|
Add:
|
|
- **"Auto-Add Care Items" button** (if no schedule exists)
|
|
- **Notification Toggles Section** (if schedule exists):
|
|
```
|
|
Notifications
|
|
├─ Watering reminders [Toggle]
|
|
├─ Fertilizer reminders [Toggle]
|
|
```
|
|
- Success feedback when schedule created
|
|
- Show task count when schedule exists
|
|
|
|
### Step 5: Update DIContainer
|
|
**File:** `PlantGuide/Core/DI/DIContainer.swift`
|
|
|
|
Update `makePlantDetailViewModel()` to inject:
|
|
- `careScheduleRepository`
|
|
- `notificationService`
|
|
|
|
### Step 6: Schedule Local Notifications
|
|
**File:** `PlantGuide/Core/Services/NotificationService.swift`
|
|
|
|
Add/verify methods:
|
|
- `scheduleCareTaskNotification(task:plantName:)` - schedules notification for task
|
|
- `cancelCareTaskNotifications(for plantID:)` - cancels all for plant
|
|
- `cancelCareTaskNotifications(for taskType:plantID:)` - cancels by type
|
|
|
|
## File Changes Summary
|
|
|
|
| File | Action | Changes |
|
|
|------|--------|---------|
|
|
| `SettingsView.swift` | Modify | Add "Notify Me Time" picker |
|
|
| `SettingsViewModel.swift` | Modify | Add notification time storage |
|
|
| `CareNotificationPreferences.swift` | Create | New model for per-plant toggles |
|
|
| `PlantDetailViewModel.swift` | Modify | Add repository, notifications, preferences |
|
|
| `PlantDetailView.swift` | Modify | Add button + notification toggles |
|
|
| `DIContainer.swift` | Modify | Update factory injection |
|
|
| `NotificationService.swift` | Modify | Add care task notification methods |
|
|
|
|
## Data Flow
|
|
|
|
```
|
|
1. User configures "Notify Me Time" in Settings (e.g., 9:00 AM)
|
|
↓
|
|
2. User taps "Auto-Add Care Items" on plant detail
|
|
↓
|
|
3. CreateCareScheduleUseCase creates tasks
|
|
↓
|
|
4. CareScheduleRepository.save() → CoreData
|
|
↓
|
|
5. For each task type where notification enabled:
|
|
NotificationService.scheduleCareTaskNotification()
|
|
↓
|
|
6. Notifications fire at configured time on scheduled dates
|
|
```
|
|
|
|
## UI Design
|
|
|
|
### Settings Screen Addition
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ NOTIFICATIONS │
|
|
├─────────────────────────────────────┤
|
|
│ Notify Me Time [9:00 AM ▼] │
|
|
│ Time to receive care reminders │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
### Plant Detail Screen
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ [Plant Header with Image] │
|
|
├─────────────────────────────────────┤
|
|
│ Care Information │
|
|
│ • Light: Bright indirect │
|
|
│ • Water: Every 7 days │
|
|
│ • Temperature: 18-27°C │
|
|
├─────────────────────────────────────┤
|
|
│ ┌─────────────────────────────────┐ │
|
|
│ │ Auto-Add Care Items │ │ ← Button (if no schedule)
|
|
│ └─────────────────────────────────┘ │
|
|
│ │
|
|
│ OR if schedule exists: │
|
|
│ │
|
|
│ Care Reminders │
|
|
│ ├─ Watering [ON ────●] │
|
|
│ └─ Fertilizer [ON ────●] │
|
|
├─────────────────────────────────────┤
|
|
│ Upcoming Tasks (8 total) │
|
|
│ • Water tomorrow │
|
|
│ • Fertilize in 14 days │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
## Verification
|
|
|
|
1. **Settings:**
|
|
- Open Settings → see "Notify Me Time" picker
|
|
- Change time → value persists on restart
|
|
|
|
2. **Plant Detail - Create Schedule:**
|
|
- Navigate to plant without schedule
|
|
- See "Auto-Add Care Items" button
|
|
- Tap → loading state → success with task count
|
|
- Button replaced with notification toggles
|
|
|
|
3. **Notification Toggles:**
|
|
- Toggle watering OFF → existing watering notifications cancelled
|
|
- Toggle watering ON → notifications rescheduled
|
|
|
|
4. **Notifications Fire:**
|
|
- Create schedule with watering in 1 minute (for testing)
|
|
- Receive local notification at configured time
|
|
|
|
5. **Persistence:**
|
|
- Close app, reopen → schedule still exists, toggles preserved
|
|
|
|
6. **Care Tab:**
|
|
- Tasks appear in Care tab grouped by date
|