# Environment for deploy/docker-compose.yml. The CI deploy job (ci.yaml) maps the
# Gitea TEST_-prefixed secrets/variables onto these unprefixed names; the prod
# deploy maps the PROD_-prefixed set the same way. Values that are identical on every
# contour (DICT_VERSION, SMTP_RELAY_HOST/PORT/TLS/USER/PASS, GRAFANA_SMTP_PORT,
# VITE_VK_APP_LINK/ID, the two VK secrets) live as ONE unprefixed Gitea entry, and the
# deploy derives TELEGRAM_MINIAPP_URL / GRAFANA_ROOT_URL / VITE_VK_ID_REDIRECT_URL from
# PUBLIC_BASE_URL. Copy to deploy/.env for a local run (set the derived ones directly).
#
# Full reference (required vs optional, defaults, secret-vs-variable): deploy/README.md.

# --- Postgres ---------------------------------------------------------------
POSTGRES_DB=scrabble
POSTGRES_USER=scrabble
POSTGRES_PASSWORD=change-me            # required

# --- Point-in-time recovery (pgBackRest -> S3; PROD main host only) ----------
# Continuous WAL archiving for PITR. PROD-ONLY: the test contour never archives (these
# stay unset there and archive_mode stays off). The artifact ships DISARMED —
# PGBACKREST_ARCHIVE_MODE defaults off; arm it only after setting up the S3 repository +
# secrets and creating the stanza, then flip it on (deploy/README.md, point-in-time
# recovery). Gitea: PROD_PGBACKREST_* — endpoint/bucket/region/archive-mode are variables,
# the two S3 keys + the cipher passphrase are secrets.
PGBACKREST_ARCHIVE_MODE=off            # on = archiving active (arm only after the stanza exists)
PGBACKREST_S3_ENDPOINT=                # S3 HOST ONLY — no https://, no port, no bucket (e.g. s3.ru-1.storage.selcloud.ru); path-style addressing
PGBACKREST_S3_PORT=                    # optional; default 443 — set only if the provider uses a non-standard S3 port
PGBACKREST_S3_BUCKET=                  # bucket name; lowercase, no dots/underscores
PGBACKREST_S3_REGION=                  # e.g. ru-1
PGBACKREST_S3_KEY=                     # secret: S3 access key id
PGBACKREST_S3_KEY_SECRET=              # secret: S3 secret access key
PGBACKREST_CIPHER_PASS=                # secret: repo encryption passphrase — KEEP SAFE, stored apart from the S3 keys (losing it makes the archive unrecoverable)

# --- Dictionary -------------------------------------------------------------
# scrabble-dictionary release tag baked into the image as the SEED dictionary for a
# FRESH volume (image build-arg; also labels the resident seed version). After first
# boot the dawg-data volume preserves versions uploaded through the admin console and
# the active version lives in the DB. On a live volume a changed value is ignored (the
# recorded .seed_version marker wins — the seed-drift guard); change a running
# contour's dictionary through /_gm/dictionary (ARCHITECTURE.md §5). One shared Gitea
# variable (DICT_VERSION) seeds both contours + pins the CI test suite.
DICT_VERSION=v1.3.1

# --- Logging ----------------------------------------------------------------
LOG_LEVEL=info

# --- Finished-game export ----------------------------------------------------
# HMAC key signing the public export download URLs (/dl/*). Required; generate a
# real contour value with `openssl rand -base64 32` (Gitea TEST_/PROD_EXPORT_SIGN_KEY).
EXPORT_SIGN_KEY=dev-export-sign-key

