Parity-Regel: Uebersicht-Service-Block in companion-app portiert
Nutzer stellte klar: Panel und companion-app sollen immer denselben
funktionalen Stand haben, auch wenn eine Anfrage nur das Panel nennt -
das ist reiner Testkomfort (Docker-Instanz laesst sich am schnellsten
ansehen), keine Scope-Entscheidung. Regel als verbindlicher Absatz in
AGENTS.md verankert, direkt unter der bestehenden Maintenance-Regel.
Erste Anwendung im selben Zug: die eben im Panel gebaute
"Naechster Service"-Kachel nach companion-app/ portiert.
- daten/service.ts: neues naechsterService() als Gegenstueck zu
naechsterTermin() im Panel - waehlt ueber Oelwechsel-/Inspektions-
Prognose und die von Hand gepflegte Hauptuntersuchung hinweg den
zeitlich naechsten Termin. bisText() liefert denselben Artikel wie
ART_BIS im Panel ("bis zum Oelwechsel" / "bis zur Inspektion").
- screens/Uebersicht.tsx: die bisherigen Kacheln "Reichweite"/
"Kilometerstand" nebeneinander plus eine separate "Service"-Kachel
mit Werteliste weichen einer Reichweiten-Kachel plus einer
Service-Kachel mit .dm-serviceblock (Knopf, nur der obere Teil) und
.dm-servicezeile (reine Anzeige) darunter - dieselbe Control/Content-
Trennung wie im Panel.
- stile/screens.css: .dm-serviceblock/.dm-servicezeile ergaenzt.
Tests: 4 neue in service.test.ts (naechsterService waehlt das frueher
faellige Datum, nimmt die Hauptuntersuchung auf, liefert nichts ohne
Servicebuch/HU, bisText-Artikel je Art), 1 neuer in screens.test.tsx,
der mit einem vi.fn() als geheZu wirklich belegt, dass ein Klick auf
den Serviceblock navigiert und ein Klick auf die Kilometerstand-Zeile
es nicht tut - dafuer bekam zeige() in screens.test.tsx erst einen
injizierbaren geheZu-Parameter (vorher hart auf () => {} verdrahtet).
npm run typecheck sauber, npm run test 100/100 (von 95), npm run build
erfolgreich.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest"
|
||||
|
||||
import { inspektionPrognose, letzterOelwechsel, oelwechselPrognose } from "./service"
|
||||
import { bisText, inspektionPrognose, letzterOelwechsel, naechsterService, oelwechselPrognose } from "./service"
|
||||
import type { Fahrzeug } from "./profilAdapter"
|
||||
|
||||
function fahrzeug(odo: number, modus = "hersteller"): Fahrzeug {
|
||||
@@ -112,3 +112,40 @@ describe("inspektionPrognose", () => {
|
||||
expect(inspektionPrognose(fahrzeug(46000), [], jetzt)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe("naechsterService", () => {
|
||||
const jetzt = new Date("2026-08-11T12:00:00")
|
||||
|
||||
it("wählt über Ölwechsel und Inspektion hinweg das zeitlich frühere Datum", () => {
|
||||
// Beide unabhängig mit derselben Formel berechnet, statt ein erwartetes
|
||||
// Datum von Hand vorzurechnen - so bleibt der Test robust gegen spätere
|
||||
// Änderungen an den Intervallen, prüft aber trotzdem die Auswahllogik.
|
||||
const oel = oelwechselPrognose(fahrzeug(46000), BUCH, jetzt)
|
||||
const insp = inspektionPrognose(fahrzeug(46000), BUCH, jetzt)
|
||||
const erwarteteArt = oel!.datum <= insp!.datum ? "Ölwechsel" : "Inspektion"
|
||||
|
||||
const s = naechsterService(fahrzeug(46000), BUCH, jetzt)
|
||||
expect(s).not.toBeNull()
|
||||
expect(s!.art).toBe(erwarteteArt)
|
||||
expect(s!.datum).toBe(erwarteteArt === "Ölwechsel" ? oel!.datum : insp!.datum)
|
||||
})
|
||||
|
||||
it("nimmt die Hauptuntersuchung auf, obwohl sie keine eigene Prognose hat", () => {
|
||||
const f = { ...fahrzeug(46000), hu: "2026-09-01" }
|
||||
const s = naechsterService(f, [], jetzt)
|
||||
expect(s).not.toBeNull()
|
||||
expect(s!.art).toBe("Hauptuntersuchung")
|
||||
expect(s!.restKm).toBeNull()
|
||||
expect(s!.datum).toBe("2026-09-01")
|
||||
})
|
||||
|
||||
it("liefert nichts ohne Servicebuch und ohne gepflegte Hauptuntersuchung", () => {
|
||||
expect(naechsterService(fahrzeug(46000), [], jetzt)).toBeNull()
|
||||
})
|
||||
|
||||
it("bisText nennt den richtigen Artikel je Art", () => {
|
||||
expect(bisText("Ölwechsel")).toBe("bis zum Ölwechsel")
|
||||
expect(bisText("Inspektion")).toBe("bis zur Inspektion")
|
||||
expect(bisText("Hauptuntersuchung")).toBe("bis zur Hauptuntersuchung")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user