Основной конфиг (config.<mode>.yml)
Конфигурация разделена на несколько областей:
app— параметры самого приложения (сервер, HTTP-клиенты, флаги безопасности, сессии, очистка кэша).oauth— параметры внешних OAuth-провайдеров (сейчас только Google для ACP).infrastructure— подключения к внешним сервисам: PostgreSQL, Redis, Cloudflare Stream и платформы.domain— бизнес-настройки (ивенты, конкурсы, правила соперников, настройки user-data batch).observability— метрики и интеграция Prometheus.
Ниже описан каждый блок.
1. app
app.server
app:
server:
id: 1 # произвольная строка/число, попадает в X-Server-Id
host: 0.0.0.0 # слушаемый адрес
port: 8080 # порт HTTP-сервераapp.http.timeouts
Таймауты для общего HTTP-клиента, используются стримами, traffic-flow и т.д. Формат — time.Duration.
app:
http:
timeouts:
request: 30s
dial: 20s
keep_alive: 20s
tls_handshake: 10s
response_header: 10s
handler: 60s # таймаут обработки HTTP-запроса (middleware)app.security
app:
security:
secret: "..." # главный секрет (JWT, подписи и т.д.)
disable_auth: false # глобально выключить проверку платформенных токенов
enable_cors: false # включить permissive CORS middleware (только для dev/тестов)
max_body_size: "4MB" # лимит размера тела запроса
rate_limit:
enabled: true # включить rate limiting (per-IP, token bucket)
rps: 100 # запросов в секунду
burst: 200 # максимальный burstRate limiter хранится in-memory; при превышении возвращается HTTP 429 Too Many Requests.
app.session.single_mode
app:
session:
single_mode:
enabled: false # если true — выдаём X-Set-Session-Token и проверяем X-Session-Token
blocking: false # если true — блокируем запрос без актуальной сессииapp.cache_clear
app:
cache_clear:
enabled: true # чистить volatile-кэши при старте контейнера
patterns:
- "marv:cache:users:*"
- "marv:cache:streams:*"app.invitation_awards
Строки с JSON-наградой, которые выдаются получателю/отправителю инвайта во V2:
app:
invitation_awards:
receiver: '{"currency":"coins","amount":100}'
sender: '{"currency":"coins","amount":50}'Если оставить строки пустыми (""), награда не отправится.
app.modules
Список модулей для загрузки. Позволяет управлять набором функционала через конфиг (без изменения кода):
app:
modules:
- user
- world
- transaction
- message
- event
- stream
- rival
- abtest
- remote_config
- product
- ads
- alert
- traffic_flow
- bots
- cron_task
- merchant
- platform
- acp_user
- systemМодули user, system, cron_task, merchant, platform, acp_user создаются по умолчанию; остальные — только если указаны.
app.routes
Включение/отключение групп HTTP-маршрутов:
app:
routes:
v1: false # V1 API (deprecated)
v2: true # V2 API (основной)
acp: true # Admin Control Panel
ext: true # External webhooksПо умолчанию все роутеры выключены (если секция не указана). Явно укажите true для нужных.
Прочие поля
app.cdn_url,app.log_dir,app.invite_bonus,app.validation.strict,app.min_version— без изменений, доступны по тем же ключам внутриapp.
2. oauth
oauth.google
Настройки Google OAuth для ACP:
oauth:
google:
client_id: "xxx.apps.googleusercontent.com" # аудитория, которую выдаёт Google в ACP UI
certs: "{}" # JWKS Google; обновляется задачей google_certscerts автоматически переписывается системной задачей google_certs, которая периодически скачивает JWKS с https://www.googleapis.com/oauth2/v3/certs. Значение по умолчанию ({}) нужно только для инициализации схемы.
3. infrastructure
infrastructure.postgres
infrastructure:
postgres:
host: localhost
port: 5432
username: app
password: secret
database: marv
pool:
max_open: 20
max_idle: 10
timeout: 300s
sslmode: disable
dry_run: falseinfrastructure.redis
infrastructure:
redis:
address: 127.0.0.1:6379
password: ""
db: 0
pool: 10
timeout: 300s # используется как pool-timeout и default TTL
store_ttl: 4h # TTL для Set() без явного timeoutinfrastructure.cloudflare
Учетные данные для Cloudflare API.
infrastructure:
cloudflare:
account_id: "..."
api_token: "..."infrastructure.platforms
Ключом остаётся api_type (строкой). Все секреты и ID перенесены в credentials, чтобы не смешивать их с мета-инфой.
infrastructure:
platforms:
"2":
type: vk
credentials:
id: "7365134"
secret_key: "..."
"30":
type: ms_start
credentials:
id: "9NPZT17FTVZ4"
package_name: "HGPOINTLTD.MergeHotel"
secret_key: "..."
merchant_profiles:
default:
type: xsolla
merchant_id: "702055"
project_id: "265997"
api_key: "..."
webhook_secret: "..."
promo:
type: xsolla
merchant_id: "702055"
project_id: "400001"
api_key: "..."
webhook_secret: "..."Поддерживаются те же type, что и раньше. Для специфичных платформ добавлены поля внутри credentials: application_key, client_id, refresh_token, uid, public_key, private_key_id, auth_token, package_name и т.п.
merchant_profiles — это словарь профилей мерчанта. Ключ — произвольное имя профиля, значение — набор полей (type, merchant_id, project_id, api_key, webhook_secret, дополнительные поля RuStore и т.д.). Профиль default используется по умолчанию и экспортируется в атрибуты без суффиксов, чтобы старые интеграции продолжили работать.
В REST‑модулях
extпрофиль выбирается по ключуmerchant_profiles: маршрут/ext/{api_type}/{profile}/{action}будет использовать конфигурациюmerchant_profiles.{profile}. Для обратной совместимости запросы вида/ext/{api_type}/{merchant_type}/{action}будут автоматически привязаны к профилюdefault, если у негоtypeсовпадает сmerchant_type.
Basic Auth заголовок для Xsolla формируется автоматически из
merchant_idиapi_key, отдельное поле в конфиге больше не требуется.
4. domain
domain:
stream:
delete_after: 1080h
entrance_timeout: 900s
proxy_url: "https://..."
subdomain: "example.cloudflarestream.com"
events:
lookback: 336h
dead_letter_queue:
enabled: true
max_retries: 3
contest:
group_size: 50
rivals:
max_count: 100
compatible_api_types:
vk: [1,2,3]
platform_rules:
- platform: app_store
api_types: [1,2,3]
user_updates:
batch_size: 250
ttl: 168h # использовалось как cache.user_updates_*5. observability
Структура не изменилась:
observability:
metrics:
http_buckets_ms: [50, 100, 200, 500, 1000, 2000, 5000]
prometheus_enabled: false6. tasks
tasks.system
Системные cron-задачи, которые поднимаются из конфигурации (без записи в БД).
tasks:
system:
- name: "Reload Google certs"
type: google_certs
schedule: "0 */6 * * *"
enabled: true
scope: all # leader (по умолчанию) или all
- name: "Persist user data updates"
type: user_data_batch_update
schedule: "*/5 * * * *"
enabled: true
scope: leaderscope управляет тем, где выполняется задача:
leader— только на активном лидере (рекомендовано для операций с единственным воркером: перенос очередей из Redis в БД и т.п.)all— на каждом сервере (подходит для задач вроде обновления сертификатов или прогрева кэшей).
7. alerts
Шлюз критических уведомлений.
alerts:
destinations:
- name: payments_slack
provider: slack # slack / telegram
endpoint: "https://hooks.slack.com/services/..."
severities: [critical]
tags: ["payments"]
template: payment_critical
- name: oncall_tg
provider: telegram
token: "<bot-token>"
chat_id: -1001234567
severities: [critical, warning]
template: default_telegram
templates:
- id: payment_critical
provider: slack
text: |
:rotating_light: *{{ .Title }}*
{{ .Message }}
{{ if .Payload.transaction_id }}ID: `{{ .Payload.transaction_id }}`{{ end }}
- id: default_telegram
provider: telegram
text: |
{{ .Title }}
{{ .Message }}
severity={{ .Severity }}destinations— куда отправлять события (Slack webhook, Telegram-чат и т.д.), плюс фильтры по severity/tag, выбор шаблона.templates— текстовые шаблоны (Gotext/template). Доступные поля:Title,Message,Severity,Tags,Payload.
Полная JSON Schema расположена в infrastructure/config/koanf/schemas/config.schema.json.
