FemeSalud’s persistence layer is a PostgreSQL database hosted on Supabase. TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/KevxxAlva/femesalud-zen-flow/llms.txt
Use this file to discover all available pages before exploring further.
public schema contains 10 tables that cover the full clinical workflow — from patient registration and appointment scheduling through consultation records, laboratory results, and clinic configuration. All tables have Row Level Security (RLS) enabled, and two database functions (has_role and is_admin) are used across RLS policies to enforce access control without duplicating logic.
The schema is managed directly in the Supabase dashboard. There are no SQL migration files tracked in the application repository — all DDL changes must be applied through the Supabase Studio or the Supabase CLI project linked to the production instance.
Tables
patients
Core patient registry. Stores demographics, gynecological history, obstetric history, family antecedents, and personal history as structured JSONB fields.
appointments
Scheduled visits linking a patient to a doctor. Tracks datetime, duration, status, and payment information including method and reference.
consultations
Detailed clinical encounter records attached to an appointment. Contains vitals, physical exam findings, colposcopy data, obstetric control, and treatment plan.
consultation_consumables
Line-item materials consumed during a consultation. Always written atomically with their parent consultation via Supabase RPC.
clinical_notes
Free-form clinical notes scoped to a patient. Supports file attachments stored in the
clinical-attachments Supabase Storage bucket.profiles
Doctor and admin user profiles. Extends
auth.users with display name, specialty, and avatar URL.user_roles
Maps authenticated users to application roles. A user may hold multiple roles. Used as the authoritative source for all RLS policy checks.
prescription_templates
Reusable prescription and indication templates created by doctors. Speeds up consultation data entry by pre-filling common indications.
clinic_info
Single-row configuration table for the practice. Stores the clinic name, address lines, phone number, and tax ID (RIF).
lab_results
Laboratory test results linked to both an appointment and a patient. Tracks test type, status, result text, result date, and an optional file URL.
Enums
Two PostgreSQL enums are defined in thepublic schema.
app_role
Controls which role a user entry in user_roles represents.
| Value | Description |
|---|---|
admin | Full access to all records, clinic settings, and user management. |
doctor | Scoped access — sees only their own patients and appointments. |
visit_type_enum
Classifies the clinical purpose of a consultation.
| Value | Description |
|---|---|
CONTROL | Routine follow-up or monitoring visit. |
EMERGENCIA | Unscheduled or urgent emergency visit. |
CONSULTA_NUEVA | First consultation for a new clinical concern. |
POST_TRATAMIENTO | Post-treatment review. |
OTRO | Any other visit type not covered above. |
Database Functions
Two helper functions are exposed in thepublic schema and called from RLS policies across tables.
has_role(_role app_role, _user_id uuid) → boolean
Returns true when the given user holds the specified role in user_roles.
is_admin(_user_id uuid) → boolean
Convenience wrapper around has_role that specifically checks for the admin role.
Key Relationships
The diagram below describes the foreign-key graph between the core tables.consultations also carry a direct patient_id foreign key to patients for queries that do not need to traverse through appointments.
Similarly, lab_results carries both appointment_id and patient_id to support direct patient-scoped queries without joining through appointments.
Row Level Security
RLS is enabled on every table in thepublic schema. The enforcement model follows two tiers:
- Admins — rows returned by the
is_admin()function see all records across all tables. - Doctors — rows visible to a given doctor are limited to patients assigned to them (
assigned_doctor_id = auth.uid()) and appointments wheredoctor_id = auth.uid(). Cascading joins restrict consultation and lab result visibility accordingly.
user_roles table using the has_role() function, keeping RLS policies consistent and avoiding hard-coded role strings scattered across policies.