Skip to content

Instantly share code, notes, and snippets.

@martin-ueding
Last active July 19, 2026 07:51
Show Gist options
  • Select an option

  • Save martin-ueding/7486e882f8a5ae1c0013ebc5f5ece193 to your computer and use it in GitHub Desktop.

Select an option

Save martin-ueding/7486e882f8a5ae1c0013ebc5f5ece193 to your computer and use it in GitHub Desktop.
JTBD Maintenance Tracker

Jobs-to-be-Done — bicycle-maintenance-playground

Reverse-engineered from app/maintenance.py, app/models/database.py, and the templates. Intended as the spec for a SQLAlchemy-based reimplementation inside Geo Activity Playground, not a description of the current code's structure.

Data source dependency

  • JTBD-0: Resolve "which bikes exist and their total distance" by joining equipments/activities in the geo-activity-playground database (equipments.name, SUM(activities.distance_km)). This is the integration seam — in GAP it should become a direct SQLAlchemy relationship/query, not a second SQLite file being cross-joined by raw path.

Repairs & Upgrades ("maintenance" entries) — ad-hoc, one-off log

  • JTBD-1: Log a one-off maintenance/repair/upgrade event for a bike: description, date, odometer km at time of event, cost, optional photo (+ auto-generated thumbnail).
  • JTBD-2: Record an optional "next due" reminder on that same entry (next_due_km and/or next_due_date) — a lightweight ungrouped reminder, separate from the recurring-task system below.
  • JTBD-3: Edit / delete a logged entry, including replacing its photo.
  • JTBD-4: List/filter (by bike) and sort (by any column, asc/desc) all logged entries.

Recurring maintenance tasks — scheduled, interval-based

  • JTBD-5: Define a recurring maintenance task (e.g. "chain lube") assignable to multiple bikes at once, with an interval expressed as days and/or km.
  • JTBD-6: Track per-task-per-bike state: last-done date/km and computed next-check date/km (last + interval).
  • JTBD-7: Mark a task done "now": stamps current date and the bike's current total km as last-done, recomputes next-check, and appends an entry to task history with an optional free-text comment.
  • JTBD-8: View task history (append-only log of completions) per bike+task.
  • JTBD-9: Edit / delete a task definition (delete cascades to its history).
  • JTBD-10: Surface overdue tasks visually (red highlight when next_check_date < today OR next_check_km < current total km) — this is the "what needs attention now" view, functionally the most valuable part.
  • JTBD-11: Filter/sort tasks, grouped by bike.

Cost analytics / statistics

  • JTBD-12: Aggregate and chart maintenance cost by bike (pie), by year (bar), cost-vs-odometer (scatter), and cost flow bike→maintenance-description (Sankey).
  • JTBD-13: Compute summary totals: grand total cost, per-bike total, per-bike-per-year breakdown table.

Admin / settings

  • JTBD-14: Set a currency symbol (global setting, persisted key/value).
  • JTBD-15: Upload a representative photo per bike (+thumbnail), used as an icon throughout the UI.

Cross-cutting

  • JTBD-16: Photo upload with thumbnail generation (Pillow) is reused for maintenance-entry photos and bike photos alike — one concern, two call sites.

Notably absent / not worth preserving as-is

No auth, no multi-user concept, hardcoded absolute path to a sibling project's DB, secret key in source, raw string-built SQL throughout (though parameterized, so not injectable), two near-duplicate route pairs (log_maintenance/track, maintenance/maintenance_log) that look like abandoned iterations rather than distinct features, and statistics.html vs statistics/index.html appear to be duplicate/superseded versions of the same page.

Suggested model split for GAP

  • MaintenanceEntry (JTBD-1..4)
  • MaintenanceTask + TaskHistory (JTBD-5..11)
  • Setting/currency + per-Equipment image field folded into GAP's existing Equipment model rather than a parallel bike_images table.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment