Some checks failed
Security Scanning / Dependency License Check (pull_request) Has been cancelled
CI Pipeline / Lint Code (pull_request) Has been cancelled
CI Pipeline / Test API Package (pull_request) Has been cancelled
CI Pipeline / Test Web Package (pull_request) Has been cancelled
CI Pipeline / Test Shared Package (pull_request) Has been cancelled
Docker Build & Deploy / Build Docker Images (pull_request) Has been cancelled
E2E Tests / End-to-End Tests (pull_request) Has been cancelled
E2E Tests / E2E Tests (Mobile) (pull_request) Has been cancelled
Security Scanning / NPM Audit (pull_request) Has been cancelled
Security Scanning / Code Quality Scan (pull_request) Has been cancelled
Security Scanning / Docker Image Security (pull_request) Has been cancelled
CI Pipeline / Build All Packages (pull_request) Has been cancelled
CI Pipeline / Generate Coverage Report (pull_request) Has been cancelled
Docker Build & Deploy / Push Docker Images (pull_request) Has been cancelled
Docker Build & Deploy / Deploy to Staging (pull_request) Has been cancelled
Docker Build & Deploy / Deploy to Production (pull_request) Has been cancelled
Security Scanning / Security Summary (pull_request) Has been cancelled
Implement comprehensive solution for managing ingredient-to-instruction mappings in cooking mode. This moves from client-side state management to persistent database storage, significantly improving reliability and user experience. ## Key Changes ### Database & Backend - Add IngredientInstructionMapping table with many-to-many relationship - Implement automatic ingredient matching algorithm with smart name extraction - Add API endpoints for mapping management (update, regenerate) - Create migration script for existing recipes ### Frontend - Simplify CookingMode to read-only display of stored mappings - Add ManageIngredientMappings page with drag-and-drop editing - Remove complex client-side state management (~200 lines) - Add navigation between cooking mode and management interface ### Testing - Add 11 comprehensive unit tests for ingredient matcher service - Update integration tests with proper mocking - All new features fully tested (24/25 API tests passing) ## Benefits - Persistent mappings across all clients/devices - Automatic generation on recipe import/creation - User control via dedicated management interface - Cleaner, more maintainable codebase 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
166 lines
6.5 KiB
Markdown
166 lines
6.5 KiB
Markdown
# Pull Request: Database-Backed Ingredient-Instruction Mapping
|
|
|
|
## Summary
|
|
|
|
This PR implements a comprehensive solution for managing ingredient-to-instruction mappings in cooking mode. The feature moves from client-side state management to a persistent database-backed approach, significantly improving reliability and user experience.
|
|
|
|
## Changes
|
|
|
|
### Database Schema
|
|
- **New Table**: `IngredientInstructionMapping`
|
|
- Many-to-many relationship between ingredients and instructions
|
|
- Includes `order` field for display ordering within instructions
|
|
- Cascade delete for data integrity
|
|
- Migration: `20251031050746_add_ingredient_instruction_mapping`
|
|
|
|
### Backend (API)
|
|
|
|
#### New Service
|
|
- **`packages/api/src/services/ingredientMatcher.service.ts`**
|
|
- Automatic ingredient matching algorithm
|
|
- Extracts core ingredient names (removes quantities/units)
|
|
- Generates name variations (plural/singular)
|
|
- Finds ingredient positions in instruction text
|
|
- Prevents duplicate mappings (same ingredient appearing multiple times)
|
|
- Cross-step tracking (ingredients only appear once across all steps)
|
|
|
|
#### API Endpoints
|
|
- **Updated GET `/api/recipes/:id`**: Now includes ingredient-instruction mappings in response
|
|
- **Updated POST `/api/recipes`**: Automatically generates mappings on recipe creation
|
|
- **Updated PUT `/api/recipes/:id`**: Regenerates mappings on recipe update
|
|
- **New POST `/api/recipes/:id/ingredient-mappings`**: Manually update mappings
|
|
- **New POST `/api/recipes/:id/regenerate-mappings`**: Re-run automatic matching
|
|
|
|
### Frontend (Web)
|
|
|
|
#### Simplified Cooking Mode
|
|
- **`packages/web/src/pages/CookingMode.tsx`** - Significantly simplified
|
|
- Removed all client-side matching logic (~200 lines removed)
|
|
- Removed localStorage state management
|
|
- Removed drag-and-drop functionality
|
|
- Now purely read-only, displays database-stored mappings
|
|
- Added "⚙️ Manage Ingredients" button for editing
|
|
|
|
#### New Management Interface
|
|
- **`packages/web/src/pages/ManageIngredientMappings.tsx`** - New dedicated page
|
|
- Similar layout to cooking mode for familiarity
|
|
- Drag-and-drop ingredients to instruction steps
|
|
- Remove ingredients with ✕ button
|
|
- Real-time preview of changes
|
|
- Save to database with "💾 Save Changes" button
|
|
- Auto-regenerate with "🔄 Regenerate Auto Mappings" button
|
|
- Navigate to cooking mode with "👨🍳 Preview in Cooking Mode" button
|
|
- Unsaved changes warning banner
|
|
|
|
- **`packages/web/src/styles/ManageIngredientMappings.css`** - Dedicated styling
|
|
|
|
#### Updated Components
|
|
- **`packages/web/src/App.tsx`**: Added route for `/recipes/:id/manage-mappings`
|
|
- **`packages/web/src/services/api.ts`**: Added API methods for mapping management
|
|
- **`packages/web/src/styles/CookingMode.css`**: Removed unused drag-and-drop styles
|
|
|
|
### Shared Types
|
|
- **`packages/shared/src/types.ts`**
|
|
- Added `IngredientInstructionMapping` interface
|
|
- Updated `Ingredient` and `Instruction` to include optional mapping arrays
|
|
|
|
### Scripts
|
|
- **`packages/api/src/scripts/regenerate-mappings.ts`** - Utility script to regenerate mappings for all existing recipes
|
|
|
|
## Testing
|
|
|
|
### Test Results
|
|
- ✅ **API Tests**: 24/25 passing (96%)
|
|
- ✅ **New Ingredient Matcher Service**: 11/11 tests passing
|
|
- ✅ **Recipe Routes**: 9/9 tests passing (includes mapping integration)
|
|
- ✅ **Storage Service**: 4/5 passing (1 pre-existing S3 test failure)
|
|
- ✅ **Shared Tests**: 16/16 passing (100%)
|
|
- ⚠️ **Web Tests**: 7/15 passing (8 pre-existing failures in axios mocking setup)
|
|
|
|
### New Test Coverage
|
|
Created comprehensive unit tests for `ingredientMatcher.service.ts`:
|
|
- ✅ Simple ingredient matching
|
|
- ✅ Ingredients with quantities in names
|
|
- ✅ Plural/singular form matching
|
|
- ✅ No duplication across steps
|
|
- ✅ No duplication of same core ingredient
|
|
- ✅ Recipes with sections
|
|
- ✅ Ingredient ordering by text position
|
|
- ✅ Error handling for missing recipes
|
|
- ✅ Save mappings functionality
|
|
- ✅ Auto-map integration
|
|
|
|
### Manual Testing Performed
|
|
- ✅ Created new test recipe with automatic mapping generation
|
|
- ✅ Regenerated mappings for 5 existing recipes (Soft Sourdough, Apple Dutch Baby, Ice Cream, etc.)
|
|
- ✅ Verified mappings persist across page refreshes
|
|
- ✅ Tested drag-and-drop in management interface
|
|
- ✅ Tested remove functionality
|
|
- ✅ Tested save persistence to database
|
|
- ✅ Verified cooking mode displays stored mappings correctly
|
|
|
|
## Migration Guide
|
|
|
|
### For Existing Recipes
|
|
Run the regeneration script to generate mappings for all existing recipes:
|
|
```bash
|
|
cd packages/api
|
|
npx tsx src/scripts/regenerate-mappings.ts
|
|
```
|
|
|
|
This was already executed and successfully generated mappings for all 5 existing recipes.
|
|
|
|
### Database Migration
|
|
The migration runs automatically when deploying the API container. No manual intervention needed.
|
|
|
|
## Benefits
|
|
|
|
1. **Reliability**: Mappings are persisted in database, not client-side localStorage
|
|
2. **Consistency**: Same mappings across all clients/devices
|
|
3. **Simplicity**: Cooking mode is now read-only with no complex state management
|
|
4. **User Control**: Dedicated management interface for editing mappings
|
|
5. **Automatic**: Mappings are generated automatically on recipe import/creation
|
|
6. **Flexible**: Users can manually adjust mappings if automatic matching is incorrect
|
|
|
|
## Breaking Changes
|
|
|
|
None. This is a new feature with backward compatibility. Existing recipes work without mappings, and the system automatically generates them.
|
|
|
|
## Future Enhancements
|
|
|
|
- [ ] Add UI to manage mappings during recipe import (for recipes with ambiguous matches)
|
|
- [ ] Add reordering of ingredients within instructions (drag-and-drop reorder)
|
|
- [ ] Add bulk mapping tools (e.g., "map all ingredients to step 1")
|
|
- [ ] Add mapping analytics/suggestions based on common patterns
|
|
|
|
## Screenshots
|
|
|
|
### Cooking Mode (Read-Only)
|
|
- Clean, distraction-free interface
|
|
- Ingredients listed inline with each step
|
|
- No edit controls visible
|
|
|
|
### Manage Ingredient Mappings
|
|
- Drag ingredients from top section to instruction steps
|
|
- Remove with ✕ button
|
|
- Save changes button persists to database
|
|
- Regenerate button re-runs automatic matching
|
|
|
|
## Related Issues
|
|
|
|
Fixes issues with ingredient mapping:
|
|
- Ingredients duplicating when dragging
|
|
- Remove button not working
|
|
- Changes not persisting across clients
|
|
- Complex client-side state management
|
|
|
|
## Review Checklist
|
|
|
|
- [x] Database migration created and tested
|
|
- [x] API tests updated and passing
|
|
- [x] Frontend tests updated (some pre-existing failures remain)
|
|
- [x] Manual testing completed
|
|
- [x] Documentation updated
|
|
- [x] No breaking changes
|
|
- [x] Backward compatible
|