alter table public.content_export_jobs drop constraint if exists content_export_jobs_format_check, drop constraint if exists content_export_jobs_status_check; alter table public.content_export_jobs add constraint content_export_jobs_format_check check (format in ('json', 'paper_json', 'print_payload', 'pdf', 'docx')); alter table public.content_export_jobs add constraint content_export_jobs_status_check check (status in ('pending', 'rendering', 'completed', 'failed')); alter table public.content_export_jobs alter column status set default 'pending'; alter table public.content_export_jobs add column if not exists asset_id uuid references public.content_assets(id) on delete set null, add column if not exists locked_at timestamptz, add column if not exists locked_by text, add column if not exists attempt_count integer not null default 0, add column if not exists max_attempts integer not null default 3, add column if not exists next_attempt_at timestamptz, add column if not exists started_at timestamptz; do $$ begin if not exists (select 1 from pg_constraint where conname = 'content_export_jobs_attempt_count_check') then alter table public.content_export_jobs add constraint content_export_jobs_attempt_count_check check (attempt_count >= 0 and max_attempts > 0 and attempt_count <= max_attempts); end if; end $$; create index if not exists idx_content_export_jobs_worker_queue on public.content_export_jobs(status, next_attempt_at, created_at) where status = 'pending'; create index if not exists idx_content_export_jobs_asset on public.content_export_jobs(tenant_id, asset_id) where asset_id is not null;