fix: Vorbereitung-Module auf 100% — Feld-Fixes, Backend-Persistenz, Endpoints

- ScopeExportTab: 11 Feldnamen-Mismatches gegen ScopeDecision Interface korrigiert
  (level→determinedLevel, riskScore→risk_score, hardTriggers→triggeredHardTriggers,
  depthDescription→depth, effortEstimate→estimatedEffort, isMandatory→required,
  triggeredByHardTrigger→triggeredBy, effortDays→estimatedEffort)
- Company Profile: GET vom Backend beim Mount, snake_case→camelCase, SDK State Fallback
- Modules: Aktivierung/Deaktivierung ans Backend schreiben (activate/deactivate Endpoints)
- Obligations: Explizites Fehler-Banner statt stiller Fallback bei Backend-Fehler
- Source Policy: BlockedContentDB Model + GET /api/v1/admin/blocked-content Endpoint
- Import: Offline-Modus Label fuer Backend-Fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-02 12:02:40 +01:00
parent 80a988dc58
commit f7a0b11e41
10 changed files with 278 additions and 39 deletions

View File

@@ -32,6 +32,7 @@ from sqlalchemy.orm import Session
from database import get_db
from compliance.db.source_policy_models import (
AllowedSourceDB,
BlockedContentDB,
SourceOperationDB,
PIIRuleDB,
SourcePolicyAuditDB,
@@ -398,6 +399,43 @@ async def delete_pii_rule(rule_id: str, db: Session = Depends(get_db)):
return {"status": "deleted", "id": rule_id}
# =============================================================================
# Blocked Content
# =============================================================================
@router.get("/blocked-content")
async def list_blocked_content(
limit: int = Query(50, ge=1, le=500),
offset: int = Query(0, ge=0),
domain: Optional[str] = None,
db: Session = Depends(get_db),
):
"""List blocked content entries."""
query = db.query(BlockedContentDB)
if domain:
query = query.filter(BlockedContentDB.domain == domain)
total = query.count()
entries = query.order_by(BlockedContentDB.created_at.desc()).offset(offset).limit(limit).all()
return {
"blocked": [
{
"id": str(e.id),
"url": e.url,
"domain": e.domain,
"block_reason": e.block_reason,
"rule_id": str(e.rule_id) if e.rule_id else None,
"details": e.details,
"created_at": e.created_at.isoformat() if e.created_at else None,
}
for e in entries
],
"total": total,
}
# =============================================================================
# Audit Trail
# =============================================================================