Phase 1 Step 3 of PHASE1_RUNBOOK.md. compliance/api/schemas.py is
decomposed into 16 per-domain Pydantic schema modules under
compliance/schemas/:
common.py ( 79) — 6 API enums + PaginationMeta
regulation.py ( 52)
requirement.py ( 80)
control.py (119) — Control + Mapping
evidence.py ( 66)
risk.py ( 79)
ai_system.py ( 63)
dashboard.py (195) — Dashboard, Export, Executive Dashboard
service_module.py (121)
bsi.py ( 58) — BSI + PDF extraction
audit_session.py (172)
report.py ( 53)
isms_governance.py (343) — Scope, Context, Policy, Objective, SoA
isms_audit.py (431) — Finding, CAPA, Review, Internal Audit, Readiness, Trail, ISO27001
vvt.py (168)
tom.py ( 71)
compliance/api/schemas.py becomes a 39-line re-export shim so existing
imports (from compliance.api.schemas import RegulationResponse) keep
working unchanged. New code should import from the domain module
directly (from compliance.schemas.regulation import RegulationResponse).
Deferred-from-sweep: all 28 class Config blocks in the original file
were converted to model_config = ConfigDict(...) during the split.
schemas.py-sourced PydanticDeprecatedSince20 warnings are now gone.
Cross-domain references handled via targeted imports (e.g. dashboard.py
imports EvidenceResponse from evidence, RiskResponse from risk). common
API enums + PaginationMeta are imported by every domain module.
Verified:
- 173/173 pytest compliance/tests/ tests/contracts/ pass
- OpenAPI 360 paths / 484 operations unchanged (contract test green)
- All new files under the 500-line hard cap (largest: isms_audit.py
at 431, isms_governance.py at 343, dashboard.py at 195)
- No file in compliance/schemas/ or compliance/api/schemas.py
exceeds the hard cap
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
169 lines
5.5 KiB
Python
169 lines
5.5 KiB
Python
"""
|
|
VVT (Verzeichnis von Verarbeitungstätigkeiten) Pydantic schemas — extracted from compliance/api/schemas.py.
|
|
|
|
Phase 1 Step 3: the monolithic ``compliance.api.schemas`` module is being
|
|
split per domain under ``compliance.schemas``. This module is re-exported
|
|
from ``compliance.api.schemas`` for backwards compatibility.
|
|
"""
|
|
|
|
from datetime import datetime, date
|
|
from typing import Optional, List, Any, Dict
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
from compliance.schemas.common import (
|
|
PaginationMeta, RegulationType, ControlType, ControlDomain,
|
|
ControlStatus, RiskLevel, EvidenceStatus,
|
|
)
|
|
|
|
|
|
# ============================================================================
|
|
# VVT Schemas — Verzeichnis von Verarbeitungstaetigkeiten (Art. 30 DSGVO)
|
|
# ============================================================================
|
|
|
|
class VVTOrganizationUpdate(BaseModel):
|
|
organization_name: Optional[str] = None
|
|
industry: Optional[str] = None
|
|
locations: Optional[List[str]] = None
|
|
employee_count: Optional[int] = None
|
|
dpo_name: Optional[str] = None
|
|
dpo_contact: Optional[str] = None
|
|
vvt_version: Optional[str] = None
|
|
last_review_date: Optional[date] = None
|
|
next_review_date: Optional[date] = None
|
|
review_interval: Optional[str] = None
|
|
|
|
|
|
class VVTOrganizationResponse(BaseModel):
|
|
id: str
|
|
organization_name: str
|
|
industry: Optional[str] = None
|
|
locations: List[Any] = []
|
|
employee_count: Optional[int] = None
|
|
dpo_name: Optional[str] = None
|
|
dpo_contact: Optional[str] = None
|
|
vvt_version: str = '1.0'
|
|
last_review_date: Optional[date] = None
|
|
next_review_date: Optional[date] = None
|
|
review_interval: str = 'annual'
|
|
created_at: datetime
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class VVTActivityCreate(BaseModel):
|
|
vvt_id: str
|
|
name: str
|
|
description: Optional[str] = None
|
|
purposes: List[str] = []
|
|
legal_bases: List[str] = []
|
|
data_subject_categories: List[str] = []
|
|
personal_data_categories: List[str] = []
|
|
recipient_categories: List[str] = []
|
|
third_country_transfers: List[Any] = []
|
|
retention_period: Dict[str, Any] = {}
|
|
tom_description: Optional[str] = None
|
|
business_function: Optional[str] = None
|
|
systems: List[str] = []
|
|
deployment_model: Optional[str] = None
|
|
data_sources: List[Any] = []
|
|
data_flows: List[Any] = []
|
|
protection_level: str = 'MEDIUM'
|
|
dpia_required: bool = False
|
|
structured_toms: Dict[str, Any] = {}
|
|
status: str = 'DRAFT'
|
|
responsible: Optional[str] = None
|
|
owner: Optional[str] = None
|
|
last_reviewed_at: Optional[datetime] = None
|
|
next_review_at: Optional[datetime] = None
|
|
created_by: Optional[str] = None
|
|
dsfa_id: Optional[str] = None
|
|
|
|
|
|
class VVTActivityUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
description: Optional[str] = None
|
|
purposes: Optional[List[str]] = None
|
|
legal_bases: Optional[List[str]] = None
|
|
data_subject_categories: Optional[List[str]] = None
|
|
personal_data_categories: Optional[List[str]] = None
|
|
recipient_categories: Optional[List[str]] = None
|
|
third_country_transfers: Optional[List[Any]] = None
|
|
retention_period: Optional[Dict[str, Any]] = None
|
|
tom_description: Optional[str] = None
|
|
business_function: Optional[str] = None
|
|
systems: Optional[List[str]] = None
|
|
deployment_model: Optional[str] = None
|
|
data_sources: Optional[List[Any]] = None
|
|
data_flows: Optional[List[Any]] = None
|
|
protection_level: Optional[str] = None
|
|
dpia_required: Optional[bool] = None
|
|
structured_toms: Optional[Dict[str, Any]] = None
|
|
status: Optional[str] = None
|
|
responsible: Optional[str] = None
|
|
owner: Optional[str] = None
|
|
last_reviewed_at: Optional[datetime] = None
|
|
next_review_at: Optional[datetime] = None
|
|
created_by: Optional[str] = None
|
|
dsfa_id: Optional[str] = None
|
|
|
|
|
|
class VVTActivityResponse(BaseModel):
|
|
id: str
|
|
vvt_id: str
|
|
name: str
|
|
description: Optional[str] = None
|
|
purposes: List[Any] = []
|
|
legal_bases: List[Any] = []
|
|
data_subject_categories: List[Any] = []
|
|
personal_data_categories: List[Any] = []
|
|
recipient_categories: List[Any] = []
|
|
third_country_transfers: List[Any] = []
|
|
retention_period: Dict[str, Any] = {}
|
|
tom_description: Optional[str] = None
|
|
business_function: Optional[str] = None
|
|
systems: List[Any] = []
|
|
deployment_model: Optional[str] = None
|
|
data_sources: List[Any] = []
|
|
data_flows: List[Any] = []
|
|
protection_level: str = 'MEDIUM'
|
|
dpia_required: bool = False
|
|
structured_toms: Dict[str, Any] = {}
|
|
status: str = 'DRAFT'
|
|
responsible: Optional[str] = None
|
|
owner: Optional[str] = None
|
|
last_reviewed_at: Optional[datetime] = None
|
|
next_review_at: Optional[datetime] = None
|
|
created_by: Optional[str] = None
|
|
dsfa_id: Optional[str] = None
|
|
created_at: datetime
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class VVTStatsResponse(BaseModel):
|
|
total: int
|
|
by_status: Dict[str, int]
|
|
by_business_function: Dict[str, int]
|
|
dpia_required_count: int
|
|
third_country_count: int
|
|
draft_count: int
|
|
approved_count: int
|
|
overdue_review_count: int = 0
|
|
|
|
|
|
class VVTAuditLogEntry(BaseModel):
|
|
id: str
|
|
action: str
|
|
entity_type: str
|
|
entity_id: Optional[str] = None
|
|
changed_by: Optional[str] = None
|
|
old_values: Optional[Dict[str, Any]] = None
|
|
new_values: Optional[Dict[str, Any]] = None
|
|
created_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|