Reference · Generated 2026-06-25 14:10:32

PostgreSQL schema

Canonical DDL from backend/schema.sql. 20 tables · 10 with tenant_id (multi-tenant isolation).

← Reference annex

audit_log tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER REFERENCES tenants (id) ON DELETE SET NULL
patient_idINTEGER REFERENCES patients (id) ON DELETE SET NULL
actionTEXT NOT NULL CHECK (action IN ('DELETE', 'EDIT'))
entity_typeTEXT NOT NULL DEFAULT 'dispensing'
entity_idINTEGER NOT NULL
performed_byINTEGER REFERENCES users (id)
snapshot_beforeTEXT NOT NULL
snapshot_afterTEXT
changed_fieldsTEXT
deletion_reasonTEXT
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

care_group_members

ColumnType
group_idINTEGER NOT NULL REFERENCES care_groups (id) ON DELETE CASCADE
user_idINTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE
display_colourTEXT NOT NULL DEFAULT '#5a7a6b'
display_nameTEXT
joined_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

care_groups

ColumnType
idSERIAL PRIMARY KEY
name_encTEXT
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
created_byINTEGER REFERENCES users (id)
timezoneTEXT NOT NULL DEFAULT 'Australia/Sydney'
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
enc_versionSMALLINT NOT NULL DEFAULT 0

care_shifts

ColumnType
idSERIAL PRIMARY KEY
group_idINTEGER NOT NULL REFERENCES care_groups (id) ON DELETE CASCADE
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
carer_idINTEGER REFERENCES users (id)
dateTEXT NOT NULL
time_slotTEXT NOT NULL DEFAULT 'full_day'
start_timeTEXT
end_timeTEXT
locationTEXT NOT NULL DEFAULT 'home'
priorityTEXT NOT NULL DEFAULT 'normal'
recurrence_ruleTEXT
handover_notesTEXT
handover_arranged_by_user_idINTEGER REFERENCES users (id)
wellbeing_noteTEXT
statusTEXT NOT NULL DEFAULT 'scheduled'
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
updated_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

care_tasks

ColumnType
idSERIAL PRIMARY KEY
shift_idINTEGER NOT NULL REFERENCES care_shifts (id) ON DELETE CASCADE
titleTEXT NOT NULL
sort_orderINTEGER NOT NULL DEFAULT 0
completedBOOLEAN NOT NULL DEFAULT FALSE
completed_atTIMESTAMPTZ
completed_byINTEGER REFERENCES users (id)
arranged_by_user_idINTEGER REFERENCES users (id)
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

dispensings tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
dateTEXT NOT NULL
timeTEXT NOT NULL
script_idINTEGER REFERENCES patient_scripts (id) ON DELETE SET NULL
volumeDOUBLE PRECISION NOT NULL
reason_type_idINTEGER REFERENCES reason_types (id)
notesTEXT
patient_idINTEGER REFERENCES patients (id) ON DELETE SET NULL
created_atTIMESTAMPTZ NOT NULL DEFAULT clock_timestamp()
updated_atTIMESTAMPTZ NOT NULL DEFAULT clock_timestamp()

invitations tenant_id

ColumnType
idSERIAL PRIMARY KEY
tokenTEXT UNIQUE NOT NULL
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
created_byINTEGER NOT NULL REFERENCES users (id)
messageTEXT
expires_atTIMESTAMPTZ NOT NULL
used_atTIMESTAMPTZ
used_byINTEGER REFERENCES users (id)
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

patient_access

ColumnType
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
user_idINTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE
roleTEXT NOT NULL DEFAULT 'carer'
granted_byINTEGER REFERENCES users (id)
granted_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

patient_appointments

ColumnType
idSERIAL PRIMARY KEY
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
dateTEXT NOT NULL
appointment_timeTEXT NOT NULL
titleTEXT NOT NULL
addressTEXT
arranged_by_user_idINTEGER REFERENCES users (id)
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
updated_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

