Ueberschrittene Servicetermine werden markiert

Wunsch des Eigentuemers: faellige oder ueberschrittene Termine dezent
gelb/orange hinterlegen und mit "ueberschritten" markieren - Service-Seite und
Mein Audi; auf der Uebersicht zusaetzlich die Kennzahl im Warnton.

Erkannt wird am DATUM, nicht an den Restkilometern. Gemessen: die Sensoren
melden -28600 bzw. -22000 bei Faelligkeit 2028 bzw. 2027, negativ heisst hier
also "noch so weit hin". Welches Vorzeichen ein tatsaechlich ueberschrittener
Wert traegt, ist an den vorliegenden Daten nicht beobachtbar - geraten wird es
nicht. Der km-Fall faellt ohnehin unter die Datumsregel: servicePrognose()
setzt datum auf heute, sobald restKm auf 0 laeuft. Der Faelligkeitstag zaehlt
mit ("bereits faellig bzw. ueberschritten").

Dabei eine Luecke im Panel gefunden, vom Test und nicht im Betrieb:
datumAusText() ist verankert und nimmt keine vollen Zeitstempel - die
Fahrzeugmeldung ist aber genau das und bei Oelwechsel und Inspektion die
Hauptquelle. Sie waere still nie als ueberschritten erkannt worden.
zeitstempelAlsDatum() schliesst sie; die App hatte die Luecke nie.

