- Add, edit, and delete experience entries and project links. - Manage skill categories and individual skill labels. - Edit the skills introduction and “How I work” text. Changes save directly to Supabase—no code edits or Git push needed. Existing content is preserved.
60 lines
2.7 KiB
SQL
60 lines
2.7 KiB
SQL
create table if not exists public.articles (
|
|
id uuid primary key default gen_random_uuid(),
|
|
slug text not null unique,
|
|
title text not null,
|
|
excerpt text not null,
|
|
published_at date not null,
|
|
read_time smallint not null check (read_time between 1 and 60),
|
|
tags text[] not null check (cardinality(tags) between 1 and 6),
|
|
accent text not null default 'mint' check (
|
|
accent in ('blue', 'lavender', 'peach', 'yellow', 'mint')
|
|
),
|
|
content jsonb not null,
|
|
created_at timestamptz not null default now()
|
|
);
|
|
|
|
create index if not exists articles_published_at_idx
|
|
on public.articles (published_at desc);
|
|
|
|
alter table public.articles add column if not exists banner jsonb;
|
|
alter table public.articles add column if not exists attachments jsonb not null default '[]'::jsonb;
|
|
|
|
alter table public.articles enable row level security;
|
|
|
|
-- Articles are exposed only through FastAPI. The server-side secret key maps to
|
|
-- service_role and bypasses RLS; browser roles receive no table privileges.
|
|
revoke all on table public.articles from anon, authenticated;
|
|
grant select, insert, update, delete on table public.articles to service_role;
|
|
|
|
-- Upload records also exist before an article is published. The article's banner
|
|
-- and attachments JSON include storage='dropbox' and the Dropbox file ID.
|
|
create table if not exists public.article_media (
|
|
upload_id text primary key check (upload_id ~ '^[a-f0-9]{32}$'),
|
|
metadata jsonb not null,
|
|
created_at timestamptz not null default now()
|
|
);
|
|
alter table public.article_media enable row level security;
|
|
revoke all on table public.article_media from anon, authenticated;
|
|
grant select, insert, update, delete on table public.article_media to service_role;
|
|
|
|
-- Persist removal intent before article changes so Dropbox outages can be retried.
|
|
create table if not exists public.article_media_deletions (
|
|
upload_id text primary key check (upload_id ~ '^[a-f0-9]{32}$'),
|
|
metadata jsonb not null,
|
|
created_at timestamptz not null default now()
|
|
);
|
|
alter table public.article_media_deletions enable row level security;
|
|
revoke all on table public.article_media_deletions from anon, authenticated;
|
|
grant select, insert, update, delete on table public.article_media_deletions to service_role;
|
|
|
|
-- Editable portfolio sections. Version checks prevent concurrent document writes
|
|
-- from silently replacing each other's changes.
|
|
create table if not exists public.portfolio_content (
|
|
key text primary key check (key in ('experience', 'skills')),
|
|
payload jsonb not null,
|
|
version bigint not null default 1
|
|
);
|
|
alter table public.portfolio_content enable row level security;
|
|
revoke all on table public.portfolio_content from anon, authenticated;
|
|
grant select, insert, update, delete on table public.portfolio_content to service_role;
|