Commit Graph

5 Commits

Author SHA1 Message Date
431315bac3 refactor(log): replace stdlib log with the application JSON logger
Every log.Printf/Fatalf becomes a structured slog call through
internal/log: request handlers use the request-scoped logger
(applog.FromContext, carrying request_id), startup failures exit via a
fatal() helper that still emits JSON, and the seedsample/dumpschema CLIs
bootstrap the same JSON logger. Stale client_test expectations aligned
with the refactored wrapper-call logging (message casing, result attr,
ERROR level).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 16:33:26 +02:00
e2b2bf9611 refactor: merge internal/sync into internal/garmin, regroup api files and routes
Garmin auth/sync routes move under /api/garmin/*; sync.Service becomes
garmin.Sync with garmin.SyncConfig/ClientConfig; applog becomes
internal/log; the test mock moves into the garmin package as MockClient
(breaking the test-only import cycle the merge created); stale test
URLs and type names updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 16:04:18 +02:00
a12fe3e810 fix(api): stop promoting the ephemeral Garmin client after setup completes
handleSetupComplete reused the onboarding client object as-is in the
permanent per-user cache, but its garmin.Config.TokenStorePath was fixed
at construction to the ephemeral setup/{hash} directory and never
corrected after that directory was renamed to the permanent {userID}
path. The next respawn of that same client (e.g. any Profile-page save,
which unconditionally calls UpdateCredentials) wrote a fresh token file
back under setup/{hash}, forcing a real re-login/MFA on the next Garmin
connect even though a valid session already existed under {userID}.

Close the ephemeral client instead and let the next garminFor call build
a fresh one against the correct, already-renamed directory.
2026-07-26 21:23:24 +02:00
7d68af5b3c feat(api): defer account creation until Garmin actually connects 2026-07-26 13:30:51 +02:00
4dceb03fc0 api: add user-resolution middleware and POST /api/setup
resolveUser attaches the session's provisioned geniusrun user (if any) to
request context without blocking; requireProvisionedUser (wired fully in
Task 13) 403s routes that need one. GET /api/session/me now reports
has_profile/display_name so the frontend can show the setup screen.
2026-07-25 17:55:13 +02:00