Add a weekly Cron Trigger that fires at 17:00 America/Chicago (Central) every Friday year-round, correct across the CST/CDT DST transition, and on fire lists the pending reports (#10 Manager.ListPending) and hands their ids to the publish step. Cloudflare crons are UTC-only, and 17:00 Central is 22:00 UTC under CDT (summer) and 23:00 UTC under CST (winter), so no single UTC cron expresses it. Register BOTH Friday UTC hours in wrangler.jsonc (`0 22 * * 5` and `0 23 * * 5`) and gate each fire: only the fire that is actually 17:00 Central does the work, so publishing runs exactly once per Friday. TinyGo/Wasm may lack the IANA tz database, so the gate does not call time.LoadLocation. Instead internal/schedule computes the US Central DST rule from first principles (CDT from the 2nd Sunday of March 02:00 to the 1st Sunday of November 02:00, else CST) behind a pure func IsFriday1700Central(time.Time), host-testable without TinyGo and cross-checked against the real America/Chicago zone (via a test-only time/tzdata import) over a 20-year sweep. - internal/schedule: pure DST gate + Run orchestrator; Publisher/PendingLister seams; LogPublisher no-op default (the seam #14 replaces). - worker/scheduled_wasm.go: js/wasm-only adapter registering the scheduled task via init()+cron.ScheduleTaskNonBlock, wiring the R2-backed lifecycle Manager to schedule.Run. worker/main.go is untouched. - wrangler.jsonc: add triggers.crons (only the triggers section changed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
63 lines
2.8 KiB
JSON
63 lines
2.8 KiB
JSON
{
|
|
// Cloudflare Worker config for local dev and deploy.
|
|
// Docs: https://developers.cloudflare.com/workers/wrangler/configuration/
|
|
"name": "libremail-bug-report-ingest",
|
|
|
|
// Entry module. The TinyGo build (see package.json "build") produces the Wasm
|
|
// binary at ./build/app.wasm and workers-assets-gen produces this shim, which
|
|
// instantiates the Wasm module. The ./build/ artifacts are git-ignored and are
|
|
// created by `pnpm run build` (which requires TinyGo).
|
|
"main": "./build/worker.mjs",
|
|
|
|
"compatibility_date": "2025-06-01",
|
|
|
|
// Wrangler runs this before dev/deploy to (re)build the Wasm + shim.
|
|
// Requires TinyGo locally; TinyGo is installed in CI.
|
|
"build": {
|
|
"command": "pnpm run build"
|
|
},
|
|
|
|
// R2 bucket for the encrypted-at-rest bug-report objects (ADR #5 / issue #9).
|
|
// The Worker encrypts each scrubbed report with AES-256-GCM before writing, so
|
|
// only ciphertext is ever stored here. "binding" is the JS var the Worker code
|
|
// reads (internal/storage.BucketBinding); "bucket_name" matches the bucket
|
|
// provisioned by infra/ (defaultR2BucketName = "libremail-bug-reports").
|
|
"r2_buckets": [
|
|
{
|
|
"binding": "REPORTS_BUCKET",
|
|
"bucket_name": "libremail-bug-reports"
|
|
}
|
|
],
|
|
|
|
// Cloudflare Secrets Store secret holding the versioned encryption keyring
|
|
// (ADR #5, Key custody): a single JSON secret {active, keys{ver: base64-32B}}.
|
|
// "binding" is read at runtime via env.BUGREPORT_ENC_KEYRING.get()
|
|
// (internal/storage.KeyringBinding). Replace "<store-id>" with the account's
|
|
// Secrets Store id at deploy time; it is not needed for `pnpm run build`
|
|
// (Wasm compile) or the devserver, so CI does not require it.
|
|
"secrets_store_secrets": [
|
|
{
|
|
"binding": "BUGREPORT_ENC_KEYRING",
|
|
"store_id": "<store-id>",
|
|
"secret_name": "bugreport-enc-keyring"
|
|
}
|
|
],
|
|
|
|
// Cron Triggers for the weekly publish job (#13): "Friday 17:00 America/Chicago
|
|
// (Central), DST-correct". Cloudflare evaluates crons in UTC only and has no
|
|
// timezone support, and 17:00 Central is a different UTC hour depending on DST:
|
|
// 22:00 UTC during Central Daylight Time (CDT, UTC-5, summer) and 23:00 UTC
|
|
// during Central Standard Time (CST, UTC-6, winter). A single UTC cron therefore
|
|
// cannot express it, so we register BOTH candidate Friday UTC hours below. The
|
|
// Worker's scheduled handler (worker/scheduled_wasm.go -> internal/schedule)
|
|
// gates each fire on the real America/Chicago rule, so exactly one of the two
|
|
// does the publish work on any given Friday and the other is a no-op. This makes
|
|
// the trigger fire at 17:00 Central year-round with no manual DST maintenance.
|
|
"triggers": {
|
|
"crons": [
|
|
"0 22 * * 5", // Fridays 22:00 UTC == 17:00 Central during CDT (summer)
|
|
"0 23 * * 5" // Fridays 23:00 UTC == 17:00 Central during CST (winter)
|
|
]
|
|
}
|
|
}
|