Skip to main content

Database Schema

This document provides a comprehensive overview of the F4E AppSheet database schema, including table structures, relationships, and key business logic.

Schema Overview

The F4E AppSheet system uses a PostgreSQL database with 16 core tables that handle different aspects of kitchen operations. The schema is designed for scalability, data integrity, and performance.

Core Tables

1. Kitchen Management

## public.kitchen Table

Master data for all kitchens in the system.

CREATE TABLE public.kitchen (
id VARCHAR(255) PRIMARY KEY,
code VARCHAR(255),
name VARCHAR(255),
kitchen_type VARCHAR(255),
capacity VARCHAR(255),
location_id VARCHAR(255),
latitude VARCHAR(255),
longitude VARCHAR(255),
phonenumber VARCHAR(255),
datecreated VARCHAR(255),
datemodified VARCHAR(255),
status VARCHAR(255)
);

Key Fields:

  • id: Unique kitchen identifier
  • kitchen_type: Central, Satellite, or School
  • capacity: Maximum meal preparation capacity
  • location_id: Geographic location reference

## kitchen_mapping Table

Kitchen management and user assignments.

CREATE TABLE public.kitchen_mapping (
id VARCHAR(255) PRIMARY KEY,
kitchen_id VARCHAR(255),
manager_email VARCHAR(255),
manager_name VARCHAR(255),
role VARCHAR(255),
cluster VARCHAR(255),
entity VARCHAR(255),
status VARCHAR(255),
created_at VARCHAR(255),
updated_at VARCHAR(255)
);

2. School Management

## public.school Table

Master data for all schools in the system.

CREATE TABLE public.school (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255),
active VARCHAR(255),
kitchen_id VARCHAR(255),
location_id VARCHAR(255),
program_type VARCHAR(255),
population VARCHAR(255),
sponsored VARCHAR(255),
gpslatitude VARCHAR(255),
gpslongitude VARCHAR(255),
date_created VARCHAR(255),
date_updated VARCHAR(255)
);

Key Fields:

  • active: School status (true/false)
  • kitchen_id: Associated kitchen
  • program_type: Type of feeding program
  • population: School population size

## school_bom Table

Bill of Materials configuration per school.

CREATE TABLE public.school_bom (
id VARCHAR(255),
school_id VARCHAR(255),
bom VARCHAR(255),
updated_at VARCHAR(255),
updated_by VARCHAR(255),
UNIQUE(school_id)
);

3. Meal Planning

## meal_plan Table

Central meal planning for different kitchen types.

CREATE TABLE public.meal_plan (
id VARCHAR(255) PRIMARY KEY,
iid INTEGER NOT NULL,
date VARCHAR(255),
menu VARCHAR(255),
kitchen_type VARCHAR(255),
status VARCHAR(255),
confirmed VARCHAR(255),
start VARCHAR(255),
"end" VARCHAR(255),
year VARCHAR(255),
month VARCHAR(255),
my_month VARCHAR(255),
"Holiday" VARCHAR(255),
created_on VARCHAR(255),
created_by VARCHAR(255),
updated_at VARCHAR(255),
updated_by VARCHAR(255),
distributed VARCHAR(255),
UNIQUE(meal_plan_unique)
);

## plan Table

Individual kitchen-specific meal plans.

CREATE TABLE public.plan (
id VARCHAR(255) PRIMARY KEY,
system_id UUID DEFAULT gen_random_uuid(),
kitchen_id VARCHAR(255),
meal VARCHAR(255),
"date" VARCHAR(255),
status VARCHAR(255),
state VARCHAR(255),
meal_plan_id VARCHAR(255),
projected_students VARCHAR(255),
projected_staff VARCHAR(255),
projected_teachers VARCHAR(255),
actual_students VARCHAR(255),
actual_staff VARCHAR(255),
actual_teachers VARCHAR(255),
total_projections VARCHAR(255),
expected_carb VARCHAR(255),
expected_stew VARCHAR(255),
actual_carb VARCHAR(255),
actual_stew VARCHAR(255),
has_fruit VARCHAR(255),
swelling VARCHAR(255),
recipe_url VARCHAR(255),
recipe_text VARCHAR(255),
"comment" TEXT,
created_at VARCHAR(255),
created_by VARCHAR(255),
updated_at VARCHAR(255),
updated_by VARCHAR(255),
closed_at VARCHAR(255),
closed_by VARCHAR(255),
UNIQUE(plan_unique)
);

4. Projection Management

## projection Table

School-level meal projections and actuals.

