跳到正文
cccskills
免费在 GitHub 公开

db-deprecate-table

Retiring a dead table by moving it to the deprecated schema and clearing every reference in both repos. Use when asked to deprecate or retire a table, when a table is no longer used, or to take a table offline without dropping it. NOT for relocating a still-used table (use db-move-table-schema).

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md10.0 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Deprecate a table

<!-- rules:stamp -->

Rules from common-docs/policies/database-changeover-doctrine.md — edit there, never here (python3 common-docs/meta/scripts/one_home.py --write).

  1. Fix what is actually broken right now.
  2. While doing that, move the changeover forward a little — a few tables at a time, each one complete in every repo.
  3. Database counts mean nothing. There are zero users; all data is test data or his own, and a count only shows how much was tested. Never lead with a number, rank by volume, argue a name or design from row counts, or put counts in a brief as evidence; design for the live-week scale (100x today).
  4. There is no real data and there are no real users. Functionality first: primitive or store capability, then rendering, then editing, then a guard on the code path. Never spend a lane protecting, reconciling or carefully copying existing rows; the data copy is a plain mover step that can run again. Never open with a data census or a preservation gate. Data destruction still stops for confirmation; data fidelity does not.
  5. Never report on graveyard tables, and do not triage public until the canonical tables are right: graveyard is dead and known (deleting it may become an explicit task; until then it never appears in findings, summaries or "worth flagging" lists), public is a queue (canonical-first triage). When he repeats this hint to an agent, the fix is a missing pointer somewhere that agent read: find it and add it.
  6. Focus on what is right, not what is wrong. Learn how the canonical system works when correct (base entity, organization_id, access, associations), so that when a table is named the correct answer is already known. Mention a legacy item only when Arman names it or a task requires it; big dug-up findings are not the small critical fixes he has in mind.
<!-- rules:stamp-end -->

Once a table is here it is dead to every database check: findings on deprecated tables are never reported or fixed — canonical-first triage.

Goal: get the table offline and reversible (SET SCHEMA deprecated, never DROP), then erase every reference. Getting it offline is priority #1; reference cleanup follows and must not block the move. Read ../db-change/TOOLKIT.md + ../db-change/SKILL.md first. Project: brsgrqvjdzwihsvnfqkf.

Step 1 — Discover every reference (this is the real work)

🚨 THE ORACLE FIRST — audit.relation_usage(schema, table) (built 2026-08-20, deprecated-sweep postmortem). One call returns EVERY DB-side mention: inbound/outbound FKs, dependent views/matviews recursively (each dependent view joins the closure, so its consumers are found too), triggers on it, every function/procedure body (qualified vs bare matches labeled), RLS policy expressions on other tables, trigger string-arguments (_version_capture tokens, org-inherit args), cron jobs, realtime publications, and the entity/shareable/deprecation registries.

select * from audit.relation_usage('<schema>', '<table>') order by via, kind, ref;

The transitive hop is the whole point: single-hop name searches missed deprecated.prompt_builtins → public.context_menu_unified_view → get_ssr_shell_data (a LIVE session hydrator) in the 2026-08-20 sweep — the table name appears nowhere in the function, only the view's name does. Never substitute a plain pg_proc ilike scan for this call. function_body_bare rows can be same-named objects in another schema — read each; function_body_qualified rows are certain.

Two checks the oracle does not cover:

-- is anything still actually reading it? (needs pg_stat_statements)
select calls, query from pg_stat_statements where query ~* '\m<table>\M' order by calls desc limit 20;

