# Inventory Service ## Overview The **Inventory Service** is the operational backbone of Bakery-IA, managing ingredient tracking, stock levels, expiration dates, and food safety compliance. It implements FIFO (First-In-First-Out) consumption logic, automated low-stock alerts, and HACCP-compliant temperature monitoring. This service is critical for achieving zero food waste, maintaining food safety standards, and ensuring bakeries never run out of essential ingredients. ## Key Features ### Comprehensive Ingredient Management - **Ingredient Catalog** - Complete database of all ingredients with categories - **Stock Tracking** - Real-time stock levels with FIFO consumption - **Batch Tracking** - Lot numbers and traceability for food safety - **Expiration Management** - Automated expiry alerts and FIFO rotation - **Low Stock Alerts** - Configurable threshold notifications - **Barcode Support** - Barcode scanning for quick stock updates - **Multi-Location** - Track inventory across multiple storage locations ### Stock Movement Tracking - **In/Out Transactions** - Complete audit trail of stock movements - **Product Transformations** - Track ingredient consumption in production - **Adjustment Logging** - Record inventory adjustments with reasons - **Historical Analysis** - Analyze consumption patterns over time - **Waste Tracking** - Monitor and categorize waste (expired, damaged, etc.) ### Food Safety Compliance (HACCP) - **Temperature Monitoring** - Critical control point temperature logs - **Food Safety Alerts** - Automated safety notifications - **Compliance Tracking** - HACCP compliance audit trail - **Expiry Management** - Prevent use of expired ingredients - **Lot Traceability** - Complete ingredient traceability - **Safety Checklists** - Digital food safety inspection forms ### Sustainability & Reporting - **Waste Reduction Tracking** - Monitor progress toward zero waste - **Environmental Impact** - Carbon footprint and sustainability metrics - **SDG Compliance** - Sustainable Development Goals reporting - **Grant Reporting** - EU grant compliance reports - **Business Model Detection** - Auto-detect B2B/B2C inventory patterns ### Dashboard & Analytics - **Real-Time KPIs** - Current stock levels, expiring items, low stock warnings - **Consumption Analytics** - Usage patterns and forecasting input - **Valuation Reports** - Current inventory value and cost tracking - **Reorder Recommendations** - Intelligent reorder point suggestions - **Expiry Calendar** - Visual timeline of expiring products ## Business Value ### For Bakery Owners - **Zero Food Waste Goal** - Reduce waste 20-40% through expiry management and FIFO - **Food Safety Compliance** - HACCP compliance built-in, avoid health violations - **Cost Control** - Track inventory value, prevent over-purchasing - **Never Stock Out** - Automated low-stock alerts ensure continuous operations - **Traceability** - Complete ingredient tracking for recalls and audits ### Quantifiable Impact - **Waste Reduction**: 20-40% through FIFO and expiry management - **Cost Savings**: €200-600/month from reduced waste and better purchasing - **Time Savings**: 8-12 hours/week on manual inventory tracking - **Compliance**: 100% HACCP compliance, avoid €5,000+ fines - **Inventory Accuracy**: 95%+ vs. 70-80% with manual tracking ### For Operations Managers - **Multi-Location Visibility** - See all inventory across locations - **Automated Reordering** - System suggests what and when to order - **Waste Analysis** - Identify patterns and reduce waste - **Compliance Reporting** - Generate HACCP reports for inspections ## Technology Stack - **Framework**: FastAPI (Python 3.11+) - Async web framework - **Database**: PostgreSQL 17 - Ingredient and stock data - **Caching**: Redis 7.4 - Dashboard KPI cache - **Messaging**: RabbitMQ 4.1 - Alert publishing - **ORM**: SQLAlchemy 2.0 (async) - Database abstraction - **Logging**: Structlog - Structured JSON logging - **Metrics**: Prometheus Client - Custom metrics ## API Endpoints (Key Routes) ### Ingredient Management - `POST /api/v1/inventory/ingredients` - Create ingredient - `GET /api/v1/inventory/ingredients` - List all ingredients - `GET /api/v1/inventory/ingredients/{ingredient_id}` - Get ingredient details - `PUT /api/v1/inventory/ingredients/{ingredient_id}` - Update ingredient - `DELETE /api/v1/inventory/ingredients/{ingredient_id}` - Delete ingredient ### Stock Management - `GET /api/v1/inventory/stock` - List current stock levels - `GET /api/v1/inventory/stock/{stock_id}` - Get stock item details - `POST /api/v1/inventory/stock/adjustment` - Adjust stock levels - `POST /api/v1/inventory/stock/receive` - Receive new stock - `POST /api/v1/inventory/stock/consume` - Consume stock (production use) - `GET /api/v1/inventory/stock/movements` - Stock movement history ### Alerts & Monitoring - `GET /api/v1/inventory/alerts` - Get active alerts - `GET /api/v1/inventory/alerts/low-stock` - Low stock items - `GET /api/v1/inventory/alerts/expiring` - Items expiring soon - `POST /api/v1/inventory/alerts/configure` - Configure alert thresholds ### Food Safety - `GET /api/v1/inventory/food-safety/compliance` - HACCP compliance status - `POST /api/v1/inventory/food-safety/temperature-log` - Log temperature reading - `GET /api/v1/inventory/food-safety/temperature-logs` - Temperature history - `POST /api/v1/inventory/food-safety/alert` - Report food safety issue ### Analytics & Reporting - `GET /api/v1/inventory/dashboard` - Dashboard KPIs - `GET /api/v1/inventory/analytics/consumption` - Consumption patterns - `GET /api/v1/inventory/analytics/waste` - Waste analysis - `GET /api/v1/inventory/analytics/valuation` - Current inventory value - `GET /api/v1/inventory/reports/haccp` - HACCP compliance report - `GET /api/v1/inventory/reports/sustainability` - Sustainability report ## Database Schema ### Main Tables **ingredients** ```sql CREATE TABLE ingredients ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, name VARCHAR(255) NOT NULL, category VARCHAR(100), -- flour, sugar, dairy, etc. unit VARCHAR(50) NOT NULL, -- kg, liters, units supplier_id UUID, reorder_point DECIMAL(10, 2), -- Minimum stock level reorder_quantity DECIMAL(10, 2), -- Standard order quantity unit_cost DECIMAL(10, 2), barcode VARCHAR(100), storage_location VARCHAR(255), storage_temperature_min DECIMAL(5, 2), storage_temperature_max DECIMAL(5, 2), shelf_life_days INTEGER, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), UNIQUE(tenant_id, name) ); ``` **stock** ```sql CREATE TABLE stock ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, ingredient_id UUID REFERENCES ingredients(id), quantity DECIMAL(10, 2) NOT NULL, unit VARCHAR(50) NOT NULL, lot_number VARCHAR(100), received_date DATE NOT NULL, expiry_date DATE, supplier_id UUID, location VARCHAR(255), unit_cost DECIMAL(10, 2), status VARCHAR(50) DEFAULT 'available', -- available, reserved, expired, damaged created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), INDEX idx_tenant_ingredient (tenant_id, ingredient_id), INDEX idx_expiry (expiry_date), INDEX idx_status (status) ); ``` **stock_movements** ```sql CREATE TABLE stock_movements ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, stock_id UUID REFERENCES stock(id), ingredient_id UUID REFERENCES ingredients(id), movement_type VARCHAR(50) NOT NULL, -- in, out, adjustment, waste, production quantity DECIMAL(10, 2) NOT NULL, unit VARCHAR(50) NOT NULL, reference_id UUID, -- production_batch_id, order_id, etc. reference_type VARCHAR(50), -- production, sale, adjustment, waste reason TEXT, performed_by UUID, created_at TIMESTAMP DEFAULT NOW(), INDEX idx_tenant_date (tenant_id, created_at), INDEX idx_ingredient (ingredient_id) ); ``` **stock_alerts** ```sql CREATE TABLE stock_alerts ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, ingredient_id UUID REFERENCES ingredients(id), alert_type VARCHAR(50) NOT NULL, -- low_stock, expiring_soon, expired, temperature severity VARCHAR(20) NOT NULL, -- low, medium, high, urgent message TEXT NOT NULL, current_quantity DECIMAL(10, 2), threshold_quantity DECIMAL(10, 2), expiry_date DATE, days_until_expiry INTEGER, is_acknowledged BOOLEAN DEFAULT FALSE, acknowledged_at TIMESTAMP, acknowledged_by UUID, created_at TIMESTAMP DEFAULT NOW(), INDEX idx_tenant_active (tenant_id, is_acknowledged) ); ``` **product_transformations** ```sql CREATE TABLE product_transformations ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, production_batch_id UUID, ingredient_id UUID REFERENCES ingredients(id), quantity_consumed DECIMAL(10, 2) NOT NULL, unit VARCHAR(50) NOT NULL, stock_consumed JSONB, -- Array of stock IDs with quantities (FIFO) created_at TIMESTAMP DEFAULT NOW() ); ``` **food_safety_compliance** ```sql CREATE TABLE food_safety_compliance ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, compliance_type VARCHAR(100), -- haccp, temperature, expiry, cleaning check_date DATE NOT NULL, status VARCHAR(50) NOT NULL, -- compliant, non_compliant, warning details TEXT, corrective_actions TEXT, verified_by UUID, created_at TIMESTAMP DEFAULT NOW() ); ``` **temperature_logs** ```sql CREATE TABLE temperature_logs ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, location VARCHAR(255) NOT NULL, -- freezer_1, fridge_2, storage_room temperature DECIMAL(5, 2) NOT NULL, unit VARCHAR(10) DEFAULT 'C', is_within_range BOOLEAN, min_acceptable DECIMAL(5, 2), max_acceptable DECIMAL(5, 2), recorded_by UUID, recorded_at TIMESTAMP DEFAULT NOW(), INDEX idx_tenant_location (tenant_id, location, recorded_at) ); ``` **food_safety_alerts** ```sql CREATE TABLE food_safety_alerts ( id UUID PRIMARY KEY, tenant_id UUID NOT NULL, alert_type VARCHAR(100), -- temperature_violation, expired_used, contamination severity VARCHAR(20) NOT NULL, location VARCHAR(255), ingredient_id UUID, description TEXT, corrective_action_required TEXT, status VARCHAR(50) DEFAULT 'open', -- open, investigating, resolved resolved_at TIMESTAMP, created_at TIMESTAMP DEFAULT NOW() ); ``` ## Events & Messaging ### Published Events (RabbitMQ) **Exchange**: `inventory` **Routing Keys**: `inventory.low_stock`, `inventory.expiring`, `inventory.food_safety` **Low Stock Alert Event** ```json { "event_type": "low_stock_alert", "tenant_id": "uuid", "ingredient_id": "uuid", "ingredient_name": "Harina integral", "current_quantity": 15.5, "unit": "kg", "reorder_point": 50.0, "recommended_order_quantity": 100.0, "days_until_stockout": 3, "severity": "high", "message": "Stock bajo: Harina integral (15.5 kg). Punto de reorden: 50 kg.", "timestamp": "2025-11-06T10:30:00Z" } ``` **Expiring Soon Alert Event** ```json { "event_type": "expiring_soon_alert", "tenant_id": "uuid", "stock_id": "uuid", "ingredient_id": "uuid", "ingredient_name": "Leche fresca", "quantity": 20.0, "unit": "liters", "lot_number": "LOT-2025-1105", "expiry_date": "2025-11-09", "days_until_expiry": 3, "location": "Nevera 1", "severity": "medium", "message": "Leche fresca expira en 3 días (20 litros, LOT-2025-1105)", "recommended_action": "Usar en producción antes del 09/11/2025", "timestamp": "2025-11-06T10:30:00Z" } ``` **Food Safety Alert Event** ```json { "event_type": "food_safety_alert", "tenant_id": "uuid", "alert_type": "temperature_violation", "severity": "urgent", "location": "Congelador 2", "temperature": -12.5, "acceptable_range": { "min": -18.0, "max": -15.0 }, "duration_minutes": 45, "affected_items": ["uuid1", "uuid2"], "message": "Violación de temperatura en Congelador 2: -12.5°C (rango: -18°C a -15°C)", "corrective_action_required": "Revisar congelador inmediatamente y verificar integridad de productos", "timestamp": "2025-11-06T10:30:00Z" } ``` ### Consumed Events - **From Procurement**: Stock received from suppliers - **From Production**: Ingredient consumption in production - **From Sales**: Finished product sales (for inventory valuation) ## Custom Metrics (Prometheus) ```python # Stock level metrics stock_quantity_gauge = Gauge( 'inventory_stock_quantity', 'Current stock quantity', ['tenant_id', 'ingredient_id', 'ingredient_name'] ) low_stock_items_total = Gauge( 'inventory_low_stock_items', 'Number of items below reorder point', ['tenant_id'] ) expiring_items_total = Gauge( 'inventory_expiring_items', 'Number of items expiring within 7 days', ['tenant_id'] ) # Waste metrics waste_quantity = Counter( 'inventory_waste_quantity_total', 'Total waste quantity', ['tenant_id', 'ingredient_category', 'reason'] # expired, damaged, etc. ) waste_value_euros = Counter( 'inventory_waste_value_euros_total', 'Total waste value in euros', ['tenant_id'] ) # Inventory valuation inventory_value_total = Gauge( 'inventory_value_euros', 'Total inventory value', ['tenant_id'] ) # Food safety metrics temperature_violations = Counter( 'inventory_temperature_violations_total', 'Temperature violations detected', ['tenant_id', 'location'] ) food_safety_alerts_total = Counter( 'inventory_food_safety_alerts_total', 'Food safety alerts generated', ['tenant_id', 'alert_type', 'severity'] ) ``` ## Configuration ### Environment Variables **Service Configuration:** - `PORT` - Service port (default: 8005) - `DATABASE_URL` - PostgreSQL connection string - `REDIS_URL` - Redis connection string - `RABBITMQ_URL` - RabbitMQ connection string **Alert Configuration:** - `LOW_STOCK_CHECK_INTERVAL_HOURS` - How often to check (default: 6) - `EXPIRY_WARNING_DAYS` - Days before expiry to alert (default: 7) - `URGENT_EXPIRY_DAYS` - Days for urgent expiry alerts (default: 3) - `ENABLE_AUTO_ALERTS` - Automatic alert generation (default: true) **FIFO Configuration:** - `ENABLE_FIFO_ENFORCEMENT` - Enforce FIFO consumption (default: true) - `FIFO_VIOLATION_ALERT` - Alert on FIFO violations (default: true) **Food Safety Configuration:** - `TEMPERATURE_CHECK_INTERVAL_MINUTES` - Temp log frequency (default: 60) - `TEMPERATURE_VIOLATION_THRESHOLD_MINUTES` - Time before alert (default: 30) - `ENABLE_HACCP_COMPLIANCE` - Enable HACCP tracking (default: true) **Sustainability Configuration:** - `TRACK_CARBON_FOOTPRINT` - Enable carbon tracking (default: true) - `TRACK_SDG_METRICS` - Enable SDG reporting (default: true) ## Development Setup ### Prerequisites - Python 3.11+ - PostgreSQL 17 - Redis 7.4 - RabbitMQ 4.1 (optional) ### Local Development ```bash cd services/inventory python -m venv venv source venv/bin/activate pip install -r requirements.txt export DATABASE_URL=postgresql://user:pass@localhost:5432/inventory export REDIS_URL=redis://localhost:6379/0 export RABBITMQ_URL=amqp://guest:guest@localhost:5672/ alembic upgrade head python main.py ``` ### Testing ```bash # Unit tests pytest tests/unit/ -v # Integration tests pytest tests/integration/ -v # FIFO logic tests pytest tests/test_fifo.py -v # Test with coverage pytest --cov=app tests/ --cov-report=html ``` ## Integration Points ### Dependencies - **Procurement Service** - Receive stock from purchase orders - **Production Service** - Consume ingredients in production - **Forecasting Service** - Provide consumption data for forecasts - **Suppliers Service** - Supplier information for stock items - **PostgreSQL** - Inventory data storage - **Redis** - Dashboard KPI cache - **RabbitMQ** - Alert publishing ### Dependents - **Production Service** - Check ingredient availability - **Procurement Service** - Get reorder recommendations - **AI Insights Service** - Analyze inventory patterns - **Frontend Dashboard** - Display inventory status - **Notification Service** - Send inventory alerts ## FIFO Implementation ### FIFO Consumption Logic ```python async def consume_ingredient_fifo( tenant_id: str, ingredient_id: str, quantity_needed: float ) -> list[dict]: """Consume ingredients using FIFO (First-In-First-Out)""" # Get available stock ordered by received_date (oldest first) available_stock = await db.query(Stock).filter( Stock.tenant_id == tenant_id, Stock.ingredient_id == ingredient_id, Stock.status == 'available', Stock.quantity > 0 ).order_by(Stock.received_date.asc()).all() consumed_items = [] remaining_needed = quantity_needed for stock_item in available_stock: if remaining_needed <= 0: break quantity_to_consume = min(stock_item.quantity, remaining_needed) # Update stock quantity stock_item.quantity -= quantity_to_consume if stock_item.quantity == 0: stock_item.status = 'depleted' # Record consumption consumed_items.append({ 'stock_id': stock_item.id, 'lot_number': stock_item.lot_number, 'quantity_consumed': quantity_to_consume, 'received_date': stock_item.received_date, 'expiry_date': stock_item.expiry_date }) remaining_needed -= quantity_to_consume if remaining_needed > 0: raise InsufficientStockError( f"Insufficient stock. Needed: {quantity_needed}, " f"Available: {quantity_needed - remaining_needed}" ) await db.commit() return consumed_items ``` ## Security Measures ### Data Protection - **Tenant Isolation** - All inventory scoped to tenant_id - **Input Validation** - Validate all quantities and dates - **Audit Trail** - Complete history of stock movements - **Access Control** - Role-based permissions ### Food Safety Security - **Temperature Log Integrity** - Tamper-proof temperature records - **Lot Traceability** - Complete ingredient tracking for recalls - **Audit Compliance** - HACCP-compliant record keeping - **Alert Escalation** - Critical food safety alerts escalate automatically ## Troubleshooting ### Common Issues **Issue**: FIFO not working correctly - **Cause**: Stock items missing received_date - **Solution**: Ensure all stock has received_date set **Issue**: Low stock alerts not firing - **Cause**: Reorder points not configured - **Solution**: Set reorder_point for each ingredient **Issue**: Expiry alerts too frequent - **Cause**: `EXPIRY_WARNING_DAYS` set too high - **Solution**: Adjust to 3-5 days instead of 7 **Issue**: Temperature violations not detected - **Cause**: Temperature logs not being recorded - **Solution**: Check temperature monitoring device integration ## Competitive Advantages 1. **FIFO Enforcement** - Automatic expiry prevention 2. **Food Safety Built-In** - HACCP compliance out-of-the-box 3. **Sustainability Tracking** - SDG reporting for EU grants 4. **Barcode Support** - Quick stock updates 5. **Multi-Location** - Track inventory across sites 6. **Spanish Market** - HACCP compliant for Spanish regulations 7. **Zero Waste Focus** - Waste reduction analytics ## Future Enhancements - **IoT Sensor Integration** - Automatic temperature monitoring - **AI-Powered Reorder Points** - Dynamic reorder point calculation - **Image Recognition** - Photo-based stock counting - **Blockchain Traceability** - Immutable ingredient tracking - **Mobile Barcode App** - Smartphone barcode scanning - **Supplier Integration** - Direct supplier ordering - **Predictive Expiry** - Predict expiry based on storage conditions --- **For VUE Madrid Business Plan**: The Inventory Service demonstrates commitment to food safety (HACCP compliance), sustainability (20-40% waste reduction), and operational excellence. The FIFO enforcement and expiry management features directly address EU food waste regulations and support SDG goals, making this ideal for grant applications. The €200-600/month cost savings and compliance benefits provide clear ROI for bakery owners.