Перейти к содержанию

frontend (web client)

1. Назначение и границы

frontend — это SPA-клиент платформы Konstructorium на React/Vite, который обслуживает три роли:

  • покупатель (каталог, карточка модели, корзина, заказы, профиль, чат),
  • продавец (публикация моделей, управление своими моделями, заказы продавца, отзывы),
  • администратор (dashboard, пользователи, товары, заказы, отзывы, уведомления, чат).

Границы ответственности фронтенда:

  • рендеринг UI и клиентских маршрутов;
  • хранение минимального клиентского auth-state;
  • вызов backend API по согласованным HTTP-контрактам;
  • обработка пользовательских сценариев и ошибок уровня UI.

Фронтенд не содержит доменную бизнес-логику сервисов (правила ролей, финальные валидации, вычисление статусов заказа) — она остаётся на стороне backend.

2. Технологический стек и зависимости

2.1 Runtime и сборка

  • react 18.2.0
  • react-dom 18.2.0
  • vite 5.0.8
  • @vitejs/plugin-react 4.2.1

2.2 Маршрутизация, данные, состояние

  • react-router-dom 6.20.0
  • react-query 3.39.3
  • axios 1.6.2
  • zustand 4.4.7

2.3 Формы, уведомления, UI

  • react-hook-form 7.48.2
  • react-toastify 9.1.3
  • tailwindcss 3.3.6
  • postcss 8.4.32
  • autoprefixer 10.4.16

2.4 3D-библиотеки

  • three 0.160.0
  • @react-three/fiber 8.15.0
  • @react-three/drei 9.92.0

2.5 Скрипты npm

Скрипт Команда Назначение
dev vite локальный dev-server
build vite build production-сборка в dist/
preview vite preview локальный просмотр build-артефакта
lint eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0 проверка линтера

3. Архитектура и композиция runtime

3.1 Точка входа

src/main.jsx инициализирует:

  • LanguageProvider (локализация),
  • QueryClientProvider (react-query cache/runtime),
  • BrowserRouter (SPA-router),
  • ToastContainer (глобальные toast-уведомления).

Параметры QueryClient:

  • refetchOnWindowFocus: false,
  • retry: 1.

3.2 App-композиция

