Data Models
Data Models
Source of truth for all table definitions: lib/db/schema/*
Tables
tenants
Isolated workspace/account. The primary boundary for access control.
id uuid PK
name text
created_at timestamptzusers
Authenticated identity, synced with auth.users.
id uuid PK (= auth.users.id)
email text
created_at timestamptztenant_users
Membership between users and tenants.
tenant_id uuid FK → tenants.id
user_id uuid FK → users.id
role enum('owner', 'member')
created_at timestamptz
PK(tenant_id, user_id)habits (example business entity)
An example entity to demonstrate the feature pattern. Replace with your own entities.
id uuid PK
tenant_id uuid FK → tenants.id
name text
description text?
target_per_day integer (default 1)
is_active boolean (default true)
created_at timestamptzRelationships
- Tenant has many users (via
tenant_users) - Tenant has many habits
- User belongs to many tenants
- Habit belongs to one tenant
Authorization
All authorization is enforced by PostgreSQL Row Level Security (RLS).
See: supabase/migrations/0002_rls.sql
Key RLS Policies
- Users can only see their own record
- Tenants visible only to members
- Habits visible only to tenant members
tenant_users: only owners can modify membership