# Make Shit Work - Base User Flow Plan **Goal:** Ensure the core plant identification flow works end-to-end ## User Flow Under Review ``` 1. User takes photo of plant 2. App calls PlantNet API to identify plant 3. App displays identification results (match list with confidence %) 4. User selects a plant from results (REPORTED NOT WORKING) 5. User taps "Save to Collection" 6. Plant is saved to user's collection ``` --- ## Investigation Tasks ### Phase 1: Verify Data Flow (Read-Only) - [ ] **T1.1** - Trace camera capture to IdentificationView handoff - File: `Presentation/Scenes/Camera/CameraView.swift` - File: `Presentation/Scenes/Camera/CameraViewModel.swift` - Verify: `capturedImage` is correctly passed to IdentificationView - [ ] **T1.2** - Verify PlantNet API call works - File: `Data/DataSources/Remote/PlantNetAPI/PlantNetAPIService.swift` - File: `Domain/UseCases/Identification/IdentifyPlantOnlineUseCase.swift` - Test: Add logging to confirm API is called and returns results - Check: API key validity, rate limits, response parsing - [ ] **T1.3** - Verify predictions are mapped correctly - File: `Data/Mappers/PlantNetMapper.swift` - File: `Presentation/Scenes/Identification/IdentificationViewModel.swift` - Verify: `PlantNetResultDTO` → `ViewPlantPrediction` mapping preserves all fields - [ ] **T1.4** - Inspect results list rendering - File: `Presentation/Scenes/Identification/IdentificationView.swift` (lines 267-278) - Verify: `predictions` array is populated and displayed - Check: `ForEach` enumerates correctly, `PredictionRow` renders --- ### Phase 2: Debug Selection Issue (PRIORITY) - [ ] **T2.1** - Analyze `selectPrediction()` implementation - File: `Presentation/Scenes/Identification/IdentificationViewModel.swift` - Find: `selectPrediction(_ prediction:)` method - Check: Does it update `@Published var selectedPrediction`? - Check: Is there a state conflict preventing updates? - [ ] **T2.2** - Check tap gesture binding in IdentificationView - File: `Presentation/Scenes/Identification/IdentificationView.swift` - Verify: `.onTapGesture { viewModel.selectPrediction(prediction) }` - Check: Is gesture attached to correct view hierarchy? - Check: Any overlapping gestures or hit testing issues? - [ ] **T2.3** - Verify visual selection feedback - File: `Presentation/Scenes/Identification/Components/PredictionRow.swift` (if exists) - Check: `isSelected` property updates row appearance - Check: Border color / checkmark renders when selected - [ ] **T2.4** - Test auto-selection of first result - File: `Presentation/Scenes/Identification/IdentificationViewModel.swift` - Code: `selectedPrediction = predictions.first` - Verify: This runs after API results are received - Check: Does it fire before user interaction is possible? --- ### Phase 3: Verify Save to Collection - [ ] **T3.1** - Trace save button action - File: `Presentation/Scenes/Identification/IdentificationView.swift` - Find: "Save to Collection" button action - Verify: Calls `viewModel.saveToCollection()` - [ ] **T3.2** - Verify `saveToCollection()` uses selected prediction - File: `Presentation/Scenes/Identification/IdentificationViewModel.swift` - Check: Does it use `selectedPrediction` (not first prediction)? - Check: What happens if `selectedPrediction` is nil? - [ ] **T3.3** - Verify prediction-to-plant mapping - File: `Data/Mappers/PredictionToPlantMapper.swift` - Verify: `ViewPlantPrediction` → `Plant` conversion is correct - Check: All required fields populated - [ ] **T3.4** - Verify SavePlantUseCase execution - File: `Domain/UseCases/Collection/SavePlantUseCase.swift` - Trace: Repository save call - Check: Core Data persistence actually commits - [ ] **T3.5** - Verify plant appears in collection - File: `Data/Repositories/InMemoryPlantRepository.swift` (current impl) - File: `Data/DataSources/Local/CoreData/CoreDataPlantStorage.swift` - Check: Which repository is active? (DI container) - Check: Fetch returns saved plants --- ## Fix Tasks (After Investigation) ### If Selection Not Working - [ ] **F1** - Fix tap gesture if not firing - [ ] **F2** - Fix `selectPrediction()` state update - [ ] **F3** - Ensure selected state propagates to view ### If Save Not Working - [ ] **F4** - Fix `saveToCollection()` to use selected prediction - [ ] **F5** - Fix repository persistence if needed - [ ] **F6** - Ensure save success/error state updates UI --- ## Key Files Reference | Component | File Path | |-----------|-----------| | Camera View | `PlantGuide/Presentation/Scenes/Camera/CameraView.swift` | | Camera VM | `PlantGuide/Presentation/Scenes/Camera/CameraViewModel.swift` | | Identification View | `PlantGuide/Presentation/Scenes/Identification/IdentificationView.swift` | | Identification VM | `PlantGuide/Presentation/Scenes/Identification/IdentificationViewModel.swift` | | PlantNet API | `PlantGuide/Data/DataSources/Remote/PlantNetAPI/PlantNetAPIService.swift` | | API DTOs | `PlantGuide/Data/DataSources/Remote/PlantNetAPI/DTOs/PlantNetDTOs.swift` | | PlantNet Mapper | `PlantGuide/Data/Mappers/PlantNetMapper.swift` | | Prediction→Plant Mapper | `PlantGuide/Data/Mappers/PredictionToPlantMapper.swift` | | Save Use Case | `PlantGuide/Domain/UseCases/Collection/SavePlantUseCase.swift` | | Plant Repository | `PlantGuide/Data/Repositories/InMemoryPlantRepository.swift` | | Core Data Storage | `PlantGuide/Data/DataSources/Local/CoreData/CoreDataPlantStorage.swift` | | DI Container | `PlantGuide/Core/DI/DIContainer.swift` | --- ## Success Criteria 1. User can take a photo and see identification results 2. User can tap any result row and see it visually selected 3. User can tap "Save to Collection" and the SELECTED plant is saved 4. Saved plant appears in collection view 5. No crashes or error states during flow --- ## Notes - Selection issue reported by user - investigate Phase 2 first - Repository may be InMemory (lost on restart) vs CoreData (persistent) - Check DI container for which repository implementation is wired