// Domain model for the F∆I Law-Heatmap client. // // These types are the lingua franca between the (eventually // gRPC-fed) repository and the UI. Names mirror the Studie's // §5.3 data model. /// Evidence tier of the lowest-tier ingredient in a value. /// Per Studie §6.7: "Regel der niedrigsten Stufe" — any composed /// figure carries the tier of its weakest input. enum EvidenceTier { /// Official / peer-reviewed: NKR, DESTATIS, ifo, ZEW. t1, /// Verbands-Erhebung: DIHK, BDI, ZDH, IHK. t2, /// Eigene strukturierte Erhebung (Phase 2/3). t3, /// Qualitatives Signal — pain indicator only, never magnitude. t4, } extension EvidenceTierLabel on EvidenceTier { String get short => switch (this) { EvidenceTier.t1 => 'T1', EvidenceTier.t2 => 'T2', EvidenceTier.t3 => 'T3', EvidenceTier.t4 => 'T4', }; String get description => switch (this) { EvidenceTier.t1 => 'amtlich / peer-reviewed', EvidenceTier.t2 => 'Verband', EvidenceTier.t3 => 'eigene Erhebung', EvidenceTier.t4 => 'qualitatives Signal', }; } /// A citable source — never an LLM, always a public document or /// dataset reference. UI surfaces these next to every figure. class Source { const Source({ required this.label, required this.url, required this.tier, this.note, }); final String label; final String url; final EvidenceTier tier; final String? note; } /// One atomic obligation (Pflicht) extracted from a norm. /// Tuple shape matches Studie §6.3. class Duty { const Duty({ required this.modality, required this.addressee, required this.action, required this.frequency, required this.sourceNorm, this.authority, this.consequence, }); final String modality; // OBLIGATION | PROHIBITION | … final String addressee; final String action; final String frequency; final String sourceNorm; final String? authority; final String? consequence; } /// One norm version — a versioned legal text identified by its /// (synthetic for now) ELI/CELEX. class Norm { const Norm({ required this.eli, required this.title, required this.jurabk, required this.paragraph, required this.standDate, required this.sourceUrl, required this.sourceSha256, }); final String eli; final String title; final String jurabk; final String paragraph; final DateTime standDate; final String sourceUrl; final String sourceSha256; } /// A heatmap point: one norm with its computed scores. /// Axes mirror §6 in the study. class Evaluation { const Evaluation({ required this.norm, required this.skmEurPerYear, required this.benefitScore, required this.affectedCount, required this.frustScore, required this.tierLowest, required this.duties, required this.sources, required this.auditEventId, this.notes, }); final Norm norm; /// Yearly bureaucracy cost across the addressee population. /// €/year, computed via SKM (`P × F × T × h`). final double skmEurPerYear; /// 0–5, composite of seven dimensions /// (safety / market / legal-certainty / EU-harmony / …). final double benefitScore; /// Number of addressees (KMU, Bürger, etc.). UI uses this for /// heatmap point size. final int affectedCount; /// 0–10, composite of readability + Verweistiefe + Akteurs- /// pluralität + Norm-Volatilität. final double frustScore; /// Lowest tier among all ingredients of any displayed figure. final EvidenceTier tierLowest; final List duties; final List sources; /// Pointer into the Ch∆In audit log (SQLite event_log row). final String auditEventId; final String? notes; }