package rules // Severity ist die Schwere eines Findings. type Severity string const ( SeverityLow Severity = "niedrig" SeverityMedium Severity = "mittel" SeverityHigh Severity = "hoch" ) // Rule ist eine versionierte Regel aus einer YAML-Datei in rules/. // Regel-IDs werden nie umbenannt oder wiederverwendet — Änderungen an // einer Regel erhöhen die Version. // // Jurisdiction ordnet eine Regel genau einer Rechtsordnung zu (aktuell // nur "DE" — deutsche Rechtslage zuerst). Damit lassen sich künftige // AT/CH-Regeln als zusätzliche Dateien ergänzen, ohne bestehende Regeln // anzufassen: eine Regel gilt nie für mehrere Rechtsordnungen gleichzeitig, // auch wenn sich Gesetzestexte ähneln — jede Rechtsordnung bekommt ihre // eigene, einzeln geprüfte Fundstelle. type Rule struct { ID string `yaml:"id"` Version int `yaml:"version"` Jurisdiction string `yaml:"land"` Title string `yaml:"titel"` Condition Condition `yaml:"bedingung"` Severity Severity `yaml:"schwere"` Sources []string `yaml:"fundstelle"` Fix string `yaml:"korrektur"` } // Condition ist eine flache UND-Bedingung über Facts. Ein nil/leeres // Feld bedeutet "keine Einschränkung durch dieses Feld". type Condition struct { Consideration []Consideration `yaml:"gegenleistung,omitempty"` DisclosurePresent *bool `yaml:"kennzeichnung_vorhanden,omitempty"` DisclosureBeforeCut *bool `yaml:"kennzeichnung_vor_kuerzung,omitempty"` } // Matches prüft, ob f alle gesetzten Bedingungsfelder erfüllt. func (c Condition) Matches(f Facts) bool { if len(c.Consideration) > 0 { found := false for _, allowed := range c.Consideration { if allowed == f.Consideration { found = true break } } if !found { return false } } if c.DisclosurePresent != nil && *c.DisclosurePresent != f.DisclosurePresent { return false } if c.DisclosureBeforeCut != nil && *c.DisclosureBeforeCut != f.DisclosureBeforeCut { return false } return true }