gendesign/.claude/rules/frontend.md
bot-backend b73161a133
All checks were successful
CI / frontend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
chore(claude-config): secret-read + psycopg2 hooks, tradein.md rule, tradein-mvp globs
- scripts/claude-hooks/check-secret-read.py — PreToolUse(Bash) guard: блокирует чтение/передачу
  .env*/.pgpass/ssh-key (cat/Get-Content/curl @file/<redirect), закрывает Bash(*) обход Read(.env)
  deny. Allow: .env.example/templates, ls/stat. Tested 12/12.
- scripts/claude-hooks/check-sql-pitfalls.py — PostToolUse(Edit|Write|MultiEdit): блокирует
  import psycopg2 в backend + tradein-mvp/backend .py (psycopg v3). Cast-trap НЕ чекаем (FP на
  comment/test-mentions). Tested 7/7.
- scripts/claude-hooks/session-preflight.py — SessionStart: статус FORGEJO/OBSIDIAN token + db-tunnel.
- .claude/rules/tradein.md — НОВОЕ: tradein-mvp gotchas (2 БД, :8000=gendesign, scheduler в
  tradein-scraper, strict SQL auto-apply + NN-collisions, rapid-merge trap).
- backend.md/sql.md/frontend.md: paths globs расширены на tradein-mvp/**.

Wiring (settings.json) — local/gitignored, отдельно. Audit 2026-06-27 P0+P1.
2026-06-27 13:02:30 +03:00

3.2 KiB
Raw Blame History

paths
frontend/**/*.{ts,tsx,jsx,js}
tradein-mvp/frontend/**/*.{ts,tsx,jsx,js}

Frontend conventions — Next.js 15 / React 19 / TypeScript 5

Critical

  • App router onlyНЕ pages/ router
  • TanStack Query для data-fetching — никакого useEffect для HTTP запросов
  • TS strict — никаких any; для unknown shape → unknown + narrow
  • TanStack Query keys — массивы: ["scrape-logs", scraperType, runIdFilter]
  • Tailwind 4 утилитарные классы; inline styles только для динамических значений
  • Server / Client components разделены явно — "use client" в начале client'а

XSS prevention (recurring bug class)

При рендере markdown / user-supplied content:

  • URL validation: allowlist schemes перед инъекцией в href= / src=:
    • https://, http://, /, #, mailto:
    • javascript:, data:, vbscript:, file: → fallback #
  • Pattern: helper safeUrl(url: string): string перед записью в attr

Reference: vault Bug_RenderMarkdown_JavascriptUrl_May14 (renderMarkdown.ts:safeUrl).

After backend schema change

cd frontend && npm run codegen

Обновляет src/lib/api-types.ts из live OpenAPI (npm run codegen = openapi-typescript … -o src/lib/api-types.ts). Без этого frontend build упадёт на missing types.

package.json + lockfile sync (CRITICAL — deploy aborts on mismatch)

Если меняешь frontend/package.json (add/remove/bump dep) — обязан также:

cd frontend && npm install --legacy-peer-deps --no-audit --no-fund

И закоммитить обновлённый frontend/package-lock.json в той же ветке.

Why: frontend/Dockerfile использует npm ci --legacy-peer-deps — этот режим требует точного match между package.json и package-lock.json. Mismatch → npm error Missing: <pkg>@<version> from lock file → builder fails → docker compose --abort-on-container-exitвесь deploy aborts (frontend + backend rollback).

  • Pre-push check: git diff main..HEAD -- frontend/package.json frontend/package-lock.json — если только один из двух тронут → STOP, regen lock.
  • Imports без deps entry (TypeScript авто-resolve через transitive) — latent bomb до first npm ci.
  • Reference incident: PR #344 (2026-05-17) добавил lucide-react без regen lockfile → deploy #135 fail → P0 hotfix PR #345 (commit 6ee20294f2).

Prettier / lint

  • 2 spaces, trailing comma, double quotes (config)
  • prettier hook auto-rewrites файл → нужен повторный git add
  • ESLint в pre-commit: no unused imports, no console.log, exhaustive deps

Запреты

  • any в TypeScript — unknown + type guard
  • useEffect для HTTP — TanStack Query
  • pages/ router — только app/
  • console.log в prod-коде
  • Inline в href/src без validation (XSS vector)
  • Hardcoded URLs — process.env.NEXT_PUBLIC_API_URL