55 lines
2.8 KiB
Markdown
55 lines
2.8 KiB
Markdown
# 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.
|