39 lines
2.0 KiB
SQL
39 lines
2.0 KiB
SQL
-- +goose Up
|
|
|
|
-- Content for the marketing site's (`/root/site`) drag-and-drop page
|
|
-- builder — an owner/manager (gated by the existing "settings" permission,
|
|
-- see internal/sitecontent) edits this from the CRM, and site/web renders
|
|
-- whatever is_visible=true holds via a public read endpoint. Deliberately a
|
|
-- flat ordered list per page, not a block tree — this is a single-page
|
|
-- marketing site, nested layout is over-engineering for what's actually
|
|
-- needed. `page` exists (rather than assuming one global list) so a second
|
|
-- page could be added later without a schema change, even though today
|
|
-- only 'home' is ever used.
|
|
--
|
|
-- `content` is a type-dependent JSONB blob (hero: heading/subheading/button
|
|
-- text+link; text: heading/body; cards: repeatable {icon,title,text,link};
|
|
-- faq: repeatable {question,answer}; cta: heading/body/button; custom_code:
|
|
-- a single raw HTML/script string) — no per-type columns, since the shape
|
|
-- genuinely varies per block type and every consumer (the CRM editor, the
|
|
-- public API, site/web's renderer) already has to switch on `type` anyway.
|
|
--
|
|
-- custom_code's content is rendered UNSANITIZED on the public site by
|
|
-- design (see internal/sitecontent's package doc) — that's what makes a
|
|
-- chat-widget embed snippet possible at all. The access control is "only a
|
|
-- settings-permission staff member can write a row here", not sanitization
|
|
-- of what they write.
|
|
CREATE TABLE site_page_blocks (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
page TEXT NOT NULL DEFAULT 'home',
|
|
position INT NOT NULL,
|
|
type TEXT NOT NULL CHECK (type IN ('hero', 'text', 'cards', 'faq', 'cta', 'custom_code')),
|
|
content JSONB NOT NULL DEFAULT '{}',
|
|
is_visible BOOLEAN NOT NULL DEFAULT true,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
CREATE INDEX site_page_blocks_page_position_idx ON site_page_blocks (page, position);
|
|
|
|
-- +goose Down
|
|
DROP TABLE site_page_blocks;
|