275 lines
16 KiB
Markdown
275 lines
16 KiB
Markdown
# 7. Техническая архитектура, стек и состав компонентов
|
||
|
||
## 7.1 Общая архитектурная схема
|
||
|
||
Программный продукт реализуется по клиент-серверной модели и включает веб-клиент, сервер бизнес-логики, базу данных, модуль интеграции и вспомогательные сервисы уведомлений.
|
||
|
||

|
||
|
||
## 7.2 Состав прикладных сервисов
|
||
|
||
Согласно действующей карте деплоя в составе проекта используются следующие сервисы:
|
||
|
||
- `web-frontend` — клиентский и менеджерский веб-интерфейс
|
||
- `apollo-backend` — сервер GraphQL и бизнес-логика
|
||
- `vault` — централизованное хранилище секретов
|
||
- `tg-bot` — Telegram-контур
|
||
- `max-bot` — MAX-контур
|
||
- `bonus-bot` — бонусный мессенджерный контур
|
||
|
||
Основные прикладные сервисы `web-frontend` и `apollo-backend` разворачиваются через `dokploy_webhook` на сервере `main`.
|
||
|
||
## 7.3 Технологический стек фронтенда
|
||
|
||
Клиентская часть программного продукта реализуется на следующих технологиях:
|
||
|
||
- `Nuxt 4` — прикладной веб-фреймворк
|
||
- `Vue 3` — библиотека пользовательского интерфейса
|
||
- `@nuxtjs/apollo` и `@vue/apollo-composable` — работа с GraphQL
|
||
- `GraphQL Code Generator` — генерация типизированных GraphQL-документов
|
||
- `Tailwind CSS` и `daisyUI` — базовая стилизация интерфейсов
|
||
- `Storybook` — контур изоляционного просмотра компонентов
|
||
- `VitePress` — подготовка проектной документации
|
||
|
||
## 7.4 Технологический стек серверной части
|
||
|
||
Серверная часть программного продукта реализуется на следующих технологиях:
|
||
|
||
- `Node.js` — среда выполнения
|
||
- `Express 5` — HTTP-сервер
|
||
- `Apollo Server 5` — GraphQL-сервер
|
||
- `Prisma 7` — доступ к данным и ORM-слой
|
||
- `PostgreSQL` — основное хранилище данных
|
||
- `Zod` — валидация структур данных в прикладных сценариях
|
||
- `Nodemailer` — отправка уведомлений по электронной почте
|
||
|
||
## 7.5 Архитектура клиентской части
|
||
|
||
Клиентская часть организована по следующим слоям:
|
||
|
||
- страницы `app/pages` — входные экранные формы
|
||
- компоненты `app/components` — переиспользуемые элементы интерфейса
|
||
- composables `app/composables` — клиентская логика и представление данных
|
||
- GraphQL-документы `graphql/operations` — отдельные запросы и мутации
|
||
- сгенерированная типизированная схема `app/composables/graphql/generated.ts`
|
||
- серверные proxy и интеграционные обработчики `server/api`
|
||
|
||
Ключевые экранные маршруты текущей реализации:
|
||
|
||
- `/products` и `/products/[slug]` — каталог и карточка товара
|
||
- `/cart` — корзина
|
||
- `/client-orders` и `/client-orders/[id]` — клиентские заявки и заказы
|
||
- `/clients` и `/clients/[id]` — менеджерский контур клиентов
|
||
- `/orders` и `/orders/[id]` — менеджерский контур заказов
|
||
- `/catalog-settings` — административные настройки каталога
|
||
- `/bonus-program`, `/bonus-system/*` — бонусный контур
|
||
|
||
## 7.6 Карта слоев и компонентов
|
||
|
||

