Files
baya-monorepo/dev/phases/_shared/frontend-conventions-checklist.md
T
2026-06-28 21:59:59 +03:30

3.3 KiB

Frontend conventions checklist (quick reference)

The authoritative rules are client/CLAUDE.md and the frontend-designer skill (invoke it for any visual work). This is a tick-list. If anything here seems to conflict with those, they win.

Boundaries & structure

  • Never add a layout above [locale]; src/app/[locale]/layout.tsx is the root layout.
  • Respect the RSC/client boundary: no next/headers, next-intl/server, or @/lib/cookies/server in client components; no @/lib/cookies/client in an RSC.
  • New route group / provider / top-level src/ folder ⇒ update the Project Structure tree in client/CLAUDE.md.

Data fetching & caching (prevent extra fetches and re-renders)

  • Fetch only through clientFetch/serverFetch (@/lib/api); domain calls live in src/services/{domain}/apis/. Never raw fetch().
  • Server state is TanStack Query: a keys.ts factory per domain, deliberate staleTime/gcTime, and cache invalidation on mutation (invalidateQueries/setQueryData) so you never refetch data you already hold. Prefer prefetch/initialData from RSC where it removes a client round-trip.
  • One hook per file (use{Action}.ts), useQuery/useMutation. Don't toast 401/403/5xx in hooks (the fetch layer already does) — only domain-specific 4xx messages.
  • Minimise re-renders: stable references (useCallback/useMemo only where it pays), select to subscribe to slices, colocate state low, lift only when shared. Don't put fast-changing state in a high context provider.

UI composition

  • Concrete MUI primitives stay MUI — use Button, Avatar, Paper, TextField, etc. (or the existing App* wrappers); never invent a new root-level Button/Avatar.
  • Composite/shareable components (built from primitives, reused in >1 place — a nurse card, an OTP input, a price-breakdown, a step header) live at the right shared level (src/components/…), not inline in a page or buried in a leaf. A component imported from >1 place gets a co-located *.test.tsx.
  • Page-only, never-reused composition can stay in the page.

i18n, theme, direction

  • Every user-visible string is a key in both messages/en.json and messages/fa.json (in sync). fa is default and RTL — design RTL-first; verify mirroring.
  • Colours come from tokens.css (var(--bal-…) / brand tokens), never hardcoded in sx. Use the pre-built APP_THEME_LTR/RTL; never createTheme() in a component.
  • MUI v9 API only (sx={{ mb: 4 }}, no v5/v6-only props).

Quality

  • Magic strings → named constants (src/constants/ or a colocated constants.ts).
  • Cookies/app state only through the cookie manager; never document.cookie/localStorage for auth.
  • No dead code (unused vars/imports are lint errors). Comment the why, not the what.
  • npm run check green; npm run test:ci green when a shared component changed.
  • Types come from the published contract in dev/contracts/ — don't guess server shapes; if a shape is missing, append a request to dev/shared-working-context/frontend/requests/for-backend.md and mock behind the services/{domain} seam meanwhile.