FridgeRadar uses MySQL 8 as its primary data store, accessed asynchronously from the FastAPI backend via SQLAlchemy 2.0 andDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/EstefanoARG/FridgeRadar/llms.txt
Use this file to discover all available pages before exploring further.
aiomysql. The entire schema — including all tables, indexes, triggers, scheduled events, views, stored procedures, and seed data — is defined in a single SQL script at backend/infra/mysql/fridgeradar_db.sql. Running that script against a fresh MySQL instance is all that is required to reach a working database state.
Requirements
MySQL 8+
The schema relies on
utf8mb4 collation, MySQL Events (event_scheduler), window functions, and DELIMITER blocks — all MySQL 8 features. Earlier versions are not supported.MySQL Event Scheduler
The SQL script issues
SET GLOBAL event_scheduler = ON automatically. Your MySQL user must have SUPER or SYSTEM_VARIABLES_ADMIN privileges for this to take effect.Initializing the Schema
Connect to MySQL and run the SQL script
Execute the bundled script from the repository root. It drops and recreates the You will be prompted for your MySQL root password. For a remote host:
fridgeradar_db database from scratch on every run:Connection String
The FastAPI backend constructs its async database URL from the environment variables defined inapp/core/config.py:
.env file before starting the backend. See Backend Deployment for the full environment variable reference.
Schema Overview
The SQL script creates the following objects insidefridgeradar_db (charset utf8mb4, collation utf8mb4_unicode_ci):
Tables
All 19 tables useInnoDB with enforced foreign key constraints:
| Table | Description |
|---|---|
usuario | User accounts with hashed passwords and account state |
hogar | Household groups with unique invitation codes |
usuario_hogar | Many-to-many join: users ↔ households with owner / admin / miembro roles |
zona | Named storage zones (refrigerator, freezer, pantry, etc.) scoped to a household |
estante | Visual shelves within a zone, with vertical position and UI color |
categoria_producto | Global product category catalog (seeded with 10 categories) |
producto | Global product catalog with barcode, unit of measure, and average shelf life |
inventario | Real per-household inventory items with quantity, purchase date, expiry date, and semáforo state |
movimiento_inventario | Audit log of every add / move / consume / delete / expire action |
receta | Recipes, either system-provided (id_usuario_creador IS NULL) or user-created |
tag_receta | Recipe tag definitions (seeded with 8 tags) |
receta_tag | Many-to-many join: recipes ↔ tags |
receta_ingrediente | Ingredients per recipe with quantity, unit, and an obligatorio flag |
receta_favorita | Per-user saved recipe favorites |
alerta | System-generated and event-generated alerts linked to a specific inventory item |
lista_compra | Per-household shopping lists with activa / completada states |
lista_compra_detalle | Line items in a shopping list with priority and comprado flag |
desperdicio | Waste log recording discarded items, quantity, and reason |
sugerencia_receta | Persisted “Tengo Hambre” suggestions with match percentage and critical-item flag |
Performance Indexes
Ten dedicated indexes are created to accelerate the queries most common in the backend:Triggers
ThreeBEFORE / AFTER triggers on the inventario table automate semáforo state management and movement logging without any application-layer code:
| Trigger | Event | Behaviour |
|---|---|---|
trg_semaforo_insert | BEFORE INSERT | Calculates estado_caducidad (verde / amarillo / rojo / vencido) from fecha_vencimiento at insert time |
trg_semaforo_update | BEFORE UPDATE | Recalculates estado_caducidad whenever fecha_vencimiento changes |
trg_log_movimiento | AFTER UPDATE | Automatically inserts a consumido row into movimiento_inventario whenever cantidad decreases |
| State | Days until expiry |
|---|---|
verde | More than 7 days |
amarillo | 3 – 7 days |
rojo | 0 – 2 days |
vencido | Past expiry date |
MySQL Events (Scheduled)
Two daily MySQL Events handle work that cannot be done at request time:| Event | Schedule | Purpose |
|---|---|---|
evt_actualizar_semaforo | Every 24 hours from startup | Bulk-updates estado_caducidad for every item in inventario — triggers only fire on write, so this event keeps states accurate as calendar days pass |
evt_generar_alertas_vencimiento | Daily at 08:00 | Inserts rows into alerta for any rojo or amarillo item that has not already received an alert today; notifies every member of the owning household |
These events require
event_scheduler = ON in MySQL. The script sets this globally. If your MySQL instance resets event_scheduler to OFF on restart, add event_scheduler=ON to your my.cnf / my.ini file under [mysqld].Views
Three views simplify complex joins for the backend:| View | Description |
|---|---|
v_inventario_completo | Full inventory with product name, category, zone, shelf, quantity, days remaining, and semáforo state; ordered by fecha_vencimiento ASC |
v_recetas_posibles | All recipes annotated with ingredient availability percentage and a usa_criticos flag indicating whether the recipe uses near-expiry items |
v_desperdicio_por_hogar | Aggregated waste metrics per household, product, and discard reason — used by the /api/v1/desperdicio endpoint |
Stored Procedures
| Procedure | Parameters | Description |
|---|---|---|
sp_tengo_hambre | p_id_hogar INT, solo_criticos BOOLEAN, limite INT | Returns recipes with ≥ 70% ingredient availability for the given household; when solo_criticos = TRUE only counts amarillo / rojo inventory items; results ordered by critical-item usage then match percentage |
sp_agregar_inventario | p_id_hogar, p_id_producto, p_id_estante, p_id_usuario, p_cantidad, p_fecha_compra, p_fecha_vencimiento, p_observaciones | Inserts an inventory item and automatically records the corresponding agregado entry in movimiento_inventario in a single transaction |
Seed Data
The script inserts initial reference data so the application is usable immediately after schema creation: 10 product categories with emoji icons and UI colors:Lácteos, Carnes, Verduras, Frutas, Bebidas, Snacks, Condimentos, Granos, Congelados, Panadería
8 recipe tags with display colors:
Vegetariano, Vegano, Sin gluten, Sin lactosa, Rápido, Económico, Alto proteico, Bajo en calorías
Resetting the Development Database
To wipe all data and reload the schema from scratch during development, re-run the initialization script:backend/infra/scripts/reset_dev.sh, but it no longer performs any automated steps — Docker was removed from the project. The script will print a reminder to reset the database manually from your MySQL client:
Backing Up the Database
Usemysqldump to create a portable backup of the database at any point: