158 lines
5.6 KiB
Python
158 lines
5.6 KiB
Python
# #region MaintenanceSchemasModule [C:2] [TYPE Module] [SEMANTICS pydantic, schema, maintenance, request, response]
|
|
# @BRIEF Pydantic models for Maintenance Banner API: request/response schemas per data-model.md.
|
|
# @LAYER API
|
|
# @RELATION DEPENDS_ON -> [EXT:Library:pydantic]
|
|
# @INVARIANT All response schemas use the standard envelope shape: { status, data, error, meta }
|
|
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ── Request Schemas ──────────────────────────────────────────
|
|
|
|
# #region MaintenanceStartRequest [C:1] [TYPE Class]
|
|
# @BRIEF POST /api/maintenance/start request body with environment scoping.
|
|
class MaintenanceStartRequest(BaseModel):
|
|
tables: list[str] = Field(..., min_length=1, max_length=100)
|
|
start_time: datetime
|
|
end_time: datetime | None = None
|
|
message: str | None = Field(None, max_length=500)
|
|
environment_id: str = Field(..., description="Target environment for the maintenance operation")
|
|
# #endregion MaintenanceStartRequest
|
|
|
|
|
|
# #region MaintenanceSettingsUpdate [C:1] [TYPE Class]
|
|
# @BRIEF PUT /api/maintenance/settings request body — all fields optional for partial update.
|
|
class MaintenanceSettingsUpdate(BaseModel):
|
|
target_environment_id: str | None = None
|
|
display_timezone: str | None = None
|
|
banner_template: str | None = None
|
|
dashboard_scope: str | None = None
|
|
excluded_dashboard_ids: list[int] | None = None
|
|
forced_dashboard_ids: list[int] | None = None
|
|
# #endregion MaintenanceSettingsUpdate
|
|
|
|
|
|
# ── Response Schemas ─────────────────────────────────────────
|
|
|
|
# #region MaintenanceStartResponse [C:1] [TYPE Class]
|
|
# @BRIEF Response for /api/maintenance/start — always 202 with task_id.
|
|
class MaintenanceStartResponse(BaseModel):
|
|
task_id: str
|
|
maintenance_id: str
|
|
status: str # "pending"
|
|
# #endregion MaintenanceStartResponse
|
|
|
|
|
|
# #region MaintenanceDashboardResult [C:1] [TYPE Class]
|
|
# @BRIEF Describes a single dashboard affected by a maintenance operation.
|
|
class MaintenanceDashboardResult(BaseModel):
|
|
id: int
|
|
title: str
|
|
chart_id: int | None = None
|
|
# #endregion MaintenanceDashboardResult
|
|
|
|
|
|
# #region MaintenanceFailedDashboard [C:1] [TYPE Class]
|
|
# @BRIEF Describes a dashboard that failed during banner apply/removal.
|
|
class MaintenanceFailedDashboard(BaseModel):
|
|
id: int
|
|
title: str
|
|
error: str
|
|
# #endregion MaintenanceFailedDashboard
|
|
|
|
|
|
# #region MaintenanceTaskResult [C:1] [TYPE Class]
|
|
# @BRIEF Result payload for a completed maintenance start task.
|
|
class MaintenanceTaskResult(BaseModel):
|
|
maintenance_id: str
|
|
status: str # "active" | "partial" | "completed" | "no_match"
|
|
affected_dashboards: int = 0
|
|
dashboards: list[MaintenanceDashboardResult] = []
|
|
failed_dashboards: list[MaintenanceFailedDashboard] = []
|
|
unmatched_tables: list[str] = []
|
|
# #endregion MaintenanceTaskResult
|
|
|
|
|
|
# #region MaintenanceEndResponse [C:1] [TYPE Class]
|
|
# @BRIEF Response for /api/maintenance/{id}/end and /api/maintenance/end-all — always 202 with task_id.
|
|
class MaintenanceEndResponse(BaseModel):
|
|
task_id: str
|
|
status: str # "pending"
|
|
# #endregion MaintenanceEndResponse
|
|
|
|
|
|
# #region MaintenanceEndTaskResult [C:1] [TYPE Class]
|
|
# @BRIEF Result payload for a completed end maintenance task.
|
|
class MaintenanceEndTaskResult(BaseModel):
|
|
maintenance_id: str
|
|
removed_from: int = 0
|
|
failed_removals: list[MaintenanceFailedDashboard] = []
|
|
# #endregion MaintenanceEndTaskResult
|
|
|
|
|
|
# #region MaintenanceEndAllTaskResult [C:1] [TYPE Class]
|
|
# @BRIEF Result payload for a completed end-all maintenance task.
|
|
class MaintenanceEndAllTaskResult(BaseModel):
|
|
closed_events: int = 0
|
|
removed_from: int = 0
|
|
failed_removals: list[MaintenanceFailedDashboard] = []
|
|
# #endregion MaintenanceEndAllTaskResult
|
|
|
|
|
|
# #region MaintenanceSettingsResponse [C:1] [TYPE Class]
|
|
# @BRIEF Response for GET /api/maintenance/settings.
|
|
class MaintenanceSettingsResponse(BaseModel):
|
|
target_environment_id: str
|
|
display_timezone: str
|
|
banner_template: str
|
|
dashboard_scope: str
|
|
excluded_dashboard_ids: list[int]
|
|
forced_dashboard_ids: list[int]
|
|
updated_at: str | None = None
|
|
# #endregion MaintenanceSettingsResponse
|
|
|
|
|
|
# #region MaintenanceEventItem [C:1] [TYPE Class]
|
|
# @BRIEF Single maintenance event summary for GET /api/maintenance/events.
|
|
class MaintenanceEventItem(BaseModel):
|
|
id: str
|
|
tables: list[str]
|
|
start_time: str
|
|
end_time: str | None = None
|
|
message: str | None = None
|
|
status: str
|
|
affected_count: int
|
|
created_at: str
|
|
# #endregion MaintenanceEventItem
|
|
|
|
|
|
# #region MaintenanceEventListResponse [C:1] [TYPE Class]
|
|
# @BRIEF Response for GET /api/maintenance/events.
|
|
class MaintenanceEventListResponse(BaseModel):
|
|
active: list[MaintenanceEventItem]
|
|
completed: list[MaintenanceEventItem]
|
|
# #endregion MaintenanceEventListResponse
|
|
|
|
|
|
# #region MaintenanceDashboardBannerState [C:1] [TYPE Class]
|
|
# @BRIEF Per-dashboard banner state for GET /api/maintenance/dashboard-banners.
|
|
class MaintenanceDashboardBannerState(BaseModel):
|
|
dashboard_id: int
|
|
active: bool
|
|
events: list[str]
|
|
start_time: str | None = None
|
|
end_time: str | None = None
|
|
# #endregion MaintenanceDashboardBannerState
|
|
|
|
|
|
# #region MaintenanceAlreadyActiveResponse [C:1] [TYPE Class]
|
|
# @BRIEF Response for duplicate /start call — idempotency hit.
|
|
class MaintenanceAlreadyActiveResponse(BaseModel):
|
|
maintenance_id: str
|
|
status: str = "already_active"
|
|
# #endregion MaintenanceAlreadyActiveResponse
|
|
|
|
# #endregion MaintenanceSchemasModule
|