Wellness Postgres Sync (CreatorTrack Fitness data layer)¶
URL: https://mkdocs.justinsforge.com/memory/general/reference_wellness_pg_sync/
The CreatorTrack Fitness app reads Postgres ONLY (no more node:sqlite/filesystem reads; that dependency is why the dev/prod systemd units had to move to Node 22, now moot). Canonical store: the lifeos wellness schema on CT 109 (lifeos_admin owns, lifeos_app SELECT; single-user, no per-workspace RLS, mirrors the finance.* grant model).
Script¶
~/forge/scripts/forge_wellness_pg_sync.py: idempotent upsert of the wellness sources intowellness.*. Fail-loud, tolerates a missing source (logs + skips, nonzero exit only on total failure). Writes aslifeos_adminviaforge_workspace_db.admin_connect(). Re-run = same state.- Tables:
wellness_facts(EAV replica of context.db facts_wellness; backs eight_sleep/garmin/inbody, ~55.9k rows),hevy_workouts,hevy_templates,garmin_activities,body_measurements,config(thresholds),sync_state(freshness stamps). - Schema migration:
forge-suite/db/migrations/20260702T194750_fitness_pg_wellness_pipeline_schema_for_fitness_app.sql.
Timer¶
~/.config/systemd/user/forge-wellness-pg-sync.{service,timer}(user units,OnCalendar=*:0/15, enabled 2026-07-02). Keeps Postgres current as the wellness pollers (Garmin/Hevy/Eight Sleep) write their sources.- The Fitness app's Refresh button also runs a
wellness_pgsync step.
Parity¶
Verified byte-identical between the new PG reads and the prior file-reads across all /api/fitness/data headline values + all 7 detail endpoints (2026-07-02 cutover). The old Flask fitness dashboard (fitness.justinsforge.com) still reads context.db directly and is unaffected; retire on its own schedule.
Hevy API fetch (2026-07-06)¶
forge_hevy_poll.py was retired 2026-07-03 (Notion decommission) but it was the ONLY thing pulling workouts from the Hevy API; the JSONL + wellness.hevy_workouts + ~/.forge-state/hevy_last_sync froze and forge-monitor fired the 86h wellness_fresh_hevy alert. Fix: forge_wellness_pg_sync.py now owns the fetch. refresh_hevy_raw() pulls ALL workouts + the exercise-template catalog from api.hevyapp.com, rewrites data/hevy/raw_hevy_workouts.jsonl + exercise_templates.json atomically, refuses to overwrite on an empty API response, and stamps hevy_last_sync. Age-gated to 6h so the 15-min timer hits Hevy ~4x/day (the intentional low cadence). Retired forge_hevy_poll cron lines removed from crontab. Commit 3d23ab5.
[Claude Code]