Голосовой центр L2: прокси транскрибации POST /v1/ai/transcribe
CI / test (push) Successful in 7m45s
CI / deploy-ift (push) Successful in 2m53s
CI / e2e-ift (push) Successful in 1m23s
CI / deploy-stage (push) Successful in 2m9s
CI / e2e-stage (push) Successful in 1m50s

Back-прокси STT для press-to-talk (канон PRODUCT-AI, голос и тап —
два канала одного движка действий):

- handler_ai_transcribe + logic_ai_transcribe (паттерн logic_geo):
  адаптеры провайдеров xai и openai-совместимый; env STT_PROVIDER,
  STT_URL, STT_API_KEY, STT_MODEL, STT_TIMEOUT_MS, STT_PROXY_URL
- multipart read_file_part в handler_upload_utils (лимит 10 MB)
- ETS rate-limit: 10 req/min на пользователя + глобальный троттлинг
  апстрима; без ключа — 503 unavailable, ошибки апстрима — 502/503
- аудио и транскрипт не персистятся (приват-инвариант канона)
- отдельный httpc-профиль: STT_PROXY_URL применяется только к STT
  (эгресс stt-egress для гео-блокированных провайдеров)
- trails в eventhub_trails.erl, маршрут в eventhub_app.erl,
  docker/.env.example дополнен STT_*

Проверка: eunit модуля 8/8; полный прогон eunit зелёный (1211 тестов),
compile без новых warning'ов.

