# CLAUDE.md

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

## Commands

```bash
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.
