// Domain model for the F∆I Recl∆Im 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 { /// Kompakt-Code für enge Layouts. String get short => switch (this) { EvidenceTier.t1 => 'T1', EvidenceTier.t2 => 'T2', EvidenceTier.t3 => 'T3', EvidenceTier.t4 => 'T4', }; /// Ein-Wort-Bedeutung, immer neben dem T-Code zu zeigen. String get headline => switch (this) { EvidenceTier.t1 => 'amtlich', EvidenceTier.t2 => 'Verband', EvidenceTier.t3 => 'Erhebung', EvidenceTier.t4 => 'Signal', }; /// Lange Form für Listen, Tooltips, Legend-Texte. String get description => switch (this) { EvidenceTier.t1 => 'amtlich oder peer-reviewed (NKR, DESTATIS, ifo, ZEW)', EvidenceTier.t2 => 'Verbands-Erhebung (DIHK, IHK, ZDH, BDI)', EvidenceTier.t3 => 'eigene strukturierte Erhebung (Phase 2/3)', EvidenceTier.t4 => 'qualitatives Signal — nur Hinweis, keine Magnitude', }; } /// 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 Absatz/paragraph of the actual normative text. class NormParagraph { const NormParagraph({required this.number, required this.text}); /// Source numbering as it appears, e.g. "(1)", "(2a)". Empty /// when the source has no Absatz numbering. final String number; final String text; } /// 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, this.paragraphs = const [], }); final String eli; final String title; final String jurabk; final String paragraph; final DateTime standDate; final String sourceUrl; final String sourceSha256; /// The actual paragraphs of the norm text, normalised by /// `text.akoma_normalize` in live mode. In demo mode the /// fixture quotes the public source verbatim under §5 UrhG /// (amtliche Werke). final List paragraphs; } /// 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, this.componentSummary = const [], }); 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; /// Compact lines for at-a-glance reading on list views. /// One line per SKM-Komponente (P / F / T / h) plus optional /// extras — each carries its tier-tag inline. Empty list ⇒ /// fall back to the notes field for the list view. final List componentSummary; }