feat(compliance-check): P12 — TDM-Override mit dokumentierter Kunden-Erlaubnis
CI / guardrail-integrity (push) Has been skipped
CI / nodejs-build (push) Successful in 3m5s
CI / test-go (push) Has been skipped
CI / detect-changes (push) Successful in 10s
CI / branch-name (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 16s
CI / loc-budget (push) Successful in 17s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 40s
CI / test-python-document-crawler (push) Has been skipped

Backend: ComplianceCheckRequest um tdm_override + tdm_override_reason
erweitert. Worker im _run_compliance_check Pfad: bei
tdm_override=True UND Reason >= 10 Zeichen wird der TDM-Vorbehalt
nur dokumentiert (job.tdm_override.{reason, original_status}) und
NICHT als Abbruch-Grund gewertet. Ohne Reason: Override ignoriert.
Audit-Spur via logger.warning(reason).

Frontend: ComplianceCheckTab um Checkbox + Pflicht-Reason-Feld
("Schriftliche Crawl-Erlaubnis vorhanden") direkt vor dem Submit-
Button. Pflicht: Reason >= 10 Zeichen. Submit sendet die Flags ans
Backend.

Anwendungsfall: Safetykon-Pattern — robots.txt + ai.txt setzen
Vorbehalt, aber Kunde hat schriftlich zugestimmt (Auftrags-Audit).

[guardrail-change] ComplianceCheckTab.tsx (511 LOC) in loc-exceptions
ergaenzt — Split nach _components/TDMOverride + CompliancePolling
ist P11-Tech-Debt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-19 08:56:50 +02:00
parent a220f0d0a7
commit 78b27d4684
3 changed files with 36 additions and 1 deletions
@@ -73,6 +73,8 @@ interface HistoryEntry {
export function ComplianceCheckTab() {
const [docs, setDocs] = useState<DocsState>(initState)
const [useAgent, setUseAgent] = useState(false)
const [tdmOverride, setTdmOverride] = useState(false)
const [tdmOverrideReason, setTdmOverrideReason] = useState('')
const [loading, setLoading] = useState(false)
const [progress, setProgress] = useState('')
const [progressPct, setProgressPct] = useState(0)
@@ -197,6 +199,8 @@ export function ComplianceCheckTab() {
body: JSON.stringify({
documents: entries,
use_agent: useAgent,
tdm_override: tdmOverride && tdmOverrideReason.trim().length >= 10,
tdm_override_reason: tdmOverrideReason.trim(),
}),
})
if (!startRes.ok) throw new Error(`Pruefung konnte nicht gestartet werden: ${startRes.status}`)
@@ -319,6 +323,11 @@ export function ComplianceCheckTab() {
</span>
</div>
<div className="bg-amber-50/60 border border-amber-200 rounded-lg p-3 space-y-2">
<label className="flex items-start gap-2 cursor-pointer"><input type="checkbox" checked={tdmOverride} onChange={e => setTdmOverride(e.target.checked)} className="mt-0.5 accent-amber-600" /><span className="text-xs text-amber-900"><strong>Schriftliche Crawl-Erlaubnis vorhanden</strong> uebergeht TDM-Vorbehalte (robots.txt / ai.txt)</span></label>
{tdmOverride && <input type="text" value={tdmOverrideReason} onChange={e => setTdmOverrideReason(e.target.value)} placeholder="z.B. Auftragsbeziehung Safetykon GmbH, Email Hr. X vom 18.05.2026" className="w-full px-3 py-2 text-xs border border-amber-300 rounded bg-white" />}
{tdmOverride && tdmOverrideReason.trim().length < 10 && <p className="text-[10px] text-amber-700">Pflicht: Reason mit min. 10 Zeichen (Audit-Spur).</p>}
</div>
{/* Submit button */}
<button
onClick={handleSubmit}