Skip to content

Phase 9: Hardening & deploy — Dropbox archive, Caddy, security pass#8

Merged
jahrling merged 2 commits into
mainfrom
claude/eloquent-wozniak-41385b
May 20, 2026
Merged

Phase 9: Hardening & deploy — Dropbox archive, Caddy, security pass#8
jahrling merged 2 commits into
mainfrom
claude/eloquent-wozniak-41385b

Conversation

@jahrling

Copy link
Copy Markdown
Owner

Summary

Final hardening and deploy session. No new features.

  • Dropbox archive pipeline. Receipt images are uploaded after OCR, verified by content_hash, then deleted locally. Local data/receipts/ is staging only; SQLite JSON is the operational record, Dropbox is the audit trail.
  • Cron jobs. scripts/sync_pending.sh (hourly) retries failed uploads + logs purge dry-run; scripts/backup_db.sh (daily 02:00) snapshots SQLite → gzip → Dropbox → verify → prune to 30.
  • Reverse proxy + prod profile. caddy/Caddyfile with tls internal; docker compose --profile prod up -d adds Caddy + healthchecks + restart: always to every service.
  • Security pass (all gated on APP_ENV=production so tests pass): HttpOnly + Secure + SameSite=Strict cookies, double-submit CSRF middleware, 5/min/IP rate limit on login, Pillow verify() on every receipt upload.
  • Observability. Structured JSON logging (root + uvicorn) + auth-gated GET /api/admin/stats (totals, OCR success rate, pending Dropbox sync count, DB size, last backup time).
  • Docs. New RUNBOOK.md (Ubuntu 24.04 + CUDA 12.8 + RTX 5070 Ti setup, iPhone CA trust, restore, purge, zero-trust swap), scripts/smoke_test.sh, GitHub Actions CI (pytest + vitest + compose build), ASSUMPTIONS.md updated with what was validated vs. left untested.

Test plan

  • Backend tests still pass — pytest -q62 passed.
  • docker compose --profile prod up -d boots healthy on the target host.
  • ollama run qwen2.5vl:7b "hello" succeeds on the RTX 5070 Ti (verify CUDA 12.8+ / Ollama ≥ 0.6 per RUNBOOK §1.6).
  • Caddy root CA installs + is trusted on iPhone Safari (RUNBOOK §2).
  • End-to-end Dropbox upload + verify + local-delete confirmed against a live token.
  • scripts/smoke_test.sh exits 0 against the live stack.

Reviewer notes

  • Frontend is not yet CSRF-aware. The middleware enforces double-submit only when APP_ENV=production. Flipping prod on before wiring the SPA to read csrf_token and echo X-CSRF-Token will 403 every write. Keep APP_ENV=development for the first deploy.
  • No QIF export route exists in the codebase despite the Phase 8 brief; the smoke test treats it as optional.
  • Required env keys (SECRET_KEY, DROPBOX_ACCESS_TOKEN) fail-fast at startup only when APP_ENV=production, so the test suite remains friction-free.
  • New OLLAMA_BASE_URL / RECEIPT_STAGING_DIR env names are aliases — model_post_init copies them into the existing ollama_url / receipts_dir fields so no call sites needed to change.

🤖 Generated with Claude Code

jahrling and others added 2 commits May 20, 2026 11:19
- Dropbox sync service: upload receipts post-OCR, verify content_hash,
  delete local file only after confirmation. Local data/receipts/ is
  now a staging buffer; SQLite JSON is the operational record, Dropbox
  the audit trail.
- Hourly retry cron (sync_pending) + daily SQLite backup (backup_db)
  with 30-snapshot retention and dry-run purge of receipts >36 months.
- Caddy reverse proxy with tls internal + prod compose profile
  (restart=always, healthchecks, named volumes incl. ollama-models).
- APP_ENV-gated production hardening: Secure+SameSite=Strict cookies,
  double-submit CSRF, 5/min/IP login rate limit, Pillow verify() on
  uploads. Tests stay green because enforcement is prod-only.
- Structured JSON logging + /api/admin/stats endpoint.
- RUNBOOK.md (Ubuntu 24.04 + CUDA 12.8 + RTX 5070 Ti setup, iPhone CA
  trust, restore, purge, zero-trust hook), smoke_test.sh, CI workflow.
- ASSUMPTIONS.md updated with what was validated vs. left untested.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jahrling jahrling merged commit 821514d into main May 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant