Skip to content

Schema: tenancy

The tenancy schema provides the workspace tenant boundary for multi-tenant isolation. Every lenser belongs to at least one workspace (their auto-created personal workspace), and organizations map to organization-type workspaces.

Tables

workspaces

Top-level tenant container. Media, keys, and other workspace-scoped resources reference this table.

ColumnTypeNotes
iduuid (PK)
slugtext UNIQUE NOT NULLURL-safe identifier, 3-64 chars, lowercase alphanumeric with hyphens/underscores
typetext NOT NULLpersonal or organization
display_nametext NOT NULLDisplay name
owner_lenser_iduuidFK -> lensers.profiles(id). NULL if org-owned.
org_iduuidFK -> organizations.organizations(id). Set for organization-type workspaces.
statustext DEFAULT 'active'active, suspended, archived
metadatajsonb DEFAULT '{}'Extensible metadata
created_attimestamptz NOT NULL DEFAULT now()
updated_attimestamptz NOT NULL DEFAULT now()Auto-updated via trigger

workspace_members

Join table linking lensers to workspaces with a role.

ColumnTypeNotes
iduuid (PK)
workspace_iduuid NOT NULLFK -> tenancy.workspaces(id) CASCADE
lenser_iduuid NOT NULLFK -> lensers.profiles(id) CASCADE
roletext DEFAULT 'member'owner, admin, member, viewer
invited_byuuidFK -> lensers.profiles(id). NULL for auto-created memberships.
joined_attimestamptz DEFAULT now()

Unique constraint: (workspace_id, lenser_id) — one membership per lenser per workspace

Workspace types

Personal: Auto-created when a lenser profile is inserted. The lenser's handle becomes the workspace slug. The lenser is the sole owner.

Organization: Created when an organization is formed. Maps org_id to organizations.organizations(id). Existing org members are backfilled as workspace members.

Auto-creation trigger

sql
-- AFTER INSERT on lensers.profiles
-- Creates personal workspace + inserts owner membership
CREATE TRIGGER trg_profiles_create_personal_workspace
    AFTER INSERT ON lensers.profiles
    FOR EACH ROW EXECUTE FUNCTION tenancy.fn_create_personal_workspace();

Helper functions

FunctionReturnsPurpose
tenancy.is_workspace_member(workspace_id)booleanChecks if current auth user is a member
tenancy.is_workspace_admin(workspace_id)booleanChecks if current auth user is admin or owner

Both are SECURITY DEFINER functions used in RLS policies.

RLS summary

workspaces: Members can read their own workspaces. Admin/owner can update. Authenticated users can create workspaces they own.

workspace_members: Members can see co-members. Admin/owner can add and remove members.