feat: add access module boundary migrations
This commit is contained in:
@@ -5,6 +5,8 @@ from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
||||
|
||||
from govoplan_core.api.v1.schemas import DeltaDeletedItem
|
||||
|
||||
RETENTION_DAY_KEYS = (
|
||||
"raw_campaign_json_retention_days",
|
||||
"generated_eml_retention_days",
|
||||
@@ -128,6 +130,9 @@ class TenantSettingsItem(BaseModel):
|
||||
slug: str
|
||||
name: str
|
||||
default_locale: str = Field(default="en", min_length=1, max_length=20)
|
||||
available_languages: list[dict[str, Any]] = Field(default_factory=list)
|
||||
system_enabled_language_codes: list[str] = Field(default_factory=list)
|
||||
enabled_language_codes: list[str] = Field(default_factory=list)
|
||||
settings: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
@@ -135,6 +140,7 @@ class TenantSettingsUpdateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
default_locale: str = Field(min_length=1, max_length=20)
|
||||
enabled_language_codes: list[str] | None = None
|
||||
|
||||
|
||||
class RoleSummary(BaseModel):
|
||||
@@ -153,6 +159,227 @@ class RoleSummary(BaseModel):
|
||||
system_required: bool = False
|
||||
|
||||
|
||||
class IdentityAccountLinkItem(BaseModel):
|
||||
id: str
|
||||
account_id: str
|
||||
email: str | None = None
|
||||
display_name: str | None = None
|
||||
is_primary: bool = False
|
||||
source: str = "local"
|
||||
|
||||
|
||||
class IdentityAdminItem(BaseModel):
|
||||
id: str
|
||||
display_name: str | None = None
|
||||
external_subject: str | None = None
|
||||
source: str = "local"
|
||||
is_active: bool = True
|
||||
accounts: list[IdentityAccountLinkItem] = Field(default_factory=list)
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class IdentityListResponse(BaseModel):
|
||||
identities: list[IdentityAdminItem]
|
||||
|
||||
|
||||
class IdentityCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
display_name: str | None = Field(default=None, max_length=255)
|
||||
external_subject: str | None = Field(default=None, max_length=255)
|
||||
source: str = Field(default="local", max_length=50)
|
||||
account_ids: list[str] = Field(default_factory=list)
|
||||
primary_account_id: str | None = None
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class IdentityUpdateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
display_name: str | None = Field(default=None, max_length=255)
|
||||
external_subject: str | None = Field(default=None, max_length=255)
|
||||
source: str | None = Field(default=None, max_length=50)
|
||||
account_ids: list[str] | None = None
|
||||
primary_account_id: str | None = None
|
||||
is_active: bool | None = None
|
||||
|
||||
|
||||
class OrganizationUnitItem(BaseModel):
|
||||
id: str
|
||||
tenant_id: str
|
||||
parent_id: str | None = None
|
||||
slug: str = Field(min_length=1, max_length=100)
|
||||
name: str = Field(min_length=1, max_length=255)
|
||||
description: str | None = None
|
||||
is_active: bool = True
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class OrganizationUnitListResponse(BaseModel):
|
||||
organization_units: list[OrganizationUnitItem]
|
||||
|
||||
|
||||
class OrganizationUnitCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
slug: str
|
||||
name: str = Field(min_length=1, max_length=255)
|
||||
parent_id: str | None = None
|
||||
description: str | None = None
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class OrganizationUnitUpdateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
slug: str | None = None
|
||||
name: str | None = Field(default=None, min_length=1, max_length=255)
|
||||
parent_id: str | None = None
|
||||
description: str | None = None
|
||||
is_active: bool | None = None
|
||||
|
||||
|
||||
class FunctionAdminItem(BaseModel):
|
||||
id: str
|
||||
tenant_id: str
|
||||
organization_unit_id: str
|
||||
slug: str = Field(min_length=1, max_length=100)
|
||||
name: str = Field(min_length=1, max_length=255)
|
||||
description: str | None = None
|
||||
role_ids: list[str] = Field(default_factory=list)
|
||||
delegable: bool = False
|
||||
act_in_place_allowed: bool = False
|
||||
is_active: bool = True
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class FunctionListResponse(BaseModel):
|
||||
functions: list[FunctionAdminItem]
|
||||
|
||||
|
||||
class FunctionCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
organization_unit_id: str
|
||||
slug: str
|
||||
name: str = Field(min_length=1, max_length=255)
|
||||
description: str | None = None
|
||||
role_ids: list[str] = Field(default_factory=list)
|
||||
delegable: bool = False
|
||||
act_in_place_allowed: bool = False
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class FunctionUpdateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
organization_unit_id: str | None = None
|
||||
slug: str | None = None
|
||||
name: str | None = Field(default=None, min_length=1, max_length=255)
|
||||
description: str | None = None
|
||||
role_ids: list[str] | None = None
|
||||
delegable: bool | None = None
|
||||
act_in_place_allowed: bool | None = None
|
||||
is_active: bool | None = None
|
||||
|
||||
|
||||
class FunctionAssignmentAdminItem(BaseModel):
|
||||
id: str
|
||||
tenant_id: str
|
||||
account_id: str
|
||||
identity_id: str | None = None
|
||||
function_id: str
|
||||
organization_unit_id: str
|
||||
applies_to_subunits: bool = False
|
||||
source: str = "direct"
|
||||
delegated_from_assignment_id: str | None = None
|
||||
acting_for_account_id: str | None = None
|
||||
valid_from: datetime | None = None
|
||||
valid_until: datetime | None = None
|
||||
is_active: bool = True
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class FunctionAssignmentListResponse(BaseModel):
|
||||
assignments: list[FunctionAssignmentAdminItem]
|
||||
|
||||
|
||||
class FunctionAssignmentCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
account_id: str
|
||||
function_id: str
|
||||
organization_unit_id: str | None = None
|
||||
identity_id: str | None = None
|
||||
applies_to_subunits: bool = False
|
||||
source: str = Field(default="direct", max_length=50)
|
||||
delegated_from_assignment_id: str | None = None
|
||||
acting_for_account_id: str | None = None
|
||||
valid_from: datetime | None = None
|
||||
valid_until: datetime | None = None
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class FunctionAssignmentUpdateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
identity_id: str | None = None
|
||||
organization_unit_id: str | None = None
|
||||
applies_to_subunits: bool | None = None
|
||||
source: str | None = Field(default=None, max_length=50)
|
||||
delegated_from_assignment_id: str | None = None
|
||||
acting_for_account_id: str | None = None
|
||||
valid_from: datetime | None = None
|
||||
valid_until: datetime | None = None
|
||||
is_active: bool | None = None
|
||||
|
||||
|
||||
class FunctionDelegationAdminItem(BaseModel):
|
||||
id: str
|
||||
tenant_id: str
|
||||
function_assignment_id: str
|
||||
delegator_account_id: str
|
||||
delegate_account_id: str
|
||||
mode: Literal["delegate", "act_in_place"] = "delegate"
|
||||
reason: str | None = None
|
||||
valid_from: datetime | None = None
|
||||
valid_until: datetime | None = None
|
||||
revoked_at: datetime | None = None
|
||||
is_active: bool = True
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class FunctionDelegationListResponse(BaseModel):
|
||||
delegations: list[FunctionDelegationAdminItem]
|
||||
|
||||
|
||||
class FunctionDelegationCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
function_assignment_id: str
|
||||
delegate_account_id: str
|
||||
mode: Literal["delegate", "act_in_place"] = "delegate"
|
||||
reason: str | None = None
|
||||
valid_from: datetime | None = None
|
||||
valid_until: datetime | None = None
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class FunctionDelegationUpdateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
reason: str | None = None
|
||||
valid_from: datetime | None = None
|
||||
valid_until: datetime | None = None
|
||||
is_active: bool | None = None
|
||||
revoked: bool | None = None
|
||||
|
||||
|
||||
class GroupSummary(BaseModel):
|
||||
id: str
|
||||
slug: str = Field(min_length=1, max_length=100)
|
||||
@@ -180,6 +407,8 @@ class UserAdminItem(BaseModel):
|
||||
last_login_at: datetime | None = None
|
||||
groups: list[GroupSummary] = Field(default_factory=list)
|
||||
roles: list[RoleSummary] = Field(default_factory=list)
|
||||
function_assignment_ids: list[str] = Field(default_factory=list)
|
||||
function_delegation_ids: list[str] = Field(default_factory=list)
|
||||
effective_scopes: list[str] = Field(default_factory=list)
|
||||
is_owner: bool = False
|
||||
is_last_active_owner: bool = False
|
||||
@@ -191,6 +420,13 @@ class UserListResponse(BaseModel):
|
||||
users: list[UserAdminItem]
|
||||
|
||||
|
||||
class UserListDeltaResponse(UserListResponse):
|
||||
deleted: list[DeltaDeletedItem] = Field(default_factory=list)
|
||||
watermark: str | None = None
|
||||
has_more: bool = False
|
||||
full: bool = False
|
||||
|
||||
|
||||
class UserCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@@ -222,6 +458,13 @@ class GroupListResponse(BaseModel):
|
||||
groups: list[GroupSummary]
|
||||
|
||||
|
||||
class GroupListDeltaResponse(GroupListResponse):
|
||||
deleted: list[DeltaDeletedItem] = Field(default_factory=list)
|
||||
watermark: str | None = None
|
||||
has_more: bool = False
|
||||
full: bool = False
|
||||
|
||||
|
||||
class GroupCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@@ -247,6 +490,13 @@ class RoleListResponse(BaseModel):
|
||||
roles: list[RoleSummary]
|
||||
|
||||
|
||||
class RoleListDeltaResponse(RoleListResponse):
|
||||
deleted: list[DeltaDeletedItem] = Field(default_factory=list)
|
||||
watermark: str | None = None
|
||||
has_more: bool = False
|
||||
full: bool = False
|
||||
|
||||
|
||||
class RoleCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@@ -280,6 +530,13 @@ class SystemAccountListResponse(BaseModel):
|
||||
roles: list[RoleSummary]
|
||||
|
||||
|
||||
class SystemAccountListDeltaResponse(SystemAccountListResponse):
|
||||
deleted: list[DeltaDeletedItem] = Field(default_factory=list)
|
||||
watermark: str | None = None
|
||||
has_more: bool = False
|
||||
full: bool = False
|
||||
|
||||
|
||||
class SystemAccountUpdateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@@ -396,12 +653,124 @@ class RetentionRunResponse(BaseModel):
|
||||
result: dict[str, Any]
|
||||
|
||||
|
||||
class ConfigurationSafetyFieldItem(BaseModel):
|
||||
key: str
|
||||
label: str
|
||||
owner_module: str
|
||||
scope: Literal["system", "tenant", "user", "group", "campaign"]
|
||||
storage: str
|
||||
ui_managed: bool
|
||||
risk: Literal["low", "medium", "high", "destructive"]
|
||||
secret_handling: Literal["none", "reference_only", "env_only"] = "none"
|
||||
required_scopes: list[str] = Field(default_factory=list)
|
||||
dry_run_required: bool = False
|
||||
validation_required: bool = True
|
||||
policy_explanation_required: bool = False
|
||||
audit_event: str | None = None
|
||||
maintenance_required: bool = False
|
||||
two_person_approval_required: bool = False
|
||||
rollback_history_required: bool = False
|
||||
notes: str | None = None
|
||||
|
||||
|
||||
class ConfigurationSafetyCatalogResponse(BaseModel):
|
||||
fields: list[ConfigurationSafetyFieldItem]
|
||||
|
||||
|
||||
class ConfigurationChangeSafetyPlanRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
key: str
|
||||
value: Any = None
|
||||
dry_run: bool = False
|
||||
maintenance_mode: bool = False
|
||||
approval_count: int = Field(default=0, ge=0)
|
||||
|
||||
|
||||
class ConfigurationChangeSafetyPlanResponse(BaseModel):
|
||||
plan: dict[str, Any]
|
||||
|
||||
|
||||
class ConfigurationChangeRequestCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
key: str
|
||||
value: Any = None
|
||||
dry_run: bool = False
|
||||
target: dict[str, Any] = Field(default_factory=dict)
|
||||
reason: str | None = Field(default=None, max_length=1000)
|
||||
|
||||
|
||||
class ConfigurationChangeRequestApproveRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
reason: str | None = Field(default=None, max_length=1000)
|
||||
|
||||
|
||||
class ConfigurationChangeRequestResponse(BaseModel):
|
||||
request: dict[str, Any]
|
||||
|
||||
|
||||
class ConfigurationControlSnapshotResponse(BaseModel):
|
||||
requests: list[dict[str, Any]] = Field(default_factory=list)
|
||||
history: list[dict[str, Any]] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ConfigurationControlDeltaResponse(ConfigurationControlSnapshotResponse):
|
||||
deleted: list[DeltaDeletedItem] = Field(default_factory=list)
|
||||
watermark: str | None = None
|
||||
has_more: bool = False
|
||||
full: bool = False
|
||||
|
||||
|
||||
class ConfigurationPackageCatalogResponse(BaseModel):
|
||||
validation: dict[str, Any]
|
||||
|
||||
|
||||
class ConfigurationPackageRunRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
package: dict[str, Any]
|
||||
tenant_id: str | None = None
|
||||
supplied_data: dict[str, Any] = Field(default_factory=dict)
|
||||
change_request_id: str | None = None
|
||||
|
||||
|
||||
class ConfigurationPackageDryRunResponse(BaseModel):
|
||||
diagnostics: list[dict[str, Any]] = Field(default_factory=list)
|
||||
required_data: list[dict[str, Any]] = Field(default_factory=list)
|
||||
plan: list[dict[str, Any]] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ConfigurationPackageApplyResponse(BaseModel):
|
||||
diagnostics: list[dict[str, Any]] = Field(default_factory=list)
|
||||
created_refs: dict[str, str] = Field(default_factory=dict)
|
||||
updated_refs: dict[str, str] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class ConfigurationPackageExportRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
tenant_id: str | None = None
|
||||
scopes: list[str] = Field(default_factory=list)
|
||||
module_ids: list[str] = Field(default_factory=list)
|
||||
object_refs: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ConfigurationPackageExportResponse(BaseModel):
|
||||
fragments: list[dict[str, Any]] = Field(default_factory=list)
|
||||
data_requirements: list[dict[str, Any]] = Field(default_factory=list)
|
||||
diagnostics: list[dict[str, Any]] = Field(default_factory=list)
|
||||
|
||||
|
||||
class SystemSettingsItem(BaseModel):
|
||||
default_locale: str = "en"
|
||||
allow_tenant_custom_groups: bool = True
|
||||
allow_tenant_custom_roles: bool = True
|
||||
allow_tenant_api_keys: bool = True
|
||||
privacy_retention_policy: PrivacyRetentionPolicyItem = Field(default_factory=PrivacyRetentionPolicyItem)
|
||||
available_languages: list[dict[str, Any]] = Field(default_factory=list)
|
||||
enabled_language_codes: list[str] = Field(default_factory=list)
|
||||
settings: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
@@ -413,6 +782,8 @@ class SystemSettingsUpdateRequest(BaseModel):
|
||||
allow_tenant_custom_roles: bool
|
||||
allow_tenant_api_keys: bool
|
||||
privacy_retention_policy: PrivacyRetentionPolicyItem | None = None
|
||||
available_languages: list[dict[str, Any]] | None = None
|
||||
enabled_language_codes: list[str] | None = None
|
||||
|
||||
|
||||
class ApiKeyAdminItem(BaseModel):
|
||||
@@ -432,6 +803,13 @@ class ApiKeyListResponse(BaseModel):
|
||||
api_keys: list[ApiKeyAdminItem]
|
||||
|
||||
|
||||
class ApiKeyListDeltaResponse(ApiKeyListResponse):
|
||||
deleted: list[DeltaDeletedItem] = Field(default_factory=list)
|
||||
watermark: str | None = None
|
||||
has_more: bool = False
|
||||
full: bool = False
|
||||
|
||||
|
||||
class AdminApiKeyCreateRequest(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@@ -463,3 +841,5 @@ class AuditAdminListResponse(BaseModel):
|
||||
page: int = 1
|
||||
page_size: int = 100
|
||||
pages: int = 1
|
||||
cursor: str | None = None
|
||||
next_cursor: str | None = None
|
||||
|
||||
Reference in New Issue
Block a user