diff --git a/felsokning/app/src/felsokning/__tests__/slutsats.test.ts b/felsokning/app/src/felsokning/__tests__/slutsats.test.ts index 8b4f135..ea76ec1 100644 --- a/felsokning/app/src/felsokning/__tests__/slutsats.test.ts +++ b/felsokning/app/src/felsokning/__tests__/slutsats.test.ts @@ -9,6 +9,7 @@ // inte blivit slutsatsen måste bemötas. Utan den är en felsökning en // gissning som råkade stämma — och det är precis den skillnaden en // försäkringsbedömare försöker avgöra. +import { readFileSync } from "node:fs"; import { describe, expect, it } from "vitest"; import { MINSTA_MOTIVERING, @@ -225,3 +226,52 @@ describe("avslutsvillkoret är detsamma i klienten och i grinden", () => { expect(await slutsatsHinder(logg)).not.toHaveLength(0); }); }); + +// ---- Hela avslutskedjan, inte bara slutsatsen --------------------------- +// +// Hittat genom att köra tio ärenden av olika karaktär hela vägen genom +// gränssnittet: samtliga gick att stänga på skärmen med utfört arbete och +// utan kundbesked — men grinden på servern kräver beskedet. Samma glapp +// som slutsatsen hade, på ett annat villkor. +// +// Testet speglar klientens kanAvslutas mot grinden för hela kedjan, så +// att nästa villkor som läggs till i grinden inte kan glömmas i klienten. +describe("klientens avslutsvillkor täcker hela grindens åtgärdskedja", () => { + const KEDJA = [ + { typ: "reproducering", status: "ja", beskrivning: "Reproducerad vid provkörning i 90 km/h på plan väg." }, + { + typ: "felorsak", + avvikelse: "Höger framhjul har 38 g obalans mot gränsen 10 g.", + orsaker: ["Normalt slitage"], + underlag: ["Mätresultat"], + sakerhet: "hog", + atgard: "Balansera om höger framhjul.", + }, + { typ: "atgard_utford", beskrivning: "Balanserade om höger framhjul.", utford: true }, + { typ: "kvalitetskontroll", resultat: "symptomet_borta", beskrivning: "Ny provkörning — ingen vibration." }, + ]; + + const gateHinder = async (handelser: unknown[]) => { + const { grinda } = await import("../../../../services/gemensam/grind.mjs"); + const { ALLA_METODIKER } = await import("../../../../services/gemensam/metodiker.mjs"); + return grinda(handelser, ALLA_METODIKER.at(-1)).map((h) => h.id); + }; + + it("utfört arbete utan kundbesked spärras av grinden", async () => { + expect(await gateHinder(KEDJA)).toContain("kundbeslut"); + }); + + it("med kundbesked försvinner det hindret", async () => { + const med = [...KEDJA, { typ: "kundbeslut", beslut: "godkant", kanal: "telefon" }]; + expect(await gateHinder(med)).not.toContain("kundbeslut"); + }); + + it("klienten kräver samma sak — kundbeslut ingår i underlagKlart", () => { + const kod = readFileSync("src/pages/felsokning/ArendeSida.tsx", "utf8"); + const rad = kod.match(/const underlagKlart =[\s\S]*?;/)?.[0] ?? ""; + expect(rad).toContain("reproducering(arende)"); + expect(rad).toContain("felorsaker(arende)"); + expect(rad).toContain("kvalitetskontroll(arende)"); + expect(rad).toContain("kundbeslut(arende)"); + }); +}); diff --git a/felsokning/app/src/pages/felsokning/ArendeSida.tsx b/felsokning/app/src/pages/felsokning/ArendeSida.tsx index 8ae42f2..e93598c 100644 --- a/felsokning/app/src/pages/felsokning/ArendeSida.tsx +++ b/felsokning/app/src/pages/felsokning/ArendeSida.tsx @@ -1257,11 +1257,17 @@ function GuideFlik({ // Underlaget: det som gör att en slutsats över huvud taget går att // motivera. Innan detta är på plats vore varför-frågan en begäran om // en gissning. + // + // Kundbeskedet hör till kedjan när arbete faktiskt utförts. Grinden på + // servern har alltid krävt det; klienten gjorde det inte, med följden + // att ett ärende gick att stänga på skärmen och nekas först vid synk. + // Samma sorts glapp som slutsatsen hade — hittat genom att köra tio + // ärenden hela vägen och jämföra mot grinden. const underlagKlart = !!reproducering(arende) && felorsaker(arende).length > 0 && atgardsposter.length > 0 && - (!utfordAtgard || !!kvalitetskontroll(arende)); + (!utfordAtgard || (!!kvalitetskontroll(arende) && !!kundbeslut(arende))); // ALVA-RULE-200. Samma granskning som kvalitetsgrinden på servern kör // — avsiktligt samma funktion, inte en klientkopia av regeln. En @@ -1443,7 +1449,8 @@ function Avslutshinder({ underlagKlart, brister }: { underlagKlart: boolean; bri {!underlagKlart && (
Underlaget är ofullständigt: avslut kräver symptomverifiering, felorsaksanalys, dokumenterad åtgärd och — - vid utförd åtgärd — kvalitetskontroll av att symptomet är borta. Se panelerna nedan. + vid utförd åtgärd — kvalitetskontroll av att symptomet är borta samt kundens besked på åtgärdsförslaget. + Se panelerna nedan.
)} {brister.length > 0 && (