|
||
|
||
## 7.7 Архитектура серверной части
|
||
|
||
Серверная часть организована по следующим основным модулям:
|
||
|
||
- `src/server.js` — инициализация HTTP-сервера и GraphQL-сервера
|
||
- `src/schema.graphql` — контракт GraphQL API
|
||
- `src/resolvers.js` — реализация GraphQL-операций
|
||
- `src/context.js` — построение контекста запроса
|
||
- `src/auth.js` — аутентификация и токены доступа
|
||
- `src/access.js` — правила авторизации и проверки ролей
|
||
- `src/prisma-client.js` — точка подключения Prisma
|
||
- `src/messenger*.js`, `src/telegram*.js`, `src/max-mini-app.js` — мессенджерный контур и мини-приложения
|
||
|
||
## 7.8 Взаимодействие фронтенда и backend
|
||
|
||
Взаимодействие клиентской и серверной части строится через GraphQL API.
|
||
|
||
На стороне Nuxt используется серверный proxy-маршрут `/api/graphql`, который:
|
||
|
||
- принимает запросы браузера
|
||
- прокидывает cookie и авторизационные заголовки
|
||
- перенаправляет запрос в `apollo-backend`
|
||
- возвращает результат в клиентское приложение
|
||
|
||
Такой подход позволяет:
|
||
|
||
- изолировать прямой backend endpoint от браузерного клиента
|
||
- централизованно передавать авторизационные данные
|
||
- поддерживать единый клиентский GraphQL endpoint
|
||
|
||
## 7.9 Интеграционные и вспомогательные HTTP-точки
|
||
|
||
Помимо GraphQL API, во фронтенд-контуре реализованы вспомогательные серверные маршруты:
|
||
|
||
- `/api/graphql` — proxy в backend GraphQL API
|
||
- `/api/auth/messenger-start` — запуск сценариев messenger login / connect
|
||
- `/api/dadata/address` — подсказки адресов
|
||
- `/api/dadata/bank` — подсказки банковских реквизитов
|
||
- `/api/dadata/party` — подсказки контрагентов
|
||
- `/api/messenger-avatar/[connectionId]` — выдача изображений, связанных с мессенджерными подключениями
|
||
|
||
## 7.10 Компонентные требования к реализации
|
||
|
||
Архитектура программного продукта должна сохранять следующие правила:
|
||
|
||
- экранная логика должна находиться на уровне страниц и composables
|
||
- переиспользуемые элементы интерфейса должны быть вынесены в компоненты
|
||
- каждый GraphQL-документ должен храниться в отдельном `.graphql` файле
|
||
- клиентский код должен использовать сгенерированные типизированные документы
|
||
- серверная логика доступа к данным должна проходить через Prisma
|
||
- бизнес-правила доступа должны контролироваться серверной частью, а не только интерфейсом
|
||
|
||
## 7.11 Требования к конфигурации и секретам
|
||
|
||
Сервисы программного продукта должны получать прикладные секреты из `Vault`.
|
||
|
||
В конфигурации сервисов допускается хранение только bootstrap-параметров для подключения к Vault. Бизнес-секреты, ключи интеграций и иные чувствительные данные должны загружаться из Vault при старте приложения.
|
||
|
||
## 7.12 Инфраструктура, деплой и эксплуатационный контур
|
||
|
||
Текущая инфраструктурная схема проекта включает прикладные сервисы, сервис секретов, мессенджерные сервисы и вспомогательный worker-контур.
|
||
|
||

