create table course_categories ( id uuid primary key default gen_random_uuid(), name text not null unique, position integer not null default 0, is_active boolean not null default true, created_at timestamptz not null default now(), updated_at timestamptz not null default now(), constraint course_categories_name_check check (char_length(trim(name)) between 1 and 120) ); insert into course_categories (name, position) select category, row_number() over (order by category) from (select distinct category from courses) categories on conflict (name) do nothing; insert into course_categories (name, position) values ('Tráfego Pago & Meta Ads', 10), ('Google Ads & YouTube', 20), ('Funis de Vendas & ROI', 30), ('Copywriting & Criativos', 40), ('Gestão & Processos de Agência', 50) on conflict (name) do nothing; create table platform_settings ( key text primary key, value jsonb not null, updated_at timestamptz not null default now(), updated_by uuid references users(id) on delete set null ); insert into platform_settings (key, value) values ('home.featuredCourseId', 'null'::jsonb), ('home.courseOrder', '[]'::jsonb), ('media.defaultCoverImageUrl', 'null'::jsonb) on conflict (key) do nothing; create table auth_rate_limits ( key text primary key, window_started_at timestamptz not null, attempts integer not null default 0 check (attempts >= 0), updated_at timestamptz not null default now() ); create index auth_rate_limits_updated_at_index on auth_rate_limits (updated_at); create trigger course_categories_set_updated_at before update on course_categories for each row execute function set_updated_at();