# --- Transactional email (Selectel relay) -----------------------------------
# Confirm-code email via the shared Selectel relay (one relay for every contour;
# limit 100 msgs / 5 min). Empty SMTP_RELAY_HOST makes the backend log codes instead
# of sending (dev). Port 465 = implicit TLS, else STARTTLS; no client cert is needed.
# TLS is implicit on port 465 and STARTTLS otherwise, unless SMTP_RELAY_TLS forces it
# (ssl|starttls) — required for Selectel's non-standard ports (1127 = SSL, 1126 =
# STARTTLS). FROM must use the prod domain (Selectel only accepts the verified sender
# domain), so it is the same on every contour; a display name is fine
# (`"Игра Эрудит" <no-reply@erudit-game.ru>`). PUBLIC_BASE_URL is the canonical https
# origin for links in the email — the contour's own public URL. Gitea
# TEST_/PROD_SMTP_RELAY_* + TEST_/PROD_PUBLIC_BASE_URL.
SMTP_RELAY_HOST=
SMTP_RELAY_PORT=465
SMTP_RELAY_TLS=                        # empty = auto by port; ssl | starttls to force
SMTP_RELAY_USER=                       # secret
SMTP_RELAY_PASS=                       # secret
SMTP_RELAY_FROM=no-reply@erudit-game.ru
PUBLIC_BASE_URL=                       # required when SMTP_RELAY_HOST is set (e.g. https://erudit-game.ru)

# Operator alerts (email). The backend emails the admin on new feedback / word complaints
# (coalesced), and Grafana emails infra alerts. Distinct senders; recipients may be several
# comma-separated addresses. Grafana reuses SMTP_RELAY_HOST/USER/PASS but dials the STARTTLS
# port (it can't do the backend's implicit TLS), GRAFANA_SMTP_PORT. All empty = off.
SMTP_RELAY_ADMIN_FROM=                 # backend admin-alert From (e.g. alerts@erudit-game.ru)
ADMIN_EMAIL=                           # backend admin-alert recipient(s), comma-separated
SMTP_RELAY_SERVICE_FROM=               # Grafana alert From; the deploy derives a bare address for Grafana (it rejects "Name" <addr>)
SERVICE_EMAIL=                         # Grafana alert recipient(s), comma-separated
GRAFANA_SMTP_PORT=                     # Grafana STARTTLS port on SMTP_RELAY_HOST (Selectel: 1126)
GF_SMTP_ENABLED=false                  # set true to enable Grafana alert emails

# --- Edge / caddy -----------------------------------------------------------
# Test: ":80" (the host caddy terminates TLS and forwards to scrabble:80 on the
# external `edge` network). Prod: a domain so caddy does its own ACME.
CADDY_SITE_ADDRESS=:80
GM_BASICAUTH_USER=gm
GM_BASICAUTH_HASH=                     # required; `caddy hash-password` bcrypt hash

# --- UI build args (baked into the gateway image) ---------------------------
VITE_TELEGRAM_BOT_ID=
VITE_TELEGRAM_LINK=                                 # friend-invite Mini App link (full URL, e.g. https://telegram.me/<bot>/<app>)
VITE_TELEGRAM_GAME_CHANNEL_NAME=                    # landing "Play in Telegram" link, the bot's game channel
VITE_VK_APP_LINK=                                   # landing "Play on VK" link (full URL, https://vk.com/app<id>)
VITE_VK_APP_ID=                                     # VK ID "Web" app id (client_id) for VK web-login linking; also the gateway's GATEWAY_VK_ID_APP_ID
VITE_VK_ID_REDIRECT_URL=                            # VK ID trusted redirect URL (e.g. https://erudit-game.ru/app/); also the gateway's exchange redirect_uri. Deploy derives it as PUBLIC_BASE_URL + /app/
VITE_GATEWAY_URL=

# --- Grafana ----------------------------------------------------------------
GRAFANA_ROOT_URL=/_gm/grafana/         # deploy derives PUBLIC_BASE_URL + /_gm/grafana/; set the full https URL for a local run
GRAFANA_ADMIN_PASSWORD=admin