CREATE TABLE public.projection (
id VARCHAR(255) PRIMARY KEY,
system_id UUID DEFAULT gen_random_uuid(),
plan_id VARCHAR(255),
school_id VARCHAR(255),
kitchen_id VARCHAR(255),
meal VARCHAR(255),
plan_date VARCHAR(255),
status VARCHAR(255),
projected_students VARCHAR(255),
projected_staff VARCHAR(255),
projected_teachers VARCHAR(255),
actual_students VARCHAR(255),
actual_staff VARCHAR(255),
actual_teachers VARCHAR(255),
planned_cooked_to_deliver VARCHAR(255),
actual_food_delivered VARCHAR(255),
missed_meals VARCHAR(255),
food_remaining VARCHAR(255),
loaves VARCHAR(255),
milk VARCHAR(255),
extra_rice VARCHAR(255),
extra_stew VARCHAR(255),
"comment" TEXT,
created_at VARCHAR(255) NOT NULL,
created_by VARCHAR(255),
updated_at VARCHAR(255),
updated_by VARCHAR(255),
closed_at VARCHAR(255),
closed_by VARCHAR(255),
_created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(projection_unique)
);

5. Consumption Tracking

## consumption Table

Ingredient consumption tracking per projection.

CREATE TABLE public.consumption (
id VARCHAR(255) PRIMARY KEY,
plan_id VARCHAR(255),
projection_id VARCHAR(255),
item VARCHAR(255),
product_name VARCHAR(255),
planned_qty VARCHAR(255),
actual_qty VARCHAR(255),
waste VARCHAR(255),
status VARCHAR(255),
"comment" VARCHAR(255),
created_at VARCHAR(255),
created_by VARCHAR(255),
updated_at VARCHAR(255),
updated_by VARCHAR(255)
);

6. Picking Management

## picking Table

Picking list management for kitchen operations.

CREATE TABLE public.picking (
id VARCHAR(255) PRIMARY KEY,
plan_id VARCHAR(255),
kitchen_id VARCHAR(255),
product_id VARCHAR(255),
product_name VARCHAR(255),
planned_qty VARCHAR(255),
actual_qty VARCHAR(255),
waste VARCHAR(255),
reason VARCHAR(255),
status VARCHAR(255),
"comment" TEXT,
created_at VARCHAR(255),
created_by VARCHAR(255),
updated_at VARCHAR(255),
updated_by VARCHAR(255),
UNIQUE(picking_unique)
);

7. Product Management

## product_master Table

Master product catalog.

CREATE TABLE public.product_master (
id VARCHAR(255) PRIMARY KEY,
product_name VARCHAR(255),
product_code VARCHAR(255),
type VARCHAR(50),
uom VARCHAR(255),
bag INTEGER,
created_at VARCHAR(255)
);

## ingredients Table

Recipe ingredients and quantities.

CREATE TABLE public.ingredients (
id VARCHAR(255) PRIMARY KEY,
product_id VARCHAR(255),
product VARCHAR(255),
product_code VARCHAR(255),
meal VARCHAR(255),
type VARCHAR(255),
qty VARCHAR(255),
count VARCHAR(255),
status VARCHAR(255),
meals_id VARCHAR(255)
);

8. Inventory Management

## stock_adjustment Table

Inventory adjustments and corrections.

CREATE TABLE public.stock_adjustment (
id VARCHAR(255),
uid UUID DEFAULT gen_random_uuid(),
kitchen_id VARCHAR(255),
item VARCHAR(255),
item_name VARCHAR(255),
qty VARCHAR(255),
type VARCHAR(255),
reason VARCHAR(255),
"comment" VARCHAR(255),
activity_date VARCHAR(255),
date VARCHAR(255),
month VARCHAR(255),
year VARCHAR(255),
raised_by VARCHAR(255),
approved_by VARCHAR(255),
approved_on VARCHAR(255),
status VARCHAR(255),
serial VARCHAR(255),
linked_to VARCHAR(255)
);

## stock_count Table

Physical stock count records.

CREATE TABLE public.stock_count (
id VARCHAR(255) PRIMARY KEY,
system_id UUID DEFAULT gen_random_uuid(),
kitchen_id VARCHAR(255),
date VARCHAR(255),
serial VARCHAR(255),
status VARCHAR(255),
rice VARCHAR(255),
beans VARCHAR(255),
maize VARCHAR(255),
salt VARCHAR(255),
cooking_oil VARCHAR(255),
w_ndengu VARCHAR(255),
gg VARCHAR(255),
briquette VARCHAR(255),
mwitemania VARCHAR(255),
created_at VARCHAR(255),
done_by VARCHAR(255),
confirmed_by VARCHAR(255),
confirmed_at VARCHAR(255),
cancelled_by VARCHAR(255),
cancelled_at VARCHAR(255),
rejected_by VARCHAR(255),
rejected_at VARCHAR(255),
rejected_comment VARCHAR(255),
updated_at VARCHAR(255),
"comment" VARCHAR(255)
);

