forked from wangziqi/gongxue-base
93 lines
4.2 KiB
SQL
93 lines
4.2 KiB
SQL
alter table public.video_explanations
|
|
add column if not exists asset_id uuid references public.content_assets(id) on delete set null,
|
|
add column if not exists access_mode text not null default 'svip',
|
|
add column if not exists free_preview_seconds integer not null default 0,
|
|
add column if not exists play_count integer not null default 0;
|
|
|
|
do $$
|
|
begin
|
|
if not exists (select 1 from pg_constraint where conname = 'video_explanations_access_mode_check') then
|
|
alter table public.video_explanations
|
|
add constraint video_explanations_access_mode_check
|
|
check (access_mode in ('free', 'svip', 'video_quota'));
|
|
end if;
|
|
|
|
if not exists (select 1 from pg_constraint where conname = 'video_explanations_free_preview_check') then
|
|
alter table public.video_explanations
|
|
add constraint video_explanations_free_preview_check
|
|
check (free_preview_seconds >= 0);
|
|
end if;
|
|
|
|
if not exists (select 1 from pg_constraint where conname = 'video_explanations_play_count_check') then
|
|
alter table public.video_explanations
|
|
add constraint video_explanations_play_count_check
|
|
check (play_count >= 0);
|
|
end if;
|
|
end $$;
|
|
|
|
create table if not exists public.video_play_quota_accounts (
|
|
id uuid primary key default gen_random_uuid(),
|
|
tenant_id uuid not null references public.tenants(id) on delete cascade,
|
|
user_id uuid not null references public.platform_users(id) on delete cascade,
|
|
quota_type text not null default 'video_play',
|
|
total_quota integer not null default 0,
|
|
used_quota integer not null default 0,
|
|
expires_at timestamptz,
|
|
source_type text,
|
|
source_id uuid,
|
|
metadata jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
unique (tenant_id, user_id, quota_type, source_type, source_id)
|
|
);
|
|
|
|
create table if not exists public.video_play_events (
|
|
id uuid primary key default gen_random_uuid(),
|
|
tenant_id uuid not null references public.tenants(id) on delete cascade,
|
|
user_id uuid not null references public.platform_users(id) on delete cascade,
|
|
video_id uuid not null references public.video_explanations(id) on delete cascade,
|
|
question_id uuid references public.questions(id) on delete set null,
|
|
entitlement_id uuid references public.entitlements(id) on delete set null,
|
|
quota_account_id uuid references public.video_play_quota_accounts(id) on delete set null,
|
|
play_token_hash text not null unique,
|
|
status text not null default 'issued' check (status in ('issued', 'started', 'completed', 'expired', 'revoked')),
|
|
access_mode text not null default 'svip' check (access_mode in ('free', 'svip', 'video_quota')),
|
|
consumed_quota integer not null default 0 check (consumed_quota >= 0),
|
|
signed_url_expires_at timestamptz,
|
|
ip_address text,
|
|
user_agent text,
|
|
metadata jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
create index if not exists idx_video_explanations_asset
|
|
on public.video_explanations(tenant_id, asset_id)
|
|
where asset_id is not null;
|
|
|
|
create index if not exists idx_video_quota_user
|
|
on public.video_play_quota_accounts(tenant_id, user_id, quota_type, expires_at);
|
|
|
|
create index if not exists idx_video_play_events_user
|
|
on public.video_play_events(tenant_id, user_id, created_at desc);
|
|
|
|
create index if not exists idx_video_play_events_video
|
|
on public.video_play_events(tenant_id, video_id, created_at desc);
|
|
|
|
do $$
|
|
declare
|
|
table_name text;
|
|
begin
|
|
foreach table_name in array array['video_play_quota_accounts', 'video_play_events']
|
|
loop
|
|
execute format('alter table public.%I enable row level security', table_name);
|
|
execute format('drop policy if exists tenant_isolation on public.%I', table_name);
|
|
execute format(
|
|
'create policy tenant_isolation on public.%I for all using (tenant_id = app.current_tenant_id() or app.is_platform_admin()) with check (tenant_id = app.current_tenant_id() or app.is_platform_admin())',
|
|
table_name
|
|
);
|
|
execute format('drop trigger if exists set_updated_at on public.%I', table_name);
|
|
execute format('create trigger set_updated_at before update on public.%I for each row execute function app.touch_updated_at()', table_name);
|
|
end loop;
|
|
end $$;
|