intermittent commit

This commit is contained in:
2026-07-14 13:22:09 +02:00
parent f2afcaa09c
commit ab07075a67
17 changed files with 1821 additions and 586 deletions

View File

@@ -3,41 +3,10 @@ from __future__ import annotations
from datetime import datetime
from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic import BaseModel, ConfigDict, Field
from govoplan_core.api.v1.schemas import DeltaDeletedItem
RETENTION_DAY_KEYS = (
"raw_campaign_json_retention_days",
"generated_eml_retention_days",
"stored_report_detail_retention_days",
"mock_mailbox_retention_days",
"audit_detail_retention_days",
)
RETENTION_POLICY_FIELD_KEYS = (
"store_raw_campaign_json",
*RETENTION_DAY_KEYS,
"audit_detail_level",
)
def default_allow_lower_level_limits() -> dict[str, bool]:
return {key: True for key in RETENTION_POLICY_FIELD_KEYS}
def normalize_allow_lower_level_limits(value: Any, *, fill_defaults: bool) -> dict[str, bool] | None:
if value in (None, ""):
return default_allow_lower_level_limits() if fill_defaults else None
if not isinstance(value, dict):
raise ValueError("allow_lower_level_limits must be an object")
normalized = default_allow_lower_level_limits() if fill_defaults else {}
for key, allowed in value.items():
clean_key = str(key)
if clean_key not in RETENTION_POLICY_FIELD_KEYS:
raise ValueError(f"Unknown retention policy field: {clean_key}")
normalized[clean_key] = bool(allowed)
return normalized
from govoplan_core.privacy.schemas import PrivacyRetentionPolicyItem, PrivacyRetentionPolicyPatchItem
class PermissionItem(BaseModel):
@@ -98,6 +67,13 @@ class TenantOwnerCandidateListResponse(BaseModel):
accounts: list[TenantOwnerCandidate]
class PagedListResponse(BaseModel):
total: int = 0
page: int = 1
page_size: int = 500
pages: int = 1
class TenantCreateRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
@@ -179,7 +155,7 @@ class IdentityAdminItem(BaseModel):
updated_at: datetime
class IdentityListResponse(BaseModel):
class IdentityListResponse(PagedListResponse):
identities: list[IdentityAdminItem]
@@ -529,7 +505,7 @@ class ResourceAccessExplanationResponse(BaseModel):
provenance: list[AccessDecisionProvenanceItem] = Field(default_factory=list)
class UserListResponse(BaseModel):
class UserListResponse(PagedListResponse):
users: list[UserAdminItem]
@@ -567,7 +543,7 @@ class UserUpdateRequest(BaseModel):
role_ids: list[str] | None = None
class GroupListResponse(BaseModel):
class GroupListResponse(PagedListResponse):
groups: list[GroupSummary]
@@ -599,7 +575,7 @@ class GroupUpdateRequest(BaseModel):
role_ids: list[str] | None = None
class RoleListResponse(BaseModel):
class RoleListResponse(PagedListResponse):
roles: list[RoleSummary]
@@ -638,7 +614,7 @@ class SystemAccountItem(BaseModel):
last_login_at: datetime | None = None
class SystemAccountListResponse(BaseModel):
class SystemAccountListResponse(PagedListResponse):
accounts: list[SystemAccountItem]
roles: list[RoleSummary]
@@ -704,42 +680,6 @@ class PolicySourceStepItem(BaseModel):
policy: dict[str, Any] = Field(default_factory=dict)
class PrivacyRetentionPolicyItem(BaseModel):
model_config = ConfigDict(extra="forbid")
store_raw_campaign_json: bool = True
raw_campaign_json_retention_days: int | None = Field(default=None, ge=0)
generated_eml_retention_days: int | None = Field(default=None, ge=0)
stored_report_detail_retention_days: int | None = Field(default=None, ge=0)
mock_mailbox_retention_days: int | None = Field(default=None, ge=0)
audit_detail_retention_days: int | None = Field(default=None, ge=0)
audit_detail_level: Literal["full", "redacted", "minimal"] = "full"
allow_lower_level_limits: dict[str, bool] = Field(default_factory=default_allow_lower_level_limits)
@field_validator("allow_lower_level_limits", mode="before")
@classmethod
def _normalize_allow_lower_level_limits(cls, value: Any) -> Any:
return normalize_allow_lower_level_limits(value, fill_defaults=True)
class PrivacyRetentionPolicyPatchItem(BaseModel):
model_config = ConfigDict(extra="forbid")
store_raw_campaign_json: bool | None = None
raw_campaign_json_retention_days: int | None = Field(default=None, ge=0)
generated_eml_retention_days: int | None = Field(default=None, ge=0)
stored_report_detail_retention_days: int | None = Field(default=None, ge=0)
mock_mailbox_retention_days: int | None = Field(default=None, ge=0)
audit_detail_retention_days: int | None = Field(default=None, ge=0)
audit_detail_level: Literal["full", "redacted", "minimal"] | None = None
allow_lower_level_limits: dict[str, bool] | None = None
@field_validator("allow_lower_level_limits", mode="before")
@classmethod
def _normalize_allow_lower_level_limits(cls, value: Any) -> Any:
return normalize_allow_lower_level_limits(value, fill_defaults=False)
class PrivacyRetentionPolicyScopeRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
@@ -912,7 +852,7 @@ class ApiKeyAdminItem(BaseModel):
created_at: datetime
class ApiKeyListResponse(BaseModel):
class ApiKeyListResponse(PagedListResponse):
api_keys: list[ApiKeyAdminItem]