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
Core CMMS Module
Core Tables
RBAC Tables
- roles
- permissions
- role_permissions
- user_roles
Purpose: User role definitions
Row-Level Security: EnabledSource:
| Column | Type | Constraints | Description |
|---|---|---|---|
id | serial | PRIMARY KEY | Role identifier |
name | text | NOT NULL, UNIQUE | Role name |
description | varchar | NULL | Role description |
is_system | boolean | NOT NULL, DEFAULT false | System role flag (non-deletable) |
created_at | timestamptz | DEFAULT now() | Creation timestamp |
sql/modules/core_cmms/03_tables.sql:18User Management
users
Purpose: Public user profile (extendsauth.users)
| Column | Type | Constraints | Description |
|---|---|---|---|
id | uuid | PRIMARY KEY, FK → auth.users.id | User identifier (matches auth.users) |
rol_id | bigint | NULL, FK → roles.id | Legacy role reference |
name | text | NOT NULL | First name |
last_name | text | NOT NULL | Last name |
location_id | bigint | NULL, FK → locations.id | User’s location |
email | text | NULL | Email address |
phone | text | NULL | Phone number |
is_active | boolean | NOT NULL, DEFAULT true | Active status |
created_at | timestamp | NOT NULL, DEFAULT now() | Creation timestamp |
updated_at | timestamptz | NOT NULL, DEFAULT now() | Last update timestamp |
created_by | uuid | NULL, DEFAULT auth.uid() | Creator user ID |
updated_by | uuid | NULL | Last updater user ID |
password_reset_at | timestamptz | NULL | Password reset timestamp |
password_reset_by | uuid | NULL | Who initiated password reset |
sql/modules/core_cmms/03_tables.sql:28
Ticket Management
- tickets
- assignees
- work_order_assignees
- special_incidents
Purpose: Work requests and work orders
Row-Level Security: Enabled with separate policies for work requests vs work ordersSource:
| Column | Type | Constraints | Description |
|---|---|---|---|
id | bigserial | PRIMARY KEY | Ticket identifier |
title | text | NOT NULL | Ticket title |
description | text | NOT NULL | Detailed description |
is_accepted | boolean | NOT NULL, DEFAULT false | Approval status (work order flag) |
is_urgent | boolean | NOT NULL | Urgency flag |
priority | priority_enum | NOT NULL | Priority level |
requester | text | NOT NULL | Requester name |
location_id | bigint | NULL, FK → locations.id | Location reference |
assignee | text | NOT NULL | Legacy assignee name |
assignee_id | bigint | NULL, FK → assignees.id | New assignee reference |
special_incident_id | integer | NULL, FK → special_incidents.id | Special incident type |
incident_date | date | NOT NULL | When incident occurred |
deadline_date | date | NULL | Due date |
is_archived | boolean | NOT NULL, DEFAULT false | Archive status |
finalized_at | timestamp | NULL | Completion timestamp |
image | text | NOT NULL | Image URL/path |
email | text | NULL | Requester email |
phone | text | NULL | Requester phone |
comments | text | NULL | Legacy comments field |
status | text | DEFAULT ‘Pendiente’ | Ticket status |
created_at | timestamp | NOT NULL, DEFAULT now() | Creation timestamp |
updated_at | timestamptz | NULL | Last update timestamp |
created_by | uuid | NULL | Creator user ID |
updated_by | uuid | NULL | Last updater user ID |
sql/modules/core_cmms/03_tables.sql:84The
is_accepted flag distinguishes work requests (false) from work orders (true).Configuration & Settings
- app_settings
- locations
- societies
Purpose: Key-value store for application settings
Row-Level Security: EnabledSource:
| Column | Type | Constraints | Description |
|---|---|---|---|
key | text | PRIMARY KEY | Setting key |
value | jsonb | NOT NULL | Setting value (JSON) |
updated_at | timestamp | NOT NULL, DEFAULT now() | Last update timestamp |
updated_by | uuid | NULL, FK → users.id | Last updater user ID |
sql/modules/core_cmms/03_tables.sql:111Announcements
- announcements
- announcement_audience_roles
Purpose: System-wide announcements with role-based targeting
Row-Level Security: EnabledSource:
| Column | Type | Constraints | Description |
|---|---|---|---|
id | bigint | PRIMARY KEY, GENERATED ALWAYS AS IDENTITY | Announcement identifier |
message | text | NOT NULL | Announcement text |
level | text | NOT NULL, DEFAULT ‘info’ | Severity level (info, warning, danger, success) |
url | text | NULL | Optional link URL |
is_active | boolean | NOT NULL, DEFAULT true | Active/visible flag |
dismissible | boolean | NOT NULL, DEFAULT true | User can dismiss flag |
starts_at | timestamptz | DEFAULT now() | Start of validity period |
ends_at | timestamptz | NULL | End of validity period |
audience_all | boolean | NOT NULL, DEFAULT true | Show to all roles (true) or specific roles (false) |
created_at | timestamptz | NOT NULL, DEFAULT now() | Creation timestamp |
updated_at | timestamptz | NOT NULL, DEFAULT now() | Last update timestamp |
created_by | uuid | NULL, FK → users.id | Creator user ID |
updated_by | uuid | NULL, FK → users.id | Last updater user ID |
sql/modules/core_cmms/03_tables.sql:118Notifications
The notification system is defined in
sql/modules/core_cmms/16_notifications.sql.- notification_outbox
- notification_deliveries
- push_subscriptions
Purpose: Outbox pattern for reliable push notification delivery
Deduplication: 5-minute window to prevent duplicate notifications
| Column | Type | Description |
|---|---|---|
id | bigint | Outbox entry identifier |
user_id | uuid | Target user |
title | text | Notification title |
body | text | Notification body |
url | text | Click target URL |
icon | text | Notification icon URL |
status | text | pending / processing / sent / failed |
retry_count | int | Number of send attempts |
max_retries | int | Maximum retry attempts |
scheduled_at | timestamptz | When to send |
sent_at | timestamptz | When successfully sent |
error | text | Error message if failed |
created_at | timestamptz | Creation timestamp |
Report Preferences
report_layout_preferences
Purpose: User-specific widget layout for report dashboards| Column | Type | Constraints | Description |
|---|---|---|---|
user_id | uuid | NOT NULL, FK → users.id, CASCADE DELETE | User identifier |
tab_id | text | NOT NULL, CHECK (length > 0) | Tab identifier |
widget_order | text[] | NOT NULL, DEFAULT [] | Ordered array of widget IDs |
created_at | timestamptz | NOT NULL, DEFAULT now() | Creation timestamp |
updated_at | timestamptz | NOT NULL, DEFAULT now() | Last update timestamp |
| PRIMARY KEY | (user_id, tab_id) | Composite key |
sql/modules/core_cmms/03_tables.sql:167
Row-Level Security (RLS)
Permission Checking Function
Theme_has_permission(code text) function:
- Gets the current user’s ID via
auth.uid() - Joins through
user_roles→role_permissions→permissions - Checks if any of the user’s roles grant the specified permission code
- Returns
boolean
Example Policies
sql/modules/core_cmms/09_policies.sql for all policy definitions.
Enums
Defined insql/modules/core_cmms/01_enums.sql:
| Enum Type | Values | Usage |
|---|---|---|
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 insql/modules/core_cmms/05_fk.sql:
Indexes
Performance indexes defined insql/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 insql/modules/core_cmms/14_storage.sql:
| Bucket | Public | Purpose | Policies |
|---|---|---|---|
branding | Yes | Company logos, login images | Read: public, Write: society:full_access |
tickets | No | Ticket attachments/images | RLS-controlled |
Realtime Configuration
Enabled for real-time updates (sql/modules/core_cmms/13_realtime.sql):
notification_deliveries- Badge count updatesticket_comments- Live comment streams
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