src/App.jsx содержит:

  • bootstrap авторизации при старте (проверка сессии через authService.getProfile()),
  • два route guard-компонента:
  • PrivateRoute для пользовательских/продавческих приватных страниц,
  • AdminRoute для административных страниц,
  • две крупные подсистемы маршрутов:
  • публично-пользовательская зона (/ и связанные роуты),
  • административная зона (/admin/*).

3.3 Модель инициализации auth

Порядок:

  1. из localStorage восстанавливается пользователь (auth-storage, admin-storage);
  2. на mount отправляется GET /api/auth/profile/ (через proxy);
  3. при валидной сессии сторы синхронизируются фактическим профилем;
  4. при 401/403 сторы очищаются;
  5. выставляются флаги initialized для снятия блокировки route guard.

Это устраняет рассинхронизацию между cookie-сессией и локальным клиентским кэшем.

4. Полный каталог UI-маршрутов

4.1 Публичные и пользовательские маршруты

Путь Доступ Экран
/ публичный главная
/login публичный вход
/register публичный регистрация
/products публичный каталог
/products/:id публичный карточка 3D-модели
/cart authenticated user корзина
/orders authenticated user мои заказы
/profile authenticated user профиль
/my-products authenticated user (seller flow) мои модели
/create-product authenticated user (seller flow) создание модели
/become-seller authenticated user заявка на роль продавца
/seller-orders authenticated user (seller flow) заказы продавца
/seller-reviews authenticated user (seller flow) отзывы продавца
/chat authenticated user чат с поддержкой
/legal/:slug публичный юридические документы (RU/EN, см. legal/developer-guide)

Поведение cookie и аналитики: баннер согласия (AnalyticsConsentBanner), трекер webAnalyticsTracker.js, AnalyticsRouteTracker — события только после granted. Отчёты staff: /admin/analytics (вкладки Трафик … Онлайн). Регламент: Веб-аналитика, Юридическая документация.

4.2 Административные маршруты

Путь Доступ Экран
/admin/login публичный вход администратора
/admin/dashboard admin (is_staff / is_superuser) dashboard
/admin/users admin пользователи
/admin/products admin товары
/admin/orders admin заказы
/admin/reviews admin отзывы
/admin/notifications admin уведомления
/admin/chat admin чат-оператор

Дополнительно:

  • /admin/ редиректит на /admin/dashboard.

5. API-каталог frontend-клиента

Базовый клиент API: src/services/api.js.

Все axios-инстансы используют withCredentials: true, то есть рассчитывают на cookie-сессию.

5.1 Auth API (/api/auth)

Метод URL (frontend) Назначение
POST /api/auth/register/ регистрация
POST /api/auth/login/ вход
POST /api/auth/logout/ выход
GET /api/auth/profile/ профиль текущего пользователя
GET /api/auth/csrf/ первичная инициализация CSRF-cookie (служебно)

5.2 User API (/api/users)

Метод URL Назначение
GET /api/users/profiles/me/ профиль текущего пользователя
PATCH /api/users/profiles/me/ обновление профиля
GET /api/users/sellers/ список продавцов
POST /api/users/profiles/request_seller_status/ запрос статуса продавца

5.3 Product API (/api/products)

Метод URL Назначение
GET /api/products/models/ каталог моделей
GET /api/products/models/{id}/ карточка модели
POST /api/products/models/ создание модели (multipart)
PATCH /api/products/models/{id}/ редактирование модели
GET /api/products/models/my_models/ модели продавца
POST /api/products/models/{id}/increment_views/ инкремент просмотров

5.4 Order API (/api/orders)

Метод URL Назначение
GET /api/orders/cart/ текущая корзина
POST /api/orders/cart/{cartId}/add_item/ добавить товар в корзину
POST /api/orders/cart/{cartId}/items/{itemId}/remove/ удалить позицию
PATCH /api/orders/cart/{cartId}/items/{itemId}/update_quantity/ изменить количество
POST /api/orders/cart/{cartId}/checkout/ оформить заказ
GET /api/orders/orders/ список заказов пользователя
GET /api/orders/orders/{id}/ детали заказа
GET /api/orders/orders/seller_orders/ заказы продавца
POST /api/orders/orders/{id}/update_payment_status/ обновить статус оплаты
POST /api/orders/orders/{id}/update_status/ обновить статус заказа

5.5 Review API (/api/reviews)

Метод URL Назначение
GET /api/reviews/reviews/ список отзывов
POST /api/reviews/reviews/ создание отзыва
GET /api/reviews/reviews/by_model/?model_3d_id={id} отзывы модели
GET /api/reviews/reviews/statistics/?model_3d_id={id} агрегированная статистика
GET /api/reviews/reviews/seller_reviews/ отзывы продавца

5.6 Admin API (/api/admin)

Dashboard

Метод URL Назначение
GET /api/admin/dashboard/stats/ метрики dashboard

Users

Метод URL Назначение
GET /api/admin/users/ список пользователей
GET /api/admin/users/{id}/ карточка пользователя
POST /api/admin/users/ создание пользователя
PATCH /api/admin/users/{id}/ редактирование пользователя
DELETE /api/admin/users/{id}/ удаление пользователя
POST /api/admin/users/{id}/toggle_active/ переключить активность
POST /api/admin/users/{id}/toggle_staff/ переключить staff-флаг
POST /api/admin/users/{id}/update_role/ сменить роль

Products

Метод URL Назначение
GET /api/admin/products/ список товаров
GET /api/admin/products/{id}/ карточка товара
POST /api/admin/products/ создание товара
PATCH /api/admin/products/{id}/ редактирование товара
DELETE /api/admin/products/{id}/ удаление товара
POST /api/admin/products/{id}/update_status/ смена статуса товара

Orders

Метод URL Назначение
GET /api/admin/orders/ список заказов
GET /api/admin/orders/{id}/ карточка заказа
POST /api/admin/orders/ создание заказа
PATCH /api/admin/orders/{id}/ редактирование заказа
DELETE /api/admin/orders/{id}/ удаление заказа
POST /api/admin/orders/{id}/update_status/ статус заказа
POST /api/admin/orders/{id}/update_payment_status/ статус оплаты

Reviews

Метод URL Назначение
GET /api/admin/reviews/ список отзывов
GET /api/admin/reviews/{id}/ карточка отзыва
POST /api/admin/reviews/ создание отзыва
PATCH /api/admin/reviews/{id}/ редактирование отзыва
DELETE /api/admin/reviews/{id}/ удаление отзыва

Seller status requests и notifications

Метод URL Назначение
GET /api/admin/seller-status-requests/ список заявок продавцов
GET /api/admin/seller-status-requests/{id}/ карточка заявки
POST /api/admin/seller-status-requests/{id}/approve/ одобрить заявку
POST /api/admin/seller-status-requests/{id}/reject/ отклонить заявку
GET /api/admin/notifications/ список уведомлений
GET /api/admin/notifications/{id}/ карточка уведомления
POST /api/admin/notifications/{id}/mark_read/ пометить прочитанным
POST /api/admin/notifications/mark_all_read/ прочитать все
GET /api/admin/notifications/unread_count/ количество непрочитанных

Admin chat endpoints

Метод URL Назначение
GET /api/admin/chat/conversations/ список диалогов
GET /api/admin/chat/conversations/{id}/ конкретный диалог
GET /api/admin/chat/messages/ список сообщений
POST /api/admin/chat/messages/ отправка сообщения

5.7 Chat API user-side (/api/chat)

Метод URL Назначение
GET /api/chat/conversations/my_conversation/ получить/создать свой диалог
GET /api/chat/conversations/{id}/ получить диалог
POST /api/chat/conversations/{id}/mark_as_read/ отметить диалог прочитанным
GET /api/chat/messages/ список сообщений
POST /api/chat/messages/ отправка сообщения
POST /api/chat/messages/{id}/mark_as_read/ отметить сообщение

6. Конфигурация и переменные окружения

6.1 Клиентские env

Переменная Обязательность Значение по умолчанию Назначение
VITE_API_BASE_URL опционально '' базовый URL API. В dev обычно пустой (через proxy), в выделенном стенде может быть домен gateway
VITE_LEGAL_* опционально см. frontend/.env.example версии документов и контакты для согласий (регистрация, оферта, продавец)
VITE_PRIVACY_POLICY_URL опционально внутренний /legal/privacy внешняя ссылка на политику, если нужна абсолютная URL

Если VITE_API_BASE_URL пуст, запросы идут относительными URL (/api/...) на тот же origin.

6.2 Dev proxy (vite.config.js)

В development запросы проксируются:

  • /api/auth -> http://localhost:8001/api
  • /api/users -> http://localhost:8002/api
  • /api/products -> http://localhost:8003/api
  • /api/orders -> http://localhost:8004/api
  • /api/reviews -> http://localhost:8005/api
  • /api/admin -> http://localhost:8006/api/admin
  • /api/chat -> http://localhost:8007/api
  • /api/analytics -> http://localhost:8008/api
  • /media/order_zips -> http://localhost:8004
  • /media -> http://localhost:8003

6.3 Production nginx proxy (frontend/nginx.conf)

nginx обслуживает:

  • SPA fallback (try_files ... /index.html) для клиентских роутов,
  • reverse-proxy к сервисам по /api/...,
  • media-проксирование и кэш (/media/, /media/order_zips/),
  • CORS-заголовки и обработку preflight OPTIONS,
  • health endpoint: /health.

Ограничения/таймауты:

  • /api/products/: client_max_body_size 150M, long timeouts;
  • /api/orders/: client_max_body_size 500M, long timeouts.

7. State management и кэширование

7.1 Zustand stores

authStore

  • ключ localStorage: auth-storage;
  • хранит: user, isAuthenticated, initialized;
  • методы: setUser, setInitialized, logout.

adminStore

  • ключ localStorage: admin-storage;
  • хранит: adminUser, isAdminAuthenticated, initialized;
  • методы: setAdminUser, setInitialized, logout.

7.2 React Query

  • предназначен для server-state;
  • retry-политика ограничена (retry: 1);
  • запрет автоматического refetch при фокусе окна (refetchOnWindowFocus: false).

Инвалидация кэша выполняется в страницах/хуках после мутаций (в зависимости от конкретного сценария).

8. Безопасность, auth и CSRF

8.1 Session/cookie модель

  • frontend работает с cookie-сессиями (withCredentials: true);
  • write-запросы (POST/PUT/PATCH/DELETE) автоматически получают заголовок X-CSRFToken.

8.2 Получение CSRF

Алгоритм:

  1. чтение csrftoken из cookie;
  2. если отсутствует — запрос в /api/auth/csrf/;
  3. fallback при ошибке — запрос в /api/products/models/;
  4. повторное чтение cookie и установка заголовка.

8.3 Обработка 401/403

  • на 401 (кроме служебных auth-check запросов) происходит редирект на /login;
  • на 403 с текстом про CSRF пишется диагностический лог в console;
  • для authAPI включён режим skip401Redirect, чтобы избежать циклических редиректов в bootstrap-проверке сессии.

9. Локализация

Текущая i18n-модель — словарная:

  • словарь: src/services/translations.js;
  • контекст: src/contexts/LanguageContext.jsx;
  • хук: src/hooks/useTranslation.js;
  • UI-переключатель: src/components/LanguageSwitcher.jsx.

Вспомогательные маппинги backend enum -> человекочитаемые строки:

  • src/utils/translationUtils.js.

10. Структура исходников frontend

Базовая структура:

frontend/
  src/
    components/        # общие компоненты UI/навигации
    contexts/          # LanguageContext
    hooks/             # useTranslation и др.
    pages/             # route-level страницы
    services/          # API-клиенты, словари переводов
    store/             # zustand stores
    utils/             # утилиты форматирования/маппинга
    App.jsx
    main.jsx
  public/
  docs/
  Dockerfile
  nginx.conf
  vite.config.js
  tailwind.config.js

11. Сценарии взаимодействия (sequence)

11.1 Инициализация сессии при старте

sequenceDiagram
  participant B as Browser
  participant FE as frontend/App.jsx
  participant A as auth_service
  B->>FE: app load
  FE->>FE: load auth/admin from localStorage
  FE->>A: GET /api/auth/profile/
  alt session valid
    A-->>FE: 200 user profile
    FE->>FE: setUser + (setAdminUser if staff)
  else session invalid
    A-->>FE: 401/403
    FE->>FE: clear auth stores
  end
  FE->>FE: initialized=true

11.2 Write-запрос с CSRF

sequenceDiagram
  participant UI as Page/Form
  participant API as axios interceptor
  participant S as backend service
  UI->>API: POST /api/... (mutating request)
  API->>API: read csrftoken from cookie
  alt token missing
    API->>S: GET /api/auth/csrf/
    S-->>API: set-cookie csrftoken=...
  end
  API->>S: POST with X-CSRFToken header
  S-->>UI: response / error

12. Эксплуатация и команды

12.1 Локальная разработка frontend

cd frontend
npm install
npm run dev

По умолчанию dev-сервер: http://localhost:3000.

12.2 Сборка frontend

cd frontend
npm install
npm run build

Артефакты: frontend/dist/.

12.3 Docker-образ frontend

Dockerfile двухэтапный:

  1. node:18-alpinenpm install + npm run build;
  2. nginx:alpine — отдача dist + прокси backend.

12.4 Сборка и проверка документации

Из корня репозитория:

pip install -r requirements-docs.txt
mkdocs serve

Публикуемая сборка:

mkdocs build --strict

Выходная директория: site/.

13. Ограничения и технический долг

Текущие известные ограничения:

  • нет выделенного 404-route для пользовательской и admin зон;
  • часть UI-паттернов (кнопки/инпуты/модалки) повторяется, отсутствует единый компонентный дизайн-слой;
  • i18n словари поддерживаются вручную, возможен дрейф ключей между RU/EN;
  • error handling не полностью унифицирован по всем страницам;
  • отсутствует централизованный форматтер дат/чисел, локальные преобразования могут отличаться.

14. Риски и контрольные меры

Риск Проявление Мера контроля
рассинхрон auth-store и cookie ложные состояния входа обязательный bootstrap GET /profile на старте
CSRF токен отсутствует 403 на мутациях interceptor с автоинициализацией CSRF
крупные payload/ZIP таймауты/обрывы увеличенные таймауты и client_max_body_size в nginx
дрейф API-контракта runtime ошибки UI синхронное обновление src/services/api.js и docs при изменениях backend
неполная локализация смешение RU/EN в интерфейсе регламент проверок ключей переводов перед релизом

15. Связанные документы

  • Архитектура фронтенда (локальная): frontend/docs/frontend-architecture.md
  • Гайд по стилизации фронтенда: frontend/docs/style-customization.md
  • Общая архитектура платформы: docs/architecture/system-overview.md
  • Контейнерная карта системы: docs/architecture/c4-and-containers.md

16. Дополнительная детализация внутренних функций (append-only)

16.1 Внутренние функции API-слоя (src/services/api.js)

getCsrfToken()

  • Назначение: прочитать актуальный csrftoken из document.cookie.
  • Вход:
  • cookie storage браузера.
  • Выход:
  • строка токена или null.
  • Side effects:
  • отсутствуют (чтение client-side состояния).

fetchCsrfToken()

  • Назначение: гарантировать наличие CSRF-cookie до mutating-запросов.
  • Вход:
  • не принимает обязательных пользовательских параметров.
  • Выход:
  • токен/null (в зависимости от результата).
  • Side effects:
  • сеть: вызов /api/auth/csrf/;
  • fallback сеть: вызов /api/products/models/ для получения cookie в reverse-proxy сценарии.
  • Edge-cases:
  • при ошибках может сработать degraded mode без токена, что затем приведет к 403 на write-операциях.

setupRequestInterceptors(apiInstance)

  • Назначение: добавить X-CSRFToken в POST/PUT/PATCH/DELETE.
  • Вход:
  • axios instance.
  • Выход:
  • зарегистрированный interceptor.
  • Side effects:
  • модификация заголовков исходящих запросов.

setupResponseInterceptors(apiInstance, skip401Redirect = false)

  • Назначение: унифицированная обработка 401/403 и fallback-диагностика.
  • Вход:
  • axios instance;
  • флаг отключения автоперехода на /login.
  • Выход:
  • зарегистрированный interceptor response/error.
  • Side effects:
  • redirect на /login (кроме исключенных сценариев);
  • попытка обновить CSRF-cookie из response headers.

16.2 Прикладные сервисные функции API-клиентов

Все функции authService, userService, productService, orderService, reviewService, adminService, chatService являются thin-wrapper над HTTP endpoint-ами и возвращают Promise axios-запроса.

Критичные прикладные функции с дополнительной логикой:

  • productService.createProduct(productData):
  • собирает multipart FormData (включая списки файлов и JSON-поля);
  • отправляет запрос создания модели в product_service.
  • chatService.sendMessage(payload) и adminService.sendChatMessage(payload):
  • передают сообщения в разные backend-контуры (user-chat и admin-chat);
  • ошибки обрабатываются на уровне страниц (toast + retry UX).
  • orderService.checkout(cartId, payload):
  • запускает checkout workflow, который может триггерить async выдачу ZIP на backend.

16.3 Функции bootstrap и route-guard логики (src/App.jsx)

initializeAuth() (внутренняя функция стартовой инициализации)

  • Назначение: синхронизировать local store с фактической backend-сессией.
  • Вход:
  • состояние authStore/adminStore;
  • результат authService.getProfile().
  • Выход:
  • согласованное состояние авторизации и роль пользователя.
  • Side effects:
  • записи в Zustand stores;
  • очистка stores при 401/403.

PrivateRoute и AdminRoute

  • Назначение: фильтрация доступа к защищенным роутам.
  • Вход:
  • флаги initialized, isAuthenticated, isAdminAuthenticated, role-поля пользователя.
  • Выход:
  • либо Outlet/экран, либо Navigate на страницу входа.

16.4 Контракты store-функций (src/store/*.js)

authStore: setUser, setInitialized, logout, loadStoredAuth

  • Вход:
  • user object или флаги инициализации.
  • Выход:
  • обновленное состояние auth-store.
  • Side effects:
  • чтение/запись/очистка localStorage ключа auth-storage.
  • Edge-cases:
  • при поврежденном JSON в storage срабатывает fallback с очисткой/сбросом.

adminStore: setAdminUser, setInitialized, logout, loadStoredAdmin

  • Аналогичный контракт для admin-состояния с ключом admin-storage.

16.5 Функции chat-страниц как прикладная логика UI

Chat page (src/pages/Chat.jsx)

  • Ключевые функции:
  • handleSubmit отправляет сообщение и очищает input;
  • query/mutation callbacks обновляют кэш и состояние диалога.
  • Вход:
  • пользовательский текст;
  • id conversation.
  • Выход:
  • обновленный список сообщений в UI.
  • Side effects:
  • запросы chatService;
  • invalidation react-query ключей;
  • toast-уведомления в случае ошибок.

AdminChat page (src/pages/AdminChat.jsx)

  • Ключевые функции:
  • выбор conversation;
  • отправка admin-сообщения;
  • перезапрос сообщений после мутации.
  • Side effects:
  • запросы через adminService chat endpoints;
  • визуальная сигнализация ошибок в админ-интерфейсе.

16.6 Функции локализации и маппинга статусов

t(key, lang, params) (src/services/translations.js)

  • Назначение: вернуть локализованную строку с подстановкой параметров.
  • Вход:
  • ключ перевода;
  • язык;
  • шаблонные параметры.
  • Выход:
  • локализованная строка либо fallback key.

localizeOrderStatus, localizePaymentStatus, localizeProductStatus, localizeRole (src/utils/translationUtils.js)

  • Назначение: преобразовать backend enum в UI-строки через функцию перевода.
  • Вход:
  • функция t;
  • enum-значение из backend payload.
  • Выход:
  • локализованная подпись статуса/роли.

16. Соответствие master-документации

Источник верхнего уровня: Master-документация проекта.

Контроль Требование Проверка Артефакт
UI-API consistency Клиентские фильтры и серверные параметры согласованы сценарии фильтрации и пагинации frontend audit + smoke
Security posture Клиент не подменяет серверные проверки ролей review protected routes и fallback QA checklist
Delivery discipline Изменение UI-контрактов сопровождается docs update ревью ссылок на сервисные контракты docs diff
Release confidence Критичный пользовательский путь проверен после релиза post-release smoke release report