You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
workouts: JSON keys diverge from CSV headers (startdate vs start, deviceid vs device_id, nested data{} vs flat columns) #27
The prime text documents the JSON shape, so it's intentional in spirit, but the divergence with CSV is significant: a downstream tool can't pick one schema and use it for both. `measurements` and `activity` have only minor unit-suffix differences (distance_m/`distance`, `hr_avg`/`hr_average`); `workouts` is the most divergent.
Expected
Either:
Pick canonical field names per row and use them in both serializers (preferred — flat snake_case with unit suffixes, e.g. `device_id`, `start_epoch`, `category` (string), `category_code` (int)).
Or, document the mapping in `prime` (currently only the JSON shape is documented).
If the intent is to keep raw Withings shape in JSON and mapped/flat shape in CSV, prime should say so explicitly. (#20 covers the same problem for `intraday`.)
Thanks — and noting #20 explicitly in the body saves a triage hop.
Triage:kind:bug · area:format · priority:medium per TRIAGE.md. Same class of CSV/JSON schema drift as #20 (intraday) but with the additional flat-vs-nested wrinkle on workouts.data{}. A decision is needed (flat snake_case both sides vs. document the raw-Withings-shape-in-JSON intent in prime) — flagging that explicitly so the maintainer can pick rather than having triage default it.
So jq '.[].date' returns three different shapes depending on the subcommand.
Counter-evidence worth weighing before treating it as a straight bug: cmd/prime.go documents the choice explicitly ("Times are LOCAL; JSON epoch seconds are zone-agnostic"), so it's deliberate, not an oversight. But it does sit against common/CONTRACT.md §2, which says JSON output preserves RFC3339 with whatever offset Go's default time.Time marshaler emits.
Filing this as a comment rather than a new issue since it overlaps this and #20. Related org-level gap: quantcli/common#27 proposes a contract clause requiring one JSON type per logical field across subcommands, which would make this decidable instead of a judgment call.
Activity
Terastar-Paperclip commentedon May 19, 2026
Thanks — and noting #20 explicitly in the body saves a triage hop.
Triage:
kind:bug·area:format·priority:mediumper TRIAGE.md. Same class of CSV/JSON schema drift as #20 (intraday) but with the additional flat-vs-nested wrinkle onworkouts.data{}. A decision is needed (flat snake_case both sides vs. document the raw-Withings-shape-in-JSON intent inprime) — flagging that explicitly so the maintainer can pick rather than having triage default it.Routing: Lead Go Engineer.
DTTerastar commentedon Jul 21, 2026
Adding a data point from a cross-repo sweep, since it widens this slightly beyond
workouts.The
date/timestamp representation is inconsistent across five subcommands, not just between JSON and CSV in one:cmd/measurements.go:64—Date time.Time→ RFC3339 with offsetcmd/activity.go:16—Date string→"2026-04-15"cmd/sleep.go:21-23,cmd/workouts.go:75-78—StartDate/EndDate int64epoch seconds, plus aDatestringcmd/intraday.go:20—Timestamp int64epoch only (this part is intraday: JSON keys do not match CSV headers (rmssd vs hrv_rmssd, duration vs duration_sec, etc.) #20)So
jq '.[].date'returns three different shapes depending on the subcommand.Counter-evidence worth weighing before treating it as a straight bug:
cmd/prime.godocuments the choice explicitly ("Times are LOCAL; JSON epoch seconds are zone-agnostic"), so it's deliberate, not an oversight. But it does sit againstcommon/CONTRACT.md§2, which says JSON output preserves RFC3339 with whatever offset Go's defaulttime.Timemarshaler emits.Filing this as a comment rather than a new issue since it overlaps this and #20. Related org-level gap: quantcli/common#27 proposes a contract clause requiring one JSON type per logical field across subcommands, which would make this decidable instead of a judgment call.