本文へ移動
cccskills
無料GitHub で公開

db-move-table-schema

Relocating a live, still-used table to another Postgres schema with every reference intact. Use when asked to move or rehome a table into a schema, or to pull a table out of public into a domain schema. NOT for retiring a table (use db-deprecate-table).

インストール方法を見る

含まれるファイル(1)

  • SKILL.md8.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Move a table to a new schema

Moving an uncertified public table into its feature schema is the useful response to a database finding on it — not patching the finding in place: canonical-first triage.

Relocate public.<table> → <new>.<table> with references intact. Postgres moves most things for you; the misses are predictable. Read ../db-change/TOOLKIT.md + ../db-change/SKILL.md first. Project: brsgrqvjdzwihsvnfqkf. Retiring a dead table → db-deprecate-table; bringing a table onto the platform standard → db-canonicalize-table.

What ALTER TABLE … SET SCHEMA carries automatically

The table's columns, PK, indexes, CHECK/UNIQUE/FK constraints (its own and inbound FK constraints — cross-schema FKs keep working), RLS policies, triggers, and owned sequences all follow. You do not re-create these.

What does NOT follow: schema-level USAGE and the schema's default privileges — these belong to the schema, not the table. The moved table's grants come along but are dead without schema USAGE: every authenticated/anon access throws permission denied for schema <new>, which wrapper RPCs swallow into a silent null (the cx_canvas_upsert returned null class). Step 2 grants it; Step 3 verifies it.

What you MUST update by hand

  1. Registry rows — platform.entity_types.schema_name and platform.shareable_resource_registry.schema_name for this token.
  2. Hardcoded public.<table> references in functions/RPCs and views (unqualified refs follow search_path; schema-qualified ones break). Find them, CREATE OR REPLACE repointed.
  3. FE access = TWO separate doors. (a) PostgREST exposure + FE types — the target schema must be exposed to PostgREST and added to the pnpm db-types --schema list (TOOLKIT.md §0 trap), else the FE loses types and 404s. (b) Schema USAGE grant (Step 2) — SET SCHEMA does not grant it. A schema can be exposed yet USAGE-denied, which surfaces as a silent null, not a 404. Both are required. supabase-js calls change from .from('<table>') to .schema('<new>').from('<table>').
  4. aidream ORM — the target schema must be in db/matrx_orm.yaml additional_schemas with a generate block; the model regenerates into that schema's models_<schema>.py. If a sub-package consumes the table, update aidream/package_integration.py.

Step 1 — Pre-flight discovery

-- functions & views referencing the qualified name
select n.nspname, p.proname from pg_proc p join pg_namespace n on n.oid=p.pronamespace
where pg_get_functiondef(p.oid) ilike '%public.<table>%' or pg_get_functiondef(p.oid) ilike '%<table>%';
select schemaname, viewname from pg_views where definition ilike '%<table>%';
-- inbound FKs (will keep working, but note them)
select conrelid::regclass as referencing, conname from pg_constraint where confrelid='public.<table>'::regclass and contype='f';
-- current policies/triggers (confirm they follow after the move)
select polname from pg_policy where polrelid='public.<table>'::regclass;
select tgname from pg_trigger where tgrelid='public.<table>'::regclass and not tgisinternal;

Grep both repos for <table> usages (FE .from, Python models/managers, package wiring).

Step 2 — Ensure the target schema is ready (the EXPOSURE BLOCKER)

