gendesign/.claude/rules/frontend.md
lekss361 8b7696ad15 chore(claude-rules): promote 3 deferred feedback rules from memory
Follow-up to #495 — integrating 3 stable feedback rules into path-scoped
rule files (per MEMORY.md sweep 2026-05-24).

- frontend.md: + package.json + lockfile sync section
  (mismatch -> npm ci fails -> deploy aborts; ref PR #345)
- deploy.md: + Post-deploy verification section
  (spawn qa-tester smoke after every deploy success on main)
- backend.md: + Web probing section
  (playwright MCP for probing scrapers, curl/curl_cffi for actual scraping)

Source feedback files deleted from ~/.claude/projects/.../memory/
and added to Removed table in MEMORY.md.
2026-05-24 11:56:06 +03:00

64 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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.
## package.json + lockfile sync (CRITICAL — deploy aborts on mismatch)
Если меняешь `frontend/package.json` (add/remove/bump dep) — **обязан** также:
```bash
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`