Initial import with GitLab CI/CD and registry deploy flow

This commit is contained in:
Yera All
2026-04-02 17:05:45 +05:00
commit 5374c202d9
338 changed files with 81297 additions and 0 deletions
+275
View File
@@ -0,0 +1,275 @@
# PostgreSQL Dev Cutover
Этот runbook описывает безопасный перевод `dev`-окружения с SQLite на PostgreSQL без переноса старых данных.
## Что считается "без простоя"
В этом проекте без переноса SQLite-данных безостановочный cutover означает не hot-swap одной и той же базы, а:
1. поднять новый PostgreSQL-backed stack параллельно;
2. прогнать smoke на новом stack;
3. переключить dev-трафик на новый gateway;
4. оставить старый SQLite stack живым до подтверждения GO;
5. при проблеме вернуть трафик обратно без восстановления данных.
Если сейчас у dev только один instance и нет возможности держать parallel stack, нужен короткий maintenance window.
## Scope
Включает:
- подготовку PostgreSQL и RabbitMQ;
- применение SQL migrations;
- запуск сервисов в `SCHEMA_MANAGEMENT_MODE=migrations`;
- smoke-проверки до и после переключения;
- rollback на старый SQLite-backed dev stack.
Не включает:
- перенос данных из SQLite;
- cleanup legacy SQLite-path;
- production cutover.
## Required Inputs
- `DEV_GATEWAY_OLD`
- `DEV_GATEWAY_NEW`
- `POSTGRES_DATABASE_URL`
- `APP_TOKEN_SECRET`
- `PUBLIC_SWITCH_METHOD`
- DNS
- reverse proxy
- load balancer route
- `RABBITMQ_URL`
Рекомендуемые значения для локально-управляемого dev:
- `POSTGRES_DATABASE_URL=postgresql://mvp:mvp@<postgres-host>:5432/mvpcc`
- `SCHEMA_MANAGEMENT_MODE=migrations`
- env template: [\.env.postgres.local.template](/e:/Zhan/.env.postgres.local.template)
## Phase 0 - Preconditions
Подтвердить перед началом:
1. Текущий SQLite-backed dev stack стабилен.
2. Перенос данных не нужен.
3. PostgreSQL доступен по сети с host, где запускаются сервисы.
4. RabbitMQ доступен по сети, если в dev нужен `EVENT_BUS_ENABLED=1`.
5. Новая dev-конфигурация использует:
- `DATABASE_URL=postgresql://...`
- `SCHEMA_MANAGEMENT_MODE=migrations`
6. Старый SQLite stack не останавливается до завершения smoke на новом stack.
## Phase 1 - Preflight
На будущем PostgreSQL-backed dev host:
1. Проверить Python зависимости:
```powershell
python -m pip install -r requirements.txt
```
2. Подготовить env-файл:
- скопировать [\.env.postgres.local.template](/e:/Zhan/.env.postgres.local.template)
- заполнить `DATABASE_URL`, `APP_TOKEN_SECRET`, интеграционные URL и при необходимости AI/Telegram/WhatsApp переменные
3. Запустить DB-only preflight:
```powershell
python scripts\postgres_dev_preflight.py --env-file .env.postgres.local.template
```
4. Убедиться, что mode не legacy:
```text
SCHEMA_MANAGEMENT_MODE=migrations
```
5. Применить миграции в PostgreSQL:
```powershell
python scripts\migrate_core_db.py
```
Ожидается:
- миграции применились без ошибок;
- в PostgreSQL появилась таблица `schema_migrations`;
- сервисы ещё не стартовали.
## Phase 2 - Bring Up Parallel Stack
Поднять новый stack параллельно старому.
Если запуск локальный:
```powershell
python scripts\local_stack.py start `
--runtime-dir .local_stack_pg `
--env-file .env.postgres.local.template `
--force-restart
```
Если это dev server / VM:
1. развернуть те же сервисы в отдельный deployment set;
2. прокинуть им:
- `DATABASE_URL=postgresql://...`
- `SCHEMA_MANAGEMENT_MODE=migrations`
3. не направлять внешний dev-трафик на новый gateway до завершения smoke.
Важно:
- новый stack должен использовать отдельный runtime/log directory;
- старый SQLite-backed stack остаётся доступным;
- нельзя смешивать новый dev-трафик со старым gateway до smoke.
## Phase 3 - Smoke Before Switch
Выполнить проверки на `DEV_GATEWAY_NEW`.
Сначала прогнать HTTP-aware preflight:
```powershell
python scripts\postgres_dev_preflight.py `
--env-file .env.postgres.local.template `
--base-url http://127.0.0.1:8080
```
1. Health:
```powershell
python scripts\live_smoke_gate12.py --base-url http://<DEV_GATEWAY_NEW> --database-url <POSTGRES_DATABASE_URL>
```
2. Focused PostgreSQL smoke:
```powershell
pytest -q tests/test_postgres_readiness.py
```
3. Дополнительно проверить вручную:
- `GET /proxy/auth/health`
- `GET /proxy/interaction/health`
- `GET /proxy/voice/health`
- `GET /proxy/ai-voice-runtime/health`
- открыть `http://<DEV_GATEWAY_NEW>/operator`
4. Если в dev включён event bus:
- проверить подключение к RabbitMQ;
- убедиться, что `event-bus-service` поднимается в `healthy`;
- убедиться, что новые записи появляются в `event_outbox`.
GO в следующую фазу только если:
- health green;
- smoke green;
- новый stack не пытается auto-create schema на старте;
- нет ошибок вида `run python scripts/migrate_core_db.py` после фактического применения миграций.
## Phase 4 - Traffic Switch
Переключение выполняется только после успешного Phase 3.
Рекомендуемый порядок:
1. уменьшить TTL у dev DNS / подготовить proxy route заранее;
2. переключить `DEV_GATEWAY` на `DEV_GATEWAY_NEW`;
3. не останавливать старый SQLite stack;
4. сразу после switch выполнить быстрый post-switch smoke.
Примеры post-switch smoke:
```powershell
python scripts\live_smoke_gate12.py --base-url http://<DEV_GATEWAY_PUBLIC> --database-url <POSTGRES_DATABASE_URL>
```
Проверить руками:
- логин;
- создание interaction;
- digital thread/message flow;
- voice event ingest;
- создание voice AI session.
## Phase 5 - Stabilization Window
В течение первых 15-30 минут после switch:
1. наблюдать логи gateway и сервисов;
2. следить за ошибками подключения к PostgreSQL;
3. следить за ошибками `schema mismatch`;
4. следить за ошибками блокировок/unique conflict в voice transcript path;
5. сравнивать user-visible поведение со старым dev stack.
Если всё стабильно:
1. объявить GO;
2. зафиксировать, что `dev` теперь PostgreSQL-backed;
3. оставить SQLite stack выключенным, но не удалённым до конца рабочего дня.
## Rollback
Rollback делается только через возврат трафика на старый SQLite-backed stack.
Триггеры rollback:
- новый gateway не проходит smoke;
- сервисы падают на startup;
- критичный API path broken;
- UI не работает;
- ошибки подключения к PostgreSQL не устраняются быстро;
- event bus / voice path деградирует.
Шаги rollback:
1. вернуть `DEV_GATEWAY_PUBLIC` на `DEV_GATEWAY_OLD`;
2. убедиться, что старый SQLite stack всё ещё жив;
3. выполнить быстрый smoke на старом stack;
4. запретить новый трафик на PostgreSQL-backed stack;
5. собрать логи с нового stack.
Rollback успешен, если:
- dev UI снова открывается на старом gateway;
- CRUD и smoke снова зелёные;
- команда работает на старом dev без дополнительных действий.
## Cutover Sheet
Перед cutover заполнить:
- время старта;
- кто выполняет switch;
- `DEV_GATEWAY_OLD`;
- `DEV_GATEWAY_NEW`;
- `POSTGRES_DATABASE_URL`;
- результат preflight;
- результат smoke до switch;
- время switch;
- результат smoke после switch;
- GO / ROLLBACK;
- короткий список замечаний.
## Minimal Command Sequence
Если нужен самый короткий practical path для dev:
```powershell
python scripts\migrate_core_db.py
python scripts\postgres_dev_preflight.py --env-file .env.postgres.local.template
python scripts\local_stack.py start --runtime-dir .local_stack_pg --env-file .env.postgres.local.template --force-restart
python scripts\postgres_dev_preflight.py --env-file .env.postgres.local.template --base-url http://127.0.0.1:8080
pytest -q tests/test_postgres_readiness.py
python scripts\live_smoke_gate12.py --database-url postgresql://mvp:mvp@localhost:5432/mvpcc
```
После этого:
1. переключить dev gateway/public route на новый stack;
2. прогнать smoke ещё раз уже через публичный dev URL;
3. оставить старый SQLite stack как rollback target.