gendesign/.claude/rules/sql.md
lekss361 ae0fce3528
refactor(claude): split 700-line CLAUDE.md into path-scoped .claude/rules/ (#188)
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>
2026-05-15 23:06:33 +03:00

2.5 KiB
Raw Blame History

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 EXISTS
  • ALTER TABLE ... ADD COLUMN IF NOT EXISTS
  • ALTER TABLE ... DROP COLUMN IF EXISTS
  • CREATE OR REPLACE VIEW
  • CREATE INDEX IF NOT EXISTS
  • ON CONFLICT DO NOTHING для seed data
  • DROP 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

  1. SQL migration first (схема) — deploy first
  2. Backend code matching new schema — deploy second
  3. Никогда наоборот — 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'а:

  1. Найти зависимые view: \d+ table_name или pg_get_viewdef('view_name'::regclass, true)
  2. DROP VIEW <dependent>;
  3. ALTER COLUMN ...;
  4. 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 без комментария почему