Реализована интеграция с СМС провайдером

This commit is contained in:
mi
2026-07-23 11:49:15 +03:00
parent cc0163eb94
commit b1ed714d5b
89 changed files with 5934 additions and 202 deletions
@@ -21,8 +21,9 @@
- `/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`;
- exact `POST /callbacks/idgtl/sms``sms-service`; остальные методы и SMS paths не публикуются;
- web-сборка frontend или прокси на dev-сервер;
- `/internal/openlines/*`, `/internal/safety/*`, `/internal/sync/*` **не публикуются** наружу — доступны только из внутренней Docker-сети.
- `/internal/openlines/*`, `/internal/safety/*`, `/internal/sync/*`, `/internal/sms/*` **не публикуются** наружу — доступны только из внутренней Docker-сети.
- Никакой другой `nginx` (ни в контейнере сервиса, ни на хосте) не терминирует внешний HTTPS для backend-контура. Site-конфиг `tohin.ru` на хосте, если используется, должен проксировать весь трафик на корневой `nginx` контейнера, а не на порты отдельных сервисов напрямую.
### Структура compose через `include`
@@ -65,12 +66,14 @@ include:
- bitrix-sync/docker-compose.yml
- bitrix-local-app/docker-compose.yml
- keycloak/docker-compose.yml
- sms-service/docker-compose.yml
- redis/docker-compose.yml
- observability/docker-compose.yml
networks:
public:
backend:
egress:
observability:
volumes:
@@ -122,6 +125,7 @@ Reverse proxy и единственная публичная точка вход
- маршрутизирует `/auth/*` в `keycloak` или проксирует отдельный auth-домен;
- маршрутизирует публичные `/bitrix/*` endpoint в `bitrix-local-app`;
- маршрутизирует `/bitrix/sync/*` webhook endpoint в `bitrix-sync`;
- маршрутизирует только exact `POST /callbacks/idgtl/sms` в `sms-service:8080`; применяет HTTPS, подтверждённый allowlist source IP Direct, body/rate limits и redaction Basic Authorization;
- закрывает `/internal/*` (в т.ч. `bitrix-local-app`, `message-safety`, `bitrix-sync` ops) от публичного доступа — только private network Docker/VPC;
- **не публикует** `message-safety` наружу;
- **production-like / production**: отдаёт **статическую сборку Expo web** из volume или каталога (`/usr/share/nginx/html` или аналог); `index.html` + assets, SPA fallback `try_files $uri /index.html`;
@@ -217,7 +221,7 @@ Python worker/service **двусторонней** синхронизации Ap
Требования:
- подключение только из приватной сети VPC (VM → managed PostgreSQL);
- одна managed база: схемы `han_app`, `bitrix_sync`, `message_safety`, `bitrix_local`, `keycloak`;
- одна managed база: схемы `han_app`, `bitrix_sync`, `message_safety`, `bitrix_local`, `keycloak`, `sms`;
- отдельные DB-пользователи с доступом только к своей схеме; исключение: `bitrix_sync_user` дополнительно имеет ограниченный GRANT на `han_app` (`sync_queue`, `entity_external_mapping`, tracked columns профиля — детали схемы TBD в спецификации database);
- TLS к managed PostgreSQL обязателен;
- миграции Alembic выполняются отдельной командой при деплое;
@@ -236,10 +240,19 @@ Identity provider. **Обязателен** в compose-контуре с пер
- включены proxy settings для работы за `nginx`;
- импорт realm в local/dev;
- использует managed PostgreSQL, схема `keycloak` (см. раздел «Managed PostgreSQL» выше);
- OTP mock / SMS SPI — см. arch-04;
- OTP mock / SMS SPI — см. arch-04; real mode вызывает только `sms-service` по сети `backend`, сам Keycloak к Direct/`egress` не подключён;
- healthcheck;
- взаимодействия — [`arch-02-api-contracts.md`](arch-02-api-contracts.md), «Frontend ↔ Keycloak», и [`arch-01-system-architecture.md`](arch-01-system-architecture.md), «Keycloak».
### sms-service и sms-worker
- `sms-service`: networks `backend`, `observability` и `egress` только если тот же process принимает callback и выполняет worker; `expose: 8080`, без host `ports`.
- При отдельном `sms-worker`: networks только `egress`, `observability` и доступ к managed PG; HTTP port не exposed/published.
- Оба используют `SMS_DATABASE_URL` к schema `sms`; только worker получает `IDGTL_SMS_API_KEY`.
- Callback credentials получает receiver для проверки и worker для формирования callback URL; Keycloak получает только `KEYCLOAK_SMS_SERVICE_TOKEN`.
- `sms-service` применяет собственные versioned migrations/seed; DDL-on-start запрещён. Readiness проверяет DB/schema, active approved `auth_otp` template, sender и API-key configuration.
- Ожидание Direct до 70 секунд происходит только в worker. `uncertain` не retry-ится автоматически; provider outage не создаёт restart loop и не отменяет active Keycloak challenge.
### redis
Кэш, rate limiting, coordination (не единственное хранилище бизнес-событий).
@@ -269,6 +282,7 @@ Identity provider. **Обязателен** в compose-контуре с пер
- `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).
- `egress`: только сервисы с утверждёнными исходящими интеграциями; для SMS — `sms-worker`, но не Keycloak. Production real mode требует фактический статический egress IP/NAT, записанный в inventory и переданный Direct для allowlist.
- `observability`: `otel-collector` + сервисы, экспортирующие telemetry.
Базы данных, Redis, Keycloak internal port и API internal port не должны публиковаться наружу. `message-safety` доступен только внутри сети `backend`. Основной пользовательский путь должен идти через `nginx` и HTTPS.
@@ -406,6 +420,7 @@ WAF не заменяет обязательные лимиты, валидац
- `bitrix-sync`: `/health/live` проверяет процесс; `/health/ready` проверяет PostgreSQL, доступ к `sync_queue`, worker state и CRM webhook config; при `BITRIX_SYNC_ENABLED=false` ready возвращает degraded/not-ready с причиной `sync_disabled`;
- `bitrix-local-app`: `/health/live` проверяет процесс; `/health/ready` показывает PostgreSQL, OAuth-токены после установки приложения, connector activation и возможность forward в API при включённом `BITRIX_API_FORWARD_URL`;
- `keycloak`: health endpoint Keycloak; readiness — подключение к managed PostgreSQL;
- `sms-service`: live — процесс; ready — schema/migrations, active approved template, sender/API key; Direct доступность — отдельный dependency status, не причина restart loop;
- `redis`: `redis-cli ping`;
Наружу через `nginx` публикуются только health endpoint, которые нужны Bitrix24 install/callback validation или внешнему мониторингу. Internal services (`message-safety`, internal `bitrix-sync`, Redis, otel) проверяются только из Docker/VPC-сети.
@@ -413,13 +428,16 @@ WAF не заменяет обязательные лимиты, валидац
## Порядок запуска
1. `redis` (managed PostgreSQL должна быть доступна до старта зависимых сервисов).
2. `keycloak`.
3. `otel-collector`.
4. `message-safety`.
5. `api-backend`.
6. `bitrix-local-app`.
7. `bitrix-sync`.
8. `nginx`.
2. `otel-collector`.
3. `api-backend` и seed OTP settings.
4. `sms-service`/worker после migrations/seed (Keycloak пока mock).
5. `keycloak`.
6. `message-safety`.
7. `bitrix-local-app`.
8. `bitrix-sync`.
9. `nginx`.
Порядок rollout SMS подробнее задаёт module-11/module-10. Зависимости запуска не образуют цикл: Keycloak стартует при недоступном `sms-service`; это блокирует только новые real-mode orders, а verify уже active challenges продолжается по snapshot.
`depends_on` не заменяет проверку готовности. Сервисы должны уметь ждать зависимости или корректно завершаться с понятной ошибкой. `api-backend` должен ждать готовности `message-safety` (healthcheck), т.к. отправка сообщения синхронно зависит от `POST /internal/safety/v1/messages/check`.