03 // Backend · Automation 2025 – 2026

Food Management System

Full-stack Flask application automating kitchen inventory, BOM calculation, and menu generation — saving ~3 hours of manual work per day for kitchen operations teams.

200+Ingredients Tracked
50+Menu Items
~3hrsSaved / Day
AutoBOM Generator
Overview

Restaurant and canteen kitchens lose significant time to manual inventory tracking — staff physically count stock, manually calculate ingredient requirements for each dish (BOM), and re-enter data across spreadsheets. This system eliminates that entirely.

The Food Management System provides a unified web interface where kitchen staff log usage, the backend automatically deducts from inventory, generates Bill of Materials for any menu combination, and fires low-stock alerts — all in real time. What took 3 hours of spreadsheet work now happens automatically on each order entry.

Tech Stack

🐍Python 3.11
🌶️Flask (Full-Stack)
🗄️SQLite / SQLAlchemy ORM
🔗Jinja2 Templates
⚙️BOM Calculation Engine
📧Alert System (Low Stock)
⚙️ System Architecture

How the System is Built

👨‍🍳
Kitchen Staff
Web UI input · Order entry
🌐
Flask Web App
Routes · Jinja2 views · REST API
⚙️
BOM Engine
Recipe lookup · Qty calculation
🗄️
Inventory DB
SQLite · Real-time deduction
📊
Reports & Alerts
Low-stock · BOM report · Menu
📋
BOM Calculation Logic

Each menu item maps to a recipe with ingredient quantities. On order entry: BOM Engine multiplies quantities × servings, checks inventory, deducts atomically, flags shortfalls before the order is confirmed.

🔔
Auto Menu Generator

Given current inventory levels, the system calculates which menu items can actually be prepared (and how many servings). Eliminates "we ran out of X" surprises mid-service.

Interaction Flow

How It Works — Step by Step

01

Inventory Registration

Kitchen manager registers each ingredient with unit type, current stock, and reorder threshold. Items are categorised (Dairy, Produce, Dry Goods, etc.) for organised reporting.

POST /inventory/add · { item, qty, unit, threshold, category }
02

Recipe / BOM Definition

Each menu item has a recipe attached — a structured list of ingredients and quantities per serving. The BOM Engine stores these as recipe-to-ingredient mappings in the database.

Butter Chicken → { chicken: 250g, cream: 50ml, spices: 15g, ... }
03

Order Entry & BOM Calculation

Staff enter an order (e.g., "20 × Butter Chicken"). The BOM Engine instantly calculates total ingredient requirements, checks current inventory atomically, and either confirms or raises a shortfall alert.

20 × recipe_bom → deduct inventory → shortfall check → confirm
04

Auto Menu Generation

The system scans current inventory against all recipe BOMs and outputs a "possible menu" — items that can be prepared today, with maximum servings per item. Reorders are auto-flagged to the purchase list.

GET /menu/possible → [{ item, max_servings, status }]
05

Reports & Low-Stock Alerts

End-of-day reports show consumption per item, remaining stock, and items that crossed reorder thresholds. Alerts are displayed in the dashboard and can trigger notifications to the purchase team.

Daily report · reorder list · waste tracking · cost summary
Engineering Problems Solved

Challenges & Solutions

Problem

Inventory race conditions on concurrent orders

When two staff members enter orders simultaneously, both reads could show sufficient stock — then both deductions leave inventory negative.

Solution

Atomic transactions with SQLAlchemy locking

Wrapped inventory deductions in atomic DB transactions with row-level locking. The second concurrent order is queued until the first commits, then re-evaluated against updated stock. Zero oversell errors in testing.

Problem

Complex BOM for composite recipes

Some dishes use sub-recipes (e.g., "Gravy Base" is itself a recipe used in 12 dishes). A flat ingredient lookup fails to resolve these nested dependencies.

Solution

Recursive BOM resolver

Built a recursive tree-resolver that expands sub-recipes into leaf ingredients before calculating totals. Handles arbitrary nesting depth and correctly aggregates repeated ingredients from multiple branches.

Problem

Manual reorder process wasted staff time

Kitchen managers had to manually scan through 200+ ingredient rows to find what needed reordering — a 45-minute daily task.

Solution

Threshold-triggered purchase list

Every inventory write triggers a threshold check. Items below reorder point are auto-added to a live "Purchase Required" list, updated in real time. The 45-minute task now takes zero effort — the list is always current.