# Магазин изделий ручной работы

Цель проекта — витрина и админка для магазина изделий ручного труда (игрушки, сувениры и т.п.) с простой загрузкой/редактированием данных через фронтенд‑админку.

Проект сделан как **монорепозиторий**:
- `client/` — фронтенд (витрина + админка)
- `server/` — бэкенд API + БД

## Стек

### Фронтенд

- **React** + **Vite**
- **axios**
- **@tanstack/react-query**
- **MUI (@mui/material)** + emotion
- **React Router**
- **Архитектура**: **FSD (Feature-Sliced Design)** — слои `app/pages/widgets/features/entities/shared`
- **Качество**: ESLint (flat config) + Prettier, границы FSD (`eslint-plugin-boundaries`)

### Бэкенд

- **Node.js**
- **Fastify** (+ CORS)
- **Prisma** (миграции)
- **SQLite** (локальная БД; легко сменить на Postgres через `DATABASE_URL`)

## Основные подходы и договорённости

### FSD на фронте

- Импорты между слоями ограничены правилами `boundaries` (например `features` может импортировать `entities/shared`, но не наоборот).
- Alias `@` указывает на `client/src` (см. `client/vite.config.ts` и `client/tsconfig.app.json`).

### Данные и админка

- Данные загружаются/редактируются через **админку на фронте**.
- Админ‑роуты бэкенда доступны только авторизованному пользователю с email из `ADMIN_EMAIL` в `server/.env`.

### Форматирование и линтинг (client)

- Prettier конфиг: `client/.prettierrc.json`
- Ignore: `client/.prettierignore`
- EditorConfig: `client/.editorconfig`
- Команды:
  - `npm run lint` / `npm run lint:fix`
  - `npm run format` / `npm run format:check`

## Запуск

### Бэкенд

**Вариант A — типовой `.env`**

```bash
cd server
cp .env.example .env   # укажите ADMIN_EMAIL
npm install
npx prisma migrate dev # если база ещё не создана
npx prisma db seed     # опционально: тестовые категории и товары
npm run dev:classic     # загрузка из `.env`
```

**Вариант B — файл [`server/.dev_env`](server/.dev_env)** (то, что уже лежит в репозитории для локального стенда; нужен **Node.js 20.6+** из‑за `node --env-file`):

```bash
cd server
npm install
npm run dev             # переменные из `.dev_env`
```

Очистка БД до «чистого» тестового состояния (SQLite + миграции + seed): в `server/` выполните `npm run db:reset:test`.

Сервер: `http://127.0.0.1:3333`. Проверка: `GET /health`.

### Фронтенд

В другом терминале:

```bash
cd client
npm install
npm run dev
```

Откройте `http://localhost:5173`. Запросы к `/api` проксируются на бэкенд (см. `client/vite.config.ts`).

## Админка

Раздел админки доступен только по прямой ссылке `/admin` и только для пользователя с email из `ADMIN_EMAIL`. Если такого пользователя нет в БД, сервер создаёт его автоматически при старте.

Для боевого размещения фронта и API на разных доменах задайте `VITE_API_URL` (например `https://api.example.com/api`) и **CORS_ORIGIN** на сервере.

### OAuth VK и Яндекс

В `server/.env` задайте `VK_CLIENT_ID`, `VK_CLIENT_SECRET`, `YANDEX_CLIENT_ID`, `YANDEX_CLIENT_SECRET`, а также **точные** публичные адреса:

- `SERVER_PUBLIC_URL` — базовый URL API (без завершающего `/`), например `https://api.example.com` или `http://127.0.0.1:3333`.
- `CLIENT_PUBLIC_URL` — базовый URL витрины, куда бэкенд редиректит после входа с JWT в query: `/auth/callback?token=...`, например `http://127.0.0.1:5173`.

**Redirect URI в кабинетах провайдеров** (должны совпадать с тем, что шлёт сервер при авторизации):

- VK: `{SERVER_PUBLIC_URL}/api/auth/oauth/vk/callback`
- Яндекс: `{SERVER_PUBLIC_URL}/api/auth/oauth/yandex/callback`

Старт входа с витрины: кнопки на странице `/auth` ведут на `GET /api/auth/oauth/vk` и `GET /api/auth/oauth/yandex` (полный URL — тот же origin, что и API: при прокси Vite это `/api/...` относительно фронта; при отдельном домене API — из `VITE_API_URL`).

### Футер витрины (опционально)

В `client/.env` можно задать `VITE_STORE_EMAIL`, `VITE_STORE_PHONE`, `VITE_STORE_SOCIAL_NOTE` для блока контактов в подвале. Для страницы «Политика конфиденциальности» задайте **`VITE_PUBLIC_SITE_URL`** (например `https://example.com`, без завершающего `/`) — иначе в dev подставится текущий origin; на проде лучше указать явно перед `npm run build`.

## API (кратко)

Публичные:
- `GET /api/categories`
- `GET /api/products?categorySlug=...`

Админ:
- `GET /api/admin/products`
- `POST /api/admin/products`
- `PATCH /api/admin/products/:id`
- `DELETE /api/admin/products/:id`
- `POST /api/admin/categories`

## Деплой

```bash
# Заполнить scripts/deploy.env (DEPLOY_HOST, DEPLOY_PATH и т.д.)

# Первичная настройка LXC: см. scripts/SERVER_SETUP.md

# Деплой только изменившихся компонентов:
./scripts/deploy-auto.sh

# Полный деплой (игнорировать diff):
./scripts/deploy-auto.sh --force

# Только фронт или только бэкенд:
./scripts/deploy-auto.sh --frontend-only
./scripts/deploy-auto.sh --backend-only
```
