Files
foundry-core/db/003-canvas.sql
T
codex-bot 6f36ef27bb
Foundry Go checks / check (push) Successful in 7m30s
Foundry Go checks / check (pull_request) Successful in 8m43s
Add versioned board canvas persistence and stable SEO slugs
2026-11-06 02:47:27 +08:00

30 lines
1.9 KiB
PL/PgSQL

BEGIN;
ALTER TABLE materials ADD COLUMN canvas_version bigint NOT NULL DEFAULT 1 CHECK (canvas_version > 0);
ALTER TABLE materials ADD COLUMN canvas_document jsonb;
ALTER TABLE materials ADD CONSTRAINT canvas_board_only CHECK (canvas_document IS NULL OR kind='board');
ALTER TABLE workspaces ADD COLUMN slug text;
UPDATE workspaces SET slug=COALESCE(NULLIF(trim(both '-' from left(trim(both '-' from regexp_replace(lower(name),'[^a-z0-9]+','-','g')),50)),''),'workspace') || '-' || id::text;
ALTER TABLE workspaces ALTER COLUMN slug SET NOT NULL;
ALTER TABLE workspaces ADD CONSTRAINT workspace_slug_unique UNIQUE(project,slug);
ALTER TABLE workspaces ADD CONSTRAINT workspace_slug_valid CHECK (slug ~ '^[a-z0-9]+(-[a-z0-9]+)*$' AND length(slug)<=100);
ALTER TABLE materials ADD COLUMN slug text;
UPDATE materials SET slug=COALESCE(NULLIF(trim(both '-' from left(trim(both '-' from regexp_replace(lower(title),'[^a-z0-9]+','-','g')),50)),''),'canvas') || '-' || id::text;
ALTER TABLE materials ALTER COLUMN slug SET NOT NULL;
ALTER TABLE materials ADD CONSTRAINT material_slug_unique UNIQUE(project,workspace_id,slug);
ALTER TABLE materials ADD CONSTRAINT material_slug_valid CHECK (slug ~ '^[a-z0-9]+(-[a-z0-9]+)*$' AND length(slug)<=100);
CREATE FUNCTION foundry_default_slug() RETURNS trigger LANGUAGE plpgsql AS $$
DECLARE label text;
BEGIN
IF NEW.slug IS NULL THEN
IF TG_TABLE_NAME='workspaces' THEN label=NEW.name; ELSE label=NEW.title; END IF;
label=left(trim(both '-' from regexp_replace(lower(label),'[^a-z0-9]+','-','g')),50);
NEW.slug=COALESCE(NULLIF(trim(both '-' from label),''),'canvas') || '-' || NEW.id::text;
END IF;
RETURN NEW;
END $$;
CREATE TRIGGER workspace_default_slug BEFORE INSERT ON workspaces FOR EACH ROW EXECUTE FUNCTION foundry_default_slug();
CREATE TRIGGER material_default_slug BEFORE INSERT ON materials FOR EACH ROW EXECUTE FUNCTION foundry_default_slug();
COMMIT;