Skip to content

Wrangler Configuration

The Aelghar backend is a Cloudflare Worker deployed via Wrangler. This document covers the full wrangler.toml structure, binding layout, cron triggers, and the staging/production environment split.


wrangler.toml Structure

name = "aelghar-api"
main = "worker/src/index.ts"
compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"]

# ─── D1 (SQLite relational database) ─────────────────────────────────────────
[[d1_databases]]
binding = "DB"
database_name = "aelghar-db"
database_id   = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"   # production D1 id

# ─── KV Namespaces ────────────────────────────────────────────────────────────
[[kv_namespaces]]
binding    = "KV"
id         = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"            # production KV namespace id

# ─── Durable Objects ─────────────────────────────────────────────────────────
[[durable_objects.bindings]]
name       = "TOWN_DO"
class_name = "TownSettlementDO"

[[durable_objects.bindings]]
name       = "MARKET_DO"
class_name = "MarketExchangeDO"

[[durable_objects.bindings]]
name       = "GUILD_DO"
class_name = "GuildDO"

[[durable_objects.bindings]]
name       = "EXPEDITION_DO"
class_name = "ExpeditionGroupDO"

[[durable_objects.bindings]]
name       = "GOVERNANCE_DO"
class_name = "TownGovernanceDO"

[[migrations]]
tag = "v1"
new_classes = [
  "TownSettlementDO",
  "MarketExchangeDO",
  "GuildDO",
  "ExpeditionGroupDO",
  "TownGovernanceDO",
]

# ─── R2 (SVG asset storage) ───────────────────────────────────────────────────
[[r2_buckets]]
binding     = "R2"
bucket_name = "aelghar-assets"

# ─── Queues ───────────────────────────────────────────────────────────────────
[[queues.producers]]
binding    = "SETTLEMENT_QUEUE"
queue      = "aelghar-settlement"

[[queues.consumers]]
queue              = "aelghar-settlement"
max_batch_size     = 10
max_batch_timeout  = 5
max_retries        = 3
dead_letter_queue  = "aelghar-settlement-dlq"

# ─── Cron Triggers ────────────────────────────────────────────────────────────
[triggers]
crons = [
  "0 * * * *",    # hourly  — weekly leaderboard recompute
  "0 */6 * * *",  # 6-hourly — monthly leaderboard recompute
  "0 3 * * *",    # 03:00 UTC daily — all-time leaderboard recompute + idempotency_key prune
  "30 3 * * *",   # 03:30 UTC daily — item_audit_log pruning (rows > 90 days)
]

Secrets

Secrets are never in wrangler.toml. They are stored as Worker Secrets via wrangler secret put.

Secret name Purpose
JWT_SECRET HMAC-SHA256 signing key for access JWTs
REFRESH_SECRET Signing key for refresh token KV key derivation
ADMIN_SECRET Bearer token for admin-only endpoints (/admin/*)
TURNSTILE_SECRET_KEY Cloudflare Turnstile secret (validate bot protection tokens)

Set secrets:

wrangler secret put JWT_SECRET
wrangler secret put REFRESH_SECRET
wrangler secret put ADMIN_SECRET
wrangler secret put TURNSTILE_SECRET_KEY

For staging environment, suffix commands with --env staging.


Pages Environment Variables

SvelteKit Pages (the frontend) requires only one public environment variable:

Variable Value
PUBLIC_TURNSTILE_SITE_KEY Turnstile site key (public — safe to expose in client bundle)

Set in the Cloudflare Pages dashboard → Settings → Environment Variables. Set separately for Preview (staging) and Production.


Staging Environment

The staging environment uses a separate D1 database and KV namespace to prevent any contact with production data.

[env.staging]
name = "aelghar-api-staging"

[[env.staging.d1_databases]]
binding       = "DB"
database_name = "aelghar-db-staging"
database_id   = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"

[[env.staging.kv_namespaces]]
binding = "KV"
id      = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"

[[env.staging.r2_buckets]]
binding     = "R2"
bucket_name = "aelghar-assets-staging"

[[env.staging.queues.producers]]
binding = "SETTLEMENT_QUEUE"
queue   = "aelghar-settlement-staging"

Secrets for staging must be set separately:

wrangler secret put JWT_SECRET --env staging
wrangler secret put ADMIN_SECRET --env staging
wrangler secret put TURNSTILE_SECRET_KEY --env staging

Deploy Commands

Production:

wrangler deploy
wrangler d1 migrations apply --database-name aelghar-db

Staging:

wrangler deploy --env staging
wrangler d1 migrations apply --database-name aelghar-db-staging --env staging

The deploy script (scripts/deploy-pages.ps1) wraps these commands and calls POST /admin/content/reload after a successful deploy. See local-dev-setup.md for the full workflow.


Route Configuration

The Worker is bound to the aelghar-docs.pages.dev domain via a Cloudflare Pages Functions setup, or alternatively deployed as a standalone Worker with routes:

routes = [
  { pattern = "api.aelghar.game/*", zone_name = "aelghar.game" }
]

SvelteKit handles all client routes (/*). Worker handles /api/* and /admin/*.


DO Namespace Notes

Each DO class has exactly one binding. Naming convention for idFromName:

DO class idFromName key pattern
TownSettlementDO "town:{town_id}"
MarketExchangeDO "market:{town_id}"
GuildDO "guild:{guild_id}"
ExpeditionGroupDO "expedition:{expedition_id}"
TownGovernanceDO "governance:{town_id}"

DO instances are created on first request to that named id. No pre-warming needed.