name = "yixi" main = "src/index.ts" compatibility_date = "2026-07-01" # One trigger, two daily ticks dispatched by event.scheduledTime (UTC): # 04:00 — noon Shanghai; trim stale sessions, expired logins and rate windows. # 16:00 — midnight Shanghai; snapshot yesterday's goal_days. # Events are never deleted. [triggers] crons = ["0 4,16 * * *"] [observability] enabled = true # Secrets (wrangler secret put ...): # COOKIE_SECRET — legacy; browser sessions are now server-side rows in # sessions_web and the cookie carries only their id, so # nothing signs anything any more. Harmless to keep. # TOKEN_KEY — AES-GCM key the gate tokens are sealed under, so a # logged-in holder can read their own key back. Never # stored in D1: a stolen database alone opens nothing. # User tokens live in the D1 `users` table as SHA-256 hashes; there is no # global access token. # # Optional, and both or neither (README step 6): # TURNSTILE_SITE_KEY — public; rendered into /register. Could be a [vars] # entry instead, kept as a secret so the pair travels # together and cannot get half-deployed. # TURNSTILE_SECRET — verifies the challenge server-side. # Leave either unset and /register renders no widget and verifies nothing, # which is a supported configuration: sign-up keeps working with only the # per-IP throttle behind it. Set both on the Pages project too, or the # hostname most people actually use is the unprotected one. # NOTE for anyone cloning this: `database_id` below is the author's own # database. It is not a credential — using it requires an API token for that # account — but you MUST replace it with the id `wrangler d1 create yixi` prints # for you. # # Getting this wrong fails in an unhelpful way: migrations are applied by # database *name*, so they land on your database and appear to succeed, while # the deployed Worker binds by *id* and ends up pointed at a database your token # cannot read. Every request then 500s with nothing obviously misconfigured. [[d1_databases]] binding = "DB" database_name = "yixi" database_id = "64215db6-0a05-4ae9-a583-19c8790bef06" # Smart Placement: run near the D1 database (APAC) instead of near the # visitor. Mainland-China traffic lands on a US-west colo while D1 sits in # Singapore; every render paid that hop once per query. Decided from live # traffic, may take a while to kick in — check the `cf-placement` header. [placement] mode = "smart"