create table if not exists public.organization_invites ( id text primary key default public.gen_hash_id() check (id ~ '^[0-9a-f]{16}$'), token text not null unique check (token ~ '^[0-9a-f]{24}$'), organization_id text not null references public.organizations(id) on delete cascade, created_by uuid not null references auth.users(id) on delete restrict, role public.organization_role not null default 'member', max_uses integer not null default 1 check (max_uses > 0), uses_count integer not null default 0 check (uses_count >= 0), expires_at timestamptz, revoked boolean not null default false, created_at timestamptz not null default now() ); create index if not exists idx_org_invites_org on public.organization_invites(organization_id); create index if not exists idx_org_invites_token on public.organization_invites(token); alter table public.organization_invites enable row level security; drop policy if exists "organization_invites_select_admins" on public.organization_invites; create policy "organization_invites_select_admins" on public.organization_invites for select to authenticated using (public.org_role(organization_id) in ('owner', 'admin')); drop policy if exists "organization_invites_insert_admins" on public.organization_invites; create policy "organization_invites_insert_admins" on public.organization_invites for insert to authenticated with check (public.org_role(organization_id) in ('owner', 'admin')); drop policy if exists "organization_invites_update_admins" on public.organization_invites; create policy "organization_invites_update_admins" on public.organization_invites for update to authenticated using (public.org_role(organization_id) in ('owner', 'admin')) with check (public.org_role(organization_id) in ('owner', 'admin'));