create schema if not exists <new>; then — always, even if the schema already existed (this is the step that gets skipped when the schema is pre-existing, and it's what broke canvas/code/legal/scraper) — GRANT USAGE ON SCHEMA <new> TO authenticated, anon, service_role; plus ALTER DEFAULT PRIVILEGES IN SCHEMA <new> GRANT … TO … for future tables · add it to the db-types --schema list · add to aidream matrx_orm.yaml.

⛔ You CANNOT expose a new schema via the MCP. Supabase's PostgREST exposed-schema list is platform config, not a role GUC (verified: nothing on authenticator.rolconfig), so no SQL you can run reaches it — not pnpm db:apply, not a read through the database tool. It must be added via the dashboard (Settings → API → Exposed schemas) or the management API (PATCH /v1/projects/{ref}/postgrest, preserving the existing list). A FE-read table moved into an unexposed schema 404s for every user the instant it moves. So: get the schema exposed FIRST (ask the user / use the mgmt API), confirm, then move. Don't blind-ALTER ROLE authenticator SET pgrst.db_schemas — you don't know the full current list and will silently un-expose other schemas.

Step 3 — Move + verify it followed

alter table public.<table> set schema <new>;
select count(*) from <new>.<table>;                                    -- unchanged
select polname from pg_policy where polrelid='<new>.<table>'::regclass; -- policies followed
select tgname  from pg_trigger where tgrelid='<new>.<table>'::regclass and not tgisinternal; -- triggers followed
select has_schema_privilege('authenticated','<new>','USAGE'),
       has_schema_privilege('anon','<new>','USAGE');                   -- MUST be true (Step 2); SET SCHEMA does NOT grant it

Repo-wide audit for this whole class — any schema with table grants but no USAGE (run after every move):

select n.nspname,
  count(*) filter (where has_table_privilege('authenticated', format('%I.%I',n.nspname,c.relname),'SELECT')) as granted_tables,
  has_schema_privilege('authenticated',n.nspname,'USAGE') as usage
from pg_namespace n join pg_class c on c.relnamespace=n.oid and c.relkind in ('r','p','v','m')
where n.nspname not like 'pg_%' and n.nspname<>'information_schema'
group by n.nspname
having not has_schema_privilege('authenticated',n.nspname,'USAGE')
   and count(*) filter (where has_table_privilege('authenticated', format('%I.%I',n.nspname,c.relname),'SELECT'))>0;
-- expected leftovers: cron, deprecated (internal/retired — correctly NO usage). Anything else FE-facing = bug.

Step 4 — Repoint the misses

Update the registry schema_name rows; CREATE OR REPLACE any function/view that named public.<table>; re-verify those RPCs run.

Step 5 — Cross-repo finalize

db-change SOP: pnpm db-types (schema added) → swap .from('<table>') → .schema('<new>').from('<table>') everywhere → pnpm sync-types (fix TS). aidream: python db/generate.py → update imports to the new model module + package_integration.py → python db/detect_applied.py → python run.py clean boot. Ledger the migration. Commit + push main on both repos.

Clean cut — no silent shim (SKILL db-change → THE CUT)

The move makes public.<t> vanish, so every stale ref errors — that's correct and desired; do NOT soften it. Register the move FIRST in scripts/dead-relations.json + platform.deprecated_relations, then repoint using pnpm check:dead-relations as your checklist until it's green (it catches the raw-SQL/comment/Python refs tsc can't). If a table genuinely can't move in the window, tripwire it (platform.deprecate_relation), never a passthrough view.

NEVER

  • Leave a compat VIEW at the old public.<t> name (the silent shim — the #1 disaster: reads/writes split silently across two tables). The old name must error or tripwire-RAISE, never pass through.
  • Move a FE-read table into a schema that isn't exposed + in the db-types list (silent 404s), or that lacks schema USAGE for authenticated/anon (silent null — SET SCHEMA does not grant it).
  • Forget the registry schema_name rows — verify_canonical/has_access resolve schema from entity_types, so a stale schema_name breaks RLS resolution.
  • Recreate policies/triggers/constraints by hand — they moved with the table; recreating them risks drift.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Admin debug system wiring for the floating AdminIndicator's live debug data and Copy Full Context. Use when adding debug visibility to a route or feature, wiring useDebugContext or the debug panel, capturing console errors, or enabling the copy-context workflow for a page.

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

Compact two-icon Copy / Copy-for-AI controls (components/agent-copy). Use when adding copy buttons to a row, card, list, or record; merging duplicate Copy/JSON/AI controls; continuing the copy rollout; or writing a Copy-for-AI payload. NOT for markdown content actions (use rich-document-actions).

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

Disclosing a surface's existing fixed AI jobs in the shell's top Agents menu. Use when a page, panel, overlay, or window already runs a mandate behind a button, assist, automatic action, or mode; when the agent-disclosure guard names a file; or during a surface check.

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

The watch-fix-rerun method for making an existing platform agent or automated process efficient and correct: baseline its ledger, run one unit yourself, fix the class behind every wasted call, rerun, record. Use when asked to improve, optimize, watch, or 'make efficient' an agent, a sandbox session, a sync job, or any recurring automated process.

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

Redux state for agent execution and firing agent shortcuts. Use when editing features/agents/redux/, building agent UI, creating a conversation, touching assembleRequest or NDJSON stream state, wiring agent-state selectors, adding a per-conversation capability, or triggering a shortcut from a button, menu, or code (useShortcutTrigger, launchAgentExecution).

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

The provision for a call site: the exhaustive menu of values that place in the code can realistically produce. Use before creating or fixing a mandate or agent that reasons about more than its own input, when deciding whether an agent can answer at all with what it is sent, or when its output 'looks right' but nobody checked it could be. NOT for building the agent (use create-agent).

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

armanisadeghi のスキルをすべて見る

このスキルの問題を報告する