Files
audi-app/AGENTS.md
T
Paul Nothaft ab2c3db679 Umsetzungsplan mit 13 Phasen anlegen und in AGENTS.md verlinken
Schrittweiser Plan fuer alle offenen Punkte inkl. Abnahmekriterien je
Schritt, Nachschlagereferenz und Definition of Done. Ergaenzt die
Entscheidungen vom 2026-08-11: kein Electron (Capacitor bzw. PWA) und
kein eigenes Backend (HA-API direkt).
2026-08-11 10:39:45 +02:00

15 KiB
Raw Blame History

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 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.

Maintenance rule (binding): whenever you change this repo in a way that affects anything recorded here — completing an open item, making or reversing a decision, adding/removing a component, discovering a new gap — update this file in the same session (tick the checkbox, adjust the status table, bump the "Last updated" date). This file must always be written in English, even though the rest of the project is German.

How this file is loaded: Claude Code does not read AGENTS.md natively; the root CLAUDE.md imports it via @AGENTS.md (official recommended pattern). Other agents (Codex, Cursor, Copilot) read AGENTS.md directly. Edit content here, not in CLAUDE.md.


Working rules

Karpathy guidelines (adopted as project standard)

From multica-ai/andrej-karpathy-skills, behavioral rules derived from Andrej Karpathy's observations on LLM coding failures. They bias toward caution over speed — for trivial tasks, use judgment.

  1. Think before coding. Don't assume. Don't hide confusion. Surface tradeoffs. State assumptions explicitly; if multiple interpretations exist, present them — don't pick silently. If a simpler approach exists, say so. Push back when warranted. If something is unclear, stop and ask.
  2. Simplicity first. Minimum code that solves the problem. Nothing speculative: no features beyond what was asked, no abstractions for single-use code, no unrequested configurability, no error handling for impossible scenarios. If 200 lines could be 50, rewrite.
  3. Surgical changes. Touch only what you must. Don't "improve" adjacent code, comments, or formatting; don't refactor what isn't broken; match existing style. Remove only orphans your change created; mention (don't delete) pre-existing dead code. Every changed line should trace directly to the request.
  4. Goal-driven execution. Define success criteria, loop until verified. "Fix the bug" → write a test that reproduces it, then make it pass. For multi-step tasks, state a brief plan with a verify step per item.

Claude Code practices (current guidance, 2026)

  • Keep this file concise and specific — instructions concrete enough to verify ("run X before Y"), markdown headers/bullets, no dense prose. Context files reduce adherence as they grow; target roughly ≤200 lines of actual instruction.
  • Don't record here what the code or git history already shows (directory dumps, dependency lists) — record pitfalls, rationale, decisions, and conventions that differ from defaults.
  • Conflicting instructions get picked arbitrarily — when updating, remove superseded rules rather than stacking corrections.
  • Verify loading with /context (file must appear under Memory files); edit via /memory.

What this project is

Private replacement for the Audi connect plug & play app (discontinued end of 2026), for exactly one vehicle (Audi RS 4 Avant competition), single user, self-hosted on Home Assistant, access via Tailscale only. Read-only toward the vehicle — no remote control. Covers: vehicle status, trip log, fuel log with Shell receipt parsing, service forecasting, insurance/tax, tire management.

License rule (hard): Audi Type fonts, four-rings SVG, and model-badge SVGs are cleared only for this one private, unpublished installation. Therefore design-system/ is brand-free (it gets uploaded to Claude Design), while the HA panel and the future sideload-only app may use the real assets. Never mix these the other way around.

Reading order for a new session:

  1. This file (overview + open items)
  2. UMSETZUNGSPLAN.md — the step-by-step execution plan for all open items (13 phases with commands and acceptance criteria); when working on an open item, follow the plan's phase
  3. SPECIFICATION.md — authoritative for the HA panel, incl. §7 "Known Gaps"
  4. COMPANION_APP_ARCHITECTURE.md — authoritative for DataMetric360 (decided, barely built)
  5. AUDIT_2026-08-10.md — accessibility/platform audit of the panel (partly done, rest below)
  6. bauauftrag.mdhistorical only; code has diverged (see SPECIFICATION.md §7)

The three projects in this repo

Area What Status
homeassistant/ HA panel (panel_custom): pyscript backend + vanilla-JS frontend finished, in use
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)

Root files: dashboard-muster*.html = original static prototype (superseded, reference only), bauauftrag.md/.html = original build brief (historical), DESIGN_BRIEF_DATAMETRIC360.md = the prompt for the Claude Design project.

homeassistant/ in one paragraph: 10 pyscript scripts + 4 modules (pyscript/modules/); trip detection via the iPhone WLAN sensor with pause tolerance, two-stage trip completion via HA history screening (odometer often updates only on the next trip), fill-up detection on fuel-level rise, Shell PDF parser (data/shell_beleg_parser.py, subprocess, the only tested part of the repo), tire km counter, backup, self-update, image management. Frontend: one file www/audi-dashboard-app.js (3,130 lines, custom element, no framework/bundler), 5 tabs + ~19 detail routes, cache-busting via audi-dashboard-version.json + loader stub. Entity IDs configured centrally in 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.

