-- 0017: universal import saved mappings — per-company, named column mappings
-- for the "Restore from other software" wizard (Task 4 of
-- docs/superpowers/plans/2026-08-02-switch-from-anywhere.md). Mirrors
-- bank_csv_maps' armor (0011): jsonb mapping kept loosely typed on purpose
-- (CLAUDE.md §12 — the TypeScript layer validates shape before applying;
-- the database only guards tenancy and identity), RLS ENABLE + FORCE keyed
-- to current_company_id(), and TRUNCATE forbidden.
--
-- Unlike bank_csv_maps (keyed per money account), these are keyed by a
-- user-chosen NAME per kind — one company may keep several journal layouts
-- ("Sage GL export", "Old payroll system") side by side.

CREATE TABLE universal_mappings (
  company_id uuid NOT NULL REFERENCES companies (id),
  id bigint GENERATED ALWAYS AS IDENTITY,
  kind text NOT NULL CHECK (kind IN ('chart', 'journal')),
  name text NOT NULL,
  mapping jsonb NOT NULL,
  updated_by uuid NOT NULL REFERENCES users (id),
  updated_at timestamptz NOT NULL DEFAULT now(),
  PRIMARY KEY (id),
  UNIQUE (company_id, id),
  UNIQUE (company_id, kind, name)
);

ALTER TABLE universal_mappings ENABLE ROW LEVEL SECURITY;
ALTER TABLE universal_mappings FORCE ROW LEVEL SECURITY;
CREATE POLICY universal_mappings_isolation ON universal_mappings
  USING (company_id = current_company_id());

-- Saved mappings are working configuration (same stance as bank_csv_maps,
-- which grants exactly this): read, insert, and upsert-update. No DELETE —
-- no delete route exists, and unused grants are attack surface.
GRANT SELECT, INSERT, UPDATE ON universal_mappings TO app;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app;

CREATE TRIGGER universal_mappings_no_truncate
  BEFORE TRUNCATE ON universal_mappings
  FOR EACH STATEMENT EXECUTE FUNCTION forbid_truncate();
