refactor: split cookie_screenshot_ocr.py (642 → 290 + 353 LOC)
CI / detect-changes (push) Successful in 7s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (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 / build-sha-integrity (push) Failing after 4s
CI / validate-canonical-controls (push) Successful in 11s
CI / loc-budget (push) Failing after 14s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m19s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 29s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped

CI hard-cap 500 LOC. cookie_screenshot_ocr.py war auf 642 gewachsen,
also gesplittet:

  - cookie_screenshot_ocr_engines.py (353 LOC, NEU)
    OCR-Engine-Funktionen: _slice_screenshot, Vision-LLM (qwen2.5vl),
    PaddleOCR, Tesseract, parse_ocr_cookie_table, parse_vision_response,
    Konstanten VISION_MODEL/OLLAMA_URL/VISION_PROMPT.

  - cookie_screenshot_ocr.py (290 LOC, REWRITE)
    Orchestration: capture_cookie_evidence_slices, _ocr_one_slice,
    ocr_slices_extract_cookies, capture_cookie_screenshot,
    extract_cookies_via_vision, cookies_to_vendor_records.
    Re-Exports der Engine-Funktionen für Backward-Kompat.

Einziger externer Importer (_phase_d1_vendors_raw.py) braucht keinen
Code-Change — Public-API stabil.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-06 23:35:33 +02:00
parent ff796fb480
commit 02879a2c3a
9 changed files with 1790 additions and 384 deletions
@@ -0,0 +1,183 @@
/**
* Hook fuer Template-Rule-Editor: laedt Regeln/Versions/History und exponiert
* Lifecycle-Actions (submit/approve/publish/reject) + Tenant-Override-CRUD.
*
* Alle API-Calls gehen ueber /api/sdk/v1/compliance/* (Next.js-Proxy zum
* backend-compliance).
*/
import { useCallback } from 'react'
import type {
ApprovalHistoryEntry,
Classification,
Rule,
RuleCondition,
RuleVersion,
TenantRuleOverride,
} from '../_types'
const API_BASE = '/api/sdk/v1/compliance'
async function req<T>(url: string, init?: RequestInit): Promise<T> {
const res = await fetch(url, {
...init,
headers: {
'Content-Type': 'application/json',
...(init?.headers || {}),
},
})
if (!res.ok) {
const text = await res.text().catch(() => res.statusText)
throw new Error(`${res.status}: ${text}`)
}
if (res.status === 204) return undefined as T
return res.json() as Promise<T>
}
export function useRuleEditorActions() {
const listRules = useCallback(
(documentType?: string) => {
const q = documentType ? `?document_type=${encodeURIComponent(documentType)}` : ''
return req<Rule[]>(`${API_BASE}/template-rules${q}`)
},
[],
)
const getRule = useCallback(
(ruleId: string) => req<Rule>(`${API_BASE}/template-rules/${ruleId}`),
[],
)
const listVersions = useCallback(
(ruleId: string) => req<RuleVersion[]>(`${API_BASE}/template-rules/${ruleId}/versions`),
[],
)
const getVersion = useCallback(
(versionId: string) => req<RuleVersion>(`${API_BASE}/template-rule-versions/${versionId}`),
[],
)
const createDraftVersion = useCallback(
(
ruleId: string,
payload: {
classification: Classification
conditions: RuleCondition
source_citation: string
rationale?: string | null
created_by?: string | null
},
) =>
req<RuleVersion>(`${API_BASE}/template-rules/${ruleId}/versions`, {
method: 'POST',
body: JSON.stringify({
rule_id: ruleId,
...payload,
}),
}),
[],
)
const updateDraftVersion = useCallback(
(
versionId: string,
patch: {
classification?: Classification
conditions?: RuleCondition
source_citation?: string
rationale?: string | null
change_summary?: string | null
},
) =>
req<RuleVersion>(`${API_BASE}/template-rule-versions/${versionId}`, {
method: 'PATCH',
body: JSON.stringify(patch),
}),
[],
)
const submitForReview = useCallback(
(
versionId: string,
payload: { change_summary: string; submitter?: string; comment?: string },
) =>
req<RuleVersion>(`${API_BASE}/template-rule-versions/${versionId}/submit-review`, {
method: 'POST',
body: JSON.stringify(payload),
}),
[],
)
const approveVersion = useCallback(
(versionId: string, payload: { approver?: string; comment?: string } = {}) =>
req<RuleVersion>(`${API_BASE}/template-rule-versions/${versionId}/approve`, {
method: 'POST',
body: JSON.stringify(payload),
}),
[],
)
const publishVersion = useCallback(
(versionId: string, payload: { approver?: string; comment?: string } = {}) =>
req<RuleVersion>(`${API_BASE}/template-rule-versions/${versionId}/publish`, {
method: 'POST',
body: JSON.stringify(payload),
}),
[],
)
const rejectVersion = useCallback(
(
versionId: string,
payload: { rejection_reason: string; rejector?: string; comment?: string },
) =>
req<RuleVersion>(`${API_BASE}/template-rule-versions/${versionId}/reject`, {
method: 'POST',
body: JSON.stringify(payload),
}),
[],
)
const getApprovalHistory = useCallback(
(versionId: string) =>
req<ApprovalHistoryEntry[]>(
`${API_BASE}/template-rule-versions/${versionId}/approval-history`,
),
[],
)
const listOverrides = useCallback(
() => req<TenantRuleOverride[]>(`${API_BASE}/tenant-rule-overrides`),
[],
)
const upsertOverride = useCallback(
(payload: {
rule_id: string
override_classification: Classification | null
reason: string
created_by?: string
}) =>
req<TenantRuleOverride>(`${API_BASE}/tenant-rule-overrides`, {
method: 'POST',
body: JSON.stringify(payload),
}),
[],
)
const deleteOverride = useCallback(
(overrideId: string) =>
req<void>(`${API_BASE}/tenant-rule-overrides/${overrideId}`, { method: 'DELETE' }),
[],
)
return {
listRules, getRule,
listVersions, getVersion,
createDraftVersion, updateDraftVersion,
submitForReview, approveVersion, publishVersion, rejectVersion,
getApprovalHistory,
listOverrides, upsertOverride, deleteOverride,
}
}