app to track my HSA eligible receipts
Find a file
Jean-Michel Tremblay e94a17160b
All checks were successful
Build and Test / build-and-test (push) Successful in 39s
Add deploy docs (CICD + Authelia/OIDC); changelog 0.1.0
deploy/CICD.md documents which git push/tag triggers which pipeline
steps; deploy/AUTH.md documents the Authelia OIDC integration contract
with a sequence diagram of the login flow. Cross-link from README and
INSTALL. The 0.1.0 release also ships the previously-committed security
hardening (server-side session expiry + nosniff on served files).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 21:20:08 -04:00
.forgejo/workflows CI: auto-deploy on release tags, drop manual deploy workflow 2026-06-19 15:45:50 -04:00
cmd/hsa Add scheduled metadata-only DB backups (spec item 11) 2026-06-19 07:12:50 -04:00
deploy Add deploy docs (CICD + Authelia/OIDC); changelog 0.1.0 2026-06-20 21:20:08 -04:00
internal Security hardening: server-side session expiry + nosniff on files 2026-06-20 20:56:38 -04:00
scripts Static portable build + env-file launcher for deployment 2026-06-19 08:32:19 -04:00
.env.example Backups: ROOT/dbbackup, hsa_sqlite_backup_YYYY_MM_DD.db naming 2026-06-19 07:34:31 -04:00
.gitignore Initial commit: HSA receipt tracker 2026-06-17 21:40:12 -04:00
call_claude.sh Initial commit: HSA receipt tracker 2026-06-17 21:40:12 -04:00
CHANGELOG.md Add deploy docs (CICD + Authelia/OIDC); changelog 0.1.0 2026-06-20 21:20:08 -04:00
config.json Initial commit: HSA receipt tracker 2026-06-17 21:40:12 -04:00
DESIGN.md AI classifier correction notes + misread review (AI tab) 2026-06-20 16:04:30 -04:00
go.mod Normalize receipt image orientation from EXIF; add changelog (0.0.1) 2026-06-19 20:26:03 -04:00
go.sum Normalize receipt image orientation from EXIF; add changelog (0.0.1) 2026-06-19 20:26:03 -04:00
plan.md Initial commit: HSA receipt tracker 2026-06-17 21:40:12 -04:00
README.md Add deploy docs (CICD + Authelia/OIDC); changelog 0.1.0 2026-06-20 21:20:08 -04:00
secret.md Initial commit: HSA receipt tracker 2026-06-17 21:40:12 -04:00
secret.sh Initial commit: HSA receipt tracker 2026-06-17 21:40:12 -04:00
SPEC.md Security hardening: server-side session expiry + nosniff on files 2026-06-20 20:56:38 -04:00

HSA Receipt Tracker

A small, mobile-first web app for two household users to capture and archive HSA-eligible receipts (photo or PDF) for future reimbursement and tax substantiation, with optional AI auto-fill of the amount/date/category/patient.

  • What it does (current behavior): SPEC.md — the source of truth.
  • Why it's built this way (history & rationale): DESIGN.md.
  • Version log: CHANGELOG.md.

Running

It's a single static Go binary (CGO_ENABLED=0, pure-Go SQLite). Configure via environment (see .env.example); ./scripts/build.sh builds it and ./scripts/run.sh runs it locally.

Deployment:

  • deploy/CICD.md — what each git push/tag triggers (branch = build+test; release tag X.Y.Z = build+deploy; pre-release tag = build+stage).
  • deploy/INSTALL.md — one-time host setup, on-disk layout, manual deploy, and rollback.
  • deploy/AUTH.md — the Authelia (OIDC) integration: which config fields must agree with which app env vars, and how access is granted/revoked.

AI classifier correction notes

When an API key is configured, each upload is read by the model to pre-fill the form. You can steer it with correction notes — free-text rules appended to the classifier prompt — managed under the AI tab. When the model misreads a receipt, that upload is recorded; the AI tab lets you review misreads one by one and attribute which note fixed each.

Notes live only in the database (private, never committed, included in /export/db backups). On first run the table is seeded once with these default notes (no PII), which you can edit or delete:

  1. Amounts that use a comma as the decimal separator (e.g. "12,50") mean 12.50, not 1250.
  2. When both a service/visit date and a separate statement, print, or due date appear, use the service date.
  3. "Patient Pay", "You Paid", "Amount Due", and "Patient Responsibility" are the amount actually paid — prefer them over subtotals or insurance-covered amounts.

These defaults are defined in code (internal/storage/ai_notes.go); this list is the human-readable copy. They are only seeded when the notes table is empty, so a deleted default does not come back on restart.