create table if not exists organization_registration_requests ( id uuid primary key, organization_name_ciphertext bytea not null, organization_name_nonce bytea not null, organization_name_key_id text not null, email text not null, status text not null default 'pending_approval', organization_id uuid references organizations(id), requested_at timestamptz not null default now(), decided_by_user_id uuid references users(id), decided_at timestamptz, decision_note text, constraint organization_registration_requests_email_lowercase check (email = lower(email)), constraint organization_registration_requests_status_valid check ( status in ('pending_approval', 'approved', 'active', 'rejected', 'suspended') ) ); create table if not exists user_invitations ( id uuid primary key, organization_id uuid not null references organizations(id) on delete cascade, email text not null, invited_by_user_id uuid not null references users(id), status text not null default 'pending', expires_at timestamptz not null, accepted_at timestamptz, created_user_id uuid references users(id), created_at timestamptz not null default now(), constraint user_invitations_email_lowercase check (email = lower(email)), constraint user_invitations_status_valid check ( status in ('pending', 'accepted', 'expired', 'revoked') ) ); create table if not exists email_outbox ( id uuid primary key, recipient_email text not null, template text not null, payload_ciphertext bytea not null, payload_nonce bytea not null, payload_key_id text not null, status text not null default 'pending', attempt_count integer not null default 0, last_error text, send_after timestamptz not null default now(), sent_at timestamptz, created_at timestamptz not null default now(), constraint email_outbox_recipient_email_lowercase check (recipient_email = lower(recipient_email)), constraint email_outbox_status_valid check ( status in ('pending', 'sending', 'sent', 'failed') ) ); create index if not exists idx_organization_registration_requests_status on organization_registration_requests (status, requested_at); create index if not exists idx_user_invitations_organization_status on user_invitations (organization_id, status); create index if not exists idx_email_outbox_status_send_after on email_outbox (status, send_after);