FigJam Diagram: HAM — Habit Tracker Architecture (expires 2026-04-13)
Personal habit tracking application. React SPA served by nginx, backed by a Fastify API with PostgreSQL. Integrates with Strava for workout sync and Claude (Anthropic API) for AI coaching.
| Public URL | https://ham.k3s.strommen.systems (Authentik forwardAuth) |
| Internal URL | https://ham.k3s.internal.strommen.systems (no auth, LAN only) |
| Namespace | ham |
| Images | harbor.k3s.internal.strommen.systems/production/ham-web:sha-943eb80 / ham-api:sha-943eb80 |
| Ports | web :80, api :3001 |
The ham namespace has two public IngressRoutes in public-ingress:
| Route | Priority | Auth | Purpose |
|---|---|---|---|
ham.k3s.strommen.systems/api/strava/webhook |
200 | None | Strava push subscription verification (Strava calls this directly) |
ham.k3s.strommen.systems |
100 | Authentik forwardAuth | All other traffic |
The higher-priority webhook route is intentionally unauthenticated — Strava sends GET verification requests to confirm the webhook subscription.
The ham-web nginx container proxies /api/* to the ham-api Service:
proxy_buffering off) for SSE (AI coach chat)index.html| Secret | Keys | Purpose |
|---|---|---|
ham-secrets |
jwt-secret, postgres-password, anthropic-api-key |
Core app secrets |
ham-sync-secrets |
strava-verify-token |
Strava webhook verification (optional) |
Bootstrap:
kubectl create secret generic ham-secrets \
--from-literal=jwt-secret="$(openssl rand -base64 32)" \
--from-literal=postgres-password="$(openssl rand -base64 32)" \
--from-literal=anthropic-api-key=<key> \
-n ham
Prometheus metrics at /metrics (port 3001). ServiceMonitor label: release: prometheus.
Scheduling note:
ham-postgresandham-apihave nodeAffinity excludingk3s-agent-4(Longhorn disabled on that node).
| Schedule | Daily 3:15 AM UTC |
| Method | pg_dump → gzip → S3 k3s-homelab-backups-855878721457/postgres-backups/ham/ |
| Retention | 7 days |
| Manifest | kubernetes/apps/ham/postgres-backup-cronjob.yaml |
kubernetes/apps/ham/
ham.yaml — Namespace, nginx ConfigMap, PostgreSQL StatefulSet+Service,
ham-api Deployment+Service, ham-web Deployment+Service,
internal Ingress, ServiceMonitor, RBAC
hamilton-rbac.yaml — WireGuard collective mesh peer RBAC (cluster-wide read + ham namespace admin)
grafana-dashboard-ham.yaml — Grafana dashboard ConfigMap
postgres-backup-cronjob.yaml — Daily PostgreSQL backup to S3 (3:15 AM UTC)
Hamilton is the tech collective mesh hub (WireGuard collective, Phase 4). hamilton-rbac.yaml grants Hamilton cluster-wide read access and full admin in the ham namespace:
ClusterRole: hamilton-cluster-reader — cluster-wide read on pods, logs, services, configmaps, events, PVCs, namespaces, nodes, deployments, statefulsets, daemonsets, replicasets, ingresses, networkpolicies, batch jobs/cronjobs. Secrets are explicitly excluded cluster-wide.RoleBinding in ham namespace — grants cluster-admin scoped to ham namespace only.