# FARMGIRL LEDGER — Disaster Recovery Runbook

*So the business's invoicing can come back to life on a brand-new Mac, even without
Devin around to explain it. Follow top to bottom.*

## What exists, and where

Every night at 3:30am (or on next wake), this laptop uploads an **encrypted** backup
to the business's own Cloudflare account (the one that runs the wholesale order
form). The vault is a Workers KV namespace called **farmgirl-vault**
(id `607f2216e00b4959b26c3cbd851c948a`) holding:

| Key | What it is |
|---|---|
| `db/latest` | The whole business ledger (every invoice, customer, payment) |
| `db/daily-01`…`daily-31` | One snapshot per day of the month (~31 days back) |
| `db/monthly-01`…`monthly-12` | One per month (~a year back) |
| `source/latest` | The app's complete source code |
| `app/latest` | The built, double-clickable Mac app |
| `meta/latest` | Small JSON: when the last backup ran, checksums |

Everything except `meta/latest` is encrypted (AES-256, PBKDF2) with **the vault
passphrase**. Without the passphrase the backups are unreadable — that's the point.

## The passphrase

Devin keeps it in ____________________ *(Devin: fill this in — a written note in
the fire box, the shared password manager, wherever — and tell your wife where.
If the laptop is destroyed, that copy is the only one that matters.)*

## Restore on a new Mac — THE EASY WAY (no terminal)

1. On any Mac, open **https://filthyfarmgirl.pages.dev** in a browser.
2. Type the vault passphrase, click the button — it downloads the app.
3. Unzip, right-click the app → Open → Open.
4. In the app: **File → Restore from Cloud Backup…**, same passphrase. Done —
   every invoice and customer comes back.
5. Service keys: copy the "FFG — service keys" note from Bitwarden, then in the app
   Settings → Key backup → **Import from clipboard**.

## Restore on a new Mac — the terminal way (backup path if the website is ever down)

1. Install Xcode command line tools (`xcode-select --install`) and Node
   (nodejs.org). Sign in to the business Cloudflare account:
   `npx wrangler login` in Terminal.
2. Download and decrypt the database (replace PASSPHRASE with the vault passphrase):

   ```bash
   npx wrangler kv key get --namespace-id=607f2216e00b4959b26c3cbd851c948a "db/latest" --remote > db.enc
   openssl enc -d -aes-256-cbc -pbkdf2 -iter 310000 -in db.enc -pass pass:PASSPHRASE | gunzip > ledger.sqlite
   ```
3. Same pattern for the app (`app/latest` → unzip) and source (`source/latest`).
4. Put the database where the app looks for it:

   ```bash
   mkdir -p ~/Library/"Application Support/Farmgirl Ledger"
   cp ledger.sqlite ~/Library/"Application Support/Farmgirl Ledger/ledger.sqlite"
   ```
5. Open `FarmgirlLedger.app`. All invoices and customers will be there.

## Service keys

The app's service keys are saved in **Bitwarden** (the shared collection — items
named "FFG — …", plus a secure note holding all keys as one block). To restore them
all at once: open Bitwarden, copy the "FFG — service keys" secure note, then in the
app open **Settings** (⌘,) → **Key backup** card → **Import keys from clipboard** —
every key lands back in place in one click.

Fallback if Bitwarden is unavailable: create fresh keys instead — log into each
service's dashboard with the business email (devin@filthyfarmgirl.com), generate a
new API key, and paste it into the matching Settings card. About half an hour,
breaks nothing.

## Verifying a backup is good (do once a year)

Run `tools/cloud-backup.sh`, then do the restore steps into a scratch folder and:

```bash
sqlite3 ledger.sqlite "PRAGMA integrity_check; SELECT COUNT(*) FROM invoices;"
```

Last verified: **2026-09-02** — full drill passed (byte-identical restore,
integrity ok, 17,780 invoices / 1,924 customers).

## Nightly schedule

`~/Library/LaunchAgents/com.filthyfarmgirl.cloudbackup.plist` runs
`tools/cloud-backup.sh` daily at 3:30am (or on next wake). Log:
`~/Library/Application Support/Farmgirl Ledger/cloud-backup.log`.