patient_scripts tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
medicine_name_rawTEXT NOT NULL
strengthTEXT
formTEXT
dose_textTEXT
frequency_textTEXT
dose_instructionsTEXT
unitTEXT NOT NULL DEFAULT 'tablet'
quantity_per_fillINTEGER
total_fills_authorisedINTEGER
fills_completedINTEGER NOT NULL DEFAULT 0
stock_adjustmentINTEGER NOT NULL DEFAULT 0
last_physical_countINTEGER
last_physical_count_atTIMESTAMPTZ
low_stock_thresholdINTEGER NOT NULL DEFAULT 7
prescriber_nameTEXT
prescriber_practiceTEXT
issued_dateTEXT
expiry_dateTEXT
image_urlTEXT
image_stored_atTIMESTAMPTZ
scan_statusTEXT NOT NULL DEFAULT 'manual'
scan_raw_textTEXT
scan_confidenceREAL
statusTEXT NOT NULL DEFAULT 'active'
color_hexTEXT NOT NULL DEFAULT '#7C3AED'
as_neededBOOLEAN NOT NULL DEFAULT FALSE
notesTEXT
created_byINTEGER REFERENCES users (id) ON DELETE SET NULL
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
updated_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

patient_sleep_entries tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
dateTEXT NOT NULL,
start_timeTEXT NOT NULL,
end_timeTEXT NOT NULL,
notesTEXT
recorded_byINTEGER NOT NULL REFERENCES users (id)
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
updated_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

patients tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
full_name_encTEXT
photo_urlTEXT
date_of_birth_encTEXT
addressTEXT
medical_summaryTEXT
created_byINTEGER REFERENCES users (id)
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
enc_versionSMALLINT NOT NULL DEFAULT 0

reason_types tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
nameTEXT NOT NULL
descriptionTEXT
color_hexTEXT NOT NULL DEFAULT '#6B7280'
display_orderINTEGER NOT NULL DEFAULT 0
activeBOOLEAN NOT NULL DEFAULT TRUE
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

schema_migrations

ColumnType
idSERIAL PRIMARY KEY
versionTEXT UNIQUE NOT NULL
descriptionTEXT
applied_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

script_alert_dismissals tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
user_idINTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE
patient_idINTEGER NOT NULL REFERENCES patients (id) ON DELETE CASCADE
script_idINTEGER NOT NULL REFERENCES patient_scripts (id) ON DELETE CASCADE
alert_typeTEXT NOT NULL
dismissed_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
alert_typeIN (

stripe_tier_local_prices

ColumnType
tier_slugTEXT NOT NULL
currencyTEXT NOT NULL
amount_centsINTEGER NOT NULL CHECK (amount_cents > 0)
stripe_price_idTEXT UNIQUE
activeBOOLEAN NOT NULL DEFAULT TRUE
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
updated_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

subscriptions tenant_id

ColumnType
idSERIAL PRIMARY KEY
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
moduleTEXT NOT NULL
statusTEXT NOT NULL DEFAULT 'inactive'
valid_untilTIMESTAMPTZ
activated_byINTEGER REFERENCES users (id)
activated_atTIMESTAMPTZ
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

tenant_memberships tenant_id

ColumnType
tenant_idINTEGER NOT NULL REFERENCES tenants (id) ON DELETE CASCADE
user_idINTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE
roleTEXT NOT NULL DEFAULT 'member'
statusTEXT NOT NULL DEFAULT 'active'
invited_byINTEGER REFERENCES users (id)
joined_atTIMESTAMPTZ NOT NULL DEFAULT NOW()

tenants

ColumnType
idSERIAL PRIMARY KEY
name_encTEXT
slugTEXT UNIQUE NOT NULL
owner_user_idINTEGER NOT NULL REFERENCES users (id)
statusTEXT NOT NULL DEFAULT 'trialing'
timezoneTEXT NOT NULL DEFAULT 'Australia/Sydney'
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
enc_versionSMALLINT NOT NULL DEFAULT 0

users

ColumnType
idSERIAL PRIMARY KEY
email_encTEXT
email_idxTEXT UNIQUE
phone_encTEXT
usernameTEXT UNIQUE NOT NULL
password_hashTEXT
roleTEXT NOT NULL DEFAULT 'user'
statusTEXT NOT NULL DEFAULT 'pending'
google_idTEXT UNIQUE
avatar_urlTEXT
profile_colourTEXT NOT NULL DEFAULT '#7C3AED'
list_on_key_contactsBOOLEAN NOT NULL DEFAULT FALSE
is_super_adminSMALLINT NOT NULL DEFAULT 0
must_change_passwordBOOLEAN NOT NULL DEFAULT FALSE
created_atTIMESTAMPTZ NOT NULL DEFAULT NOW()
last_loginTIMESTAMPTZ
enc_versionSMALLINT NOT NULL DEFAULT 0