project-mcd-tracker updated 2026-03-21mcd-tracker
Vision
McDonald's BOGO coupon tracker. McDonald's receipt surveys give you a code redeemable for a buy-one-get-one sandwich. Most locations enforce a limit of 5 codes per month per location (rolling 30-day window per code used). This app tracks usage across locations so users always know how many codes they have left and when slots reopen.
Meta-purpose: Full-lifecycle DORA Elite proof — validate the pal-e-platform development experience from devops → backend → frontend → mobile. Exercise every SOP, every pipeline stage, every architectural pattern. The app is the vehicle; the dev process is the deliverable.
User Stories
Who uses the expense tracker, what they need, and how we measure success. mcd-tracker is a personal tool for Lucas to track McDonald's receipt codes and spending.
| Role | Story | Success Metric | story:X key |
|---|---|---|---|
| Superuser (Lucas) | I can deploy and manage the mcd-tracker stack (API + app) through the standard platform pipeline. | Deploys via ArgoCD. Zero manual kubectl for routine operations. | story:superuser-deploy |
| User (Lucas) | I can log a receipt code from my phone in <10 seconds — scan or type the code, confirm, done. | Receipt entry takes <3 taps. Works on mobile (Capacitor). | story:user-log-code |
| User (Lucas) | I can see my spending history, daily/weekly/monthly totals, and whether I'm on budget. | Dashboard loads in <2s. Budget vs actual visible at a glance. | story:user-view-spending |
| User (Lucas) | I can see which codes have been redeemed and which are still available, so I don't waste a trip. | Code status (redeemed/available) is accurate and up-to-date. | story:user-track-codes |
Active: Plan: mcd-tracker (plan-mcd-tracker) — 10 phases, all NOT STARTED. Workflow: devops → backend → frontend → mobile.
Not yet created. Will be created when work begins. Workflow order:
- DevOps first — service onboarding via pal-e-services + k8s manifests in pal-e-deployments. Production namespace ready before code is written.
- Backend second — FastAPI + Postgres (CNPG sidecar pattern). Alembic migrations. Keycloak JWT auth. Integration tests. Deployed to prod.
- Frontend third — HTML/CSS in
mcd-tracker-playground(pal-e-playground project). Once design locks, promote to SvelteKit inmcd-tracker-app. Deploy to prod. - Mobile last — Swift/SwiftUI iOS app (
mcd-tracker-ios). Same API. Woodpecker CI on Mac agent (local backend). Fastlane → TestFlight → App Store.
board-mcd-tracker — Continuous kanban. Backlog → Todo → Next Up → In Progress → Done.
Not yet created. Will be created when plan is created.
SvelteKit app scaffolded + merged (2026-03-16). PR #2 on mcd-tracker-app: 10 routes, keycloak-js PKCE auth, 41 tests, Capacitor config, Dockerfile, CI pipeline. Playground live (12 pages). Backend: 13 endpoints, 144 tests. Next: service onboarding → deploy → verify on phone. Then Phase 7a (E2E tests) and Phase 10a (security hardening) before App Store.
Milestones
2026-03-16: Backend complete + audited. 12 endpoints, 130 tests, full repo audit passed. Playground live with receipt-first workflow.
Architecture
Three views of the system (all created and updated to reflect receipt-first workflow + Capacitor):
- Domain Model (
arch-domain-mcd-tracker) — User, Location, Receipt, CouponUsage. Two codes: survey code (receipt) + BOGO code (coupon). Rolling 30-day window. - Data Flow (
arch-dataflow-mcd-tracker) — 7 flows: scan receipt + OCR, complete survey + save BOGO, redeem at counter, check availability, auto-detect location (GPS/Overpass), slot limit rejection, Keycloak auth. - Deployment (
arch-deployment-mcd-tracker) — archbox (dev) → Forgejo → Woodpecker (Linux + Mac agents) → Harbor → ArgoCD → k3s. Capacitor wraps SvelteKit for iOS. Dual-channel: web + App Store.
- Stack: Python FastAPI + Postgres (CNPG sidecar) + Keycloak OIDC — matches basketball-api pattern exactly.
- Auth: Dedicated Keycloak realm
mcd-tracker. Roles: user, admin. - Rolling window: 5 codes per location per 30-day rolling window. Each code usage starts an independent 30-day timer.
- Receipt-first workflow: Camera → OCR → survey → BOGO code → save. Two codes: survey code (from receipt) and BOGO code (from survey). Receipt entity links them.
- Capacitor for iOS (not Swift): SvelteKit + Capacitor = one codebase for web + iOS. Native camera (
@capacitor/camera) and GPS (@capacitor/geolocation) via plugins. Same code runs on both platforms — native APIs on iOS, browser fallback on web. Eliminates the need for a separate Swift app. - iOS pipeline: MacBook Air M1 as Woodpecker agent (local backend). Capacitor generates Xcode project.
npx cap sync && xcodebuild → Fastlane → TestFlight → App Store. - Frontend progression: Playground (HTML/CSS) → SvelteKit (production web + Capacitor iOS). Two stages, not three.
mcd-tracker. Roles: user, admin.@capacitor/camera) and GPS (@capacitor/geolocation) via plugins. Same code runs on both platforms — native APIs on iOS, browser fallback on web. Eliminates the need for a separate Swift app.npx cap sync && xcodebuild → Fastlane → TestFlight → App Store.- Stack: Python FastAPI + Postgres (CNPG sidecar) + Keycloak OIDC — matches basketball-api pattern exactly.
- Auth: Dedicated Keycloak realm
mcd-tracker. Roles: user, admin. - Rolling window: 5 codes per location per 30-day rolling window. Each code usage starts an independent 30-day timer. When a timer expires, that slot reopens. Not calendar-month based.
- iOS pipeline: MacBook Air M1 as Woodpecker agent (local backend). Swift code written on archbox (Linux), pushed to Forgejo, Mac builds via
xcodebuild+ Fastlane. $99/yr Apple Developer Program required for App Store. - Frontend progression: Playground (HTML/CSS) → SvelteKit (production web) → Swift (native iOS). Each stage validates UX before the next begins.
| Repo | Platform | Role | Status |
|---|---|---|---|
mcd-tracker-api | Forgejo | FastAPI backend | LIVE — 8 endpoints, 58 tests |
mcd-tracker-playground | Forgejo | HTML/CSS prototypes (served at playground.tail5b443a.ts.net/mcd-tracker/) | Scaffolded — 7 pages, design iteration in progress |
mcd-tracker-app | Forgejo | SvelteKit + Capacitor (web + iOS from one codebase). Native camera/GPS via Capacitor plugins. | Not created |
Removed: mcd-tracker-swift — Capacitor wraps the SvelteKit app as a native iOS app. No separate Swift codebase needed.
| Repo | Platform | Role | Status |
|---|---|---|---|
mcd-tracker-api |
Forgejo | FastAPI backend | Not created |
mcd-tracker-playground |
Forgejo | HTML/CSS design experiments | Not created |
mcd-tracker-app |
Forgejo | SvelteKit frontend (promoted from playground) | Not created |
mcd-tracker-ios |
Forgejo | Swift/SwiftUI iOS app | Not created |
Infrastructure
| Component | Details |
|---|---|
| Dev machine | archbox — Arch Linux, 1.8T NVMe, x86_64 |
| iOS build server | MacBook Air M1 — Woodpecker agent (local backend), Xcode, Fastlane, Capacitor builds (npx cap sync + xcodebuild) |
| k8s namespace | mcd-tracker (via pal-e-services onboarding) |
| Container registry | Harbor — mcd-tracker/api, mcd-tracker/app |
| Keycloak realm | mcd-tracker (separate from westside-basketball). App client is public (keycloak-js + PKCE, not Auth.js). |
| CI | Woodpecker — Linux agent (test/build/push) + Mac agent (npx cap sync + xcodebuild + Fastlane) |
| GitOps | ArgoCD — pal-e-deployments/overlays/mcd-tracker/prod |
Inbox
Untriaged TODOs — discovered work awaiting scoping into the plan.
| Slug | Summary | Discovered |
|---|---|---|
| empty |