Nutrition Management Data Specifications
Shared Entity References
This module references the following shared entities defined in their owning modules. Nutrition does not redefine these tables — it uses foreign-key references only.
| Shared Entity |
Owning Module |
Table(s) |
FK Used Here |
| Patients |
ehr-patient-mgmt |
patients, patient_demographics, patient_identifiers |
patients.patient_id |
| Providers |
ehr-patient-mgmt |
providers, provider_credentials |
providers.provider_id |
| Encounters |
scheduling |
encounters, encounter_details |
encounters.encounter_id |
| Users & Auth |
ehr-patient-mgmt |
users, roles, permissions |
users.user_id |
| Facilities |
ehr-patient-mgmt |
facilities, departments, locations |
facilities.facility_id, departments.department_id, locations.location_id |
| Patient Allergies |
ehr-patient-mgmt |
patient_allergies |
patient_allergies.allergy_id |
Entity Relationship Diagram
erDiagram
patients ||--o{ diet_orders : "has"
encounters ||--o{ diet_orders : "context"
providers ||--o{ diet_orders : "ordered by"
users ||--o{ diet_orders : "entered/modified by"
patients ||--o{ meal_plans : "has"
encounters ||--o{ meal_plans : "context"
diet_orders ||--o{ meal_plans : "derived from"
patients ||--o{ meal_service_records : "has"
meal_plans ||--o{ meal_service_records : "for plan"
patients ||--o{ nutrition_assessments : "has"
encounters ||--o{ nutrition_assessments : "during"
providers ||--o{ nutrition_assessments : "performed by"
patients ||--o{ nutrition_screening : "has"
encounters ||--o{ nutrition_screening : "during"
users ||--o{ nutrition_screening : "screened by"
facilities ||--o{ menu_cycles : "configured for"
diet_type_definitions ||--o{ menu_cycles : "applies to"
menu_cycles ||--o{ menu_items : "references via IDs"
facilities ||--o{ kitchen_production_orders : "for"
kitchen_production_orders ||--o{ tray_tickets : "generates"
patients ||--o{ tray_tickets : "for"
diet_orders ||--o{ tray_tickets : "based on"
patients ||--o{ food_allergen_alerts : "has"
patient_allergies ||--o{ food_allergen_alerts : "derived from"
patients ||--o{ enteral_parenteral_orders : "has"
encounters ||--o{ enteral_parenteral_orders : "during"
providers ||--o{ enteral_parenteral_orders : "ordered by"
diet_type_definitions {
bigint diet_type_id PK
}
diet_orders {
bigint order_id PK
bigint patient_id FK
bigint encounter_id FK
bigint ordering_provider_id FK
bigint diet_type_id FK
bigint entered_by FK
bigint last_modified_by FK
}
meal_plans {
bigint plan_id PK
bigint patient_id FK
bigint encounter_id FK
bigint diet_order_id FK
bigint generated_by FK
}
meal_service_records {
bigint service_id PK
bigint plan_id FK
bigint patient_id FK
bigint delivered_by FK
}
nutrition_assessments {
bigint assessment_id PK
bigint patient_id FK
bigint encounter_id FK
bigint assessed_by FK
}
nutrition_screening {
bigint screening_id PK
bigint patient_id FK
bigint encounter_id FK
bigint screened_by FK
}
menu_items {
bigint item_id PK
}
menu_cycles {
bigint cycle_id PK
bigint facility_id FK
bigint diet_type_id FK
}
kitchen_production_orders {
bigint production_id PK
bigint facility_id FK
}
tray_tickets {
bigint ticket_id PK
bigint production_id FK
bigint patient_id FK
}
food_allergen_alerts {
bigint alert_id PK
bigint patient_id FK
bigint source_allergy_id FK
}
enteral_parenteral_orders {
bigint order_id PK
bigint patient_id FK
bigint encounter_id FK
bigint ordered_by FK
}
Table Definitions
Conventions: PostgreSQL-style DDL, TIMESTAMP WITH TIME ZONE for audit/clinical times, JSONB for structured lists, UAE context (halal, Arabic names, emirate-aware where relevant).
1. diet_orders
Purpose
Stores all inpatient diet orders per patient/encounter, including texture, fluid restriction, supplements, allergen context, and cultural/religious preferences (e.g., halal, vegetarian) for UAE facilities. Orders typically originate from CPOE but can be modified by dietitians.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
order_id |
BIGINT |
NO |
IDENTITY |
PK |
Diet order identifier |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient receiving diet |
encounter_id |
BIGINT |
NO |
— |
FK → encounters.encounter_id |
Inpatient encounter context |
ordering_provider_id |
BIGINT |
NO |
— |
FK → providers.provider_id |
Physician or dietitian placing order |
diet_type_id |
BIGINT |
NO |
— |
FK → diet_type_definitions.diet_type_id |
Ordered diet type (e.g., Diabetic, Renal) |
texture_modification |
VARCHAR(50) |
YES |
— |
IDDSI level code |
Texture level (e.g., IDDSI 4 Pureed) |
fluid_restriction_ml |
INTEGER |
YES |
— |
≥ 0 |
Daily fluid limit in mL |
supplements |
JSONB |
YES |
'[]' |
Valid JSON array |
Oral nutrition supplements (product, frequency) |
cultural_preference |
VARCHAR(50) |
YES |
— |
— |
e.g., Halal, Vegetarian, No pork, Ramadan fasting |
food_allergens |
JSONB |
YES |
'[]' |
— |
Snapshot of relevant food allergens for this order |
start_datetime |
TIMESTAMP WITH TIME ZONE |
NO |
CURRENT_TIMESTAMP |
— |
When diet becomes active |
end_datetime |
TIMESTAMP WITH TIME ZONE |
YES |
— |
> start_datetime if not null |
When diet stops |
status |
VARCHAR(20) |
NO |
'active' |
IN ('draft','active','on-hold','completed','cancelled') |
Order lifecycle state |
order_datetime |
TIMESTAMP WITH TIME ZONE |
NO |
CURRENT_TIMESTAMP |
— |
When order was placed |
entered_by |
BIGINT |
NO |
— |
FK → users.user_id |
User who entered order (CPOE user) |
last_modified_by |
BIGINT |
YES |
— |
FK → users.user_id |
Last user to modify |
cancel_reason |
TEXT |
YES |
— |
Required if status='cancelled' |
Reason for cancellation |
uae_facility_id |
BIGINT |
NO |
— |
FK → facilities.facility_id |
Ordering facility (for multi-facility groups) |
created_at |
TIMESTAMP WITH TIME ZONE |
NO |
CURRENT_TIMESTAMP |
— |
Record creation time |
updated_at |
TIMESTAMP WITH TIME ZONE |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update time |
SQL DDL
SQLCREATE TABLE diet_orders (
order_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
patient_id BIGINT NOT NULL,
encounter_id BIGINT NOT NULL,
ordering_provider_id BIGINT NOT NULL,
diet_type_id BIGINT NOT NULL,
texture_modification VARCHAR(50),
fluid_restriction_ml INTEGER,
supplements JSONB NOT NULL DEFAULT '[]'::jsonb,
cultural_preference VARCHAR(50),
food_allergens JSONB NOT NULL DEFAULT '[]'::jsonb,
start_datetime TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
end_datetime TIMESTAMPTZ,
status VARCHAR(20) NOT NULL DEFAULT 'active',
order_datetime TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
entered_by BIGINT NOT NULL,
last_modified_by BIGINT,
cancel_reason TEXT,
uae_facility_id BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_diet_orders_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_diet_orders_encounter
FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_diet_orders_provider
FOREIGN KEY (ordering_provider_id) REFERENCES providers(provider_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_diet_orders_diet_type
FOREIGN KEY (diet_type_id) REFERENCES diet_type_definitions(diet_type_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_diet_orders_entered_by
FOREIGN KEY (entered_by) REFERENCES users(user_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_diet_orders_last_modified_by
FOREIGN KEY (last_modified_by) REFERENCES users(user_id)
ON UPDATE CASCADE ON DELETE SET NULL,
CONSTRAINT fk_diet_orders_facility
FOREIGN KEY (uae_facility_id) REFERENCES facilities(facility_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT chk_diet_orders_status
CHECK (status IN ('draft','active','on-hold','completed','cancelled')),
CONSTRAINT chk_diet_orders_fluid_restriction
CHECK (fluid_restriction_ml IS NULL OR fluid_restriction_ml >= 0),
CONSTRAINT chk_diet_orders_end_after_start
CHECK (end_datetime IS NULL OR end_datetime > start_datetime),
CONSTRAINT chk_diet_orders_cancel_reason
CHECK (status <> 'cancelled' OR cancel_reason IS NOT NULL)
);
CREATE INDEX idx_diet_orders_patient_active
ON diet_orders(patient_id, status)
WHERE status = 'active';
CREATE INDEX idx_diet_orders_encounter
ON diet_orders(encounter_id);
CREATE INDEX idx_diet_orders_facility_meal
ON diet_orders(uae_facility_id, start_datetime);
CREATE INDEX idx_diet_orders_diet_type
ON diet_orders(diet_type_id);
Terminology Bindings
| Field |
Terminology |
Example Value |
texture_modification |
IDDSI Levels |
IDDSI-4 (Pureed) |
cultural_preference |
Local value set (UAE dietary preferences) |
HALAL_ONLY, NO_PORK, VEGETARIAN |
food_allergens |
Facility allergen master (aligned with UAE food safety) |
{"allergenCode":"NUTS"} |
FHIR Resource Mapping
Diet orders are represented as NutritionOrder resources.
| Table Field |
FHIR Resource |
FHIR Path |
order_id |
NutritionOrder |
NutritionOrder.id |
patient_id |
NutritionOrder |
NutritionOrder.patient.reference (Patient/{id}) |
encounter_id |
NutritionOrder |
NutritionOrder.encounter.reference |
ordering_provider_id |
NutritionOrder |
NutritionOrder.orderer.reference (Practitioner/{id}) |
diet_type_id |
NutritionOrder |
NutritionOrder.oralDiet.type.coding |
texture_modification |
NutritionOrder |
NutritionOrder.oralDiet.texture.modifier.coding |
fluid_restriction_ml |
NutritionOrder |
NutritionOrder.oralDiet.fluidConsistencyType or extension |
supplements |
NutritionOrder |
NutritionOrder.supplement (array) |
cultural_preference |
NutritionOrder |
NutritionOrder.extension (UAE dietary preference extension) |
food_allergens |
AllergyIntolerance (source) / NutritionOrder |
NutritionOrder.allergyIntolerance (references) |
start_datetime |
NutritionOrder |
NutritionOrder.dateTime / NutritionOrder.oralDiet.schedule |
status |
NutritionOrder |
NutritionOrder.status |
uae_facility_id |
NutritionOrder |
NutritionOrder.extension (managing facility) |
2. meal_plans
Purpose
Represents the generated daily meal plan per patient per date and meal type (breakfast, lunch, dinner, snacks), derived from active diet orders and menu cycles. Used to drive kitchen production and tray ticket generation.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
plan_id |
BIGINT |
NO |
IDENTITY |
PK |
Meal plan identifier |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient |
encounter_id |
BIGINT |
NO |
— |
FK → encounters.encounter_id |
Encounter context |
diet_order_id |
BIGINT |
NO |
— |
FK → diet_orders.order_id |
Source diet order |
meal_date |
DATE |
NO |
— |
— |
Date of meal |
meal_type |
VARCHAR(20) |
NO |
— |
IN ('breakfast','lunch','dinner','snack') |
Meal type |
menu_items_json |
JSONB |
NO |
'[]' |
— |
List of menu items (IDs, portions) |
calories_planned |
NUMERIC(6,1) |
YES |
— |
≥ 0 |
Planned kcal for this meal |
protein_planned |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Planned protein (g) |
status |
VARCHAR(20) |
NO |
'planned' |
IN ('planned','sent-to-kitchen','served','cancelled') |
Plan status |
generated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
When plan generated |
generated_by |
BIGINT |
YES |
— |
FK → users.user_id |
User or system account |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE meal_plans (
plan_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
patient_id BIGINT NOT NULL,
encounter_id BIGINT NOT NULL,
diet_order_id BIGINT NOT NULL,
meal_date DATE NOT NULL,
meal_type VARCHAR(20) NOT NULL,
menu_items_json JSONB NOT NULL DEFAULT '[]'::jsonb,
calories_planned NUMERIC(6,1),
protein_planned NUMERIC(5,1),
status VARCHAR(20) NOT NULL DEFAULT 'planned',
generated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
generated_by BIGINT,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_meal_plans_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_meal_plans_encounter
FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_meal_plans_diet_order
FOREIGN KEY (diet_order_id) REFERENCES diet_orders(order_id)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT fk_meal_plans_generated_by
FOREIGN KEY (generated_by) REFERENCES users(user_id)
ON UPDATE CASCADE ON DELETE SET NULL,
CONSTRAINT chk_meal_plans_meal_type
CHECK (meal_type IN ('breakfast','lunch','dinner','snack')),
CONSTRAINT chk_meal_plans_status
CHECK (status IN ('planned','sent-to-kitchen','served','cancelled')),
CONSTRAINT chk_meal_plans_calories
CHECK (calories_planned IS NULL OR calories_planned >= 0),
CONSTRAINT chk_meal_plans_protein
CHECK (protein_planned IS NULL OR protein_planned >= 0)
);
CREATE INDEX idx_meal_plans_patient_date
ON meal_plans(patient_id, meal_date);
CREATE INDEX idx_meal_plans_encounter_date
ON meal_plans(encounter_id, meal_date, meal_type);
CREATE INDEX idx_meal_plans_status
ON meal_plans(status);
Terminology Bindings
| Field |
Terminology |
Example Value |
meal_type |
Local value set |
breakfast |
FHIR Resource Mapping
Meal plans are not directly modeled in base FHIR; they can be represented using NutritionOrder plus CarePlan or ServiceRequest.
| Table Field |
FHIR Resource |
FHIR Path |
plan_id |
CarePlan |
CarePlan.id |
patient_id |
CarePlan |
CarePlan.subject.reference |
encounter_id |
CarePlan |
CarePlan.encounter.reference |
meal_date |
CarePlan |
CarePlan.period.start / end (single-day) |
meal_type |
CarePlan |
CarePlan.activity.detail.code (meal category) |
menu_items_json |
CarePlan |
CarePlan.activity.detail.description or extension |
calories_planned |
CarePlan |
CarePlan.goal.target.detailQuantity (kcal) |
3. meal_service_records
Purpose
Captures actual meal delivery events and patient intake for each meal, including satisfaction scores and consumption percentage, supporting KPIs like calorie delivery vs target and food waste rate.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
service_id |
BIGINT |
NO |
IDENTITY |
PK |
Meal service record ID |
plan_id |
BIGINT |
NO |
— |
FK → meal_plans.plan_id |
Related meal plan |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient |
meal_type |
VARCHAR(20) |
NO |
— |
IN ('breakfast','lunch','dinner','snack') |
Meal type |
delivered_datetime |
TIMESTAMPTZ |
YES |
— |
— |
When tray delivered |
delivered_by |
BIGINT |
YES |
— |
FK → users.user_id |
Diet technician / staff |
consumption_percentage |
INTEGER |
YES |
— |
0–100 |
Estimated consumption |
calories_delivered |
NUMERIC(6,1) |
YES |
— |
≥ 0 |
Estimated kcal consumed |
protein_delivered |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Estimated protein consumed (g) |
patient_satisfaction_score |
NUMERIC(2,1) |
YES |
— |
1.0–5.0 |
Satisfaction rating |
notes |
TEXT |
YES |
— |
— |
Free-text notes (e.g., nausea, refused) |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE meal_service_records (
service_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
plan_id BIGINT NOT NULL,
patient_id BIGINT NOT NULL,
meal_type VARCHAR(20) NOT NULL,
delivered_datetime TIMESTAMPTZ,
delivered_by BIGINT,
consumption_percentage INTEGER,
calories_delivered NUMERIC(6,1),
protein_delivered NUMERIC(5,1),
patient_satisfaction_score NUMERIC(2,1),
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_meal_service_plan
FOREIGN KEY (plan_id) REFERENCES meal_plans(plan_id)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT fk_meal_service_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_meal_service_delivered_by
FOREIGN KEY (delivered_by) REFERENCES users(user_id)
ON UPDATE CASCADE ON DELETE SET NULL,
CONSTRAINT chk_meal_service_meal_type
CHECK (meal_type IN ('breakfast','lunch','dinner','snack')),
CONSTRAINT chk_meal_service_consumption
CHECK (consumption_percentage IS NULL OR (consumption_percentage >= 0 AND consumption_percentage <= 100)),
CONSTRAINT chk_meal_service_calories
CHECK (calories_delivered IS NULL OR calories_delivered >= 0),
CONSTRAINT chk_meal_service_protein
CHECK (protein_delivered IS NULL OR protein_delivered >= 0),
CONSTRAINT chk_meal_service_satisfaction
CHECK (patient_satisfaction_score IS NULL OR (patient_satisfaction_score >= 1.0 AND patient_satisfaction_score <= 5.0))
);
CREATE INDEX idx_meal_service_patient_date
ON meal_service_records(patient_id, delivered_datetime);
CREATE INDEX idx_meal_service_plan
ON meal_service_records(plan_id);
Terminology Bindings
| Field |
Terminology |
Example Value |
meal_type |
Local value set |
dinner |
FHIR Resource Mapping
Meal service and intake can be represented as Observation (intake) and QuestionnaireResponse (satisfaction).
| Table Field |
FHIR Resource |
FHIR Path |
service_id |
Observation |
Observation.id (intake) |
patient_id |
Observation |
Observation.subject.reference |
delivered_datetime |
Observation |
Observation.effectiveDateTime |
consumption_percentage |
Observation |
Observation.valueQuantity (LOINC calorie intake code) |
patient_satisfaction_score |
QuestionnaireResponse |
QuestionnaireResponse.item.answer.valueDecimal |
4. nutrition_assessments
Purpose
Stores comprehensive dietitian assessments including anthropometrics, BMI, lab markers, malnutrition risk, and nutrition care plan text. Supports malnutrition documentation KPIs and clinical decision-making.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
assessment_id |
BIGINT |
NO |
IDENTITY |
PK |
Assessment ID |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient |
encounter_id |
BIGINT |
NO |
— |
FK → encounters.encounter_id |
Encounter |
assessed_by |
BIGINT |
NO |
— |
FK → providers.provider_id |
Dietitian |
assessment_date |
DATE |
NO |
CURRENT_DATE |
— |
Date of assessment |
bmi |
NUMERIC(5,2) |
YES |
— |
≥ 0 |
Body Mass Index |
weight_kg |
NUMERIC(5,2) |
YES |
— |
≥ 0 |
Current weight |
height_cm |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Height |
ideal_body_weight |
NUMERIC(5,2) |
YES |
— |
≥ 0 |
IBW (kg) |
calorie_target |
NUMERIC(6,1) |
YES |
— |
≥ 0 |
Daily kcal target |
protein_target |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Daily protein target (g) |
malnutrition_risk |
VARCHAR(20) |
YES |
— |
IN ('low','moderate','high') |
Risk category |
findings |
TEXT |
YES |
— |
— |
Narrative assessment |
care_plan_text |
TEXT |
YES |
— |
— |
Nutrition care plan |
lab_values_json |
JSONB |
YES |
'{}' |
— |
Key lab markers (albumin, prealbumin, electrolytes, glucose) with LOINC codes |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE nutrition_assessments (
assessment_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
patient_id BIGINT NOT NULL,
encounter_id BIGINT NOT NULL,
assessed_by BIGINT NOT NULL,
assessment_date DATE NOT NULL DEFAULT CURRENT_DATE,
bmi NUMERIC(5,2),
weight_kg NUMERIC(5,2),
height_cm NUMERIC(5,1),
ideal_body_weight NUMERIC(5,2),
calorie_target NUMERIC(6,1),
protein_target NUMERIC(5,1),
malnutrition_risk VARCHAR(20),
findings TEXT,
care_plan_text TEXT,
lab_values_json JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_nut_assess_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_nut_assess_encounter
FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_nut_assess_provider
FOREIGN KEY (assessed_by) REFERENCES providers(provider_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT chk_nut_assess_bmi
CHECK (bmi IS NULL OR bmi >= 0),
CONSTRAINT chk_nut_assess_weight
CHECK (weight_kg IS NULL OR weight_kg >= 0),
CONSTRAINT chk_nut_assess_height
CHECK (height_cm IS NULL OR height_cm >= 0),
CONSTRAINT chk_nut_assess_ibw
CHECK (ideal_body_weight IS NULL OR ideal_body_weight >= 0),
CONSTRAINT chk_nut_assess_calorie_target
CHECK (calorie_target IS NULL OR calorie_target >= 0),
CONSTRAINT chk_nut_assess_protein_target
CHECK (protein_target IS NULL OR protein_target >= 0),
CONSTRAINT chk_nut_assess_malnutrition_risk
CHECK (malnutrition_risk IS NULL OR malnutrition_risk IN ('low','moderate','high'))
);
CREATE INDEX idx_nut_assess_patient_date
ON nutrition_assessments(patient_id, assessment_date);
CREATE INDEX idx_nut_assess_encounter
ON nutrition_assessments(encounter_id);
Terminology Bindings
| Field |
Terminology |
Example Value |
malnutrition_risk |
Local value set |
high |
lab_values_json |
LOINC |
{"718-7":{"value":13.5,"unit":"g/dL"}} |
FHIR Resource Mapping
Nutrition assessments map primarily to Observation and CarePlan.
| Table Field |
FHIR Resource |
FHIR Path |
assessment_id |
Observation |
Observation.id (overall assessment) |
patient_id |
Observation |
Observation.subject.reference |
assessment_date |
Observation |
Observation.effectiveDateTime |
bmi |
Observation |
Observation.code (LOINC BMI) + valueQuantity |
weight_kg |
Observation |
Observation.code (LOINC body weight) |
height_cm |
Observation |
Observation.code (LOINC body height) |
malnutrition_risk |
Observation |
Observation.interpretation |
care_plan_text |
CarePlan |
CarePlan.description |
calorie_target |
CarePlan |
CarePlan.goal.target.detailQuantity (kcal) |
5. nutrition_screening
Purpose
Stores initial nursing nutrition screening results using validated tools (e.g., NRS-2002, MUST), including scores, risk level, and whether an automatic dietitian referral was triggered.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
screening_id |
BIGINT |
NO |
IDENTITY |
PK |
Screening ID |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient |
encounter_id |
BIGINT |
NO |
— |
FK → encounters.encounter_id |
Encounter |
screened_by |
BIGINT |
NO |
— |
FK → users.user_id |
Nurse or clinician user |
screening_date |
DATE |
NO |
CURRENT_DATE |
— |
Date of screening |
tool_used |
VARCHAR(30) |
NO |
— |
IN ('NRS-2002','MUST','SGA') |
Screening tool |
score |
INTEGER |
NO |
— |
≥ 0 |
Tool score |
risk_level |
VARCHAR(20) |
NO |
— |
IN ('low','moderate','high') |
Derived risk |
referred_to_dietitian |
BOOLEAN |
NO |
FALSE |
— |
Auto/manual referral flag |
referral_datetime |
TIMESTAMPTZ |
YES |
— |
— |
When referral created |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE nutrition_screening (
screening_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
patient_id BIGINT NOT NULL,
encounter_id BIGINT NOT NULL,
screened_by BIGINT NOT NULL,
screening_date DATE NOT NULL DEFAULT CURRENT_DATE,
tool_used VARCHAR(30) NOT NULL,
score INTEGER NOT NULL,
risk_level VARCHAR(20) NOT NULL,
referred_to_dietitian BOOLEAN NOT NULL DEFAULT FALSE,
referral_datetime TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_nut_screen_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_nut_screen_encounter
FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_nut_screen_user
FOREIGN KEY (screened_by) REFERENCES users(user_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT chk_nut_screen_tool
CHECK (tool_used IN ('NRS-2002','MUST','SGA')),
CONSTRAINT chk_nut_screen_risk
CHECK (risk_level IN ('low','moderate','high')),
CONSTRAINT chk_nut_screen_score
CHECK (score >= 0),
CONSTRAINT chk_nut_screen_referral
CHECK (referred_to_dietitian = FALSE OR referral_datetime IS NOT NULL)
);
CREATE INDEX idx_nut_screen_patient_date
ON nutrition_screening(patient_id, screening_date);
CREATE INDEX idx_nut_screen_encounter
ON nutrition_screening(encounter_id);
CREATE INDEX idx_nut_screen_risk
ON nutrition_screening(risk_level);
Terminology Bindings
| Field |
Terminology |
Example Value |
tool_used |
Local value set (validated tools) |
NRS-2002 |
risk_level |
Local value set |
high |
FHIR Resource Mapping
Screening results can be represented as Observation or QuestionnaireResponse.
| Table Field |
FHIR Resource |
FHIR Path |
screening_id |
Observation |
Observation.id |
tool_used |
Observation |
Observation.code.text |
score |
Observation |
Observation.valueInteger |
risk_level |
Observation |
Observation.interpretation |
referred_to_dietitian |
ServiceRequest |
ServiceRequest.status / intent (referral) |
Purpose
Master list of available food items with nutritional composition, allergen content, and suitability for various textures and dietary patterns, including halal flag per UAE requirements.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
item_id |
BIGINT |
NO |
IDENTITY |
PK |
Menu item ID |
item_name_en |
VARCHAR(150) |
NO |
— |
— |
English name (e.g., "Chicken Biryani") |
item_name_ar |
VARCHAR(150) |
NO |
— |
— |
Arabic name (e.g., "برياني دجاج") |
category |
VARCHAR(50) |
NO |
— |
— |
Food category (e.g., Main, Side, Dessert) |
calories |
NUMERIC(6,1) |
YES |
— |
≥ 0 |
kcal per serving |
protein_g |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Protein grams |
carbs_g |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Carbohydrates grams |
fat_g |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Fat grams |
fiber_g |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Fiber grams |
sodium_mg |
INTEGER |
YES |
— |
≥ 0 |
Sodium mg |
allergens |
JSONB |
YES |
'[]' |
— |
List of allergen codes (e.g., EGG, NUTS) |
is_halal |
BOOLEAN |
NO |
TRUE |
— |
Halal-compliant flag (default TRUE in UAE) |
is_vegetarian |
BOOLEAN |
NO |
FALSE |
— |
Vegetarian suitable |
is_vegan |
BOOLEAN |
NO |
FALSE |
— |
Vegan suitable |
texture_suitable_for |
VARCHAR(50) |
YES |
— |
— |
IDDSI level(s) supported |
is_active |
BOOLEAN |
NO |
TRUE |
— |
Active in current menu |
uae_food_code |
VARCHAR(50) |
YES |
— |
— |
Local food code if used by catering partner |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE menu_items (
item_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
item_name_en VARCHAR(150) NOT NULL,
item_name_ar VARCHAR(150) NOT NULL,
category VARCHAR(50) NOT NULL,
calories NUMERIC(6,1),
protein_g NUMERIC(5,1),
carbs_g NUMERIC(5,1),
fat_g NUMERIC(5,1),
fiber_g NUMERIC(5,1),
sodium_mg INTEGER,
allergens JSONB NOT NULL DEFAULT '[]'::jsonb,
is_halal BOOLEAN NOT NULL DEFAULT TRUE,
is_vegetarian BOOLEAN NOT NULL DEFAULT FALSE,
is_vegan BOOLEAN NOT NULL DEFAULT FALSE,
texture_suitable_for VARCHAR(50),
is_active BOOLEAN NOT NULL DEFAULT TRUE,
uae_food_code VARCHAR(50),
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT chk_menu_items_nutrients_nonnegative
CHECK (
(calories IS NULL OR calories >= 0) AND
(protein_g IS NULL OR protein_g >= 0) AND
(carbs_g IS NULL OR carbs_g >= 0) AND
(fat_g IS NULL OR fat_g >= 0) AND
(fiber_g IS NULL OR fiber_g >= 0) AND
(sodium_mg IS NULL OR sodium_mg >= 0)
)
);
CREATE INDEX idx_menu_items_active_category
ON menu_items(is_active, category);
CREATE INDEX idx_menu_items_halal
ON menu_items(is_halal);
CREATE INDEX idx_menu_items_name_en
ON menu_items(item_name_en);
Terminology Bindings
| Field |
Terminology |
Example Value |
category |
Local food category list |
MAIN_DISH |
allergens |
Facility allergen master |
{"code":"MILK","display":"Milk"} |
texture_suitable_for |
IDDSI |
IDDSI-5 |
FHIR Resource Mapping
Menu items are non-clinical; they can be represented as Basic or NutritionProduct (if using FHIR R5 concepts; in R4, Basic or ObservationDefinition can be used).
| Table Field |
FHIR Resource |
FHIR Path |
item_id |
Basic |
Basic.id |
item_name_en |
Basic |
Basic.code.text |
calories |
Basic |
Basic.extension (nutrient details) |
Purpose
Defines rotating menu cycles (e.g., 4-week rotation) per facility and diet type, specifying which menu items are available on each day and meal type.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
cycle_id |
BIGINT |
NO |
IDENTITY |
PK |
Menu cycle ID |
cycle_name |
VARCHAR(100) |
NO |
— |
— |
Name (e.g., "Adult 4-week cycle") |
cycle_length_days |
INTEGER |
NO |
— |
> 0 |
Length of rotation |
facility_id |
BIGINT |
NO |
— |
FK → facilities.facility_id |
Facility |
effective_date |
DATE |
NO |
— |
— |
Start date |
diet_type_id |
BIGINT |
NO |
— |
FK → diet_type_definitions.diet_type_id |
Applicable diet type |
day_number |
INTEGER |
NO |
— |
1–cycle_length_days |
Day in cycle |
meal_type |
VARCHAR(20) |
NO |
— |
IN ('breakfast','lunch','dinner','snack') |
Meal type |
menu_item_ids |
TEXT |
NO |
— |
Comma-separated list of menu_items.item_id |
Items available |
is_active |
BOOLEAN |
NO |
TRUE |
— |
Active row |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE menu_cycles (
cycle_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
cycle_name VARCHAR(100) NOT NULL,
cycle_length_days INTEGER NOT NULL,
facility_id BIGINT NOT NULL,
effective_date DATE NOT NULL,
diet_type_id BIGINT NOT NULL,
day_number INTEGER NOT NULL,
meal_type VARCHAR(20) NOT NULL,
menu_item_ids TEXT NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_menu_cycles_facility
FOREIGN KEY (facility_id) REFERENCES facilities(facility_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_menu_cycles_diet_type
FOREIGN KEY (diet_type_id) REFERENCES diet_type_definitions(diet_type_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT chk_menu_cycles_cycle_length
CHECK (cycle_length_days > 0),
CONSTRAINT chk_menu_cycles_day_number
CHECK (day_number >= 1 AND day_number <= cycle_length_days),
CONSTRAINT chk_menu_cycles_meal_type
CHECK (meal_type IN ('breakfast','lunch','dinner','snack'))
);
CREATE INDEX idx_menu_cycles_facility_diet_day_meal
ON menu_cycles(facility_id, diet_type_id, day_number, meal_type)
WHERE is_active = TRUE;
Terminology Bindings
| Field |
Terminology |
Example Value |
meal_type |
Local value set |
lunch |
FHIR Resource Mapping
Menu cycles are operational; if exposed, they can be represented as PlanDefinition.
| Table Field |
FHIR Resource |
FHIR Path |
cycle_id |
PlanDefinition |
PlanDefinition.id |
cycle_name |
PlanDefinition |
PlanDefinition.title |
meal_type |
PlanDefinition |
PlanDefinition.action.code |
8. kitchen_production_orders
Purpose
Aggregated production orders for kitchen per facility, date, and meal type, listing total trays and quantities of each menu item required. Drives kitchen production dashboard and replaces manual tallies.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
production_id |
BIGINT |
NO |
IDENTITY |
PK |
Production order ID |
meal_date |
DATE |
NO |
— |
— |
Date of meal service |
meal_type |
VARCHAR(20) |
NO |
— |
IN ('breakfast','lunch','dinner','snack') |
Meal type |
facility_id |
BIGINT |
NO |
— |
FK → facilities.facility_id |
Facility |
total_trays |
INTEGER |
NO |
0 |
≥ 0 |
Total trays to produce |
production_items_json |
JSONB |
NO |
'{}' |
— |
Map of menu_item_id → quantity |
status |
VARCHAR(20) |
NO |
'planned' |
IN ('planned','in-progress','completed','cancelled') |
Production status |
completed_datetime |
TIMESTAMPTZ |
YES |
— |
— |
When production completed |
generated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
When generated |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE kitchen_production_orders (
production_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
meal_date DATE NOT NULL,
meal_type VARCHAR(20) NOT NULL,
facility_id BIGINT NOT NULL,
total_trays INTEGER NOT NULL DEFAULT 0,
production_items_json JSONB NOT NULL DEFAULT '{}'::jsonb,
status VARCHAR(20) NOT NULL DEFAULT 'planned',
completed_datetime TIMESTAMPTZ,
generated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_kitchen_prod_facility
FOREIGN KEY (facility_id) REFERENCES facilities(facility_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT chk_kitchen_prod_meal_type
CHECK (meal_type IN ('breakfast','lunch','dinner','snack')),
CONSTRAINT chk_kitchen_prod_total_trays
CHECK (total_trays >= 0),
CONSTRAINT chk_kitchen_prod_status
CHECK (status IN ('planned','in-progress','completed','cancelled'))
);
CREATE INDEX idx_kitchen_prod_facility_date_meal
ON kitchen_production_orders(facility_id, meal_date, meal_type);
CREATE INDEX idx_kitchen_prod_status
ON kitchen_production_orders(status);
Terminology Bindings
| Field |
Terminology |
Example Value |
meal_type |
Local value set |
breakfast |
FHIR Resource Mapping
Production orders are operational; if exposed, they can be modeled as Task.
| Table Field |
FHIR Resource |
FHIR Path |
production_id |
Task |
Task.id |
facility_id |
Task |
Task.location |
status |
Task |
Task.status |
9. tray_tickets
Purpose
Individual patient tray specifications used for tray assembly and delivery, including bed location, diet type, allergen alerts, menu items, and barcodes for scanning.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
ticket_id |
BIGINT |
NO |
IDENTITY |
PK |
Tray ticket ID |
production_id |
BIGINT |
NO |
— |
FK → kitchen_production_orders.production_id |
Parent production order |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient |
bed_location |
VARCHAR(50) |
NO |
— |
— |
Bed/room (e.g., "3W-305B") |
diet_type |
VARCHAR(100) |
NO |
— |
— |
Diet description at time of tray generation |
allergen_alerts |
JSONB |
NO |
'[]' |
— |
List of allergen warnings |
menu_items |
JSONB |
NO |
'[]' |
— |
Items on tray (item IDs, portions) |
special_instructions |
TEXT |
YES |
— |
— |
e.g., "Ramadan fasting – deliver at Iftar" |
barcode |
VARCHAR(64) |
NO |
— |
UNIQUE |
Tray barcode |
status |
VARCHAR(20) |
NO |
'pending' |
IN ('pending','assembled','delivered','returned','cancelled') |
Tray status |
assembled_datetime |
TIMESTAMPTZ |
YES |
— |
— |
When assembled |
delivered_datetime |
TIMESTAMPTZ |
YES |
— |
— |
When delivered |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE tray_tickets (
ticket_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
production_id BIGINT NOT NULL,
patient_id BIGINT NOT NULL,
bed_location VARCHAR(50) NOT NULL,
diet_type VARCHAR(100) NOT NULL,
allergen_alerts JSONB NOT NULL DEFAULT '[]'::jsonb,
menu_items JSONB NOT NULL DEFAULT '[]'::jsonb,
special_instructions TEXT,
barcode VARCHAR(64) NOT NULL UNIQUE,
status VARCHAR(20) NOT NULL DEFAULT 'pending',
assembled_datetime TIMESTAMPTZ,
delivered_datetime TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_tray_tickets_production
FOREIGN KEY (production_id) REFERENCES kitchen_production_orders(production_id)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT fk_tray_tickets_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT chk_tray_tickets_status
CHECK (status IN ('pending','assembled','delivered','returned','cancelled'))
);
CREATE INDEX idx_tray_tickets_production
ON tray_tickets(production_id);
CREATE INDEX idx_tray_tickets_patient
ON tray_tickets(patient_id);
CREATE INDEX idx_tray_tickets_status
ON tray_tickets(status);
Terminology Bindings
| Field |
Terminology |
Example Value |
diet_type |
Local diet type label |
Diabetic 1800 kcal |
FHIR Resource Mapping
Tray tickets can be represented as Task resources linked to NutritionOrder.
| Table Field |
FHIR Resource |
FHIR Path |
ticket_id |
Task |
Task.id |
patient_id |
Task |
Task.for.reference |
status |
Task |
Task.status |
barcode |
Task |
Task.identifier.value |
10. food_allergen_alerts
Purpose
Patient-specific food allergen flags derived from patient_allergies, normalized into food allergen categories relevant to menu items (e.g., eggs, nuts, gluten). Used for real-time allergen checks during diet order entry and tray assembly.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
alert_id |
BIGINT |
NO |
IDENTITY |
PK |
Allergen alert ID |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient |
allergen_type |
VARCHAR(50) |
NO |
— |
— |
Allergen category (e.g., NUTS, EGG, GLUTEN) |
allergen_detail |
VARCHAR(255) |
YES |
— |
— |
Detail (e.g., "Peanut", "Tree nuts") |
source_allergy_id |
BIGINT |
YES |
— |
FK → patient_allergies.allergy_id |
Source allergy record |
is_active |
BOOLEAN |
NO |
TRUE |
— |
Active flag |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE food_allergen_alerts (
alert_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
patient_id BIGINT NOT NULL,
allergen_type VARCHAR(50) NOT NULL,
allergen_detail VARCHAR(255),
source_allergy_id BIGINT,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_food_allergen_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_food_allergen_source
FOREIGN KEY (source_allergy_id) REFERENCES patient_allergies(allergy_id)
ON UPDATE CASCADE ON DELETE SET NULL
);
CREATE INDEX idx_food_allergen_patient_active
ON food_allergen_alerts(patient_id)
WHERE is_active = TRUE;
CREATE INDEX idx_food_allergen_type
ON food_allergen_alerts(allergen_type);
Terminology Bindings
| Field |
Terminology |
Example Value |
allergen_type |
Local food allergen categories (aligned with UAE food safety) |
SHELLFISH |
FHIR Resource Mapping
Allergen alerts are derived from AllergyIntolerance.
| Table Field |
FHIR Resource |
FHIR Path |
alert_id |
AllergyIntolerance |
AllergyIntolerance.id (derived) |
patient_id |
AllergyIntolerance |
AllergyIntolerance.patient.reference |
allergen_type |
AllergyIntolerance |
AllergyIntolerance.code (coded allergen) |
11. enteral_parenteral_orders
Purpose
Stores enteral nutrition (EN) and parenteral nutrition (TPN) orders, including formula, rate, volume, additives, and targets. Integrates with Pharmacy Information System for TPN compounding and supports TPN order accuracy KPI.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
order_id |
BIGINT |
NO |
IDENTITY |
PK |
EN/TPN order ID |
patient_id |
BIGINT |
NO |
— |
FK → patients.patient_id |
Patient |
encounter_id |
BIGINT |
NO |
— |
FK → encounters.encounter_id |
Encounter |
nutrition_type |
VARCHAR(20) |
NO |
— |
IN ('EN','TPN') |
Enteral vs parenteral |
formula_name |
VARCHAR(100) |
YES |
— |
— |
Formula or TPN regimen name |
rate_ml_hr |
NUMERIC(6,1) |
YES |
— |
≥ 0 |
Infusion rate (mL/hr) |
total_volume |
INTEGER |
YES |
— |
≥ 0 |
Total volume per day (mL) |
calorie_target |
NUMERIC(6,1) |
YES |
— |
≥ 0 |
Daily kcal target |
protein_target |
NUMERIC(5,1) |
YES |
— |
≥ 0 |
Daily protein target (g) |
additives |
JSONB |
YES |
'[]' |
— |
Additives (electrolytes, vitamins) |
start_datetime |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Start time |
end_datetime |
TIMESTAMPTZ |
YES |
— |
> start_datetime if not null |
End time |
status |
VARCHAR(20) |
NO |
'active' |
IN ('draft','active','on-hold','completed','cancelled') |
Order status |
ordered_by |
BIGINT |
NO |
— |
FK → providers.provider_id |
Ordering physician |
order_datetime |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
When ordered |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE enteral_parenteral_orders (
order_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
patient_id BIGINT NOT NULL,
encounter_id BIGINT NOT NULL,
nutrition_type VARCHAR(20) NOT NULL,
formula_name VARCHAR(100),
rate_ml_hr NUMERIC(6,1),
total_volume INTEGER,
calorie_target NUMERIC(6,1),
protein_target NUMERIC(5,1),
additives JSONB NOT NULL DEFAULT '[]'::jsonb,
start_datetime TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
end_datetime TIMESTAMPTZ,
status VARCHAR(20) NOT NULL DEFAULT 'active',
ordered_by BIGINT NOT NULL,
order_datetime TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_enpn_patient
FOREIGN KEY (patient_id) REFERENCES patients(patient_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_enpn_encounter
FOREIGN KEY (encounter_id) REFERENCES encounters(encounter_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT fk_enpn_ordered_by
FOREIGN KEY (ordered_by) REFERENCES providers(provider_id)
ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT chk_enpn_type
CHECK (nutrition_type IN ('EN','TPN')),
CONSTRAINT chk_enpn_rate
CHECK (rate_ml_hr IS NULL OR rate_ml_hr >= 0),
CONSTRAINT chk_enpn_volume
CHECK (total_volume IS NULL OR total_volume >= 0),
CONSTRAINT chk_enpn_calorie_target
CHECK (calorie_target IS NULL OR calorie_target >= 0),
CONSTRAINT chk_enpn_protein_target
CHECK (protein_target IS NULL OR protein_target >= 0),
CONSTRAINT chk_enpn_status
CHECK (status IN ('draft','active','on-hold','completed','cancelled')),
CONSTRAINT chk_enpn_end_after_start
CHECK (end_datetime IS NULL OR end_datetime > start_datetime)
);
CREATE INDEX idx_enpn_patient_active
ON enteral_parenteral_orders(patient_id, status)
WHERE status = 'active';
CREATE INDEX idx_enpn_encounter
ON enteral_parenteral_orders(encounter_id);
CREATE INDEX idx_enpn_type_status
ON enteral_parenteral_orders(nutrition_type, status);
Terminology Bindings
| Field |
Terminology |
Example Value |
nutrition_type |
Local value set |
TPN |
formula_name |
Facility enteral formula catalog / RxNorm |
Isosource 1.5 |
additives |
SNOMED CT / RxNorm where applicable |
{"code":"313002","display":"Potassium chloride"} |
FHIR Resource Mapping
EN/TPN orders map to NutritionOrder and MedicationRequest (for TPN components).
| Table Field |
FHIR Resource |
FHIR Path |
order_id |
NutritionOrder |
NutritionOrder.id |
patient_id |
NutritionOrder |
NutritionOrder.patient.reference |
nutrition_type |
NutritionOrder |
NutritionOrder.intent / extension |
formula_name |
NutritionOrder |
NutritionOrder.enteralFormula.baseFormulaProductName |
rate_ml_hr |
NutritionOrder |
NutritionOrder.enteralFormula.administration.rateQuantity |
total_volume |
NutritionOrder |
NutritionOrder.enteralFormula.maxVolumeToDeliver |
additives |
NutritionOrder |
NutritionOrder.enteralFormula.additiveType / extension |
12. diet_type_definitions
Purpose
Master list of diet types with allowed and excluded food categories and texture constraints. Used to validate diet orders and filter menu items.
Field Specifications
| Field |
Type |
Nullable |
Default |
Constraint |
Description |
diet_type_id |
BIGINT |
NO |
IDENTITY |
PK |
Diet type ID |
diet_name_en |
VARCHAR(100) |
NO |
— |
— |
English name (e.g., "Renal 2g Na") |
diet_name_ar |
VARCHAR(100) |
NO |
— |
— |
Arabic name |
description |
TEXT |
YES |
— |
— |
Description |
allowed_categories |
TEXT |
YES |
— |
— |
Comma-separated allowed food categories |
excluded_categories |
TEXT |
YES |
— |
— |
Comma-separated excluded categories |
texture_level |
VARCHAR(50) |
YES |
— |
— |
Default texture (IDDSI) |
is_active |
BOOLEAN |
NO |
TRUE |
— |
Active flag |
created_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
— |
Creation time |
updated_at |
TIMESTAMPTZ |
NO |
CURRENT_TIMESTAMP |
ON UPDATE |
Last update |
SQL DDL
SQLCREATE TABLE diet_type_definitions (
diet_type_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
diet_name_en VARCHAR(100) NOT NULL,
diet_name_ar VARCHAR(100) NOT NULL,
description TEXT,
allowed_categories TEXT,
excluded_categories TEXT,
texture_level VARCHAR(50),
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX ux_diet_type_name_en
ON diet_type_definitions(diet_name_en)
WHERE is_active = TRUE;
Terminology Bindings
| Field |
Terminology |
Example Value |
texture_level |
IDDSI |
IDDSI-6 |
FHIR Resource Mapping
Diet types can be represented as ValueSet or CodeSystem and referenced from NutritionOrder.
| Table Field |
FHIR Resource |
FHIR Path |
diet_type_id |
CodeSystem |
CodeSystem.concept.code |
diet_name_en |
CodeSystem |
CodeSystem.concept.display |
Data Volume Estimates
Assumptions: 300-bed UAE hospital, average occupancy 85%, 3 main meals + snacks, dietitian coverage.
| Table |
Estimated Rows / Day |
5-Year Volume (approx) |
Notes |
diet_orders |
350–500 |
~650k–900k |
Includes changes and cancellations |
meal_plans |
900–1,200 |
~1.6M–2.2M |
3–4 plans per patient per day |
meal_service_records |
900–1,200 |
~1.6M–2.2M |
One per delivered meal |
nutrition_assessments |
40–60 |
~75k–110k |
High-risk and follow-ups |
nutrition_screening |
80–120 |
~150k–220k |
One per admission, some repeats |
menu_items |
Static ~500 |
~500–800 |
Slowly growing master data |
menu_cycles |
Static ~4 cycles × variants |
~200–400 |
Per facility/diet/meal/day |
kitchen_production_orders |
3–4 per facility/day |
~27k–36k |
Breakfast, lunch, dinner, snacks |
tray_tickets |
900–1,200 |
~1.6M–2.2M |
One per meal per patient |
food_allergen_alerts |
0.5–1 per patient |
~50k–80k |
Depends on allergy prevalence |
enteral_parenteral_orders |
10–20 |
~18k–36k |
ICU and high-dependency patients |
diet_type_definitions |
~40 |
~40–80 |
Master data |
Indexes defined above are sized to support these volumes; partitioning by year may be considered for meal_service_records, tray_tickets, and diet_orders in large multi-hospital deployments.
Data Retention Policy (UAE Context)
Retention must comply with UAE MOH, DOH, DHA regulations and UAE PDPL for health data. Unless stricter local emirate rules apply, clinical nutrition records are treated as part of the medical record.
| Table |
Retention Period |
Rationale / Notes |
diet_orders |
Minimum 25 years from last encounter or as per MOH/DHA/DOH medical record retention |
Part of clinical orders; needed for medico-legal traceability and audit. |
meal_plans |
10 years |
Operational detail; can be archived after 10 years while preserving diet orders. |
meal_service_records |
10 years |
Supports quality KPIs and adverse event investigations (e.g., aspiration, hypoglycaemia). |
nutrition_assessments |
25 years |
Core clinical documentation forming part of patient record. |
nutrition_screening |
25 years |
Admission screening is part of clinical record and risk documentation. |
menu_items |
Retain active + 10 years after deactivation |
Master data; keep historical versions for traceability of past meals. |
menu_cycles |
10 years |
Needed to reconstruct historical meal offerings if required. |
kitchen_production_orders |
5–10 years |
Operational logs; retain at least 5 years for food safety and incident review. |
tray_tickets |
5–10 years |
Supports investigation of wrong-diet/allergen incidents; can be archived earlier than core clinical data. |
food_allergen_alerts |
25 years |
Derived from allergy records; must be retained in line with allergy documentation. |
enteral_parenteral_orders |
25 years |
High-risk therapy orders; part of core clinical record. |
diet_type_definitions |
Retain indefinitely with versioning |
Needed to interpret historical diet orders and meal plans. |
Additional PDPL considerations:
- Implement logical deletion / archival rather than physical deletion for clinical tables, with access controls and pseudonymisation where used for analytics.
- Ensure data subject rights (access, rectification, restriction) are supported via higher-level services; schema includes
created_at/updated_at for auditability.
- For NABIDH/Malaffi integration, nutrition-related data exposed via FHIR APIs must follow their specific profiles and consent models.