# --- Telegram validator + bot -----------------------------------------------
# The token is shared: the validator uses it as the HMAC secret, the bot for the
# Bot API. The bot-link wiring (validator/relay/mTLS addresses) is hard-wired in
# docker-compose.yml; the mTLS material is NOT here — run `deploy/gen-certs.sh`
# (writes deploy/certs/, gitignored) before `docker compose up`.
AWG_CONF=                              # required; AmneziaWG sidecar config (the bot's Telegram egress)
TELEGRAM_BOT_TOKEN=                    # required
TELEGRAM_GAME_CHANNEL_ID=
TELEGRAM_CHAT_ID=                      # moderated discussion chat (channel's linked group); empty disables gating
TELEGRAM_SUPPORT_CHAT_ID=              # private forum supergroup for the support relay (topic per user); empty disables it
TELEGRAM_PROMO_BOT_TOKEN=             # optional standalone promo bot token; empty disables it
TELEGRAM_BOT_USERNAME=               # main bot @username without the @ (promo message); required when the promo token is set
TELEGRAM_BOT_LINK=                    # main bot Mini App link for the promo button (reuse VITE_TELEGRAM_LINK); required when the promo token is set
TELEGRAM_PROMO_START_PARAM=           # promo button startapp payload — a variant-seed deep link (default verudit_ru-scrabble_en) adding English Scrabble for new users; empty forwards the user's /start payload
TELEGRAM_MINIAPP_URL=                  # required; deploy derives it as PUBLIC_BASE_URL + /telegram/
TELEGRAM_TEST_ENV=false
TELEGRAM_API_BASE_URL=

# --- Client-version gate (ARCHITECTURE.md §2) -------------------------------
# The hard minimum + the soft recommended client build. Empty ⇒ dormant. Plain (unprefixed) Gitea
# variables, shared across contours; in the test contour the stamped client version is a commit hash
# (unparseable ⇒ fail-open), so these only enforce on real semver prod builds. Recommended must be ≥ min.
GATEWAY_MIN_CLIENT_VERSION=
GATEWAY_RECOMMENDED_CLIENT_VERSION=

# --- VK Mini App ------------------------------------------------------------
# The VK app's "protected key" (client_secret): the gateway verifies the Mini App
# launch-parameter signature in-process under it (a pure offline HMAC, no VK API call).
# Empty disables the VK auth path (auth.vk). Set from the Gitea TEST_/PROD_ secret.
GATEWAY_VK_APP_SECRET=
# VK ID web login (browser VK-identity linking) — a SEPARATE VK "Web" app: the gateway runs
# the confidential OAuth 2.1 code exchange under this protected key. The app id + redirect URL
# come from VITE_VK_APP_ID / VITE_VK_ID_REDIRECT_URL above. All three empty disables link.vk.*.
GATEWAY_VK_ID_CLIENT_SECRET=

# --- Payments: Robokassa (direct RUB rail) ----------------------------------
# The shop's merchant login + the two pass phrases (Password1 signs the launch request,
# Password2 signs/verifies the Result callback). An empty login leaves the direct rail off.
# ROBOKASSA_TEST=1 runs test payments against the shop's TEST pass phrases (no real money);
# empty/0 is live. Mapped in compose to BACKEND_ROBOKASSA_*; Gitea TEST_/PROD_ secrets, with
# PROD_BACKEND_ROBOKASSA_TEST a variable so go-live is a flag flip, not a secret redeploy.
ROBOKASSA_MERCHANT_LOGIN=
ROBOKASSA_PASSWORD1=
ROBOKASSA_PASSWORD2=
ROBOKASSA_TEST=
# Multi-shop direct rail (D42): the vars above seed the "web" channel; add per-channel shops here.
# ROBOKASSA_WEB_* overrides the web shop; ROBOKASSA_ANDROID_* adds the android (RuStore) shop. Each
# credits the one direct wallet; an empty login drops that channel (routing falls back to web). The
# Robokassa cabinet points each shop's Result URL at /pay/robokassa/result/web and .../android.
ROBOKASSA_WEB_MERCHANT_LOGIN=
ROBOKASSA_WEB_PASSWORD1=
ROBOKASSA_WEB_PASSWORD2=
ROBOKASSA_WEB_TEST=
ROBOKASSA_ANDROID_MERCHANT_LOGIN=
ROBOKASSA_ANDROID_PASSWORD1=
ROBOKASSA_ANDROID_PASSWORD2=
ROBOKASSA_ANDROID_TEST=

# --- Gateway anti-abuse ------------------------------------------------------
# Planted honeytoken bearer value: any request presenting it is flagged — a 24h IP ban
# where the IP ban is on (prod), logs + a ban metric otherwise (test). Plant the value
# somewhere an attacker would find it; empty disables the trap. Gitea
# TEST_/PROD_GATEWAY_HONEYTOKEN (secret).
GATEWAY_HONEYTOKEN=