Farbe nach Rolle geteilt wie --bad/--bad-flaeche: --warn ist die Flaeche,
--warn-text die Schrift. Grund: #FF9F0A als Text auf Weiss sind 2.06:1. Auf dem
12% hinterlegten Grund misst --warn-text 4.90:1 (Tag, #A15800) bzw. 9.30:1
(Nacht).

Geprueft: 15 Faelle gegen die echten Panel-Funktionen, 7 in der App, 14
Paritaetsfaelle Panel gegen App, 3 Rendertests ueber alle drei Anzeigestellen.
Gegenprobe: mit ausgehaengter Entscheidung fallen 9 Tests. 327/327, tsc sauber,
Panel als Modul geparst, Manifest und Buendel auf 2026.9.6.6, Container sauber
gestartet.

Offen: optisch nicht gesehen - der Testbestand enthaelt keinen ueberschrittenen
Termin. In OFFEN.md vermerkt.
This commit is contained in:
2026-09-07 13:39:52 +02:00
parent 4d721b6602
commit 27196f9e78
19 changed files with 2874 additions and 2409 deletions
+96 -1
View File
@@ -1,6 +1,6 @@
# AGENTS.md — Project state, review findings, open items, and working rules
**Last updated: 2026-09-06** (Die Batteriehistorie zeichnete stehende Werte als frische Messungen auf - der Vorschlag aus CB war messbar falsch, Abschnitt DI; davor: die ausgelieferte .ipa registriert zwei eigene Plugins nicht, Abschnitt DH). Davor: 2026-09-05, Audit-Durchgang, Abschnitt DC. (Tankstelle zweizeilig und antippbar, die Belegkarte sagt bei
**Last updated: 2026-09-07** (Überschrittene Servicetermine werden markiert, Abschnitt DJ). Davor: 2026-09-06 (Die Batteriehistorie zeichnete stehende Werte als frische Messungen auf - der Vorschlag aus CB war messbar falsch, Abschnitt DI; davor: die ausgelieferte .ipa registriert zwei eigene Plugins nicht, Abschnitt DH). Davor: 2026-09-05, Audit-Durchgang, Abschnitt DC. (Tankstelle zweizeilig und antippbar, die Belegkarte sagt bei
fehlender Position die Wahrheit statt einen toten Knopf zu zeigen, der Regler bekommt einen
Speichern-Knopf, und die Share-Erweiterung trug eine andere Versionsnummer als die App;
dazu die Kopfmarke statt der Firmierung des Betreibers und ein
@@ -12708,3 +12708,98 @@ Daten des Eigentümers, und welche davon bleiben, entscheidet er. Sollte er
später mehr als tageweises Löschen brauchen (mehrere Tage auf einmal, oder eine
Kennzeichnung verdächtiger Einträge), ist das ein eigener Auftrag - heute ist
nichts davon angefragt.
## DJ. Überschrittene Servicetermine werden markiert (2026.9.6.6)
Wunsch des Eigentümers: fällige oder überschrittene Servicetermine hervorheben -
dezent gelb/orange transparent hinterlegt und mit „überschritten" markiert, auf
der Service-Seite und in „Mein Audi"; auf der Übersicht zusätzlich mit der
Kennzahl selbst im Warnton.
### Woran „überschritten" erkannt wird - und woran nicht
**Am Datum, nicht an den Restkilometern.** Das ist keine Bequemlichkeit: die
Kilometerseite trägt je nach Quelle ein anderes Vorzeichen. Am 07.09.2026 an den
echten Sensoren gemessen:
| Sensor | Wert | Fälligkeit laut Datum |
|---|---|---|
| `oil_change_distance` | **-28600** | 2028-07-23 |
| `inspection_distance` | **-22000** | 2027-10-21 |
Negativ heißt hier also „noch so weit hin", nicht „überschritten" - `Math.abs()`
in `meldungsPrognose()` ist damit richtig. Welches Vorzeichen ein *tatsächlich*
überschrittener Fahrzeugwert trägt, ist an den vorliegenden Daten **nicht
beobachtbar**; geraten wird es nicht. Dazu klemmt `servicePrognose()` ihre
Restkilometer ohnehin mit `Math.max(0, ...)`, die Information wäre dort also
auch verworfen.
Das Datum ist eindeutig, und der km-Fall fällt darunter: `servicePrognose()`
setzt `datum` auf **heute**, sobald `restKm` auf 0 läuft. Die Regel lautet
deshalb: **überschritten, sobald das Datum nicht mehr in der Zukunft liegt** -
der Fälligkeitstag selbst zählt mit, denn gefragt war „bereits fällig bzw.
überschritten".
Genommen wird das **erste lesbare** der übergebenen Daten - also das, das an
dieser Stelle auch angezeigt wird. So kann die Markierung nicht von dem
abweichen, was daneben steht.
### Eine Lücke im Panel, die der Test gefangen hat
`datumAusText()` im Panel ist verankert (`^…$`) und nimmt **keine** vollen
Zeitstempel. Die Fahrzeugmeldung (`fm.ts`) ist aber genau das - und bei Ölwechsel
und Inspektion die Hauptquelle. Ohne Korrektur wäre sie stillschweigend nie als
überschritten erkannt worden. Aufgefallen ist das im isolierten Test gegen die
echten Panel-Funktionen, nicht im Betrieb; `zeitstempelAlsDatum()` schließt sie,
bewusst eng gefasst (`/^\d{4}-\d{2}-\d{2}T/`) statt mit einem allgemeinen
`new Date()`, das auch deutete, was `datumAusText()` gerade abgelehnt hat.
Die App hatte diese Lücke nicht: ihr `ISO`-Muster akzeptiert `[T ]` seit jeher.
Damit sind beide Datumsleser jetzt gleich weit.
### Farbe: --warn ist die Fläche, --warn-text die Schrift
Gemessen statt gewählt. `--warn` ist im Tagmodus `#FF9F0A` - als **Text** auf
Weiß sind das **2,06:1**, weit unter der 4,5:1-Grenze, die dieses Projekt sich
selbst gesetzt hat (siehe Abschnitt CP, wo `--fg3` aus demselben Grund
abgedunkelt wurde). Deshalb dieselbe Rollenteilung wie bei `--bad` /
`--bad-flaeche`:
| | Fläche (12 % hinterlegt) | Schrift `--warn-text` | Kontrast auf dem hinterlegten Grund |
|---|---|---|---|
| Tag | `#FF9F0A` → Grund `#FFF3E2` | **`#A15800`** | **4,90:1** |
| Nacht | `#FFD60A` → Grund `#33311E` | `#FFD60A` | **9,30:1** |
Nachts trägt `--warn` selbst genug Kontrast, tagsüber nicht. `#B36200` wäre
näher am reinen Orange, fällt auf dem hinterlegten Grund aber auf 4,11:1 und
damit unter die Grenze - deshalb `#A15800`.
### Geprüft
* **15 Fälle** gegen die echten Panel-Funktionen (aus der Panel-Quelle
geschnitten, nicht nachgebaut), darunter beide Zeitstempel-Richtungen und die
Tagesgrenze.
* **7 Fälle** in `service.test.ts` für die App; gegengeprüft, dass die
Tagesgrenze wirklich gemessen wird (`<=` auf `<` gedreht → genau der
„heute zählt mit"-Test fällt).
* **14 Paritätsfälle** in `paritaet_ueberschritten.test.ts`: Panel und App
urteilen über dieselben Eingaben gleich, geprüft gegen die aus der Panel-Quelle
geschnittene Funktion.
* **3 Rendertests** über alle drei Anzeigestellen, mit einem Profil, dessen
Hauptuntersuchung in der Vergangenheit liegt. Der Regelbestand der
Beispieldaten taugte dafür nicht (Wartungsplan 2026-02-10 + 24 Monate);
`beispielApi()` nimmt dafür jetzt ein abweichendes Profil entgegen - additiv,
alle bisherigen Aufrufer unverändert.
* Gegenprobe über alles: mit ausgehängter Entscheidung (`terminUeberschritten`
liefert immer `false`) fallen **9 Tests**, darunter alle drei Rendertests.
* 327/327 App-Tests, `tsc` sauber, beide Panel-Dateien als **Modul** geparst,
Manifest und Bündel gleichauf auf `2026.9.6.6`, Testcontainer sauber gestartet.
### Was offen bleibt
**Optisch nicht gesehen.** Die Markierung ist über Rendertests und gemessene
Kontraste belegt, nicht über ein Bild - der Testbestand enthält keinen
überschrittenen Termin (Ölwechsel 2028, Inspektion 2027, HU 2028), und für einen
Blick ins laufende Panel fehlte die angemeldete Sitzung. Nach der Regel dieses
Projekts (Abschnitt S: ein sauberer Testlauf beweist kein Layout) steht das
ausdrücklich als offen, nicht als erledigt.