Skip to content

Commit 8cec002

Browse files
authored
Update ROADMAP with v1.5.7 and v1.7 details
Added v1.5.7 and v1.7 updates to the roadmap, detailing new features like the In-App File Viewer and the FIT Pipeline. Included changes to various modules and dependencies, along with pre-conditions for upcoming versions.
1 parent e63bac0 commit 8cec002

1 file changed

Lines changed: 108 additions & 40 deletions

File tree

docs/ROADMAP.md

Lines changed: 108 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,27 @@ in a future version.
149149

150150
---
151151

152+
### v1.5.7 — In-App File Viewer
153+
154+
Third tab in the existing `QTabWidget` structure (Tab 1 "Actions", Tab 2 "Dashboards", Tab 3 "Files"). Renders Excel output directly inside the app via AG Grid Community (MIT licence). JSON output is intentionally excluded — Open Folder in Tab 1 is the intended path for JSON.
155+
156+
**What changes:**
157+
- `garmin_app_base.py` — Tab 3 "Files" added to `QTabWidget`. `QComboBox` lists recent output files from `dashboards/` folder (`.xlsx` only), scanned on tab switch. `QWebEngineView` renders selected file via AG Grid. "Open File" button calls `os.startfile(path)` — opens in whatever the system has registered for `.xlsx` (Excel, LibreOffice, WPS).
158+
- `app/panel_outputs.py` — after a successful dashboard build, Tab 3 file list is refreshed automatically (same pattern as Tab 2 dashboard rescan after build).
159+
160+
**What does not change:**
161+
- Tab 1 and Tab 2 — unchanged
162+
- Dashboard build pipeline — no changes to specialists or plotters
163+
- JSON workflow — Open Folder remains the access path
164+
165+
**Dependencies:**
166+
- AG Grid Community (MIT) — loaded via CDN into QWebEngineView. No new Python package. Requires internet on first load unless bundled locally.
167+
- Offline fallback: if AG Grid fails to load, a plain HTML table is rendered from the XLSX data as fallback.
168+
169+
**Licence:** AG Grid Community is MIT-licenced without restrictions. Handsontable CE is explicitly excluded — Commons Clause makes it incompatible with redistribution.
170+
171+
---
172+
152173
## Planned — v1.6
153174

154175
### v1.6 — Dashboard Render Registry
@@ -264,16 +285,97 @@ A dialog in `panel_outputs.py` that replaces the fixed specialist list with free
264285

265286
## Planned — v1.7
266287

267-
- **Garmin FIT Pipeline & Plugin Architecture**
268-
The existing Garmin Health pipeline is being rebuilt into a plugin model — `garmin_map.py``garmin_health_map.py`, new `garmin_fit_map.py` as a second Garmin source (activity data via API + bulk import). `field_map.py` is being extended to become a source-agnostic broker. Goal: both Garmin sources run as equal pipelines side by side.
288+
### v1.7 — FIT Pipeline
289+
290+
Standalone plugin pipeline for Garmin activity data (.fit files). The existing
291+
Health pipeline is not modified — the FIT pipeline runs as an independent,
292+
parallel pipeline alongside it. Full concept in `docs/KONZEPT_fit_pipeline.md`.
293+
294+
**Architecture:**
295+
- `garmin/fit/` — isolated pipeline: `fit_master.py`, `fit_api.py`, `fit_import.py`,
296+
`fit_parser.py` (stable shell + adapter layer), `fit_normalizer.py`,
297+
`fit_quality.py`, `fit_writer.py`
298+
- `garmin_data/fit/` — own directory: `raw/` (.fit originals), `summary/` (JSON),
299+
`tracks/` (GeoJSON, GPS only on demand), `log/`
300+
- `fit_map.py` — peer broker alongside `field_map.py` and `context_map.py`;
301+
`garmin_fit_map.py` registered beneath it
302+
- Two entry points: Bulk Import (manual .fit files) + Sync (Garmin Connect API)
303+
- Both paths merge at `fit_parser.py` — identical pipeline from there onward
304+
305+
**Quality model:** matrix per activity — `file_integrity`, `session`, `gps`,
306+
`fields`, `duplicate`, `merge_candidate`, `extreme_event`, `event_type`.
307+
Merge candidates flagged silently at import; lazy hint shown when user opens
308+
the activity. No auto-merge — user decides always.
309+
310+
**Documentation:** `docs/MAINTENANCE_FIT.md` and `docs/REFERENCE_FIT.md`
311+
created with first module and maintained in every session that touches FIT modules.
312+
313+
*Pre-condition: PyQt6 migration (v1.5.4) complete for GUI control elements
314+
(Import/Sync buttons in `panel_outputs.py`). Pipeline itself has no blocker.*
315+
316+
---
317+
318+
### v1.7.1 — FIT GUI Integration
269319

