04e0a1e8ec
Guidad Felsökning / test-och-bygg (push) Has been cancelled
Guidad Felsökning / tjanster (push) Has been cancelled
Guidad Felsökning / terraform (push) Has been cancelled
Guidad Felsökning / leverantorskedja (push) Has been cancelled
Guidad Felsökning / aterstallning (push) Has been cancelled
Guidad Felsökning / publicera (push) Has been cancelled
Guidad Felsökning / driftsatt (push) Has been cancelled
228 lines
9.2 KiB
JavaScript
228 lines
9.2 KiB
JavaScript
// ALVA-SPEC-041 · Försäkringsvillkor som underlag.
|
|
//
|
|
// ---- Varför den här modulen aldrig svarar ja eller nej ------------------
|
|
//
|
|
// Den avgör ingenting. Den kan inte avgöra något, och en version som såg
|
|
// ut att göra det vore skadlig på ett sätt som inte märks förrän någon
|
|
// förlitat sig på den.
|
|
//
|
|
// Skälet är inte försiktighet utan sakförhållandet: vad som gäller
|
|
// bestäms av KUNDENS EGET försäkringsbrev och de villkor som gällde när
|
|
// avtalet tecknades — inte av vad ett bolag skriver på sin webbplats i
|
|
// dag, och inte av vad vi noterat. Samma bolag har flera produkter med
|
|
// olika gränser, gränserna ändras, och ett tecknat avtal följer sina egna
|
|
// villkor även efter att bolaget ändrat dem.
|
|
//
|
|
// Modulen ger därför tre saker och inte ett fjärde:
|
|
//
|
|
// 1. VAD SOM AVGÖR frågan — de villkorstyper som styr maskinskada,
|
|
// oberoende av bolag. Den delen är stabil.
|
|
// 2. VAD REGISTRET SÄGER — noterade gränser per bolag och produkt, med
|
|
// källa och datum. Underlag för ett samtal, inte ett besked.
|
|
// 3. VAD SOM MÅSTE KONTROLLERAS i det enskilda fallet.
|
|
//
|
|
// Det fjärde — ett utfall — finns inte, och `bedom()` returnerar med
|
|
// avsikt inget fält som liknar ett.
|
|
//
|
|
// ---- Registrets hållbarhet ----------------------------------------------
|
|
//
|
|
// Uppgifterna nedan är avlästa från bolagens egna sidor vid det datum som
|
|
// står på varje post. De åldras. En post äldre än GILTIGHETSTID_DAGAR
|
|
// märks som föråldrad i gränssnittet i stället för att tigas ihjäl —
|
|
// en gammal siffra som ser aktuell ut är värre än ingen siffra.
|
|
//
|
|
// Organisationen kan lägga till bolag och produkter. Ett register som
|
|
// bara vi fyller kommer aldrig att täcka de mindre bolagen.
|
|
|
|
/** En post äldre än så här märks som föråldrad. */
|
|
export const GILTIGHETSTID_DAGAR = 180;
|
|
|
|
/**
|
|
* Vad som avgör en maskinskadefråga, oavsett bolag.
|
|
*
|
|
* Den här listan är modulens stabila del. Gränserna nedanför ändras;
|
|
* frågorna gör det inte.
|
|
*/
|
|
export const AVGORANDE_VILLKOR = [
|
|
{
|
|
id: "alder",
|
|
rubrik: "Vehicle age",
|
|
fraga: "Is the vehicle within the age limit of the policy in force?",
|
|
text: "Machine damage cover ends at an age limit that differs by insurer and by product tier within the same insurer.",
|
|
},
|
|
{
|
|
id: "stracka",
|
|
rubrik: "Odometer",
|
|
fraga: "Is the recorded distance within the limit?",
|
|
text: "Age and distance are alternative ceilings — whichever is reached first ends the cover. The odometer reading therefore has to be documented, not estimated.",
|
|
},
|
|
{
|
|
id: "plotsligt",
|
|
rubrik: "Sudden and unforeseen",
|
|
fraga: "Is the failure sudden and unforeseen, rather than gradual?",
|
|
text: "Machine damage cover is written for sudden internal failure. Gradual deterioration, wear and ageing are normally excluded — and this is the exclusion most claims turn on.",
|
|
},
|
|
{
|
|
id: "komponent",
|
|
rubrik: "Component in scope",
|
|
fraga: "Is the failed component named in the policy's list?",
|
|
text: "Cover is usually limited to an enumerated list — powertrain, steering, brake and electrical systems are common; wear parts, exhaust and bodywork usually are not.",
|
|
},
|
|
{
|
|
id: "underhall",
|
|
rubrik: "Maintenance history",
|
|
fraga: "Has the vehicle been serviced according to the manufacturer's schedule?",
|
|
text: "Neglected or undocumented servicing is a common ground for reduction or refusal. The service record is evidence, and its absence is also evidence.",
|
|
},
|
|
{
|
|
id: "orsak",
|
|
rubrik: "Excluded cause",
|
|
fraga: "Was the failure caused by something the policy excludes?",
|
|
text: "Wrong fuel, lack of oil or coolant, frost damage, tuning or modification, competition use and consequential damage from an earlier unrepaired fault are typical exclusions.",
|
|
},
|
|
{
|
|
id: "sjalvrisk",
|
|
rubrik: "Deductible",
|
|
fraga: "What is the deductible, and does it exceed the repair cost?",
|
|
text: "Deductibles are often graded by vehicle age. A claim below the deductible is not worth filing, and saying so early is part of the service.",
|
|
},
|
|
];
|
|
|
|
/**
|
|
* Noterade gränser per bolag och produkt.
|
|
*
|
|
* `kontrollerad` är avläsningsdatum, inte giltighetsdatum. Ingen post här
|
|
* uttalar sig om vad som gäller för en enskild kund.
|
|
*/
|
|
export const BOLAG = [
|
|
{
|
|
id: "if",
|
|
namn: "If",
|
|
marknad: "SE",
|
|
produkter: [
|
|
{ namn: "Maskinskadeförsäkring", maxAlderAr: 10, maxMil: 12_000 },
|
|
{ namn: "Stor bilförsäkring", maxAlderAr: 10, maxMil: 15_000 },
|
|
],
|
|
kalla: "https://www.if.se/privat/forsakringar/bilforsakring/maskinskadeforsakring",
|
|
kontrollerad: "2026-08-06",
|
|
},
|
|
{
|
|
id: "folksam",
|
|
namn: "Folksam",
|
|
marknad: "SE",
|
|
produkter: [
|
|
{ namn: "Maskinskadeförsäkring", maxAlderAr: 8, maxMil: 15_000 },
|
|
{ namn: "Bilförsäkring Stor", maxAlderAr: 10, maxMil: 15_000 },
|
|
],
|
|
kalla: "https://www.folksam.se/forsakringar/bilforsakring/maskinskadeforsakring",
|
|
kontrollerad: "2026-08-06",
|
|
},
|
|
{
|
|
id: "trygghansa",
|
|
namn: "Trygg-Hansa",
|
|
marknad: "SE",
|
|
produkter: [
|
|
{ namn: "Maskinskadeförsäkring", maxAlderAr: 8, maxMil: 12_000 },
|
|
{ namn: "Bilförsäkring stor / märkesförsäkring", maxAlderAr: 10, maxMil: 15_000 },
|
|
],
|
|
kalla: "https://www.trygghansa.se/forsakringar/bilforsakring/maskinskadeforsakring",
|
|
kontrollerad: "2026-08-06",
|
|
},
|
|
{
|
|
id: "svedea",
|
|
namn: "Svedea",
|
|
marknad: "SE",
|
|
produkter: [{ namn: "Maskinskadeförsäkring", maxAlderAr: 10, maxMil: 15_000 }],
|
|
kalla: "https://www.svedea.se/bilforsakring/maskinskadeforsakring",
|
|
kontrollerad: "2026-08-06",
|
|
},
|
|
{
|
|
id: "watercircles",
|
|
namn: "WaterCircles",
|
|
marknad: "SE",
|
|
produkter: [{ namn: "Maskinskadeförsäkring", maxAlderAr: 12, maxMil: 17_000 }],
|
|
kalla: "https://www.watercircles.se/tips-och-rad/maskinskadeforsakring/10925/",
|
|
kontrollerad: "2026-08-06",
|
|
},
|
|
{
|
|
id: "hedvig",
|
|
namn: "Hedvig",
|
|
marknad: "SE",
|
|
produkter: [{ namn: "Maskinskadeskydd", maxAlderAr: 8, maxMil: 12_000 }],
|
|
kalla: "https://www.hedvig.com/se/forsakringar/bilforsakring/maskinskadeforsakring",
|
|
kontrollerad: "2026-08-06",
|
|
},
|
|
];
|
|
|
|
/** Är posten äldre än giltighetstiden? */
|
|
export function foraldrad(post, nu = new Date()) {
|
|
const d = new Date(post.kontrollerad);
|
|
if (Number.isNaN(d.getTime())) return true;
|
|
return (nu - d) / 86_400_000 > GILTIGHETSTID_DAGAR;
|
|
}
|
|
|
|
/** Bredaste och smalaste noterade gräns — spannet, inte ett svar. */
|
|
export function spann(bolag = BOLAG) {
|
|
const produkter = bolag.flatMap((b) => b.produkter);
|
|
if (produkter.length === 0) return null;
|
|
return {
|
|
alderAr: { minsta: Math.min(...produkter.map((p) => p.maxAlderAr)), storsta: Math.max(...produkter.map((p) => p.maxAlderAr)) },
|
|
mil: { minsta: Math.min(...produkter.map((p) => p.maxMil)), storsta: Math.max(...produkter.map((p) => p.maxMil)) },
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Underlag för ett samtal med kunden. INTE ett utfall.
|
|
*
|
|
* Returnerar avsiktligt inget fält som säger täckt eller ej. Det som
|
|
* returneras är: vilka noterade produkter fordonet ligger inom respektive
|
|
* utanför, vilka frågor som återstår, och det obligatoriska nästa steget
|
|
* — att läsa kundens eget försäkringsbrev.
|
|
*
|
|
* Ett fordon som ligger utanför SAMTLIGA noterade gränser får ändå inget
|
|
* "nej". Registret kan vara ofullständigt, produkten kan vara en annan,
|
|
* och villkoren vid tecknandet kan ha varit andra.
|
|
*/
|
|
export function bedom({ alderAr, mil, bolagId } = {}, register = BOLAG, nu = new Date()) {
|
|
const urval = bolagId ? register.filter((b) => b.id === bolagId) : register;
|
|
|
|
const inom = [];
|
|
const utanfor = [];
|
|
const oklart = [];
|
|
|
|
for (const b of urval) {
|
|
for (const p of b.produkter) {
|
|
const post = { bolag: b.namn, produkt: p.namn, gransAr: p.maxAlderAr, gransMil: p.maxMil, kalla: b.kalla, foraldrad: foraldrad(b, nu) };
|
|
const alderKant = typeof alderAr === "number";
|
|
const milKant = typeof mil === "number";
|
|
if (!alderKant && !milKant) {
|
|
oklart.push(post);
|
|
continue;
|
|
}
|
|
const overAlder = alderKant && alderAr > p.maxAlderAr;
|
|
const overMil = milKant && mil > p.maxMil;
|
|
if (overAlder || overMil) utanfor.push(post);
|
|
else if (alderKant && milKant) inom.push(post);
|
|
else oklart.push(post);
|
|
}
|
|
}
|
|
|
|
return {
|
|
inom,
|
|
utanfor,
|
|
oklart,
|
|
// Frågorna som återstår oavsett vad gränserna säger. Ålder och
|
|
// sträcka är bara två av sju, och de fem andra avgör oftare.
|
|
kvarstaende: AVGORANDE_VILLKOR.filter((v) => !["alder", "stracka"].includes(v.id)),
|
|
nastaSteg:
|
|
"Read the customer's own policy document and the terms in force when it was taken out. The register is a starting point for the conversation, never the answer.",
|
|
};
|
|
}
|
|
|
|
/** Förbehållet. Ska stå i varje vy som visar registret. */
|
|
export const FORBEHALL =
|
|
"ALVA does not decide whether a claim is covered and cannot do so. Cover is determined by the customer's own " +
|
|
"policy and the terms in force when it was taken out — not by this register, which records what insurers " +
|
|
"published on the dates shown. Figures age, insurers differ between their own product tiers, and an existing " +
|
|
"policy keeps its original terms. Use this to frame the conversation and the questions; the insurer decides.";
|