feat(cra): kuratierte Maßnahmen-Bibliothek — alle 40 CRA-Anforderungen belegt

- data/measures_curated.json: 24 deduplizierte, standard-gestützte Maßnahmen
  (9 bestehende M540-548 + 15 neue M600-614), Volltext + norm_refs + multi-reg
  covers. Deckt alle 40 CRA-AI-x (vorher nur 17).
- cra_annex_i_data lädt die Bibliothek defensiv: MEASURES=Superset, MEASURE_DETAILS
  (Volltext), mapped_measures aus covers abgeleitet. Fallback = hartkodierte 9.
- Mapper: open_measures tragen jetzt name+description+norm_refs (echte Volltexte).
- useCRA: merge nutzt Backend-Volltexte statt Demo-Lookup.
- Tests: Coverage (40/40) + Volltext im Assessment.

Quelle: extern handkuratiert/recherchiert, hier dedupliziert + gemappt. Maschinen-
VO/NIS2/IEC-Maßnahmen folgen, sobald deren Spine existiert.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-16 07:44:13 +02:00
parent 4c206aa332
commit 6c619ecc42
5 changed files with 203 additions and 6 deletions
@@ -258,3 +258,33 @@ SEVERITY_WEIGHT = {
"MEDIUM": 30,
"LOW": 10,
}
# ── Kuratierte Maßnahmen-Bibliothek (Source of Truth: data/measures_curated.json) ──
# Deduplizierte, standard-gestützte Maßnahmen. Beim Import: MEASURES (id->Name) wird
# Superset, MEASURE_DETAILS trägt den Volltext, und jede CRA-Anforderung bekommt
# mapped_measures aus dem `covers`-Feld. Defensiv: bei fehlender/kaputter JSON bleibt
# das hartkodierte 9er-Set + Mapping erhalten.
import json as _json
import os as _os
MEASURE_DETAILS: dict = {}
try:
_MEAS_PATH = _os.path.join(_os.path.dirname(__file__), "..", "data", "measures_curated.json")
with open(_MEAS_PATH, encoding="utf-8") as _fh:
_curated = _json.load(_fh)
MEASURE_DETAILS = {m["id"]: m for m in _curated if m.get("id")}
for _m in _curated:
if _m.get("id") and _m.get("name"):
MEASURES[_m["id"]] = _m["name"]
_cover_map: dict = {}
for _m in _curated:
for _c in _m.get("covers", []):
_cover_map.setdefault(_c, []).append(_m["id"])
for _r in ANNEX_I_REQUIREMENTS:
_ids = _cover_map.get(_r["req_id"])
if _ids:
_r["mapped_measures"] = _ids
except Exception: # noqa: BLE001 — Bibliothek optional; Fallback = hartkodiertes Set
pass