from datetime import datetime from pydantic import BaseModel, Field, field_validator from admin_app.core import AdminCredentialStrategy from shared.contracts import AdminPermission, ServiceName, StaffRole, ToolLifecycleStatus, ToolParameterType class AdminRootResponse(BaseModel): service: str status: str message: str environment: str class AdminHealthResponse(BaseModel): service: str status: str version: str class AdminSystemInfoResponse(BaseModel): service: str app_name: str environment: str version: str api_prefix: str debug: bool class AdminAuthenticatedStaffResponse(BaseModel): id: int email: str display_name: str role: StaffRole is_active: bool class AdminCurrentAccessResponse(BaseModel): service: str staff_account: AdminAuthenticatedStaffResponse permissions: list[str] class AdminCapabilityResponse(BaseModel): service: str action: str allowed: bool role: StaffRole class AdminAuditEntryResponse(BaseModel): id: int actor_staff_account_id: int | None event_type: str resource_type: str resource_id: str | None outcome: str message: str | None payload_json: dict | None ip_address: str | None user_agent: str | None created_at: datetime class AdminAuditListResponse(BaseModel): service: str events: list[AdminAuditEntryResponse] class AdminRuntimeApplicationConfigurationResponse(BaseModel): app_name: str environment: str version: str api_prefix: str debug: bool class AdminRuntimeDatabaseConfigurationResponse(BaseModel): host: str port: int name: str cloud_sql_configured: bool class AdminPanelSessionConfigurationResponse(BaseModel): access_cookie_name: str refresh_cookie_name: str cookie_path: str same_site: str secure_cookies: bool class AdminSystemRuntimeConfigurationPayload(BaseModel): application: AdminRuntimeApplicationConfigurationResponse database: AdminRuntimeDatabaseConfigurationResponse panel_session: AdminPanelSessionConfigurationResponse class AdminConfigurationSourceResponse(BaseModel): key: str source: str mutable: bool description: str class AdminSystemRuntimeConfigurationResponse(BaseModel): service: str runtime: AdminSystemRuntimeConfigurationPayload class AdminSystemSecurityConfigurationResponse(BaseModel): service: str security: AdminCredentialStrategy class AdminSystemConfigurationResponse(BaseModel): service: str runtime: AdminSystemRuntimeConfigurationPayload security: AdminCredentialStrategy sources: list[AdminConfigurationSourceResponse] class AdminLoginRequest(BaseModel): email: str password: str = Field(min_length=1) @field_validator("email") @classmethod def validate_email(cls, value: str) -> str: normalized = value.strip().lower() if "@" not in normalized or normalized.startswith("@") or normalized.endswith("@"): raise ValueError("email must be a valid administrative login") return normalized class AdminRefreshTokenRequest(BaseModel): refresh_token: str = Field(min_length=1) class AdminSessionResponse(BaseModel): session_id: int access_token: str refresh_token: str token_type: str expires_in_seconds: int staff_account: AdminAuthenticatedStaffResponse class AdminLogoutResponse(BaseModel): service: str status: str message: str session_id: int class AdminPanelWebSessionResponse(BaseModel): service: str status: str message: str session_id: int expires_in_seconds: int staff_account: AdminAuthenticatedStaffResponse redirect_to: str | None = None class AdminPanelLogoutResponse(BaseModel): service: str status: str message: str session_id: int | None redirect_to: str class AdminToolManagementMetricResponse(BaseModel): key: str label: str value: str description: str class AdminToolLifecycleStageResponse(BaseModel): code: ToolLifecycleStatus label: str description: str class AdminToolParameterTypeResponse(BaseModel): code: ToolParameterType label: str description: str class AdminToolManagementActionResponse(BaseModel): key: str label: str href: str required_permission: AdminPermission description: str class AdminToolOverviewResponse(BaseModel): service: str mode: str metrics: list[AdminToolManagementMetricResponse] workflow: list[AdminToolLifecycleStageResponse] actions: list[AdminToolManagementActionResponse] next_steps: list[str] class AdminToolContractsResponse(BaseModel): service: str publication_source_service: ServiceName publication_target_service: ServiceName lifecycle_statuses: list[AdminToolLifecycleStageResponse] parameter_types: list[AdminToolParameterTypeResponse] publication_fields: list[str] published_tool_fields: list[str] class AdminToolDraftSummaryResponse(BaseModel): draft_id: str tool_name: str display_name: str status: ToolLifecycleStatus summary: str owner_name: str | None = None updated_at: datetime | None = None class AdminToolDraftListResponse(BaseModel): service: str storage_status: str message: str drafts: list[AdminToolDraftSummaryResponse] supported_statuses: list[ToolLifecycleStatus] class AdminToolReviewQueueEntryResponse(BaseModel): entry_id: str tool_name: str display_name: str status: ToolLifecycleStatus gate: str summary: str owner_name: str | None = None queued_at: datetime | None = None class AdminToolReviewQueueResponse(BaseModel): service: str queue_mode: str message: str items: list[AdminToolReviewQueueEntryResponse] supported_statuses: list[ToolLifecycleStatus] class AdminToolPublicationSummaryResponse(BaseModel): publication_id: str tool_name: str display_name: str description: str domain: str version: int status: ToolLifecycleStatus parameter_count: int implementation_module: str implementation_callable: str published_by: str | None = None published_at: datetime | None = None class AdminToolPublicationListResponse(BaseModel): service: str source: str target_service: ServiceName publications: list[AdminToolPublicationSummaryResponse]