diff --git a/backend-compliance/compliance/api/canonical_control_routes.py b/backend-compliance/compliance/api/canonical_control_routes.py index a87dac1..c97bee2 100644 --- a/backend-compliance/compliance/api/canonical_control_routes.py +++ b/backend-compliance/compliance/api/canonical_control_routes.py @@ -954,7 +954,7 @@ async def backfill_normative_strength( # 2. Normative strength korrigieren basierend auf source_type changes = [] - stats = {"total": len(obligations), "unchanged": 0, "capped_to_should": 0, "capped_to_can": 0, "no_source": 0} + stats = {"total": len(obligations), "unchanged": 0, "capped_to_should": 0, "capped_to_may": 0, "no_source": 0} for obl in obligations: if not obl.parent_source: @@ -975,8 +975,8 @@ async def backfill_normative_strength( }) if new_strength == "should": stats["capped_to_should"] += 1 - elif new_strength == "can": - stats["capped_to_can"] += 1 + elif new_strength == "may": + stats["capped_to_may"] += 1 else: stats["unchanged"] += 1 diff --git a/backend-compliance/compliance/data/source_type_classification.py b/backend-compliance/compliance/data/source_type_classification.py index 7569524..fbfbe25 100644 --- a/backend-compliance/compliance/data/source_type_classification.py +++ b/backend-compliance/compliance/data/source_type_classification.py @@ -23,19 +23,20 @@ Mapping: source_regulation (aus control_parent_links) -> source_type # --- Typ-Definitionen --- SOURCE_TYPE_LAW = "law" # Gesetz/Verordnung/Richtlinie — normative_strength bleibt SOURCE_TYPE_GUIDELINE = "guideline" # Leitlinie/Standard — max "should" -SOURCE_TYPE_FRAMEWORK = "framework" # Framework/Best Practice — max "can" +SOURCE_TYPE_FRAMEWORK = "framework" # Framework/Best Practice — max "may" # Max erlaubte normative_strength pro source_type +# DB-Constraint erlaubt: must, should, may (NICHT "can") NORMATIVE_STRENGTH_CAP: dict[str, str] = { SOURCE_TYPE_LAW: "must", # keine Begrenzung SOURCE_TYPE_GUIDELINE: "should", # max "should" - SOURCE_TYPE_FRAMEWORK: "can", # max "can" + SOURCE_TYPE_FRAMEWORK: "may", # max "may" (= "kann") } # Reihenfolge fuer Vergleiche (hoeher = staerker) STRENGTH_ORDER: dict[str, int] = { - "can": 1, - "may": 1, # Alias fuer "can" + "may": 1, # KANN (DB-Wert) + "can": 1, # Alias — wird in cap_normative_strength zu "may" normalisiert "should": 2, "must": 3, } @@ -46,7 +47,7 @@ def cap_normative_strength(original: str, source_type: str) -> str: Begrenzt die normative_strength basierend auf dem source_type. Beispiel: - cap_normative_strength("must", "framework") -> "can" + cap_normative_strength("must", "framework") -> "may" cap_normative_strength("should", "law") -> "should" cap_normative_strength("must", "guideline") -> "should" """ diff --git a/backend-compliance/tests/test_source_type_classification.py b/backend-compliance/tests/test_source_type_classification.py index 503ca1c..a35b1e7 100644 --- a/backend-compliance/tests/test_source_type_classification.py +++ b/backend-compliance/tests/test_source_type_classification.py @@ -71,16 +71,16 @@ class TestCapNormativeStrength: assert cap_normative_strength("should", SOURCE_TYPE_GUIDELINE) == "should" def test_must_from_framework_capped(self): - assert cap_normative_strength("must", SOURCE_TYPE_FRAMEWORK) == "can" + assert cap_normative_strength("must", SOURCE_TYPE_FRAMEWORK) == "may" def test_should_from_framework_capped(self): - assert cap_normative_strength("should", SOURCE_TYPE_FRAMEWORK) == "can" + assert cap_normative_strength("should", SOURCE_TYPE_FRAMEWORK) == "may" - def test_can_from_framework_stays(self): - assert cap_normative_strength("can", SOURCE_TYPE_FRAMEWORK) == "can" + def test_may_from_framework_stays(self): + assert cap_normative_strength("may", SOURCE_TYPE_FRAMEWORK) == "may" - def test_can_from_law_stays(self): - assert cap_normative_strength("can", SOURCE_TYPE_LAW) == "can" + def test_may_from_law_stays(self): + assert cap_normative_strength("may", SOURCE_TYPE_LAW) == "may" class TestGetHighestSourceType: diff --git a/docs-src/services/sdk-modules/normative-verbindlichkeit.md b/docs-src/services/sdk-modules/normative-verbindlichkeit.md index 5f03f75..db3307a 100644 --- a/docs-src/services/sdk-modules/normative-verbindlichkeit.md +++ b/docs-src/services/sdk-modules/normative-verbindlichkeit.md @@ -159,7 +159,7 @@ Ablauf: ```python def cap_normative_strength(original: str, source_type: str) -> str: """ - cap_normative_strength("must", "framework") → "can" + cap_normative_strength("must", "framework") → "may" cap_normative_strength("should", "law") → "should" cap_normative_strength("must", "guideline") → "should" """ @@ -173,7 +173,7 @@ In der Control-Detail-Ansicht werden Obligations mit farbcodierten Badges angeze |---|---|---|---| | `must` | **MUSS** | Rot | Gesetzliche Pflicht | | `should` | **SOLL** | Gelb/Amber | Empfohlen, Begruendungspflicht bei Abweichung | -| `can` / `may` | **KANN** | Gruen | Freiwillige Best Practice | +| `may` | **KANN** | Gruen | Freiwillige Best Practice | ## Haeufige Fragen