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>
48 lines
1.9 KiB
Markdown
48 lines
1.9 KiB
Markdown
---
|
||
paths: 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/types/openapi.ts` из live OpenAPI. Без этого frontend build упадёт на missing types.
|
||
|
||
## 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`
|