# Архитектура фронтенда ## Модули - `src/context/AuthContext.jsx` — OTP-аутентификация через Supabase Auth и загрузка профиля пользователя с ролью. Неизвестный email показывает подсказку обратиться к администратору. - `src/context/ThemeContext.jsx` — управление светлой и тёмной темой через `data-theme`. - `src/hooks/usePwaStatus.js` — клиентское состояние PWA: online/offline, install prompt, standalone и offline readiness. - `src/hooks/useOrders.js` — локальный state заказов, истории, чатов, фильтров, действий и **сгруппированных наборов доставки** (deliverySetBuckets). - `src/hooks/useOrderGroups.js` — работа с группами заказов: загрузка, обновление статусов, ручное согласование доставки и самовывоза. Метод `saveManualDeliveryChoice` принимает `deliveryType`, `pickupDate`, `pickupTimeSlot`. - `src/services/deliverySetViews.js` — чистые функции группировки импортированных заказов в наборы доставки с buckets: «На подходе», «Готово к запуску», «Ожидает клиента», «Нужна ручная работа», «Согласовано», «Завершено». - `src/services/orderService.js` — чистые функции бизнес-логики заказов, покрытые тестами. - `src/services/supabase/orderRepository.js` — адаптер реальных чтений/записей заказов и чатов в Supabase, включая source-поля 1С и delivery-set поля. - `src/services/supabase/orderGroupRepository.js` — репозиторий групп заказов. Маппинг полей включает `deliveryType`, `pickupDate`, `pickupTimeSlot`. Метод `updateOrderGroupDeliveryChoice` поддерживает как доставку, так и самовывоз. - `src/services/deliveryWorkflow.js` — карта статусов доставки и переходов. Включает статус `pickup` (Самовывоз) с переходами в/из других статусов. - `src/services/orderGroupViews.js` — метки и цвета для статусов, включая `pickup: "Самовывоз"`. - `src/services/deliveryInvitationApi.js` — API для приглашений доставки. `confirmDeliveryChoice` принимает `deliveryType`, `pickupDate`, `pickupTimeSlot`. - `src/services/driverDeliveries.js` — фильтрация и группировка доставок для рабочей области водителя. - `src/layouts/AppShell.jsx` — общий shell с боковой навигацией, уведомлениями и переключением темы. - `src/components/logistics/LogisticsReadinessBoard.jsx` — интерактивная доска с bucket-ами наборов доставки. - `src/components/logistics/DeliverySetDetailPanel.jsx` — детальная карточка набора доставки: source-поля 1С, production-шаги, слоты, действия. - `src/components/client/DeliverySlotsPicker.jsx` — публичный виджет выбора даты и половины дня доставки. - `src/components/client/PickupSlotsPicker.jsx` — публичный виджет выбора даты и половины дня самовывоза. Отображает доступные даты (сегодня до 12:00, завтра, послезавтра, без выходных), слоты «До обеда»/«После обеда», и информационный блок о стоимости хранения: «Бесплатное хранение — 2 рабочих дня. С 3-го рабочего дня — 300₽/день.». - `src/components/client/DeliveryChoiceFlow.jsx` — публичный поток согласования доставки или самовывоза по приглашению. Принимает `deliveryType` и показывает динамические лейблы. - `src/components/client/DeliveryStateNotice.jsx` — информационный экран для clients со статусом ссылки. - `src/pages/ClientDeliveryPage.jsx` — публичная страница согласования доставки с вкладками 🚚 Доставка / 🏪 Самовывоз. Переключение типа получения, отображение соответствующего пикера слотов. - `src/components/orders/*` — фильтры, список заказов, карточка заказа, история статусов и поиск по чату. - `src/components/orders/OrderDetailPanel.jsx` — карточка заказа с управлением доставкой и самовывозом. Вкладки Доставка/Самовывоз, поля даты самовывоза и половины дня, кнопка статуса «Самовывоз». - `src/components/orders/OrderEditorPanel.jsx` — создание и редактирование заказа менеджером или администратором. - `src/components/dashboard/ProductionQueuePanel.jsx` — отдельный блок производственной очереди. - `src/components/dashboard/RoleWorkspacePanel.jsx` — рабочая панель с delivery-set bucket-ами для логиста. - `src/components/admin/UserDirectoryPanel.jsx` — панель пользователей, ролей и последних входов. - `src/components/logistics/BotControlPanel.jsx` — сценарии отправки в чатбот и переноса слотов доставки. - `src/components/admin/AuditPanel.jsx` — журнал ошибок, исключений и обзор последних системных событий. ## Ролевой доступ - 1С остаётся источником создания и прогресса заказов. Веб-приложение не создаёт заказы. - Начальник производства переводит заказ через очередь и производство к готовности. - **Логист** видит наборы доставки, слоты, сообщения чатбота и ручную обработку исключений. - **Водитель** видит только назначенные доставки и может переводить их через статусы `Загружен`, `В пути`, `Доставлен`, `Проблема доставки`. - **Администратор** видит весь массив заказов, доставок и системные логи. - **Менеджер** может назначить тип доставки (доставка/самовывоз), дату и половину дня. - Клиент не является авторизованным пользователем приложения. Клиент использует публичную ссылку приглашения. ## Ключевые экраны - `/login` — email + OTP flow. При отсутствии `VITE_SUPABASE_*` включается demo-режим. Подсказка проверять входящие и спам. Неизвестный email: «Email не найден в системе. Обратитесь к администратору.» - `/dashboard` — role-based control center: для логиста — LogisticsReadinessBoard с наборами доставки, для водителя — план маршрута и быстрые действия. - `/delivery/:token` — публичная страница согласования доставки для клиента с вкладками Доставка/Самовывоз. - `public/manifest.webmanifest` + `public/service-worker.js` — installable PWA-оболочка и базовое кеширование shell для demo offline. ## Тип получения: Доставка и Самовывоз ### Переключатель типа На клиентской странице (`ClientDeliveryPage`) и в карточке заказа (`OrderDetailPanel`) реализованы вкладки: - **🚚 Доставка** — стандартный флоу с выбором даты и половины дня. - **🏪 Самовывоз** — выбор даты самовывоза (сегодня/завтра/послезавтра, без выходных) и половины дня. ### Статус «Самовывоз» В `deliveryWorkflow.js` добавлен статус `pickup` с переходами: - `pending_confirmation` → `pickup` - `manual_confirmation_required` → `pickup` - `pickup` → `assigned_to_driver`, `delivered`, `cancelled` ### База данных Колонки в `order_groups`: - `delivery_type text DEFAULT 'delivery'` — тип получения - `pickup_date date` — дата самовывоза - `pickup_time_slot text` — «До обеда» / «После обеда» RPC `confirm_delivery_choice_by_token` обновлён: при `delivery_type = 'pickup'` устанавливает `delivery_status = 'pickup'`, `pickup_date` и `pickup_time_slot`. Edge function `confirm-delivery-choice` передаёт `p_delivery_type`, `p_pickup_date`, `p_pickup_time_slot` в RPC. ## Источник заказов: 1С → Supabase - Заказы импортируются из 1С через XML и сохраняются в `public.orders` с source-полями: `source_order_number`, `source_customer_name`, `source_accept_at`, `source_ship_at` и т.д. - Заказы группируются в **наборы доставки** (delivery sets) по `delivery_set_key` из n8n или по нормализованному телефону+имя клиента. - Набор доставки считается готовым к запуску, когда все его заказы имеют `source_accept_at` и ни один не имеет `source_ship_at`. - Поле `source_sms_legacy_at` сохраняется как историческое и **не должно** запускать новый сценарий доставки. ## Дизайн-концепт - Минималистичная сетка с крупными панелями, прозрачными поверхностями и мягкими границами. - Светлая тема использует холодно-зелёный акцент на светлом фоне. - Тёмная тема построена на глубоких графитовых поверхностях с ярким мятным accent. - Мобильная версия складывает layout в вертикальный поток; боковая панель становится верхним блоком. ## Интеграционный слой - `src/supabaseClient.js` создаёт клиент Supabase через env-переменные. - `src/services/safeSupabaseCall.js` стандартизирует обработку ошибок. - Данные UI разложены по сущностям, совпадающим с таблицами Supabase: `orders`, `order_history`, `chat_messages`, `delivery_slots`, `delivery_invitations`. - В `orders` синхронизированы поля `status`, `delivery_agreement_status`, `assigned_driver_id`, а также source-поля 1С и delivery-set данные. ## Деплой - Docker-сборка через `docker-compose.app.yml` (multi-stage: Node.js build → Caddy serve). - Автодеплой: Gitea webhook → systemd `supersam-webhook` → `deploy.sh` (git pull + docker build). - Домен: `https://dost.supersamsev.ru/`