Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ jobs:
- name: Format
run: ruff format --check .

# The floor is enforced rather than advertised: a number in the README
# goes stale the first time somebody adds a module and forgets, and a
# badge only reports what already happened. Actual coverage is 96%, so
# 90 leaves headroom for a change to be in progress without blocking it.
- name: Test
run: pytest --cov=app --cov-report=term-missing
run: pytest --cov=app --cov-report=term-missing --cov-fail-under=90

migrations:
name: Migrations on PostgreSQL
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
# Activity Hub

[![CI](https://github.com/Danielededo/activity-hub/actions/workflows/ci.yml/badge.svg)](https://github.com/Danielededo/activity-hub/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Python 3.11](https://img.shields.io/badge/Python-3.11-3776AB?logo=python&logoColor=white)](backend/requirements.txt)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.115-009688?logo=fastapi&logoColor=white)](backend/requirements.txt)
[![React 19](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=black)](frontend/package.json)
[![PostgreSQL 16](https://img.shields.io/badge/PostgreSQL-16-4169E1?logo=postgresql&logoColor=white)](docker-compose.yml)

Self-hosted training log. Feed it the FIT, TCX and GPX files your watch or
Strava exports, and get your history back as numbers and charts that stay on
your own machine.

One user, no accounts, no external services, no telemetry. Units are metric
throughout.
throughout. There is no map tile server either: drawing your routes over a
borrowed basemap would mean telling a stranger where you exercise, which is
the opposite of the point.

<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/images/dashboard-dark.png">
Expand Down Expand Up @@ -294,7 +301,7 @@ PostgreSQL.

| Job | What it proves |
| --- | --- |
| Lint and test | `ruff check` and `ruff format` are clean and the backend suite passes |
| Lint and test | `ruff check` and `ruff format` are clean, the backend suite passes, and coverage is at or above 90% — the run fails below it |
| Migrations on PostgreSQL | The schema applies to a real PostgreSQL 16, `alembic check` finds no drift from the models, and the downgrade path works |
| Frontend lint, test and build | ESLint is clean, the jsdom suite passes, and the bundle builds |
| Images and compose stack | Both images build, the stack comes up health-gated, and a profile plus an upload round-trips through the dashboard's own origin |
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/utils/track.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { haversineDistance } from './geo'
* consecutive ones can be hundreds of metres apart quite legitimately, and a
* distance ceiling would throw away real riding at a high stride.
*/
export const IMPLAUSIBLE_SPEED_MS = 120_000 / 3_600
const IMPLAUSIBLE_SPEED_MS = 120_000 / 3_600

/**
* Cumulative metres and seconds along a track, and the speed of each hop.
Expand Down Expand Up @@ -79,7 +79,7 @@ export function distanceSeries(samples) {
}

/** How many points a comparison grid gets. More than any chart has pixels for. */
export const GRID_POINTS = 240
const GRID_POINTS = 240

/**
* Two or more distance series resampled onto one shared grid.
Expand Down
Loading