Refs EventHub/EventHubBack#79
Refs EventHub/EventHubFront#76
This commit is contained in:
2026-08-20 23:56:35 +03:00
parent f4d89a262c
commit 1ef9020c40
7 changed files with 547 additions and 20 deletions
+30 -18
View File
@@ -1,28 +1,28 @@
# Скопируйте в .env (файл .env в .gitignore). Для локальной разработки: EVENTHUB_ENV=dev
# 小泻芯锌懈褉褍泄褌械 胁 .env (褎邪泄谢 .env .gitignore). 袛谢褟 谢芯泻邪谢褜薪芯泄 褉邪蟹褉邪斜芯褌泻懈: EVENTHUB_ENV=dev
# Режим: dev | stage | prod (stage/prod — обязательные сильные секреты)
# 袪械卸懈屑: dev | stage | prod (stage/prod 芯斜褟蟹邪褌械谢褜薪褘械 褋懈谢褜薪褘械 褋械泻褉械褌褘)
EVENTHUB_ENV=dev
RELEASE_COOKIE=ваш-очень-длинный-секретный-куки-минимум-32-символа
GRAFANA_ADMIN_PASSWORD=сложный-уникальный-пароль
RELEASE_COOKIE=胁邪褕-芯褔械薪褜-写谢懈薪薪褘泄-褋械泻褉械褌薪褘泄-泻褍泻懈-屑懈薪懈屑褍屑-32-褋懈屑胁芯谢邪
GRAFANA_ADMIN_PASSWORD=褋谢芯卸薪褘泄-褍薪懈泻邪谢褜薪褘泄-锌邪褉芯谢褜
# JWT (минимум 32 символа, не из denylist — см. infra_secrets)
JWT_SECRET=замените-на-случайную-строку-минимум-32-символа-для-user-jwt
ADMIN_JWT_SECRET=замените-на-другую-случайную-строку-минимум-32-символа
# JWT (屑懈薪懈屑褍屑 32 褋懈屑胁芯谢邪, 薪械 懈蟹 denylist 褋屑. infra_secrets)
JWT_SECRET=蟹邪屑械薪懈褌械-薪邪-褋谢褍褔邪泄薪褍褞-褋褌褉芯泻褍-屑懈薪懈屑褍屑-32-褋懈屑胁芯谢邪-写谢褟-user-jwt
ADMIN_JWT_SECRET=蟹邪屑械薪懈褌械-薪邪-写褉褍谐褍褞-褋谢褍褔邪泄薪褍褞-褋褌褉芯泻褍-屑懈薪懈屑褍屑-32-褋懈屑胁芯谢邪
# Seed админов (обязательны в stage/prod при пустой таблице admin; в dev — опционально)
# Seed 邪写屑懈薪芯胁 (芯斜褟蟹邪褌械谢褜薪褘 胁 stage/prod 锌褉懈 锌褍褋褌芯泄 褌邪斜谢懈褑械 admin; dev 芯锌褑懈芯薪邪谢褜薪芯)
ADMIN_SUPER_EMAIL=superadmin@eventhub.local
ADMIN_SUPER_PASSWORD=замените-сильный-пароль-суперадмина
ADMIN_SUPER_PASSWORD=蟹邪屑械薪懈褌械-褋懈谢褜薪褘泄-锌邪褉芯谢褜-褋褍锌械褉邪写屑懈薪邪
ADMIN_EMAIL=admin@eventhub.local
ADMIN_PASSWORD=замените-сильный-пароль-админа
ADMIN_PASSWORD=蟹邪屑械薪懈褌械-褋懈谢褜薪褘泄-锌邪褉芯谢褜-邪写屑懈薪邪
ADMIN_MODER_EMAIL=moderator@eventhub.local
ADMIN_MODER_PASSWORD=замените-сильный-пароль-модератора
ADMIN_MODER_PASSWORD=蟹邪屑械薪懈褌械-褋懈谢褜薪褘泄-锌邪褉芯谢褜-屑芯写械褉邪褌芯褉邪
ADMIN_SUPPORT_EMAIL=support@eventhub.local
ADMIN_SUPPORT_PASSWORD=замените-сильный-пароль-поддержки
ADMIN_SUPPORT_PASSWORD=蟹邪屑械薪懈褌械-褋懈谢褜薪褘泄-锌邪褉芯谢褜-锌芯写写械褉卸泻懈
# Email: EMAIL_TRANSPORT=auto|smtp|http_api|log (auto: API key http_api, else SMTP_HOST smtp, else log)
# Email: EMAIL_TRANSPORT=auto|smtp|http_api|log (auto: API key http_api, else SMTP_HOST smtp, else log)
EMAIL_TRANSPORT=auto
# HTTP API (HTTPS when outbound SMTP ports blocked). Canon: Resend (Brevo optional).
# HTTP API (HTTPS when outbound SMTP ports blocked). Canon: Resend (Brevo optional).
EMAIL_API_KEY=
EMAIL_API_PROVIDER=resend
# EMAIL_API_URL=https://api.resend.com/emails
@@ -30,7 +30,7 @@ EMAIL_API_PROVIDER=resend
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
VAPID_SUBJECT=mailto:admin@calentiq.com
# SMTP (пусто SMTP_HOST + нет API key = только лог; пароль не коммитить)
# SMTP (锌褍褋褌芯 SMTP_HOST + 薪械褌 API key = 褌芯谢褜泻芯 谢芯谐; 锌邪褉芯谢褜 薪械 泻芯屑屑懈褌懈褌褜)
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
@@ -38,12 +38,24 @@ SMTP_PASS=
SMTP_FROM=noreply@calentiq.com
SMTP_TLS=if_available
PUBLIC_APP_URL=https://stage.calentiq.com
# Окно напоминаний о booking (часы до старта; Back#70)
# 袨泻薪芯 薪邪锌芯屑懈薪邪薪懈泄 芯 booking (褔邪褋褘 写芯 褋褌邪褉褌邪; Back#70)
REMINDER_LEAD_HOURS=24
# Uploads (avatar/cover) — каталог на volume /app/data (Back#71)
# Uploads (avatar/cover) 泻邪褌邪谢芯谐 薪邪 volume /app/data (Back#71)
UPLOAD_DIR=/app/data/uploads
UPLOAD_MAX_BYTES=2097152
# OpenCage (DevOps#16). = /v1/geo -> 503 (degrade). Free: 2500/, 1 rps.
# OpenCage (DevOps#16). 象耱铋 觌 = /v1/geo -> 503 (degrade). Free: 2500/耋蜿, 1 rps.
OPENCAGE_API_KEY=
OPENCAGE_TIMEOUT_MS=3000
# STT-прокси голосового центра (Back#79, Front#76). Без STT_API_KEY
# /v1/ai/transcribe отвечает 503 unavailable, клиент деградирует в палитру.
# Провайдеры: xai (POST {STT_URL}, Bearer) | openai (OpenAI-совместимый).
STT_PROVIDER=xai
STT_URL=https://api.x.ai/v1/stt
STT_API_KEY=
# Опционально: модель для openai-провайдера и таймаут апстрима.
STT_MODEL=
STT_TIMEOUT_MS=15000
# Опционально: HTTP-эгресс (сервис stt-egress в стеке, vless-образ);
# гео-блокированные STT-провайдеры вызываются через него.
STT_PROXY_URL=