alter table public.content_assets add column if not exists upload_status text not null default 'not_required', add column if not exists verified_at timestamptz, add column if not exists verified_by uuid references public.platform_users(id) on delete set null, add column if not exists verified_size_bytes bigint, add column if not exists verified_checksum_sha256 text, add column if not exists verification_details jsonb not null default '{}'::jsonb, add column if not exists preview_object_key text, add column if not exists preview_status text not null default 'none', add column if not exists security_flags jsonb not null default '{}'::jsonb; update public.content_assets set upload_status = case when storage_provider in ('local_dev', 'supabase_storage', 'aliyun_oss', 'tencent_cos') and object_key is not null then 'verified' else 'not_required' end, verified_at = case when storage_provider in ('local_dev', 'supabase_storage', 'aliyun_oss', 'tencent_cos') and object_key is not null then coalesce(verified_at, updated_at, created_at, now()) else verified_at end, verified_size_bytes = case when storage_provider in ('local_dev', 'supabase_storage', 'aliyun_oss', 'tencent_cos') and object_key is not null then coalesce(verified_size_bytes, file_size_bytes) else verified_size_bytes end, verified_checksum_sha256 = case when storage_provider in ('local_dev', 'supabase_storage', 'aliyun_oss', 'tencent_cos') and object_key is not null then coalesce(verified_checksum_sha256, checksum_sha256) else verified_checksum_sha256 end, preview_status = case when preview_url is not null and preview_url <> '' then 'ready' else preview_status end where upload_status = 'not_required' or verified_at is null or preview_status = 'none'; do $$ begin if not exists (select 1 from pg_constraint where conname = 'content_assets_upload_status_check') then alter table public.content_assets add constraint content_assets_upload_status_check check (upload_status in ('not_required', 'pending', 'verified', 'failed')); end if; if not exists (select 1 from pg_constraint where conname = 'content_assets_preview_status_check') then alter table public.content_assets add constraint content_assets_preview_status_check check (preview_status in ('none', 'pending', 'ready', 'failed')); end if; if not exists (select 1 from pg_constraint where conname = 'content_assets_verified_size_check') then alter table public.content_assets add constraint content_assets_verified_size_check check (verified_size_bytes is null or verified_size_bytes >= 0); end if; if not exists (select 1 from pg_constraint where conname = 'content_assets_verified_checksum_check') then alter table public.content_assets add constraint content_assets_verified_checksum_check check (verified_checksum_sha256 is null or verified_checksum_sha256 ~ '^[a-f0-9]{64}$'); end if; end $$; create index if not exists idx_content_assets_upload_status on public.content_assets(tenant_id, upload_status, status, updated_at desc); create index if not exists idx_content_assets_preview on public.content_assets(tenant_id, preview_status) where preview_status <> 'none';