feat(cra): versioned assessment snapshots — CRA Art. 13 running system (step 3)

Persist each CRA assessment as a versioned, auditable snapshot over the product
lifecycle. Reuses the existing compliance_cra_documents table (NO new schema,
frozen DB respected): doc_type='doc_risk_assessment', full assessment in
generation_context, requirements_coverage summary, auto-incrementing version,
prior version superseded. New endpoints: POST /projects/{id}/assess-snapshot,
GET /projects/{id}/assess-snapshots (history), GET /assess-snapshots/{id}.
Additive (no contract baseline change).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-14 09:27:09 +02:00
parent 0d0955caac
commit cf917ab733
3 changed files with 160 additions and 5 deletions
@@ -0,0 +1,25 @@
"""Tests for the CRA snapshot Markdown builder (pure; DB path verified live)."""
from compliance.services.cra_snapshot_store import assessment_markdown
def test_markdown_contains_summary_findings_and_cross_links():
a = {
"findings_total": 2, "coverage_pct": 100.0,
"by_risk": {"CRITICAL": 1, "HIGH": 1, "MEDIUM": 0, "LOW": 0},
"requirements_touched": ["CRA-AI-8", "CRA-AI-15"],
"mapped": [{"finding_id": "x", "priority_tier": "P0",
"primary_requirement": "CRA-AI-8", "priority_reason": "P0 — kritisch"}],
"cross_links": [{"safety_ref": "Zweihandschaltung", "cyber_finding_ids": ["x"]}],
}
md = assessment_markdown(a)
assert "CRA-Cyber-Risikobeurteilung" in md
assert "Befunde gesamt: 2" in md
assert "2 / 40" in md
assert "[P0] x → CRA-AI-8" in md
assert "Cyber trifft Safety" in md
assert "Zweihandschaltung" in md
def test_markdown_handles_empty_assessment():
md = assessment_markdown({})
assert "Befunde gesamt: 0" in md