alter table public.subcontractor_payments add column if not exists po_number text, add column if not exists project_id uuid references public.projects(id) on delete set null, add column if not exists due_date date, add column if not exists terms text default 'Net 15', add column if not exists sent_at timestamptz, add column if not exists approved_at timestamptz, add column if not exists cancelled_at timestamptz; alter table public.subcontractor_payments drop constraint if exists subcontractor_payments_status_check; update public.subcontractor_payments set status = 'ready_to_pay' where status = 'pending'; alter table public.subcontractor_payments add constraint subcontractor_payments_status_check check (status in ('draft', 'sent', 'approved', 'ready_to_pay', 'paid', 'cancelled')); with numbered as ( select id, 'PO-' || to_char(coalesce(created_at, now()), 'YYYY') || '-' || lpad((row_number() over (order by created_at, id))::text, 4, '0') as generated_po_number from public.subcontractor_payments where po_number is null ) update public.subcontractor_payments sp set po_number = numbered.generated_po_number from numbered where sp.id = numbered.id; create unique index if not exists subcontractor_payments_po_number_key on public.subcontractor_payments(po_number) where po_number is not null; drop policy if exists "External reads own subcontractor purchase orders" on public.subcontractor_payments; create policy "External reads own subcontractor purchase orders" on public.subcontractor_payments for select using ( get_my_role() = 'external' and profile_id = auth.uid() ); drop policy if exists "External updates own subcontractor purchase orders" on public.subcontractor_payments; create policy "External updates own subcontractor purchase orders" on public.subcontractor_payments for update using ( get_my_role() = 'external' and profile_id = auth.uid() ) with check ( get_my_role() = 'external' and profile_id = auth.uid() );