Skip to main content

Database Schema

The MLM CMMS database is built on PostgreSQL and organized into modular SQL scripts for deterministic bootstrapping. This document provides a comprehensive reference of the database structure.

Module Organization

The database schema is organized into three main modules:

core_cmms

Foundation module with RBAC, tickets, users, notifications, and core functionality

assets

Asset management, categories, and preventive maintenance

inventory

Inventory, parts, warehouses, stock movements, and reservations

Execution Order

The SQL modules must be executed in the exact order shown below. Do not reorder files without an explicit migration plan.

Core CMMS Module

1

Extensions

00_extensions.sql - PostgreSQL extensions (e.g., uuid-ossp, pg_cron)
2

Enums

01_enums.sql - Enumerated types (priority, assignee sections, etc.)
3

Permission Actions

02_permission_action.sql - Permission action enum type
4

Tables

03_tables.sql - Core table definitions
5

Functions & Triggers

04_functions_triggers.sql - Stored procedures and triggers
6

Foreign Keys

05_fk.sql - Foreign key constraints
7

Views

06_views.sql - Database views
8

Indexes

07_indexes.sql - Performance indexes
9

RLS

08_rls.sql - Enable Row-Level Security
10

Policies

09_policies.sql - RLS policies
11

Admin Permissions

10_seed_admin_permissions.sql - Permission registry seed data
12

Bootstrap Data

11_seed_bootstrap.sql - Initial roles and system data
13

Updates

12_updates.sql - Schema updates and migrations
14

Realtime

13_realtime.sql - Supabase Realtime configuration
15

Storage

14_storage.sql - Supabase Storage buckets and policies
16

Grants

15_grants_auth.sql - Schema grants and authentication setup
17

Notifications

16_notifications.sql - Notification system tables and functions

Core Tables

RBAC Tables

Purpose: User role definitions
ColumnTypeConstraintsDescription
idserialPRIMARY KEYRole identifier
nametextNOT NULL, UNIQUERole name
descriptionvarcharNULLRole description
is_systembooleanNOT NULL, DEFAULT falseSystem role flag (non-deletable)
created_attimestamptzDEFAULT now()Creation timestamp
Row-Level Security: EnabledSource: sql/modules/core_cmms/03_tables.sql:18

User Management

users

Purpose: Public user profile (extends auth.users)
ColumnTypeConstraintsDescription
iduuidPRIMARY KEY, FK → auth.users.idUser identifier (matches auth.users)
rol_idbigintNULL, FK → roles.idLegacy role reference
nametextNOT NULLFirst name
last_nametextNOT NULLLast name
location_idbigintNULL, FK → locations.idUser’s location
emailtextNULLEmail address
phonetextNULLPhone number
is_activebooleanNOT NULL, DEFAULT trueActive status
created_attimestampNOT NULL, DEFAULT now()Creation timestamp
updated_attimestamptzNOT NULL, DEFAULT now()Last update timestamp
created_byuuidNULL, DEFAULT auth.uid()Creator user ID
updated_byuuidNULLLast updater user ID
password_reset_attimestamptzNULLPassword reset timestamp
password_reset_byuuidNULLWho initiated password reset
Row-Level Security: Enabled Source: sql/modules/core_cmms/03_tables.sql:28

Ticket Management

Purpose: Work requests and work orders
ColumnTypeConstraintsDescription
idbigserialPRIMARY KEYTicket identifier
titletextNOT NULLTicket title
descriptiontextNOT NULLDetailed description
is_acceptedbooleanNOT NULL, DEFAULT falseApproval status (work order flag)
is_urgentbooleanNOT NULLUrgency flag
prioritypriority_enumNOT NULLPriority level
requestertextNOT NULLRequester name
location_idbigintNULL, FK → locations.idLocation reference
assigneetextNOT NULLLegacy assignee name
assignee_idbigintNULL, FK → assignees.idNew assignee reference
special_incident_idintegerNULL, FK → special_incidents.idSpecial incident type
incident_datedateNOT NULLWhen incident occurred
deadline_datedateNULLDue date
is_archivedbooleanNOT NULL, DEFAULT falseArchive status
finalized_attimestampNULLCompletion timestamp
imagetextNOT NULLImage URL/path
emailtextNULLRequester email
phonetextNULLRequester phone
commentstextNULLLegacy comments field
statustextDEFAULT ‘Pendiente’Ticket status
created_attimestampNOT NULL, DEFAULT now()Creation timestamp
updated_attimestamptzNULLLast update timestamp
created_byuuidNULLCreator user ID
updated_byuuidNULLLast updater user ID
Row-Level Security: Enabled with separate policies for work requests vs work ordersSource: sql/modules/core_cmms/03_tables.sql:84
The is_accepted flag distinguishes work requests (false) from work orders (true).

Configuration & Settings

Purpose: Key-value store for application settings
ColumnTypeConstraintsDescription
keytextPRIMARY KEYSetting key
valuejsonbNOT NULLSetting value (JSON)
updated_attimestampNOT NULL, DEFAULT now()Last update timestamp
updated_byuuidNULL, FK → users.idLast updater user ID
Row-Level Security: EnabledSource: sql/modules/core_cmms/03_tables.sql:111

Announcements