|
||
|
||
Сервисы проекта и способ их развёртывания:
|
||
|
||
| Сервис | Путь в репозитории | Роль | Deploy mode | Сервер |
|
||
| --- | --- | --- | --- | --- |
|
||
| web-frontend | `web-frontend` | клиентский и менеджерский веб-интерфейс | `dokploy_webhook` | `main` |
|
||
| apollo-backend | `apollo-backend` | GraphQL API и бизнес-логика | `dokploy_webhook` | `main` |
|
||
| hatchet-worker | `hatchet-worker` | фоновый worker-контур | `dokploy_webhook` | `main` |
|
||
| tg-bot | `tg-bot` | Telegram-контур | `dokploy_webhook` | `main` |
|
||
| max-bot | `max-bot` | MAX-контур | `dokploy_webhook` | `main` |
|
||
| bonus-bot | `bonus-bot` | бонусный сервис | `dokploy_webhook` | `main` |
|
||
| vault | `vault` | сервис секретов | `dokploy_webhook` | `main` |
|
||
|
||
Серверная карта текущего проекта:
|
||
|
||
- сервер `main`
|
||
- Tailscale user: `root`
|
||
- Tailscale host: `dsrptlab`
|
||
|
||
Эксплуатационные операции доступа и диагностики выполняются через Tailscale SSH.
|
||
|
||
## 7.13 Dokploy и цепочка развёртывания
|
||
|
||
Для основных сервисов проекта используется режим `dokploy_webhook`.
|
||
|
||
Это означает следующую последовательность:
|
||
|
||
1. изменения фиксируются в Git-репозитории;
|
||
2. изменения публикуются в `main`;
|
||
3. Dokploy получает webhook-событие;
|
||
4. Dokploy выполняет сборку соответствующего сервиса;
|
||
5. сервис перезапускается с загрузкой секретов из Vault;
|
||
6. после старта выполняются bootstrap-действия, предусмотренные образом и entrypoint-командой.
|
||
|
||
Текущие особенности прикладных сервисов:
|
||
|
||
- `web-frontend` стартует через загрузку Vault env и запуск `.output/server/index.mjs`
|
||
- `apollo-backend` стартует через загрузку Vault env, `prisma migrate deploy` и запуск `src/server.js`
|
||
- bot-сервисы стартуют через общий паттерн загрузки Vault env и запуск `node src/server.js`
|
||
|
||
## 7.14 Vault и хранение секретов
|
||
|
||
Сервис `vault` развернут как отдельное приложение на базе образа `hashicorp/vault:1.21.3`.
|
||
|
||
Текущие инфраструктурные правила работы Vault:
|
||
|
||
- используется `raft` storage
|
||
- данные Vault сохраняются в `/vault/data`
|
||
- конфигурация сервиса хранится в `vault/config/vault.hcl`
|
||
- при старте выполняется проверка и, при необходимости, автоматический unseal из переменных окружения
|
||
- прикладные сервисы подключаются к Vault через bootstrap-переменные `VAULT_ADDR`, `VAULT_TOKEN`, `VAULT_KV_MOUNT`, `VAULT_SHARED_PATH`, `VAULT_PROJECT_PATH`, `VAULT_ENABLED`
|
||
|
||
Прикладные сервисы используют общий shell-bootstrap `load-vault-env.sh`, который:
|
||
|
||
- ожидает доступность Vault по health endpoint
|
||
- загружает shared secrets
|
||
- загружает project secrets
|
||
- экспортирует секреты в runtime environment процесса
|
||
|
||
## 7.15 Структура сервисных каталогов
|
||
|
||
Текущая сервисная структура репозитория:
|
||
|
||
- `web-frontend` — Nuxt-приложение, GraphQL operations, VitePress-документация
|
||
- `apollo-backend` — Apollo Server, Prisma schema, миграции, импорт каталога
|
||
- `tg-bot` — Telegram-сервис
|
||
- `max-bot` — MAX-сервис
|
||
- `bonus-bot` — бонусный сервис
|
||
- `hatchet-worker` — worker-контур
|
||
- `vault` — Dockerfile, конфигурация и entrypoint Vault
|
||
- `hatchet` — docker-compose инфраструктурного контура Hatchet
|
||
|
||
## 7.16 Контур фоновых процессов
|
||
|
||
В проекте присутствует отдельный контур фонового исполнения задач:
|
||
|
||
- `hatchet-worker` как прикладной worker
|
||
- `hatchet-engine` как движок исполнения
|
||
- `hatchet-dashboard` как интерфейс мониторинга
|
||
- отдельный `postgres` для Hatchet-контура
|
||
|
||
Конфигурация этого контура находится в `hatchet/docker-compose.yml`.
|
||
|
||
## 7.17 Зафиксированные runtime-версии и технологические зависимости
|
||
|
||
### Базовые runtime и контейнерные образы
|
||
|
||
| Компонент | Текущая версия |
|
||
| --- | --- |
|
||
| Node base image для web/backend/bots | `node:22-bookworm-slim` |
|
||
| Vault image | `hashicorp/vault:1.21.3` |
|
||
| Hatchet Postgres | `postgres:15.6` |
|
||
| Nuxt | `4.4.2` |
|
||
| Vue | `3.5.30` |
|
||
| Apollo Server | `5.5.0` |
|
||
| Prisma / Prisma Client | `7.6.0` |
|
||
| Mermaid | `11.14.0` |
|
||
| VitePress | `1.6.4` |
|
||
|
||
### Основные зависимости фронтенда
|
||
|
||
| Библиотека | Версия | Назначение |
|
||
| --- | --- | --- |
|
||
| `@nuxtjs/apollo` | `5.0.0-alpha.16` | GraphQL-клиентский слой |
|
||
| `@vue/apollo-composable` | `4.2.2` | composable API для GraphQL |
|
||
| `@apollo/client` | `3.14.1` | Apollo client runtime |
|
||
| `@nuxt/eslint` | `1.15.2` | linting Nuxt-проекта |
|
||
| `@nuxtjs/tailwindcss` | `6.14.0` | Tailwind integration |
|
||
| `daisyui` | `5.5.19` | UI primitives |
|
||
| `graphql` | `16.13.2` | GraphQL runtime |
|
||
| `@sentry/vue` | `10.46.0` | error tracking |
|
||
| `storybook` | `8.6.14` | UI component review |
|
||
|
||
### Основные зависимости backend
|
||
|
||
| Библиотека | Версия | Назначение |
|
||
| --- | --- | --- |
|
||
| `@apollo/server` | `5.5.0` | GraphQL server |
|
||
| `@as-integrations/express5` | `1.1.2` | Apollo + Express integration |
|
||
| `express` | `5.2.1` | HTTP server |
|
||
| `@prisma/client` | `7.6.0` | data access |
|
||
| `@prisma/adapter-pg` | `7.6.0` | Prisma adapter |
|
||
| `pg` | `8.20.0` | PostgreSQL driver |
|
||
| `graphql` | `16.13.2` | GraphQL runtime |
|
||
| `zod` | `4.3.6` | validation |
|
||
| `nodemailer` | `8.0.4` | email notifications |
|
||
| `dotenv` | `17.3.1` | env bootstrap in local/runtime layers |
|
||
|
||
## 7.18 Технические конфигурационные файлы
|
||
|
||
Ключевые технические файлы текущей реализации:
|
||
|
||
- `deploy-map.toml` — карта сервисов, deploy mode и серверов
|
||
- `web-frontend/nuxt.config.ts` — конфигурация Nuxt и Apollo
|
||
- `web-frontend/codegen.ts` — конфигурация GraphQL codegen
|
||
- `apollo-backend/prisma.config.ts` — конфигурация Prisma
|
||
- `apollo-backend/prisma/schema.prisma` — модель данных
|
||
- `web-frontend/scripts/load-vault-env.sh` — Vault bootstrap frontend
|
||
- `apollo-backend/scripts/load-vault-env.sh` — Vault bootstrap backend
|
||
- `vault/config/vault.hcl` — конфигурация Vault
|
||
- `vault/entrypoint.sh` — startup/unseal логика Vault
|