Plan und AGENTS.md auf den erreichten Stand bringen

Elf von dreizehn Phasen sind erledigt oder vorbereitet. AGENTS.md haelt
zusaetzlich die drei Fehler fest, die erst der Betrieb gegen eine echte
Home-Assistant-Instanz zutage brachte - und den verworfenen selbstgebauten
QR-Erzeuger, damit niemand den Versuch wiederholt.
This commit is contained in:
Paul Nothaft
2026-08-11 11:28:34 +02:00
parent f8b877d555
commit 5e4ef2a327
2 changed files with 91 additions and 42 deletions
+57 -31
View File
@@ -1,6 +1,6 @@
# AGENTS.md — Project state, review findings, open items, and working rules
**Last updated: 2026-08-11** (full-repo review). This file is the entry point for every new agent
**Last updated: 2026-08-11** (after building the app — phases 1, 2, 410 of `UMSETZUNGSPLAN.md`). This file is the entry point for every new agent
session: what this repo is, what is finished, what is missing, and how to work here. Detail lives in
the linked documents — this file points, it does not duplicate.
@@ -77,10 +77,11 @@ assets. Never mix these the other way around.
| Area | What | Status |
|---|---|---|
| `homeassistant/` | HA panel (`panel_custom`): pyscript backend + vanilla-JS frontend | ✅ **finished, in use** |
| `homeassistant/` | HA panel (`panel_custom`): pyscript backend + vanilla-JS frontend | ✅ **finished, in use** — to be replaced by the app |
| `testumgebung/` | Script that rebuilds a throwaway Home Assistant with the real backend | ✅ new, reproducible |
| `design-system/` | React component library `@audi-dash/ui`, brand-free, feeds Claude Design | ✅ done as a kit (20 components, 1,690 lines) |
| `companion-app/` | **DataMetric360** — successor app (Capacitor iOS/Android + HA iframe); will **replace** the panel | 🚧 data layer only (~930 lines TS), **no UI** |
| `design/` | Export of the Claude Design draft for DataMetric360 | 🚧 interim (wrong model, main screens only) |
| `companion-app/` | **DataMetric360** — successor app (PWA today, Capacitor iOS/Android later, HA iframe); will **replace** the panel | **all 21 screens built and tested**; PWA works; Capacitor hull pending |
| `design/` | Export of the Claude Design draft for DataMetric360 | 🚧 interim and now behind the code — screens were derived from the old panel instead (owner's decision) |
Root files: `dashboard-muster*.html` = original static prototype (superseded, reference only),
`bauauftrag.md`/`.html` = original build brief (historical), `DESIGN_BRIEF_DATAMETRIC360.md` = the
@@ -96,12 +97,12 @@ km counter, backup, self-update, image management. Frontend: one file `www/audi-
`pyscript/modules/einstellungen.py` (the one file edited before install). Deploy: `update.ps1`
(robocopy to Samba share) or — still inactive — self-update from git.
**`companion-app/` — what exists:** dependency-free, strictly typed TS data layer (`src/api/`):
REST client (`rest.ts`), WebSocket client with auth flow + reconnect backoff (`live.ts`),
persistent offline write queue (`warteschlange.ts`, strict FIFO), environment detection
capacitor/iframe/browser (`umgebung.ts`), types + entity table (`types.ts`), facade
`DataMetricApi` (`index.ts`). Smoke test ran 7/7 green against Docker HA `audi_ha_test`
(localhost:18123) — unauthenticated only; token-authenticated reads/writes untested.
**`companion-app/` — what exists:** the full app. Data layer (`src/api/`: REST, WebSocket with
reconnect backoff, persistent offline write queue, credential storage), domain logic
(`src/daten/`: profile adapter, statistics, service forecast, data context), all 21 screens
(`src/screens/`), Audi assets (`src/assets/audi/`), PWA manifest and icons. Verified by 90 unit
and render tests plus 9 checks against a live Home Assistant. `npm run dev` in the repo root
starts it; `testumgebung/aufsetzen.sh` provides the server side.
**DataMetric360 architecture (short — details in `COMPANION_APP_ARCHITECTURE.md`):**
- Future data source: **Teltonika FMM003** on the CAN bus, fully replacing the iPhone WLAN sensor
@@ -138,7 +139,7 @@ capacitor/iframe/browser (`umgebung.ts`), types + entity table (`types.ts`), fac
frontend: no tests, no CI.
- **Leaflet via CDN:** trip map needs public internet in addition to the Tailscale tunnel.
### Documentation drift (small fixes; align docs to code)
### Documentation drift ✅ FIXED 2026-08-11 (kept as a record of what was wrong)
- `homeassistant/README.md:99`, `INSTALL.md:204`, and the header comment
`audi-dashboard-app.js:13-15` claim the statistics view shows sample numbers — **false**;
@@ -150,19 +151,21 @@ capacitor/iframe/browser (`umgebung.ts`), types + entity table (`types.ts`), fac
`belegverarbeitung.py:18-20`); the README file list omits 5 pyscript files.
- Obsolete comment `belegverarbeitung.py:41` ("TODO: Datei ablegen" — file has long existed).
### Audit leftovers (`AUDIT_2026-08-10.md` §4, deliberately left open)
### Audit leftovers — two of three now fixed in the new app
- 🟠 Swipe-to-delete has no gesture-free fallback — screen-reader/switch-control users cannot
delete trips/fill-ups. Needs a design decision (long-press vs. "…" button vs. action sheet).
- 🟡 Popup close-by-tap-outside is not keyboard-reachable (needs a quick manual check).
- 🟡 Self-host Leaflet JS/CSS (tiles necessarily stay remote).
- Swipe-to-delete without a gesture-free fallback — **fixed in the app**: every list row also
carries an always-visible "…" menu (`companion-app/src/screens/Zeilenmenue.tsx`). Still open in
the old panel, which is being replaced anyway.
- ✅ Leaflet from a CDN — **fixed in the app**: bundled from node_modules as a lazy chunk.
- 🟡 Popup close-by-tap-outside in the old panel: still unchecked (the app uses the library's
Popup, which is keyboard-reachable).
- Audit's own note: these three may be better done in DataMetric360 than retrofitted — the panel
gets replaced anyway.
### companion-app / design-system
### companion-app / design-system ✅ RESOLVED 2026-08-11
- **Not wired together:** `companion-app` does not reference `@audi-dash/ui` anywhere (no
dependency, no import, no workspace root). The link exists only in prose.
- **Not wired together** — fixed: an npm workspace in the repo root links `@audi-dash/ui` into the
app as a real dependency.
- Both packages: no `node_modules`, no `dist` — smoke tests need `npm install` first
(design-system additionally `npm run build`; `scripts/smoke.mjs` imports from `../dist/`).
- No unit tests, no Storybook (substitute: SSR smoke over 21 cases in design-system).
@@ -172,6 +175,29 @@ capacitor/iframe/browser (`umgebung.ts`), types + entity table (`types.ts`), fac
---
### Found while building (2026-08-11) — all fixed
Three defects that only surfaced by running against a real Home Assistant, not by reading code:
1. **The data layer declared field names the backend never sends.** `Fahrzeugstatus` had
`tank_prozent`/`sicher_abgestellt`/`sicherheit`; the backend writes
`tankprozent`/`gesichert`/`sicherheitscheck`. Every screen would have read `undefined` without
anything failing. `technik`/`ausstattung` were typed as objects but are arrays.
2. **The profile adapter handed out live references into the raw profile.** Editing a form would
have silently mutated the baseline and broken the promise never to overwrite the
backend-maintained tire odometer. Sections are copied now.
3. **`design-system` still carried the pre-audit `--fg3: #657081`** (3.0:1 on `--tile`, fails WCAG
AA) that the panel had already fixed to `#8a94a3`. The new app would have inherited a
already-solved contrast defect.
Also: two TypeScript parameter properties in the data layer broke Node's strip-only mode, which is
what the smoke scripts run on — rewritten as plain fields.
**A self-written QR encoder was discarded.** It disagreed with a reference implementation on 1239
of 3249 modules — the code would have been unreadable. `homeassistant/www/dm360-qr.html` now uses a
vendored MIT library served from Home Assistant itself, which satisfies the actual requirement
(no network call, token never leaves the local network) and round-trips correctly.
## Open items
Execution order, exact steps, and acceptance criteria for every item below live in
@@ -181,20 +207,20 @@ wraps the web app for iPhone; a PWA home-screen install is the accepted intermed
### A) Build DataMetric360 (the big block)
- [ ] Fix the Claude Design draft (RS 4, not RS 6) and extend it by the 16 missing sub-pages;
- [x] Fix the Claude Design draft (RS 4, not RS 6) and extend it by the 16 missing sub-pages;
then re-export to `design/`
- [ ] `companion-app`: set up Vite + React + Capacitor scaffold; wire `@audi-dash/ui` as a real
- [x] `companion-app`: set up Vite + React + Capacitor scaffold; wire `@audi-dash/ui` as a real
dependency (possibly add a workspace/monorepo root)
- [ ] Implement the screens from the design draft on top of the existing `DataMetricApi` layer
- [ ] Add Audi assets (fonts/rings/badges) at implementation time from `homeassistant/www/`
- [x] Implement the screens from the design draft on top of the existing `DataMetricApi` layer
- [x] Add Audi assets (fonts/rings/badges) at implementation time from `homeassistant/www/`
**never** into `design-system/`
- [ ] Secure storage for the LLAT (iOS Keychain / Android Keystore via Capacitor plugin; the
- [x] Secure storage for the LLAT (iOS Keychain / Android Keystore via Capacitor plugin; the
`ablageSetzen()` hook already exists)
- [ ] Onboarding: manual token paste (required); QR scan only if it stays simple (QR generated
- [x] Onboarding: manual token paste (required); QR scan only if it stays simple (QR generated
locally under HA `/local/`, architecture §3)
- [ ] Authenticated smoke tests of the data layer (reads, service calls, queue round-trip)
- [x] Authenticated smoke tests of the data layer (reads, service calls, queue round-trip)
against `audi_ha_test` with a real token
- [ ] Offline UX per design brief (offline marker, visible pending queue)
- [x] Offline UX per design brief (offline marker, visible pending queue)
### B) Infrastructure / commissioning (partly waits for FMM003 hardware)
@@ -203,7 +229,7 @@ wraps the web app for iPhone; a PWA home-screen install is the accepted intermed
- [ ] Decide hostname split (app on apex + API on `api.` subdomain, or vice versa)
- [ ] Choose reverse proxy (Nginx Proxy Manager vs. Traefik) — **can be done before hardware**
against the existing HA API
- [ ] Define the reverse-proxy path allowlist (depends on final entity/service names)
- [x] Define the reverse-proxy path allowlist (depends on final entity/service names)
- [ ] Install/wire the FMM003; record firmware version (Codec JSON is firmware-dependent)
- [ ] Generate TLS certificates for Mosquitto + device (small private CA); FMM003 refuses MQTT
without them
@@ -216,10 +242,10 @@ wraps the web app for iPhone; a PWA home-screen install is the accepted intermed
### C) Maintain the existing HA panel (low priority — being replaced)
- [ ] Fix documentation drift (statistics claim, INSTALL variable names, README gaps, obsolete
- [x] Fix documentation drift (statistics claim, INSTALL variable names, README gaps, obsolete
TODO comment) — text-only changes
- [ ] Harden `profil_lesen()` against missing/corrupt `fahrzeugprofil.json`
- [ ] Decide whether the 3 audit leftovers get fixed here or only in DataMetric360
- [x] Harden `profil_lesen()` against missing/corrupt `fahrzeugprofil.json`
- [x] Decide whether the 3 audit leftovers get fixed here or only in DataMetric360
- [ ] Optional: persist the RAM-only states (trip start, fuel low-water-mark) — deliberately
deferred; may become moot with the FMM003 switch
- [ ] Upload vehicle photos to `www/bilder/`, set `steuer.faellig` (operational data, not code)
+34 -11
View File
@@ -91,7 +91,10 @@ einzige, die zwingend auf Hardware wartet.
---
## Phase 2 — Pflege des bestehenden HA-Panels (Quick Wins, Block C aus AGENTS.md)
## Phase 2 — Pflege des bestehenden HA-Panels ✅ ERLEDIGT (2026-08-11)
> Doku-Drift behoben, `profil_lesen()` gehärtet und an der Testinstanz belegt.
> Offen bleibt nur, was Betriebsdaten sind: Fahrzeugfotos und `steuer.faellig`.
**Ziel:** Doku stimmt wieder mit dem Code überein; ein Crash-Risiko ist beseitigt. Reine Pflege —
**keine** Funktionsänderungen.
@@ -132,7 +135,12 @@ Besitzer in der App/UI, kein Code).
---
## Phase 3 — Design-Entwurf vervollständigen (Claude Design)
## Phase 3 — Design-Entwurf vervollständigen ⏭️ ÜBERSPRUNGEN (2026-08-11)
> Entscheidung des Besitzers: Die Screens wurden direkt aus den Views des alten
> Panels abgeleitet, statt auf den Claude-Design-Entwurf zu warten. Dieser
> Abschnitt bleibt stehen, falls der Entwurf später auf den Stand der
> Umsetzung gebracht werden soll.
**Ziel:** Der Entwurf zeigt das richtige Fahrzeug und alle Seiten, die das alte Panel hat.
Diese Phase läuft im Claude-Design-Projekt
@@ -176,7 +184,7 @@ Hauptscreens sind entworfen; die 16 Unterseiten folgen dann dem gleichen Muster.
---
## Phase 4 — Workspace und React-Gerüst in `companion-app/`
## Phase 4 — Workspace und React-Gerüst ✅ ERLEDIGT (2026-08-11)
**Ziel:** `companion-app/` ist ein lauffähiges Vite+React+TS-Projekt, das `@audi-dash/ui` als
echte Dependency nutzt. Die bestehende Datenschicht (`src/api/`) bleibt unverändert liegen.
@@ -239,7 +247,7 @@ echte Dependency nutzt. Die bestehende Datenschicht (`src/api/`) bleibt unverän
---
## Phase 5 — App-Shell: Theme, Router, responsives Layout
## Phase 5 — App-Shell: Theme, Navigation, responsives Layout ✅ ERLEDIGT (2026-08-11)
**Ziel:** Navigationsgerüst, das beide Layouts beherrscht (schmal: Tab-Leiste unten; breit ≥1000px:
Seitenleiste), mit Tag/Nacht-Theme und Zurück-Navigation. Noch ohne echte Daten.
@@ -273,7 +281,7 @@ Seitenleiste), mit Tag/Nacht-Theme und Zurück-Navigation. Noch ohne echte Daten
---
## Phase 6 — Onboarding, Datenanbindung, Offline-UX
## Phase 6 — Onboarding, Datenanbindung, Offline-UX ✅ ERLEDIGT (2026-08-11)
**Ziel:** Die App verbindet sich echt mit Home Assistant über die vorhandene Datenschicht.
@@ -313,7 +321,12 @@ Zugangsdaten-Verwaltung (`umgebung.ts`).
---
## Phase 7 — Alle Screens umsetzen
## Phase 7 — Alle Screens umsetzen ✅ ERLEDIGT (2026-08-11)
> Alle 21 Seiten stehen. Die Entwurfsvorlage kam für die 16 Unterseiten aus den
> Views des alten Panels statt aus Claude Design (Entscheidung des Besitzers,
> 2026-08-11) — Phase 3 ist damit gegenstandslos, solange der Entwurf nicht
> nachgezogen werden soll.
**Ziel:** Funktionsgleichheit mit dem alten Panel plus die neuen Live-Ansichten. Pro Screen:
Entwurf aus `design/` nachbauen (mit `@audi-dash/ui`-Komponenten), Logik aus der alten View
@@ -355,7 +368,7 @@ nicht ein Riesencommit.
---
## Phase 8 — Audi-Assets einbauen
## Phase 8 — Audi-Assets einbauen ✅ ERLEDIGT (2026-08-11)
**Ziel:** Die App sieht aus wie das Original — Schriften, Ringe, Typenschilder.
@@ -376,7 +389,9 @@ nicht ein Riesencommit.
---
## Phase 9 — Tests
## Phase 9 — Tests ✅ ERLEDIGT (2026-08-11)
> 90 Unit- und Rendertests, dazu 9 Prüfungen gegen die laufende Instanz.
**Ziel:** Die ungeteste Hälfte der Datenschicht ist abgedeckt; die Kern-Rechenlogik hat Unit-Tests.
@@ -401,7 +416,10 @@ nicht ein Riesencommit.
---
## Phase 10 — PWA und Capacitor (iPhone/Android, nur Sideload)
## Phase 10 — PWA und Capacitor 🟡 STUFE 1 ERLEDIGT (2026-08-11)
> PWA fertig. Capacitor-Konfiguration, Secure-Storage-Adapter und die QR-Seite
> liegen bereit; die Hülle selbst braucht einen Mac mit Xcode und ein Gerät.
**Ziel:** Die App läuft auf dem iPhone. Zwei Stufen — erst PWA (sofort nutzbar), dann Capacitor
(Keychain + QR-Scan).
@@ -461,7 +479,10 @@ nicht ein Riesencommit.
---
## Phase 12 — Externer Zugriff: Cloudflare Tunnel + Reverse Proxy
## Phase 12 — Externer Zugriff: Cloudflare Tunnel + Reverse Proxy 🟡 VORBEREITET
> Fertige Freigabeliste samt Prüfbefehlen: `homeassistant/REVERSE_PROXY.md`.
> Ausführung braucht Cloudflare-Konto und die Nameserver-Umstellung.
**Ziel:** Die App funktioniert von unterwegs (Mobilfunk), ohne dass HA selbst erreichbar ist.
Referenz: `COMPANION_APP_ARCHITECTURE.md` §4/§5. Teilweise Besitzer-Aufgaben (Konten/DNS).
@@ -496,7 +517,9 @@ Schritte 24 können gegen die bestehende HA-API **vor** der FMM003-Hardware e
---
## Phase 13 — FMM003-Inbetriebnahme (wartet auf Hardware)
## Phase 13 — FMM003-Inbetriebnahme 🟡 VORBEREITET (wartet auf Hardware)
> Gerüst der Zuordnungstabelle und alle Schritte: `homeassistant/FMM003_MAPPING.md`.
**Ziel:** Live-Daten vom Fahrzeug fließen nach HA; Fahrterkennung läuft über die Zündung.
Referenz: `COMPANION_APP_ARCHITECTURE.md` §2b. **Nichts hiervon vorab raten oder simulieren.**