frontend (web client)¶
1. Назначение и границы¶
frontend — это SPA-клиент платформы Konstructorium на React/Vite, который обслуживает три роли:
- покупатель (каталог, карточка модели, корзина, заказы, профиль, чат),
- продавец (публикация моделей, управление своими моделями, заказы продавца, отзывы),
- администратор (dashboard, пользователи, товары, заказы, отзывы, уведомления, чат).
Границы ответственности фронтенда:
- рендеринг UI и клиентских маршрутов;
- хранение минимального клиентского auth-state;
- вызов backend API по согласованным HTTP-контрактам;
- обработка пользовательских сценариев и ошибок уровня UI.
Фронтенд не содержит доменную бизнес-логику сервисов (правила ролей, финальные валидации, вычисление статусов заказа) — она остаётся на стороне backend.
2. Технологический стек и зависимости¶
2.1 Runtime и сборка¶
react18.2.0react-dom18.2.0vite5.0.8@vitejs/plugin-react4.2.1
2.2 Маршрутизация, данные, состояние¶
react-router-dom6.20.0react-query3.39.3axios1.6.2zustand4.4.7
2.3 Формы, уведомления, UI¶
react-hook-form7.48.2react-toastify9.1.3tailwindcss3.3.6postcss8.4.32autoprefixer10.4.16
2.4 3D-библиотеки¶
three0.160.0@react-three/fiber8.15.0@react-three/drei9.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-querycache/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¶
Порядок:
- из
localStorageвосстанавливается пользователь (auth-storage,admin-storage); - на mount отправляется
GET /api/auth/profile/(через proxy); - при валидной сессии сторы синхронизируются фактическим профилем;
- при
401/403сторы очищаются; - выставляются флаги
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¶
Алгоритм:
- чтение
csrftokenиз cookie; - если отсутствует — запрос в
/api/auth/csrf/; - fallback при ошибке — запрос в
/api/products/models/; - повторное чтение 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 двухэтапный:
node:18-alpine—npm install+npm run build;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:
- запросы через
adminServicechat 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 |