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  timestamptz

users

Authenticated identity, synced with auth.users.

id          uuid PK (= auth.users.id)
email       text
created_at  timestamptz

tenant_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     timestamptz

Relationships

  • 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

On this page