From 80558976c54615a1c82fe257b6f0317bd1a986cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20P=C3=A1scoa?= Date: Sun, 11 Oct 2026 19:54:09 +0100 Subject: [PATCH 01/16] feat: daily D1 backups to R2 with a scheduled Workflow - BackupWorkflow (splitpro-backup, 03:00 UTC): starts a D1 REST export, polls until the signed URL is ready, streams the SQL dump into the splitpro-backups R2 bucket, then prunes dumps older than BACKUP_RETENTION_DAYS (default 90) - failures are logged to Workers Logs and retried per step - wrangler.example.jsonc / README: bucket, workflow, vars, restore steps --- README.md | 12 ++++ src/server/workflows/backup.ts | 126 +++++++++++++++++++++++++++++++++ worker/index.ts | 1 + wrangler.example.jsonc | 15 +++- 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/server/workflows/backup.ts diff --git a/README.md b/README.md index 53df55798..0c812e3af 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,18 @@ setting belongs only in `previews.vars`, not production `vars`. - `drizzle-kit` and `wrangler d1 migrations` own the schema. `migrations/0001_balance_view_and_triggers.sql` is hand-written (the `BalanceView` view and a trigger). Back it up before regenerating migrations. +## Backups + +- **Time Travel:** D1 keeps point-in-time history for 30 days on the Workers Paid plan. + Restore with `npx wrangler d1 time-travel restore splitpro --timestamp=`. +- **Daily dump to R2:** the `splitpro-backup` Workflow (03:00 UTC) exports the database through the + D1 REST API into the `splitpro-backups` bucket (`d1/splitpro--