Files
frontend/CLAUDE.md

2.8 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

npm run dev        # Start dev server on port 3000
npm run build      # Type-check (tsc -b) then Vite build
npm run preview    # Preview production build
npm run lint       # ESLint check

No test runner is configured.

Architecture

This is a React 19 + Vite frontend following Feature-Sliced Design (FSD). Layers are strictly ordered — lower layers must not import from higher ones:

app → pages → widgets → features → entities → shared

Path aliases map directly to FSD layers (@app/*, @pages/*, @widgets/*, @features/*, @entities/*, @shared/*) via vite-tsconfig-paths.

Layer responsibilities

  • app/ — global providers (React Query, router), global CSS (styles/). Entry: App.tsx wraps QueryProvider → RouterProvider.
  • pages/ — route-level page components. Each page composes widgets.
  • widgets/ — self-contained UI blocks (Hero, CurrencyConverter, NetworksTable, etc.). Contain their own model/, ui/, and barrel index.ts.
  • features/ — user-facing capabilities. Currently only auth/ (hooks + API calls).
  • shared/ — cross-cutting utilities, never feature-specific:
    • api/ — fetch wrapper (base.ts), CSRF token cache (csrf.ts), in-memory access token store (tokenStore.ts)
    • config/routes.ts (ROUTES const), env.ts (VITE_API_URL), constants.ts
    • ui/ — reusable components (Button, PrimaryButton, FormField, Pill, Title, TokenIcon, Notification) with CSS Modules
    • lib/ — generic hooks (useDebounce, useLocalStorage) and utils (cn)

Auth flow

Authentication uses two-step email+code flows for both registration and login. The access token lives in an in-memory tokenStore (not localStorage). It is refreshed against https://app.auth.elcsa.ru/v1/jwt/refresh using an HttpOnly cookie. useAuth() triggers this refresh on app load via React Query; useIsAuthenticated() derives auth state from that query.

Every API request (via shared/api/base.ts) attaches a CSRF token fetched from /csrf/token (cached in module scope) and the Bearer token if present. On 401 it attempts one silent refresh before throwing.

Routing

ProtectedRoute redirects unauthenticated users to /login. GuestRoute redirects already-authenticated users away from /login and /register. The converter page (/converter) is public but not a guest-only route.

Styling

Plain CSS Modules (.module.css) — no Tailwind or CSS-in-JS. Global design tokens live in src/app/styles/variables.css.

Environment

VITE_API_URL must be set (used in src/shared/config/env.ts). Create a .env.local for local development.