feat(b17): DSMS-CID-Anchor für Audit-Walk-Video (Stufe 3, #7)

Video + walk.json werden nach Aufnahme zu DSMS-IPFS hochgeladen.
Die zurückgegebenen CIDs sind manipulationssichere Audit-Anker —
Reviewer können das Walk-Video Monate später noch verifizieren und
auf Unverändertheit prüfen.

consent-tester:
  - _upload_to_dsms(): Best-Effort-Upload zu /api/v1/documents
    (Bearer-Token, document_type=audit_walk_video|meta). DSMS-Down
    bricht den Walk nicht ab — CID fehlt einfach im result.
  - record_audit_walk(): nach video.webm + walk.json erzeugt, beide
    hochladen. walk.json wird re-written sodass es BEIDE CIDs
    selbstreferenziell enthält.
  - ENV: DSMS_GATEWAY_URL + DSMS_BEARER konfigurierbar.

backend:
  - _b17_wiring._publicize_gateway_url(): DSMS gibt intern
    http://dsms-node:8080/ipfs/{cid} zurück. Für die Audit-Mail
    wird das via env DSMS_PUBLIC_GATEWAY (default
    https://dsms-dev.breakpilot.ai) durch eine extern erreichbare
    URL ersetzt.
  - Render-Block: gelber DSMS-Anchor-Hinweis mit Video-CID +
    walk.json-CID, beide als klickbare Links zur public Gateway.

Real-World-Smoke gegen Elli:
  - Video-CID: QmbdFwtSymPuWGYYdC6eNZ1eEvVLsTYmoRRxEo5L6BXgwt
  - walk.json-CID: QmWaTqwZq4KVd5wYFVAKB12uZtAosPqoG1X4m1azysXYJi
  - DSMS-Upload erfolgreich, gateway_url im response

Tests: 12/12 grün (+2 für DSMS-Anchor-Render-Pfade inkl.
Internal-Host → Public-Gateway-Rewrite).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-07 17:32:34 +02:00
parent 80c4778017
commit c7d2038ad9
3 changed files with 134 additions and 1 deletions
@@ -72,6 +72,31 @@ class TestRender:
html = _render(walk)
assert "Keine Akkordeons gefunden" in html
def test_dsms_anchor_rendered_when_cid_present(self):
walk = dict(_FAKE_WALK)
walk["video"] = dict(walk["video"])
walk["video"]["dsms"] = {
"cid": "QmTestCidVideoXX1234567890ABCDEFGHJKLMN",
"gateway_url": "http://dsms-node:8080/ipfs/QmTestCidVideo",
}
walk["walk_json_dsms"] = {
"cid": "QmTestCidMetaXX1234567890ABCDEFGHJKLMN",
"gateway_url": "http://dsms-node:8080/ipfs/QmTestCidMeta",
}
html = _render(walk)
assert "DSMS-Anchor" in html
assert "QmTestCidVideoXX1234" in html
# Internal gateway-host must be rewritten to public for the mail
assert "dsms-node:8080" not in html
def test_no_dsms_block_when_cid_absent(self):
walk = dict(_FAKE_WALK)
walk["video"] = dict(walk["video"])
walk["video"].pop("dsms", None)
walk.pop("walk_json_dsms", None)
html = _render(walk)
assert "DSMS-Anchor" not in html
class TestRunB17:
def test_no_request_skipped(self):