Table Relationships

Primary Relationships

Key Relationships

  1. Kitchen → Plan: One kitchen can have multiple plans
  2. Plan → Projection: One plan can have multiple projections (one per school)
  3. Projection → Consumption: One projection generates multiple consumption records (per item)
  4. Plan → Picking: One plan generates one picking list
  5. School → School_BOM: One school has one BOM configuration (Primary/Highschool)
  6. Product_Master → Ingredients: Products used in ingredient definitions

Data Volume Statistics

Based on current system analysis:

TableSizeRow CountKey Operations
consumption296 MB~40M rowsHigh-frequency inserts/updates
projection81 MB~5M rowsMedium-frequency updates
picking17 MB~1M rowsMedium-frequency operations
plan4 MB~100K rowsLow-frequency, high-impact
school1.5 MB~10K rowsLow-frequency updates
kitchen160 KB~100 rowsVery low-frequency updates

Indexes and Performance

Critical Indexes

-- Plan table indexes
CREATE INDEX idx_plan_status_date_id ON plan(status, date, id);
CREATE INDEX idx_plan_kitchen_id ON plan(kitchen_id);

-- Projection table indexes
CREATE INDEX idx_projection_plan_id ON projection(plan_id);
CREATE INDEX idx_projection_school_id ON projection(school_id);
CREATE INDEX idx_projection_plan_id_status ON projection(plan_id, status);

-- Consumption table indexes
CREATE INDEX idx_consumption_plan_item_status ON consumption(plan_id, item, status);
CREATE INDEX idx_consumption_projection_id ON consumption(projection_id);

-- Picking table indexes
CREATE INDEX idx_picking_plan_id_kitchen_id_product_id ON picking(plan_id, kitchen_id, product_id);

-- School table indexes
CREATE INDEX idx_school_kitchen_active ON school(kitchen_id, active);

Performance Considerations

  1. High-Volume Tables: consumption and projection tables require careful indexing
  2. Frequent Queries: Status-based queries are most common
  3. Aggregation Queries: Plan totals require efficient aggregation
  4. Time-Based Queries: Date-based filtering is frequent

Data Integrity

Constraints

  1. Primary Keys: All tables have unique primary keys
  2. Foreign Keys: Referential integrity maintained through foreign key constraints
  3. Unique Constraints: Business-unique combinations enforced
  4. Check Constraints: Data validation at database level

Audit Fields

All tables include audit fields:

  • created_at: Record creation timestamp
  • created_by: User who created the record
  • updated_at: Last update timestamp
  • updated_by: User who last updated the record

Data Synchronization

External System Integration

  1. School Database Sync: Regular sync with external school database
  2. Kitchen Data Sync: Periodic sync of kitchen master data
  3. Real-time Updates: Critical data updated in real-time
  4. Batch Processing: Non-critical data processed in batches

Sync Procedures

-- School data sync procedure
CREATE OR REPLACE PROCEDURE public.sync_school_data()
LANGUAGE plpgsql
AS $procedure$
BEGIN
-- Sync logic for school data
END;
$procedure$;

-- Kitchen data sync procedure
CREATE OR REPLACE PROCEDURE public.sync_kitchen_data()
LANGUAGE plpgsql
AS $procedure$
BEGIN
-- Sync logic for kitchen data
END;
$procedure$;

Business Logic Implementation

Trigger Functions

The schema includes 11 trigger functions that implement business logic:

  1. Data Consistency: Maintains referential integrity
  2. Business Rules: Enforces business logic automatically
  3. Calculations: Performs complex calculations
  4. Status Management: Manages status transitions
  5. Audit Logging: Tracks all changes

Materialized Views

For performance optimization:

-- Projection totals materialized view
CREATE MATERIALIZED VIEW mv_projection_totals AS
SELECT
plan_id,
COALESCE(SUM(CAST(projected_students AS INTEGER)), 0) as total_projected_students,
COALESCE(SUM(CAST(projected_staff AS INTEGER)), 0) as total_projected_staff,
COALESCE(SUM(CAST(projected_teachers AS INTEGER)), 0) as total_projected_teachers,
COALESCE(SUM(CAST(actual_students AS INTEGER)), 0) as total_actual_students,
COALESCE(SUM(CAST(actual_staff AS INTEGER)), 0) as total_actual_staff,
COALESCE(SUM(CAST(actual_teachers AS INTEGER)), 0) as total_actual_teachers,
MAX(updated_at) as last_projection_update
FROM projection
GROUP BY plan_id;

This database schema provides a robust foundation for the F4E AppSheet system, ensuring data integrity, performance, and scalability while supporting complex business processes.