DataMetric360 architecture (short — details in COMPANION_APP_ARCHITECTURE.md):

  • Future data source: Teltonika FMM003 on the CAN bus, fully replacing the iPhone WLAN sensor and the VAG integration.
  • Current data path (since 2026-08-11): Codec JSON → MQTT/TLS → Mosquitto add-on → HA. Traccar is dropped (the decision log deliberately remains in the architecture doc, marked ÜBERHOLT).
  • Frontend access: HA REST + WebSocket with a long-lived access token (no hass object).
  • External access: Cloudflare Tunnel + reverse proxy with a path allowlist; HA itself stays unreachable. Domain datametric360.app registered (all-inkl, 2026-08-11).
  • Distribution: sideload only (license reason) — hence real Audi assets are allowed there.
  • Trip detection moves to FMM003 ignition; the pause-tolerance feature (fahrten_pausenzeit_min) is a deliberate product decision and must be preserved.

Review findings (2026-08-11)

HA panel — known gaps (most also in SPECIFICATION.md §7)

  • GPS is dead schema: start_lat/lon, addresses, route, avg_speed_kmh never populated. The trip-detail map draws a fabricated line via fakeTrack() (audi-dashboard-app.js:414) — not a real track.
  • No GPS fallback in trip completion: trips without an odometer match stay status="offen" forever (modules/fahrtabschluss_logik.py:16-20).
  • RAM-only state: running trip (_fahrt_start_ts) and fuel low-water-mark (_tiefststand_pct) do not survive an HA restart. Deliberately deferred hardening.
  • Inactive features: BATTERIE_SENSOR = "" (entire battery-history feature is a no-op) and UPDATE_REPO_URL = "" (self-update inactive), both in pyscript/modules/einstellungen.py. www/bilder/ has no vehicle photos (all slots show placeholders); steuer.faellig unset.
  • Robustness: profil_lesen() in modules/profil.py does not handle a missing/corrupt fahrzeugprofil.json — all callers throw.
  • Tests: only the receipt parser is tested (data/tests/test_shell_beleg_parser.py, 10 real receipts) — and its test PDFs are gitignored, so a fresh clone can't run it. Backend and 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)

  • 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; vStat() computes real values from TRIPS/FILLS.
  • INSTALL.md step 4 names variables that no longer exist (DOORS_SENSOR, WINDOWS_SENSOR, LOCK_ENTITY, BATTERY_VOLTAGE_SENSOR) — actual names: TUER_SENSOREN/FENSTER_SENSOREN/ TUERSCHLOSS_SENSOREN/BATTERIE_SENSOR.
  • homeassistant/README.md:110 mentions the removed 97% full-tank rule (removal documented in 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)

  • 🟠 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).
  • Audit's own note: these three may be better done in DataMetric360 than retrofitted — the panel gets replaced anyway.

companion-app / design-system

  • 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.
  • 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).
  • design/ export (2026-08-11) has two known, already-commissioned fixes not yet in the export: shows RS 6 instead of RS 4, and 16 sub-pages the HA panel already has are missing (list in design/README.md).

Open items

Execution order, exact steps, and acceptance criteria for every item below live in UMSETZUNGSPLAN.md (phases 113). Additional decisions of 2026-08-11: no Electron (Capacitor wraps the web app for iPhone; a PWA home-screen install is the accepted intermediate step) and no separate backend (the app talks to the HA REST/WebSocket API directly).

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; then re-export to design/
  • 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/never into design-system/
  • 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 locally under HA /local/, architecture §3)
  • 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)

B) Infrastructure / commissioning (partly waits for FMM003 hardware)

  • Switch datametric360.app nameservers at all-inkl to Cloudflare ("full setup") — prerequisite for the tunnel; domain carries nothing else, so this is consequence-free
  • 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)
  • 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
  • Decide broker reachability for the vehicle: port-forward 8883 vs. VPS broker with Mosquitto bridge over Tailscale
  • Capture the first real Codec JSON message (mosquitto_sub/MQTT Explorer) and build the field mapping from it — do not guess beforehand (explicit decision)
  • Move trip detection to FMM003 ignition (reuse the fahrterkennung.py pattern, keep pause tolerance); then remove sensor.iphone_wifi_connection from einstellungen.py

C) Maintain the existing HA panel (low priority — being replaced)

  • 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
  • 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)

D) Once the panel is superseded

  • Archive audi-dashboard-app.js, don't delete (settled decision, architecture §1)

Working conventions (observed — keep them)

  • German is the project language: identifiers, comments, commits, UI texts. Exceptions: design-system/ uses English props/JSDoc (Claude Design audience) — and this file, which is English by rule.
  • Decisions are logged, including rejected ones (see the Traccar section of the architecture doc); superseded sections stay in place marked "ÜBERHOLT" rather than being deleted.
  • Numbers in de-DE format; font weights 300/400 only, never ≥600 (only those cuts exist).
  • Real vehicle/movement data stays local (data/ contents and receipt PDFs are gitignored).
  • Security principle: HA is never publicly exposed; only narrowly scoped surfaces (MQTT broker, proxy allowlist) may be exposed, each by explicit decision.