# AGENTS.md — shop (craftshop monorepo) ## Project structure - `client/` — frontend (React + Vite + TypeScript + MUI), **FSD architecture**: `app/pages/widgets/features/entities/shared` - `server/` — backend (Fastify + Prisma + SQLite) - `shared/constants/` — JS + `.d.ts` files shared between client and server (order statuses, delivery carriers, payment methods, upload limits) ## Developer commands ### Client (`cd client`) | Command | What it does | |---|---| | `npm run dev` | Vite dev server on `:5173`, proxies `/api` and `/uploads` to `http://127.0.0.1:3333` | | `npm run build` | Runs `tsc -b` first, then `vite build` | | `npm run lint` | ESLint (flat config) | | `npm run lint:fix` | ESLint with `--fix` | | `npm run format` | Prettier write all | | `npm run format:check` | Prettier check only | | `npm test` | vitest run | | `npm run test:watch` | vitest watch mode | ### Server (`cd server`) | Command | What it does | |---|---| | `npm run dev` | `node --env-file=.env --watch src/index.js` (requires Node 20.6+) | | `npm run dev:classic` | `node --watch src/index.js` (loads `.env` via dotenv) | | `npm run lint` | ESLint (flat config) | | `npm run lint:fix` | ESLint with `--fix` | | `npm run format` | Prettier write all | | `npm run format:check` | Prettier check only | | `npm test` | vitest run | | `npm run db:reset:test` | Reset SQLite DB + re-run migrations + seed (uses `.env`) | ### Build order (when changing both packages) ```bash cd server && npm run db:migrate # if schema changed cd server && npm test # server tests first cd client && npm run lint && npm run format:check && npm test # then client cd client && npm run build # full typecheck + build ``` ## Conventions - **Language**: Отвечай пользователю **на русском**. - **Single quotes**, no semicolons, trailing commas, 120 print width (Prettier + ESLint enforce). - **FSD import boundaries** enforced by `eslint-plugin-boundaries`. Lower layers cannot import upper layers. If ESLint complains about an import, the architecture is wrong. - **Aliases**: `@/` → `client/src/`, `@shared/` → `shared/` (configured in both vite.config.ts and tsconfig). - **API requests**: Use `apiClient` (axios wrapper from `shared/api/`) with `@tanstack/react-query`. Invalidate queries after mutations. - **UI**: Prefer MUI components over custom HTML/CSS. - **`no-console`**: ESLint error; use `console.warn/error/info` only. - **Admin access**: Only users with email matching `ADMIN_EMAIL` env var can access admin routes. Server auto-creates the admin user on startup. - **Server helpers**: `slugify`, `parseMaterialsInput`, `mapProductForApi` are decorated on fastify instance, accessed via `request.server.*`. ## Testing - **Client**: vitest + jsdom + @testing-library/react. Setup file: `client/src/testing/setup.ts`. - **Server**: vitest with globals enabled. - Test files live in `__tests__/` directories next to the code they test. ## OAuth - VK callback: `{SERVER_PUBLIC_URL}/api/auth/oauth/vk/callback` - Yandex callback: `{SERVER_PUBLIC_URL}/api/auth/oauth/yandex/callback` - Required env vars: `VK_CLIENT_ID`, `VK_CLIENT_SECRET`, `YANDEX_CLIENT_ID`, `YANDEX_CLIENT_SECRET`, `SERVER_PUBLIC_URL`, `CLIENT_PUBLIC_URL` ## Notable quirks - `.env` is gitignored. Copy `.env.example` to `.env` for local dev. - Vite dev server (client) relies on backend running at `127.0.0.1:3333`. Start server first. - Rich text rendering uses `shared/ui/RichTextMessageContent` (TipTap). Pass `tone="review"`, `tone="chat"`, or `tone="default"`. - `db:reset:test` runs `prisma migrate reset --force`, which destroys all data.