Code (both repos): grep <table> for .from('<table>'), .schema(...).from('<table>'), generated type names, Python model/manager names (aidream/db/models*.py, db/managers/**), package wiring in aidream/package_integration.py, and raw SQL strings (from <table>, SELECT 1 FROM <table> ACL joins in .py/.sql). Also grep for every ref the oracle returned — a dependent view or RPC it surfaces can be called from code by ITS name with the table name appearing nowhere in the repo.

A 0-row table can still be LIVE. Verified: note_shares had 0 rows but was joined by RAG-search ACL (matrx-rag/search.py: SELECT 1 FROM public.note_shares) — deprecating it turned an empty result into a missing-relation error, breaking search. Row count ≠ usage. The query string is what breaks; grep it before you move. (Recovery: alter table deprecated.<t> set schema public — reversible, which is why we never DROP.)

Step 2 — Confirm it's truly dead

If reads remain: repoint or delete those consumers if quick; otherwise deprecate now (reversible) and track the remaining cleanup in the Open items queue of ../common-docs/operations/db-changeover-board.md (the tracker that replaced the deleted docs/db_rebuild/CHANGEOVER_PROGRESS.md). Do not block the move on a long repoint — but never deprecate a table with live, load-bearing reads you haven't accounted for.

Step 3 — Resolve FKs in BOTH directions

Inbound (tables that point AT this one): a cross-schema FK keeps working after the move, so the move won't break — but a dead table shouldn't be referenced. Drop or repoint inbound FK constraints that shouldn't exist. If an inbound FK represents real data you can't yet sever, that table isn't dead — reconsider.

🚨 Outbound (this table pointing at LIVE tables) — the step that gets forgotten, and it breaks live pages. SET SCHEMA carries every outbound FK along, so the retired table keeps advertising itself in pg_constraint as a child of live tables. Any catalog-walking function then discovers it and queries it as the signed-in user, who has no USAGE on deprecated → 42501 permission denied for schema deprecated, and the whole call dies. That is exactly how every /projects/<id> page broke on 2026-08-13: get_project_references walked the FKs into projects.projects and hit two retired flashcard tables. Always finish the move with the idempotent sweep — it is safe and expected to re-run:

do $$ declare r record; begin
  for r in select conname, conrelid::regclass as from_table from pg_constraint
    where contype='f' and conrelid::regclass::text like 'deprecated.%'
      and confrelid::regclass::text not like 'deprecated.%'
  loop execute format('alter table %s drop constraint %I', r.from_table, r.conname); end loop;
end $$;

migrations/drop_graveyard_to_live_fks.sql is this sweep. It was run ONCE (2026-07-28) and treated as done; every table retired afterwards re-created the problem — 78 such FKs had accumulated by 2026-08-13. It is not a one-time migration, it is a post-condition of every deprecated move.

Step 4 — Deactivate the registration FIRST (enforced, 2026-08-12)

platform._enforce_entity_is_table now ERRORs when an ACTIVE entity_types row ends up pointing at deprecated — the DDL-sync trigger repoints schema_name during your SET SCHEMA, so moving a still-active registered table into deprecated fails with a check_violation. Deactivate before you move (this is the guard doing its job, not a bug):

update platform.entity_types set is_active=false where token='<token>';   -- or delete the row

Step 5 — Move it (idempotent, verify no data lost)

do $$ begin
  if to_regclass('public.<table>') is not null then
    execute 'alter table public.<table> set schema deprecated';
  end if;
end $$;
select count(*) from deprecated.<table>;   -- equals the pre-move count

Step 6 — De-register the rest

Remove the remaining platform footprint so nothing resolves to it:

delete from platform.entity_relationships where child_type='<token>' or parent_type='<token>';
delete from platform.shareable_resource_registry where table_name='<table>';

Leave satellite rows (associations/comments/…) keyed by the token in place unless they're now orphaned — sweep separately; they're harmless and reversible.

Step 7 — Cross-repo cleanup + finalize

deprecated IS in the db-types schema list, so the table still appears under the deprecated schema in FE types — that's fine; the point is to delete every code usage. Then run the finalize SOP (db-change/SKILL.md): pnpm db-types → remove FE usages → pnpm sync-types (fix TS); python db/generate.py → remove aidream usages + package_integration.py entry → python db/detect_applied.py → python run.py clean boot. Record the migration in the ledger. Commit + push main on both repos.

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

SET SCHEMA deprecated makes public.<t> vanish → stale refs error (correct). Register it in scripts/dead-relations.json + platform.deprecated_relations and clear pnpm check:dead-relations (it finds the raw-SQL/Python/comment refs tsc misses). Never leave a readable old table or a compat view as a "fallback"; if it can't be moved yet, tripwire it (platform.deprecate_relation — data preserved, reads/writes RAISE).

NEVER

  • DROP TABLE — SET SCHEMA deprecated only (DROP is a separate PITR-gated step).
  • Leave the old name readable as a silent fallback — move it (vanishes → errors) or tripwire it (RAISES). Never a passthrough view.
  • Deprecate a table that still has live reads you haven't repointed or tracked.
  • Leave a generated type / Python model / package_integration.py reference pointing at the moved table.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

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月22日 更新

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月22日 更新

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月22日 更新

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月22日 更新

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月22日 更新

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月22日 更新

查看 armanisadeghi 的全部技能

报告此技能的问题