← back to Inline Editor

db/migrations/001_page_overrides.sql

54 lines

-- @dw/inline-editor — Postgres schema (dw_unified)
-- Append-only audit + current-state override layer.

CREATE TABLE IF NOT EXISTS page_overrides (
  site         TEXT NOT NULL,
  path         TEXT NOT NULL,
  selector     TEXT NOT NULL,
  kind         TEXT NOT NULL CHECK (kind IN ('text','html','image','image_alt','href')),
  value        TEXT NOT NULL,
  updated_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_by   TEXT NOT NULL,
  PRIMARY KEY (site, path, selector)
);
CREATE INDEX IF NOT EXISTS idx_page_overrides_site_path ON page_overrides(site, path);

-- Append-only — no UPDATE, no DELETE in normal use. Reverts are new rows.
CREATE TABLE IF NOT EXISTS page_edit_log (
  id            BIGSERIAL PRIMARY KEY,
  site          TEXT NOT NULL,
  path          TEXT NOT NULL,
  selector      TEXT NOT NULL,
  kind          TEXT NOT NULL,
  old_value     TEXT,
  new_value     TEXT NOT NULL,
  editor_email  TEXT NOT NULL,
  editor_ip     INET,
  editor_ua     TEXT,
  is_revert     BOOLEAN NOT NULL DEFAULT FALSE,
  ts            TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_page_edit_log_site_path ON page_edit_log(site, path, ts DESC);
CREATE INDEX IF NOT EXISTS idx_page_edit_log_editor    ON page_edit_log(editor_email, ts DESC);

-- Editor file uploads — metadata; the actual bytes land under site's public/uploads
CREATE TABLE IF NOT EXISTS page_uploads (
  id            BIGSERIAL PRIMARY KEY,
  site          TEXT NOT NULL,
  url           TEXT NOT NULL,            -- the public URL (/uploads/abc.jpg)
  abs_path      TEXT NOT NULL,            -- filesystem path on origin
  mime_type     TEXT NOT NULL,
  bytes         BIGINT NOT NULL,
  uploaded_by   TEXT NOT NULL,
  uploader_ip   INET,
  ts            TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_page_uploads_site ON page_uploads(site, ts DESC);

-- Rate limit table (sliding window — cleaned periodically)
CREATE TABLE IF NOT EXISTS page_edit_ratelimit (
  editor_email  TEXT NOT NULL,
  ts            TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_page_edit_ratelimit ON page_edit_ratelimit(editor_email, ts DESC);