Old CLAUDE.md was 700 lines — exceeded Anthropic 200-line recommendation,
adherence degraded under context pressure.
Refactor per research findings:
- CLAUDE.md 700 -> 97 lines (essential only, pointers to rules)
- .claude/rules/{backend,frontend,sql,git-pr,deploy}.md (NEW, path-scoped)
- ~/.claude/CLAUDE.md (NEW, 21 lines) — personal cross-project prefs
- memory/ — deleted 12 feedback files promoted to proper layer (CLAUDE.md
rules table, .claude/rules/, ~/.claude/CLAUDE.md). 7 remaining = workflow
details.
- .gitignore: !.claude/agents/, !.claude/rules/ exceptions
Total auto-loaded per session: 97 (CLAUDE.md) + 21 (~/.claude) = 118 lines
vs prior 700. Rules in .claude/rules/ load only when matching paths touched.
Resolves conflict no_self_review vs pre_push_review: now single rule in
git-pr.md Review workflow section (pre-push = local lint; post-push =
external Claude window posting as lekss361).
Code-reviewer feedback applied:
- paths: frontmatter added to git-pr.md
- Auto-merge scope blocked-list now includes .claude/rules/*.md changes
to prevent self-extending rules without human approval.
Co-authored-by: lekss361 <claudestars@proton.me>
2.5 KiB
| paths |
|---|
| data/sql/**/*.sql |
SQL conventions — PostgreSQL 16 / PostGIS 3.4
File naming
NN_topic.sql где NN — следующий sequential номер. Проверка: ls data/sql/ | sort | tail -5.
Structure
-- Контекст: что делает файл, зачем, порядок применения, dependencies.
BEGIN;
-- DDL здесь (idempotent)
COMMIT;
Idempotency (обязательно)
CREATE TABLE IF NOT EXISTSALTER TABLE ... ADD COLUMN IF NOT EXISTSALTER TABLE ... DROP COLUMN IF EXISTSCREATE OR REPLACE VIEWCREATE INDEX IF NOT EXISTSON CONFLICT DO NOTHINGдля seed dataDROP INDEX IF EXISTSпередCREATE INDEXесли меняется тип column
Auto-apply на prod
data/sql/NN_*.sql применяются автоматически через deploy.yml (tracking через _schema_migrations). Каждый файл — ровно один раз, по NN order. Idempotency критична.
Если auto-apply падает → deploy exit 1, containers не обновляются. Diagnose: GHA log → "Apply DB migrations". Fix: psql -f file.sql через SSH tunnel + INSERT INTO _schema_migrations (filename) VALUES ('NN_xxx.sql') ON CONFLICT DO NOTHING.
Migration order
- SQL migration first (схема) — deploy first
- Backend code matching new schema — deploy second
- Никогда наоборот — deployed code напорется на несовместимую схему
psycopg v3 CAST trap
В Python через psycopg v3 / SQLAlchemy text(...):
- ❌
:param::type— игнорируется парсером - ✅
CAST(:param AS type)— canonical
В чистом SQL (.sql файл, без bind params) — обычный ::type работает.
Reference: vault Pattern_CAST_AS_Type.
VIEW dependencies
Перед ALTER COLUMN type column'а:
- Найти зависимые view:
\d+ table_nameилиpg_get_viewdef('view_name'::regclass, true) DROP VIEW <dependent>;ALTER COLUMN ...;CREATE OR REPLACE VIEW <dependent> AS SELECT ...;
Reference: 93_cad_parcels_geom_multipolygon.sql (Polygon → MultiPolygon migration).
Запреты
- ❌
DROP TABLE/TRUNCATEбез явного approval пользователя - ❌ Не-idempotent файлы (без
IF EXISTS) — на случай ре-apply - ❌ Миграции без
BEGIN...COMMITобёртки - ❌ Hardcoded даты / IDs без комментария почему