Purpose: System-wide announcements with role-based targeting
ColumnTypeConstraintsDescription
idbigintPRIMARY KEY, GENERATED ALWAYS AS IDENTITYAnnouncement identifier
messagetextNOT NULLAnnouncement text
leveltextNOT NULL, DEFAULT ‘info’Severity level (info, warning, danger, success)
urltextNULLOptional link URL
is_activebooleanNOT NULL, DEFAULT trueActive/visible flag
dismissiblebooleanNOT NULL, DEFAULT trueUser can dismiss flag
starts_attimestamptzDEFAULT now()Start of validity period
ends_attimestamptzNULLEnd of validity period
audience_allbooleanNOT NULL, DEFAULT trueShow to all roles (true) or specific roles (false)
created_attimestamptzNOT NULL, DEFAULT now()Creation timestamp
updated_attimestamptzNOT NULL, DEFAULT now()Last update timestamp
created_byuuidNULL, FK → users.idCreator user ID
updated_byuuidNULL, FK → users.idLast updater user ID
Row-Level Security: EnabledSource: sql/modules/core_cmms/03_tables.sql:118

Notifications

The notification system is defined in sql/modules/core_cmms/16_notifications.sql.
Purpose: Outbox pattern for reliable push notification delivery
ColumnTypeDescription
idbigintOutbox entry identifier
user_iduuidTarget user
titletextNotification title
bodytextNotification body
urltextClick target URL
icontextNotification icon URL
statustextpending / processing / sent / failed
retry_countintNumber of send attempts
max_retriesintMaximum retry attempts
scheduled_attimestamptzWhen to send
sent_attimestamptzWhen successfully sent
errortextError message if failed
created_attimestamptzCreation timestamp
Deduplication: 5-minute window to prevent duplicate notifications

Report Preferences

report_layout_preferences

Purpose: User-specific widget layout for report dashboards
ColumnTypeConstraintsDescription
user_iduuidNOT NULL, FK → users.id, CASCADE DELETEUser identifier
tab_idtextNOT NULL, CHECK (length > 0)Tab identifier
widget_ordertext[]NOT NULL, DEFAULT []Ordered array of widget IDs
created_attimestamptzNOT NULL, DEFAULT now()Creation timestamp
updated_attimestamptzNOT NULL, DEFAULT now()Last update timestamp
PRIMARY KEY(user_id, tab_id)Composite key
Row-Level Security: Enabled Source: sql/modules/core_cmms/03_tables.sql:167

Row-Level Security (RLS)

All tables have RLS enabled. Access is controlled through policies that check public.me_has_permission(code) against the user’s assigned permissions.

Permission Checking Function

The me_has_permission(code text) function:
  1. Gets the current user’s ID via auth.uid()
  2. Joins through user_rolesrole_permissionspermissions
  3. Checks if any of the user’s roles grant the specified permission code
  4. Returns boolean

Example Policies

-- Read tickets (work orders)
CREATE POLICY tickets_select_work_orders ON public.tickets
  FOR SELECT
  USING (
    is_accepted = true
    AND (
      me_has_permission('work_orders:read')
      OR me_has_permission('work_orders:full_access')
    )
  );

-- Insert tickets (work orders)
CREATE POLICY tickets_insert_rbac ON public.tickets
  FOR INSERT
  WITH CHECK (
    me_has_permission('work_orders:create')
    OR me_has_permission('work_orders:full_access')
  );
See sql/modules/core_cmms/09_policies.sql for all policy definitions.

Enums

Defined in sql/modules/core_cmms/01_enums.sql:
Enum TypeValuesUsage
priority_enum'BAJA', 'MEDIA', 'ALTA'Ticket priority
assignee_section_enum'ELECTRICIDAD', 'MECANICA', 'CIVIL', 'SIN ASIGNAR', etc.Assignee department
assignee_role_enum'primary', 'support', 'observer'Role in work order assignment
permission_action'create', 'read', 'read_own', 'update', 'delete', 'work', 'import', 'export', 'approve', 'assign', 'disable', 'full_access', 'cancel', 'manage_roles', 'manage_permissions'Permission action types
The permission_action enum must match the TypeScript PermissionAction type in src/rbac/permissionRegistry.ts:1-16.

Foreign Key Relationships

Key relationships defined in sql/modules/core_cmms/05_fk.sql:
users.id ←→ auth.users.id
users.location_id → locations.id

tickets.location_id → locations.id
tickets.assignee_id → assignees.id
tickets.special_incident_id → special_incidents.id

work_order_assignees.work_order_id → tickets.id (CASCADE DELETE)
work_order_assignees.assignee_id → assignees.id

role_permissions.role_id → roles.id (CASCADE DELETE)
role_permissions.permission_id → permissions.id (CASCADE DELETE)

user_roles.user_id → auth.users.id (CASCADE DELETE)
user_roles.role_id → roles.id (CASCADE DELETE)

Indexes

Performance indexes defined in sql/modules/core_cmms/07_indexes.sql include:
  • Ticket filtering: idx_tickets_is_accepted, idx_tickets_status, idx_tickets_created_by
  • Permission lookups: idx_permissions_code, idx_permissions_resource_action
  • Role assignments: idx_user_roles_user_id, idx_role_permissions_role_id
  • Notification queries: idx_notification_deliveries_user_unread

Storage Buckets

Defined in sql/modules/core_cmms/14_storage.sql:
BucketPublicPurposePolicies
brandingYesCompany logos, login imagesRead: public, Write: society:full_access
ticketsNoTicket attachments/imagesRLS-controlled

Realtime Configuration

Enabled for real-time updates (sql/modules/core_cmms/13_realtime.sql):
  • notification_deliveries - Badge count updates
  • ticket_comments - Live comment streams
Both tables use REPLICA IDENTITY FULL to send complete row data on changes.

Next Steps

RBAC System

Understand how permissions and roles work

Architecture

Review the overall system architecture

Database Functions

Explore available database functions

Database Setup

Initialize a new database