Grok version

This commit is contained in:
mi
2026-07-09 12:39:52 +03:00
parent ea8bb6181a
commit 8835677860
7 changed files with 353 additions and 155 deletions
@@ -17,7 +17,7 @@
- Весь backend-контур поднимается **одной командой** `docker compose up -d` из корня репозитория (`backend/`).
- Корневой `docker-compose.yml` — единственный источник правды для production-like среды. Отдельных compose-файлов для production-деплоя отдельных сервисов не должно быть.
- **Один `nginx`** поднимается из корневого `docker-compose.yml` и является единой публичной точкой входа с маршрутизацией на все сервисы:
- `/api/*`, `/realtime/*``api-backend`;
- `/api/*` `api-backend` (REST и `WS /api/v1/realtime`; отдельный path `/realtime/*` **не** используется);
- `/auth/*``keycloak`;
- `/bitrix/*` (public: `/bitrix/handler`, `/bitrix/install`, `/bitrix/placement`, `/health/*` для `bitrix-local-app`) → `bitrix-local-app`;
- `/bitrix/sync/*` (public: webhook CRM sync для `bitrix-sync`) → `bitrix-sync`;
@@ -118,7 +118,7 @@ Reverse proxy и единственная публичная точка вход
- **единый домен MVP** (напр. `tohin.ru` с путями `/api/*`, `/auth/*`, web): считается веб-доменом; порт `80` — только redirect на HTTPS для всего server block; после редиректа весь пользовательский трафик — HTTPS;
- **auth** на том же host, что API (`/auth/*`): следует политике host (redirect-only на :80 или HTTPS-only для выделенного API-host);
- **Bitrix callbacks** (`/bitrix/*`, `/bitrix/sync/*`): только HTTPS; порт `80` не обслуживает эти location — только redirect;
- маршрутизирует `/api/*` и `/realtime/*` в `api-backend`;
- маршрутизирует `/api/*` в `api-backend` (включая WebSocket upgrade для `/api/v1/realtime`);
- маршрутизирует `/auth/*` в `keycloak` или проксирует отдельный auth-домен;
- маршрутизирует публичные `/bitrix/*` endpoint в `bitrix-local-app`;
- маршрутизирует `/bitrix/sync/*` webhook endpoint в `bitrix-sync`;
@@ -127,6 +127,7 @@ Reverse proxy и единственная публичная точка вход
- **production-like / production**: отдаёт **статическую сборку Expo web** из volume или каталога (`/usr/share/nginx/html` или аналог); `index.html` + assets, SPA fallback `try_files $uri /index.html`;
- **local dev** (опционально): при `FRONTEND_DEV_PROXY_ENABLED=true` проксирует `/` на Expo dev server (`EXPO_DEV_SERVER_URL`, напр. `http://host.docker.internal:8081`);
- передает upstream-сервисам `Host`, `X-Real-IP`, `X-Forwarded-For`, `X-Forwarded-Proto`, `X-Forwarded-Host`, `X-Request-ID`;
- если входящий запрос **без** `X-Request-ID`, nginx **генерирует** UUID и устанавливает заголовок до proxy_pass (I3);
- задает разумные `proxy_connect_timeout`, `proxy_read_timeout`, `client_max_body_size`;
- применяет edge rate limits для auth, API и download endpoints;
- ограничивает частоту соединений и размер тела запроса;
@@ -188,8 +189,8 @@ Python worker/service **двусторонней** синхронизации Ap
- поддерживает graceful shutdown и rate limiting Bitrix REST;
- не блокирует пользовательский API при ошибках Битрикс24;
- не участвует в OTP-flow, не создаёт `UserIdentity`/`ClientProfile`;
- **не участвует** в hot path чата Open Lines.
- `bitrix-sync` должен быть подключаем через .env (если отключили, то синхронизация с битрикс24 не проводится; если не отключили - проводится)
- **не участвует** в hot path чата Open Lines;
- включается/отключается флагом **`BITRIX_SYNC_ENABLED`** в `.env` (default `true`): при `false` сервис не стартует или работает в no-op (синхронизация с Bitrix24 CRM не выполняется).
### bitrix-local-app
@@ -223,29 +224,33 @@ Python worker/service **двусторонней** синхронизации Ap
### keycloak
Identity provider.
Identity provider. **Обязателен** в compose-контуре с первого запуска.
Требования:
- отдельный realm для приложения;
- отдельный frontend client с PKCE;
- backend client для service-to-service сценариев;
- отдельный frontend client с PKCE (обязателен);
- confidential backend client **optional** (не используется в hot path MVP; S2S между сервисами — service tokens);
- публичный issuer должен соответствовать HTTPS URL, видимому frontend-приложению;
- включены proxy settings для работы за `nginx`;
- импорт realm в local/dev;
- использует managed PostgreSQL, схема `keycloak` (см. раздел «Managed PostgreSQL» выше);
- healthcheck.
- OTP mock / SMS SPI — см. arch-04;
- healthcheck;
- взаимодействия — [`arch-02-api-contracts.md`](arch-02-api-contracts.md), «Frontend ↔ Keycloak», и [`arch-01-system-architecture.md`](arch-01-system-architecture.md), «Keycloak».
### redis
Очереди, кеш, rate limiting.
Кэш, rate limiting, coordination (не единственное хранилище бизнес-событий).
Требования:
- не использовать как единственное надежное хранилище бизнес-событий;
- хранить счетчики API-level rate limits;
- поддерживать TTL для лимитных ключей;
- sync_queue хранится в PostgreSQL (`han_app`), Redis может использоваться для wake-up/locking/queue optimization.
- хранить счетчики API-level rate limits и idempotency keys (`api-backend`);
- поддерживать TTL для лимитных и idempotency ключей;
- **не** хранить OTP counters для `api-backend` (OTP — зона Keycloak/SPI);
- sync_queue хранится в PostgreSQL (`han_app`), Redis может использоваться для wake-up/locking/queue optimization;
- разделение DB index (I4): см. arch-04 (`REDIS_URL`, `MESSAGE_SAFETY_REDIS_URL`).
### otel-collector
@@ -261,9 +266,9 @@ Identity provider.
Рекомендуемые сети:
- `public`: `nginx`, frontend dev access, внешний HTTPS entrypoint.
- `backend`: API, `message-safety`, `bitrix-sync`, `bitrix-local-app`, `redis` (managed PostgreSQL — вне compose, в VPC).
- `observability`: otel-collector.
- `public`: `nginx`, `keycloak` (для прокси `/auth/*`), frontend static/dev access, внешний HTTPS entrypoint.
- `backend`: `api-backend`, `message-safety`, `bitrix-sync`, `bitrix-local-app`, `keycloak`, `redis` (managed PostgreSQL — вне compose, в VPC).
- `observability`: `otel-collector` + сервисы, экспортирующие telemetry.
Базы данных, Redis, Keycloak internal port и API internal port не должны публиковаться наружу. `message-safety` доступен только внутри сети `backend`. Основной пользовательский путь должен идти через `nginx` и HTTPS.
@@ -320,8 +325,9 @@ Identity provider.
Рекомендуемая схема:
- **веб-домен** (MVP: `tohin.ru` или `app.example.ru`): `/api/*`, `/auth/*`, `/realtime/*`, web frontend; `:80` → redirect HTTPS; `:443` — TLS + маршрутизация;
- **выделенный API-домен** (post-MVP, опционально): отдельный `server { listen 443 ssl; ... }` **без** `listen 80`; только `/api/*`, `/realtime/*`;
- **веб-домен** (MVP: `tohin.ru` или `app.example.ru`): `/api/*` (REST + WS realtime), `/auth/*`, web frontend; `:80` → redirect HTTPS; `:443` — TLS + маршрутизация;
- **выделенный API-домен** (post-MVP, опционально): отдельный `server { listen 443 ssl; ... }` **без** `listen 80`; только `/api/*`;
- для `location` WebSocket (`/api/v1/realtime`): `proxy_http_version 1.1`, `Upgrade`/`Connection` headers, увеличенный `proxy_read_timeout`;
- домен или path `/bitrix/*``bitrix-local-app`; `/bitrix/sync/*``bitrix-sync`;
- `GET/POST /bitrix/handler` и `GET/POST /bitrix/install` доступны публично для Bitrix24;
- `/bitrix/placement` доступен публично как заглушка UI настроек коннектора;
@@ -396,7 +402,7 @@ WAF не заменяет обязательные лимиты, валидац
- `nginx`: на веб-домене — `301` с `:80` на HTTPS; на API-домене (если выделен) — `:80` не слушает; `:443` — HTTP 200/301 и успешная TLS handshake;
- `api-backend`: HTTP 200 от `/health/ready`;
- `message-safety`: HTTP 200 от `/health/ready` (проверяет PostgreSQL, Redis, workers, read S3-quarantine);
- `bitrix-sync`: процесс жив, подключение к App DB доступно;
- `bitrix-sync`: HTTP 200 от `/health/live` и `/health/ready` (ready — PostgreSQL + доступ к `sync_queue`);
- `bitrix-local-app`: HTTP 200 от `/health/live`, readiness показывает наличие OAuth-токенов после установки приложения;
- `keycloak`: health endpoint Keycloak; readiness — подключение к managed PostgreSQL;
- `redis`: `redis-cli ping`;