270-
*Pre-conditions (resolved before plugin work begins):*
271-
- `garmin_normalizer.py` — add real transformation layer; current pass-through insufficient once two sources deliver differing raw schemas
272-
- `run_import()` — narrow QUALITY_LOCK scope; currently held across entire bulk loop including file writes
320+
Import and Sync control elements for the FIT pipeline added to `panel_outputs.py`.
321+
Steuerungslogik only — no activity view, no dashboards, no map display.
322+
Those follow after PyQt6 migration is stable and the pipeline is proven.
323+
324+
**What changes:**
325+
- `app/panel_outputs.py` — FIT Import button (Bulk), FIT Sync button;
326+
same subprocess pattern, same log window as Health pipeline
327+
- `REFERENCE_GLOBAL.md` — two new ENV variables:
328+
`GARMIN_FIT_IMPORT_PATH` (Bulk Import source folder),
329+
`GARMIN_FIT_SYNC_ENABLED` (FIT Sync on/off, separate from Health Sync)
330+
- `compiler/build_manifest.py` — all new FIT modules added to `SHARED_SCRIPTS`
331+
332+
**What does not change:**
333+
- Health pipeline controls — unchanged
334+
- `garmin_security.py` — existing token reused, no second auth path
335+
- `scheduler/daily_update.py` — FIT Sync path must be fully headless;
336+
no GUI dependency allowed
337+
338+
*Pre-condition: v1.7 FIT Pipeline stable.*
339+
340+
---
341+
342+
### v1.7.2 — Context Integration & Location Fallback
343+
344+
Location-aware context collection extended with GPS data from FIT activities
345+
and a formal state tracking layer (`quality_context.json`).
346+
347+
**Fallback chain (coordinates per day):**
348+
1. GPS start point from .fit (only when GPS track present and bounding box < 50 km)
349+
2. `quality_context.json` (travel block or home)
350+
3. `local_config.csv` (manual)
351+
4. GUI default (home location)
352+
353+
**`quality_context.json` — new module `context_quality.py`**
354+
Single source of truth for which dates were fetched with which coordinates.
355+
Travel entries imported from `local_config.csv` on sync — CSV cleared to
356+
header-only after import. Removing a travel block triggers re-fetch of affected
357+
dates with home coordinates. Sole write authority: `context_quality.py`,
358+
symmetric to `garmin_quality.py`.
359+
Validation at CSV import: multiple travel blocks → hard stop. Overlapping
360+
date ranges → hard stop.
361+
362+
**Extreme Events**
363+
Activity with GPS bounding box > 50 km flagged as `extreme_event: true` in
364+
`fit_quality_log.json`. Two categories:
365+
- Slow (< 50 km/h between any two GPS points) → context pull 1× per hour
366+
- Fast (> 50 km/h between two points) → context pull every 50 km
367+
368+
Context pull runs automatically after merge confirmation (if merge candidate)
369+
or on import. Weather data written directly into activity summary JSON —
370+
not into `context_data/`. Implemented via `activity_context_plugin.py`
371+
(same APIs as context pipeline, output only differs).
372+
Historical data available without time limit (Open-Meteo) — no urgency.
373+
374+
*Pre-condition: v1.7.1 stable. FIT pipeline delivering GPS tracks reliably.*
273375

274376
---
275377

276-
### v1.7.1 — PDF Report
378+
### v1.7.3 — PDF Report
277379

278380
A standalone workflow for generating a formatted health report as PDF — separate from the Create Reports pipeline. Triggered via a dedicated **PDF Report** button in the Outputs section of the GUI (not via the Create Reports dialog, to avoid collision with Daily Update and the existing report workflow).
279381

@@ -294,8 +396,6 @@ A standalone workflow for generating a formatted health report as PDF — separa
294396

295397
**LLM step is fully optional** — report renders completely without it. No API calls, no cloud dependency, no model lock-in. User chooses their own LLM (Open WebUI, ChatGPT, anything).
296398

297-
*Pre-condition: v1.7 FIT Pipeline stable — Activity data available via `field_map.py` broker before PDF Report is built.*
298-
299399
---
300400

301401
### Sync Mode "auto" — Deprecation Candidate
@@ -339,38 +439,6 @@ Prerequisite: v2.0 multi-source architecture stable.
339439
Natural companion to `context_dataformat.json` (schema definition, analogous
340440
to `garmin_dataformat.json`).
341441

342-
**`quality_context.json` — Context Location State Tracking**
343-
344-
Location-aware state tracking for the context pipeline — analogous to
345-
`quality_log.json` for the Garmin pipeline.
346-
347-
Current problem: `context_writer.already_written()` is a file-existence check
348-
only. If a travel period is entered in `local_config.csv` after the affected
349-
days were already downloaded with home coordinates, the next sync silently
350-
skips those days — wrong weather/pollen data remains without any warning.
351-
352-
Concept:
353-
- `quality_context.json` is the single source of truth for which dates were
354-
fetched with which coordinates. Home location is the implicit default for
355-
all dates not explicitly listed.
356-
- Travel entries are written into the JSON from `local_config.csv` on sync.
357-
Each date in a travel block gets a `true`/`false` flag (fetched / pending).
358-
After import, the CSV is cleared back to header-only.
359-
- Removing a travel block from the JSON triggers a re-fetch of the affected
360-
dates with home coordinates (old `/raw/` files deleted first).
361-
- A backup of `quality_context.json` is written before every destructive
362-
operation. Diff between backup and current JSON determines which dates need
363-
correction.
364-
- Validation at CSV import time: multiple travel blocks in one CSV → hard
365-
stop, no import. Overlapping date ranges with existing JSON blocks → hard
366-
stop, no import.
367-
- Home coordinate changes → Schema 2 migration path (not in scope here).
368-
- Sole write authority: new `context_quality.py` module, symmetric to
369-
`garmin_quality.py`. `context_collector.py` remains orchestrator and calls
370-
`context_quality` — it does not write the JSON directly.
371-
372-
---
373-
374442
**context_data/ Backup**
375443

376444
`context_data/` (weather, pollen, air quality, Brightsky) has no backup path and no restore workflow. The mirror covers it when configured, but the mirror is optional and manually triggered. Re-fetching from Open-Meteo is possible but not unlimited for historical ranges. Becomes a must-have once external sources with restricted backfill windows are added (v2.0 multi-source). Trigger: any new source that cannot freely re-fetch its history.

0 commit comments

Comments
 (0)