Database Schema & Security
Everything revolves around multi-tenant isolation. We use a shared database with Row Level Security (RLS) to ensure zero data leakage between customers.
Every SQL query executed by our applications automatically includes a tenant filter. This isn't done at the code level (where it's easy to forget), but at the Database Level.
-- SQL Example
CREATE POLICY tenant_isolation_policy ON table_name
USING (tenant_id = auth.uid_tenant());
Immutable Isolation
Once RLS is enabled, even a raw `SELECT *` from a compromised service will only return data belonging to the authenticated session's tenant.
Core Entities
| Column | Type | Description |
|---|---|---|
| id | UUID (PK) | Unique identifier for the tenant |
| name | String | Display name of the organization |
| slug | String (Unique) | URL-friendly identifier |
| plan | Enum | Current platform-wide billing plan |
| Column | Type | Description |
|---|---|---|
| id | UUID (PK) | Unique user ID |
String | User's email for login | |
| tenant_id | UUID (FK) | Primary tenant owner |
| Column | Type | Description |
|---|---|---|
| id | UUID (PK) | Sub ID |
| tenant_id | UUID (FK) | Owner of the subscription |
| module_id | String | The SaaS module (e.g., 'weddingos') |
| status | Enum | Active, Cancelled, Past Due |
Audit Logging
Every changes (CUD) are captured in the 'audit.logs' table for compliance.
Encrypted PII
Sensitive data is encrypted at-rest using AES-256 GCM.
Prisma Proxy
All DB access goes through a hardened repository layer.