Repository navigation
v3.0.0
API-backed React dashboard, deployed to Vercel (API mode) and GitHub Pages
(static mode) from the same source.
Added
- Deployment:
vercel.json,requirements.txtandscripts/vercel-build.sh
run the export at build time and serve the React app in API mode with
api/graphql.pyas a Python serverless function; the GitHub Pages
workflow now builds the React app in static mode under/<repo>/with a
404.htmlfallback for deep links. - React views: Overview (KPIs, daily-distance heatmap, monthly distance and
pace, recent runs, personal bests, training load, weight vs distance,
temperature vs pace, weather strip), Activity (pace-coloured Canvas route
with playback, scrubbing and hover, synced elevation / pace / cadence /
temperature charts, previous / next navigation, keyboard shortcuts) and
Activities (filter, sort, CSV export), Year in Review (infographic with
hours-per-month stairs, diamond-per-day grid, weight summary),
Performance (KPIs, pace trend, distance histogram, weekday and
time-of-day pace, cadence vs pace, monthly table), Weight (KPIs, daily and
7-day average, monthly change, weekday change, weekly km vs change,
up/down table), Weather Impact (KPIs, HKO range, sky conditions,
temperature bands, humidity vs pace, warning and extremes tables),
Training Load (CTL/ATL/TSB, weekly distance with 4-week average and week
drill-down, weekday distance, biggest weeks) and Settings (preferences
form, data summary). All nine v2 views now have React equivalents. HKO
warning icons and the v2 preferences store (localStorage) are ported. frontend/: Vite + React 19 + TypeScript scaffold for the v3 dashboard
with aDataSourceabstraction (GraphQL via graphql-request + Codegen,
or static JSON), TanStack Query hooks, a TypeScript port of the year
statistics, Tailwind CSS 4 theme tokens from v2, the nine-view shell and
the Overview KPI row; 35 Vitest tests; CI job for lint, typecheck, tests
and both builds.run365-schema: prints the GraphQL SDL; CI checks
frontend/schema.graphqlis current.run365days.api: Flask application factory with a Strawberry GraphQL
schema (meta,activities,activity,weight,weather,
warnings,yearaggregates) served at/api/graphql, reading the
exported SQLite database read-only;api/graphql.pyis the Vercel entry.run365days.dashboard.stats: pure year aggregations (totals, monthly,
weekly, daily distance, training load, personal bests).run365days.export: one intermediate record set written two ways by
run365-export, a SQLite database (SQLAlchemy 2.0 models) for the API
and split JSON files for the static dashboard build.run365days.cliconsole scripts:run365-activities,run365-weather,
run365-dashboard,run365-export.RUN365_DATA_DIRenvironment variable to relocate the data directory.- Google-style docstrings on every public module, class and function,
enforced by ruff's pydocstyle rules. .pre-commit-config.yamlrunning ruff lint and format.- A lint-and-test job in GitHub Actions that gates the Pages deployment and
also runs on pull requests. - Garmin activity summaries, daily wellness summaries and sleep data for the
challenge period underdata/raw/garmin/. - MIT licence with a personal-data exclusion for
data/. docs/with architecture, data-pipeline, deployment, changelog and
roadmap pages.- "Tag release" workflow (
workflow_dispatch) that creates an annotated
tag and a GitHub Release with notes taken from this changelog.
Changed
- Package moved to
src/at the repository root (withtests/and
pyproject.tomlbeside it) and reorganised by feature
(activities,weather,weight,dashboard,common,cli) instead
of by layer (models,parsers,collectors,analysis,export). - Raw data moved under
data/raw/{garmin,weather,weight}/with snake_case
file names; generated files go to git-ignoreddata/processed/. - The dashboard page now lives at
src/dashboard/static/index.html
and GitHub Pages publishes that folder. - Code formatted with ruff (line length 100, modern typing syntax).
- README rewritten as a full engineering guide.
Removed
- The v2 static page (
src/dashboard/static/index.html), the
run365-dashboardCLI and thedata.jspayload functions
(build_payload,payload_to_js,write_data_js,inline_data); the
React app has reached parity with all nine views. - The original Garmin account export folder (profile, consent history,
social data, golf, Connect IQ, pre-2021 records, raw FIT bundle). Earlier
tags still contain it; see the privacy note in the README. - Generated JSON that had been committed (
run365_*_data.json,
DailyWeightExtract.json). - The empty
run365days.vizpackage.
Fixed
- Vercel deployment: invalid
runtimekey, PEP 668 pip refusal (uv venv),
export anchored to the checkout viaRUN365_DATA_DIR, function bundle
size (venv under/tmp,excludeFiles), Flask missing at runtime
(extras are not installed, so Flask and Strawberry became core
dependencies) and the module-levelappassignment Vercel's function
detection requires. Seedocs/deployment.md. run365-activitiesfailed withTypeError: Object of type int64 is not JSON serializablebecause the coordinate-distance helper returns a numpy
integer segment count.
Deprecated
- The v1 scripts are parked in
legacy/for reference and will be deleted
oncedevelopreaches feature parity.