Created comprehensive proposal document analyzing how to add product lots with expiration dates to the InventorySetupStep during onboarding. Key recommendations: - Use inline stock entry approach after each ingredient - Support multiple lots per ingredient with different expiration dates - Include smart features: auto-suggest expiration, validation warnings - Phase 1 MVP: basic lot entry with quantity, expiration, supplier - Phase 2: Multi-lot support - Phase 3: Smart features and auto-suggestions Document includes: - Current state analysis of inventory system - JTBD alignment with detailed references - 3 detailed UI/UX options with mockups - Implementation recommendations with code examples - Success metrics and risk mitigation - 4-phase rollout plan This addresses critical gap where users complete onboarding with zero actual stock in system, preventing immediate value from FIFO, expiration alerts, and waste prevention features.
19 KiB
Proposal: Add Product Lots with Expiration Dates to Inventory Onboarding
Date: 2025-11-06 Status: Proposal for Review Context: Enhance InventorySetupStep in onboarding to support lot/batch management with expiration tracking
📋 Executive Summary
Problem: Current inventory onboarding only creates ingredient definitions (master data) without actual stock quantities or expiration tracking. This creates a critical gap for bakeries managing perishable ingredients.
Solution: Enhance the InventorySetupStep to allow users to add one or more stock lots per ingredient, including quantities and expiration dates, using a simplified version of the existing AddStockModal pattern.
Impact:
- ✅ Immediate inventory visibility from day one
- ✅ FIFO (First-In-First-Out) management ready
- ✅ Expiration alerts functional immediately
- ✅ Waste prevention starts on day one
- ✅ Better data quality for AI forecasting
🔍 Current State Analysis
What Exists Today
-
InventorySetupStep (Onboarding):
- Creates ingredient definitions (master data)
- No stock quantities
- No expiration dates
- Users define WHAT they have, not HOW MUCH
-
InitialStockEntryStep (AI-Assisted Path Only):
- Simple quantity entry
- No expiration dates
- No lot/batch numbers
- No multi-lot support
-
AddStockModal (Post-Onboarding):
- Comprehensive lot management
- Expiration dates, batch numbers, storage requirements
- Used after onboarding is complete
The Gap
Users complete onboarding with:
- ✅ Ingredients defined (master data)
- ❌ Zero actual stock in system
- ❌ No expiration tracking
- ❌ Cannot use FIFO/waste alerts
- ❌ Must manually add stock post-onboarding
Impact of Gap:
- System shows "0 stock" for everything
- No expiration alerts for weeks/months
- Forecasting starts with no data
- Poor first impression ("Why is everything empty?")
🎯 JTBD Alignment
Primary Jobs Addressed
From JTBD Analysis (docs/jtbd-analysis-inventory-setup.md):
-
"Help me understand dependencies" (Line 347-349)
- Need: Know what I need before I can do something else
- Solution: Add stock immediately after defining ingredients
-
"Tell me if I'm doing it right" (Line 331-334)
- Need: Real-time validation and helpful error messages
- Solution: Validate expiration dates, warn about near-expiry stock
-
"Don't make me think" (Line 336-339)
- Need: Smart defaults, suggested values
- Solution: Auto-suggest expiration based on ingredient type
-
"Set up foundational data correctly" (Line 100-104)
- Sub-job: Add inventory items - "What do they cost? When should I reorder?"
- Solution: Add actual quantities with dates during setup
Forces of Progress
Push Forces (Lines 153-172):
- Waste and inefficiency: Overordering leads to spoilage ✅ Directly addressed
- Manual tracking unreliable: No visibility into stock levels ✅ Directly addressed
Pull Forces (Lines 173-194):
- Real-time inventory tracking: Start from day one ✅ Enabled
- Peace of mind: Always know what's in stock ✅ Enabled
Anxiety Forces to Mitigate (Lines 195-220):
- Fear of complexity: Keep it simple, optional ✅ Simplified form
- Time pressure: Make it quick and skipable ✅ Optional step
- Uncertainty about requirements: Clear guidance ✅ Contextual help
💡 Proposed Solution
Approach: "Quick Stock Entry" After Each Ingredient
Core Concept: After adding an ingredient in InventorySetupStep, immediately prompt to add initial stock (optional but encouraged).
User Flow
1. User adds ingredient (e.g., "All-Purpose Flour")
└─> Ingredient created ✓
2. System shows inline prompt:
"Add initial stock for Flour?"
[Add Stock] [Skip for Now]
3. If user clicks [Add Stock]:
└─> Simplified stock entry form appears inline
└─> User enters:
- Quantity (required)
- Expiration date (optional but recommended)
- Supplier (optional, dropdown from existing)
- Batch/Lot number (optional)
└─> [Save Stock] [Add Another Lot] [Cancel]
4. Stock saved ✓
└─> Shows summary: "20 kg expires on 2025-12-15"
└─> Option to [Add Another Lot] for same ingredient
5. User continues to next ingredient or completes step
Alternative: Dedicated "Stock Entry" Sub-Step
Two-phase approach within InventorySetupStep:
Phase 1: Add Ingredients (current behavior) Phase 2: Add Stock Lots (new)
┌─────────────────────────────────────────┐
│ Inventory Setup │
│ │
│ [✓ Add Ingredients] [→ Add Stock] │
│ │
│ You've added 8 ingredients │
│ │
│ Would you like to add initial stock │
│ quantities and expiration dates? │
│ │
│ ○ Yes, add stock now (recommended) │
│ Track quantities and prevent waste │
│ │
│ ○ Skip for now │
│ Add stock later from inventory page │
│ │
│ [Continue →] │
└─────────────────────────────────────────┘
If user selects "Yes":
- Shows list of ingredients
- Each ingredient has [+ Add Stock] button
- Inline form appears per ingredient
- Can add multiple lots per ingredient
🎨 UI/UX Design Recommendations
Option 1: Inline Stock Entry (Recommended)
Advantages:
- ✅ Contextual - add stock right after defining ingredient
- ✅ Minimal cognitive load
- ✅ Clear cause-and-effect relationship
- ✅ Natural flow
Design:
┌─────────────────────────────────────────────────────────┐
│ All-Purpose Flour [Edit] │
│ Category: Flour | Unit: kg | Cost: $1.50/kg │
├─────────────────────────────────────────────────────────┤
│ │
│ 📦 Add Initial Stock (Optional) │
│ │
│ Quantity (kg) * Expiration Date │
│ [ 25.0 ] [ 2025-12-15 ] 📅 │
│ │
│ Supplier Batch/Lot Number │
│ [Mill Brothers ▼] [ LOT-2024-11 ] │
│ │
│ [✓ Save Stock] [+ Add Another Lot] [Skip] │
│ │
│ ℹ️ Expiration tracking helps prevent waste and enables │
│ First-In-First-Out (FIFO) inventory management │
└─────────────────────────────────────────────────────────┘
Option 2: Separate Stock Entry Screen
Advantages:
- ✅ Clearer separation of concerns
- ✅ Can see all ingredients at once
- ✅ Bulk actions possible
- ✅ Better for users with many items
Design:
┌─────────────────────────────────────────────────────────┐
│ Step 2/2: Add Initial Stock Quantities │
│ │
│ Add stock for the ingredients you just created. │
│ This is optional but recommended for accurate tracking. │
│ │
│ Progress: 3 of 8 ingredients have stock │
│ [████░░░░░░] 38% │
│ │
├─────────────────────────────────────────────────────────┤
│ All-Purpose Flour [Add Stock] │
│ Quantity: 25 kg | Expires: 2025-12-15 [✓ Added] │
│ │
│ Bread Flour [Add Stock] │
│ No stock added yet [+ Add] │
│ │
│ Active Dry Yeast [Add Stock] │
│ Quantity: 2 kg | Expires: 2025-11-30 [✓ Added] │
│ │
│ ... (5 more ingredients) │
│ │
│ │
│ [Skip All] [Continue →] │
└─────────────────────────────────────────────────────────┘
Option 3: Simplified "Quick Add" Modal (Hybrid)
Advantages:
- ✅ Focused attention on stock entry
- ✅ Can reuse existing AddStockModal design
- ✅ Familiar pattern for users
- ✅ Easy to implement
Design:
┌─────────────────────────────────────────┐
│ Add Stock: All-Purpose Flour │
├─────────────────────────────────────────┤
│ │
│ Current Quantity * │
│ [ 25.0 ] kg │
│ │
│ Expiration Date │
│ [ 2025-12-15 ] 📅 │
│ ⚠️ This ingredient expires in 40 days │
│ │
│ Supplier (Optional) │
│ [ Mill Brothers ▼ ] │
│ │
│ Batch/Lot Number (Optional) │
│ [ LOT-2024-11 ] │
│ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ │
│ [Save & Add Another Lot] │
│ [Save & Close] │
│ [Cancel] │
└─────────────────────────────────────────┘
🏗️ Implementation Recommendations
Recommended Approach: Option 1 - Inline Stock Entry
Why:
- Most aligned with JTBD principle "Don't make me think"
- Natural flow - no context switching
- Progressive disclosure - only shows when relevant
- Maintains momentum in onboarding
- Optional but visible - encourages action without forcing it
Form Fields (Simplified)
Required:
current_quantity(number)
Recommended (show by default):
expiration_date(date picker)supplier_id(select from existing suppliers)
Optional (collapsed/advanced):
batch_number(text)lot_number(text)received_date(date, default: today)storage_location(text/select)unit_cost(number, default from ingredient)
Not included (use ingredient defaults):
- Storage requirements (refrigeration, etc.) - use from ingredient
- Production stage - default to RAW_INGREDIENT
- Quality status - default to "good"
Smart Defaults & Auto-Suggestions
-
Expiration Date Suggestions:
If ingredient.is_perishable && ingredient.shelf_life_days: Suggest: today + shelf_life_days Show: "Typical shelf life: 30 days → Expires: 2025-12-06" -
Supplier Pre-Selection:
If only 1 supplier exists: Auto-select it If ingredient previously purchased from supplier: Pre-select that supplier -
Batch Number Generation:
Offer to auto-generate: "BATCH-[DATE]-[INCREMENT]" Example: "BATCH-20251106-001"
Validation Rules
// Frontend validation
if (currentQuantity <= 0) {
error("Quantity must be greater than zero")
}
if (expirationDate && expirationDate < today) {
warning("This date is in the past. Is this correct?")
}
if (expirationDate && expirationDate < today + 3 days) {
alert("⚠️ This ingredient expires very soon!")
}
if (expirationDate && expirationDate > today + 365 days) {
warning("Unusual expiration date (> 1 year). Please verify.")
}
// Suggest storage requirements
if (ingredient.category === 'dairy' && !storage_location) {
suggest("Consider adding storage location: Refrigerator")
}
User Guidance
Contextual Help Text:
- "Expiration tracking helps prevent waste and enables First-In-First-Out (FIFO) management"
- "Add multiple lots if you have ingredients with different expiration dates"
- "You can always add more stock later from the Inventory page"
Empty State:
- "No stock added yet. The system will show 0 available until you add stock."
Success Feedback:
- "✓ Stock added: 25 kg expires on 2025-12-15"
- "You can add another lot if you have more with a different expiration date"
📊 Success Metrics
Leading Indicators
-
Stock Entry Rate: % of ingredients with at least one stock lot added during onboarding
- Target: 60%+ (users add stock for most ingredients)
-
Expiration Date Completeness: % of stock lots with expiration dates
- Target: 80%+ for perishable items, 40%+ overall
-
Multi-Lot Usage: % of ingredients with 2+ stock lots
- Target: 20%+ (shows understanding of lot concept)
-
Time to Complete: Average time spent on stock entry
- Target: < 2 minutes per ingredient
-
Skip Rate: % of users who skip stock entry
- Target: < 40% (most users add at least some stock)
Lagging Indicators
-
Expiration Alert Effectiveness: % of expired items caught before use
- Target: 90%+ (shows system is working)
-
Waste Reduction: Compare waste rates pre/post implementation
- Target: 15% reduction in expired ingredient waste
-
System Usage: % of users actively using inventory tracking
- Target: 85%+ weekly active users
-
User Satisfaction: NPS score for inventory setup
- Target: +40 or higher
Data Quality Metrics
-
Stock Accuracy: % of stock records with complete data
- Measure: quantity, expiration date, supplier filled out
-
FIFO Compliance: % of stock consumption following FIFO
- Measure via stock movement logs
🚀 Implementation Phases
Phase 1: MVP - Basic Lot Entry (Week 1-2)
Scope:
- Inline stock entry form after ingredient creation
- Fields: quantity, expiration date, supplier
- Single lot per ingredient
- Skip option clearly visible
Success Criteria:
- Users can add at least one stock lot per ingredient
- Expiration dates are captured
- Can skip if desired
Phase 2: Enhanced - Multi-Lot Support (Week 3)
Scope:
- "Add Another Lot" button
- Support multiple lots per ingredient with different expiration dates
- Visual list of lots added
- Edit/delete lots before completing step
Success Criteria:
- Users can add 2+ lots for same ingredient
- Clear visual feedback of lots added
- Easy to manage multiple lots
Phase 3: Smart Features (Week 4-5)
Scope:
- Auto-suggest expiration dates based on shelf life
- Batch number auto-generation
- Supplier pre-selection logic
- Advanced validation warnings
- Contextual help tooltips
Success Criteria:
- 50%+ of users use at least one smart feature
- Reduced data entry errors
- Faster completion times
Phase 4: Bulk & Import (Future)
Scope:
- Bulk stock entry (CSV import)
- Copy from previous orders
- Templates for common stock patterns
Success Criteria:
- Power users can import dozens of lots quickly
- Support for large-scale bakeries
🎯 Recommended Next Steps
-
Validate with Users (2-3 days)
- Interview 3-5 bakery owners
- Show mockups of Option 1, 2, 3
- Ask: "Which feels most natural? What's confusing?"
-
Create Detailed Designs (1 week)
- High-fidelity mockups of chosen option
- Mobile responsive designs
- Interaction specifications
- Error state designs
-
Technical Spike (2-3 days)
- Verify API support for batch stock creation
- Test performance with multiple lots
- Identify any backend changes needed
-
Implement Phase 1 (2 weeks)
- Build MVP inline stock entry
- Unit tests for validation
- Integration with existing inventory hooks
-
User Testing (3-5 days)
- Usability testing with 5-8 users
- Measure completion time, skip rate
- Collect qualitative feedback
-
Iterate & Launch Phase 2 (1-2 weeks)
- Address feedback from testing
- Add multi-lot support
- Launch to production
🔒 Risk Mitigation
Risk 1: Users Feel Overwhelmed
Mitigation:
- Make stock entry optional but recommended
- Progressive disclosure - show advanced fields only if needed
- Clear "Skip" option with explanation
- Celebrate small wins ("3 of 8 done!")
Risk 2: Takes Too Long
Mitigation:
- Simplify form to essential fields only
- Smart defaults reduce typing
- Allow saving and resuming later
- Bulk actions in Phase 4
Risk 3: Poor Data Quality
Mitigation:
- Real-time validation
- Contextual warnings
- Educational tooltips
- Show impact: "Expiration tracking helps prevent $X waste/month"
Risk 4: Technical Complexity
Mitigation:
- Reuse existing AddStockModal logic
- Build incrementally (MVP first)
- Leverage existing API endpoints
- Thorough testing before launch
📚 References
- JTBD Analysis:
docs/jtbd-analysis-inventory-setup.md - Inventory API Types:
frontend/src/api/types/inventory.ts(lines 179-308) - Existing Components:
AddStockModal.tsx- Full stock entry modalInitialStockEntryStep.tsx- Simple quantity entryInventorySetupStep.tsx- Current ingredient creation
✅ Conclusion
Adding lot/batch management with expiration tracking to the inventory onboarding step directly addresses critical JTBD needs, reduces waste, and enables immediate system value. The recommended inline approach balances simplicity with power, making it easy for users while capturing essential data for bakery operations.
Recommendation: Proceed with Option 1 (Inline Stock Entry) → Phase 1 MVP → User Validation → Iterate based on feedback.
Document Owner: Product & Engineering Team Status: Awaiting Approval Next Review: After user validation interviews