Full optimization cycle: Protocol (15 files): - 4-layer SSOT architecture for agent prompts & skills - Anti-Corruption Protocol consolidated from 5 duplicates - Tag-to-tier permissiveness matrix (all @tags allowed at all tiers) Axiom config: - complexity_rules: all 22+ tags available on C1-C5 - contract_type_overrides: removed (was narrowing per-type) - 18 new tags added, LAYER enum expanded (Infra, Frontend, Atom, etc.) - RELATION predicates expanded (USES, CONTAINS, BELONGS_TO, etc.) Code fixes: - 2216 @TAG: normalized to @TAG (colon→space) - 518 [DEF] blocks migrated to #region/#endregion (37 files) - VERIFIES→BINDS_TO, :Class/:Function suffixes removed, paths→IDs - 1173-line _external_stubs.py deleted (EXT: handled natively) - Batch EXT: reference audit (240 targets: 132 external, 99 internal, 9 fix) - QA regression check: 0 regressions across all checks Infrastructure: - DuckDB rebuild stabilized (appender API, INSERT OR IGNORE) - Anchor regex fix (parent-child BINDS_TO now resolves) - EXT:*/DTO:/NEED_CONTEXT: regex fixed in validator - 34MB Doxygen API portal (3194 contract pages)
216 lines
7.4 KiB
Python
216 lines
7.4 KiB
Python
# #region MaintenanceModels [C:2] [TYPE Module] [SEMANTICS sqlalchemy, maintenance, banner, event, settings, model]
|
|
# @BRIEF SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.
|
|
# @LAYER Domain
|
|
# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]
|
|
# @RELATION DEPENDS_ON -> [MappingModels]
|
|
# @INVARIANT MaintenanceDashboardBanner has unique partial index on (environment_id, dashboard_id) WHERE status='active'
|
|
# @INVARIANT MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint
|
|
|
|
import enum
|
|
import uuid
|
|
|
|
from sqlalchemy import (
|
|
CheckConstraint,
|
|
Column,
|
|
DateTime,
|
|
Enum as SQLEnum,
|
|
ForeignKey,
|
|
Index,
|
|
Integer,
|
|
JSON,
|
|
String,
|
|
Text,
|
|
)
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.sql import func
|
|
|
|
from .mapping import Base
|
|
|
|
|
|
# #region MaintenanceEventStatus [C:1] [TYPE Class]
|
|
class MaintenanceEventStatus(str, enum.Enum):
|
|
PENDING = "pending"
|
|
APPLYING = "applying"
|
|
ACTIVE = "active"
|
|
PARTIAL = "partial"
|
|
ENDING = "ending"
|
|
COMPLETED = "completed"
|
|
FAILED = "failed"
|
|
# #endregion MaintenanceEventStatus
|
|
|
|
|
|
# #region MaintenanceDashboardBannerStatus [C:1] [TYPE Class]
|
|
class MaintenanceDashboardBannerStatus(str, enum.Enum):
|
|
ACTIVE = "active"
|
|
REMOVED = "removed"
|
|
# #endregion MaintenanceDashboardBannerStatus
|
|
|
|
|
|
# #region MaintenanceDashboardStateStatus [C:1] [TYPE Class]
|
|
class MaintenanceDashboardStateStatus(str, enum.Enum):
|
|
PENDING_APPLY = "pending_apply"
|
|
ACTIVE = "active"
|
|
REMOVING = "removing"
|
|
REMOVED = "removed"
|
|
APPLY_FAILED = "apply_failed"
|
|
REMOVAL_FAILED = "removal_failed"
|
|
# #endregion MaintenanceDashboardStateStatus
|
|
|
|
|
|
# #region DashboardScope [C:1] [TYPE Class]
|
|
class DashboardScope(str, enum.Enum):
|
|
PUBLISHED_ONLY = "published_only"
|
|
DRAFT_ONLY = "draft_only"
|
|
ALL = "all"
|
|
# #endregion DashboardScope
|
|
|
|
|
|
# #region MaintenanceEvent [C:1] [TYPE Class]
|
|
# @BRIEF A record of a maintenance event with table list, time window, status, and linked dashboard states.
|
|
# @RELATION DEPENDS_ON -> [MaintenanceDashboardState]
|
|
class MaintenanceEvent(Base):
|
|
__tablename__ = "maintenance_events"
|
|
|
|
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)
|
|
task_id = Column(String, nullable=True, index=True)
|
|
environment_id = Column(String, nullable=False)
|
|
tables = Column(JSON, nullable=False)
|
|
start_time = Column(DateTime(timezone=True), nullable=False)
|
|
end_time = Column(DateTime(timezone=True), nullable=True)
|
|
message = Column(Text, nullable=True)
|
|
status = Column(
|
|
SQLEnum(MaintenanceEventStatus),
|
|
nullable=False,
|
|
default=MaintenanceEventStatus.PENDING,
|
|
index=True,
|
|
)
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
dashboard_states = relationship(
|
|
"MaintenanceDashboardState",
|
|
back_populates="maintenance_event",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
# #endregion MaintenanceEvent
|
|
|
|
|
|
# #region MaintenanceDashboardBanner [C:1] [TYPE Class]
|
|
# @BRIEF The canonical "one chart per dashboard" entity. Unique partial index enforces single active banner per dashboard.
|
|
# @INVARIANT Unique partial index (environment_id, dashboard_id) WHERE status='active'
|
|
class MaintenanceDashboardBanner(Base):
|
|
__tablename__ = "maintenance_dashboard_banners"
|
|
|
|
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)
|
|
environment_id = Column(String, nullable=False)
|
|
dashboard_id = Column(Integer, nullable=False, index=True)
|
|
chart_id = Column(Integer, nullable=True)
|
|
banner_text = Column(Text, nullable=True)
|
|
status = Column(
|
|
SQLEnum(MaintenanceDashboardBannerStatus),
|
|
nullable=False,
|
|
default=MaintenanceDashboardBannerStatus.ACTIVE,
|
|
)
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
dashboard_states = relationship(
|
|
"MaintenanceDashboardState", back_populates="banner"
|
|
)
|
|
|
|
__table_args__ = (
|
|
Index(
|
|
"ix_banner_unique_active",
|
|
"environment_id",
|
|
"dashboard_id",
|
|
unique=True,
|
|
postgresql_where=(status == "active"),
|
|
),
|
|
)
|
|
# #endregion MaintenanceDashboardBanner
|
|
|
|
|
|
# #region MaintenanceDashboardState [C:1] [TYPE Class]
|
|
# @BRIEF Links a maintenance event to a dashboard via a banner. Tracks per-dashboard-per-event lifecycle.
|
|
# @RELATION DEPENDS_ON -> [MaintenanceEvent]
|
|
# @RELATION DEPENDS_ON -> [MaintenanceDashboardBanner]
|
|
class MaintenanceDashboardState(Base):
|
|
__tablename__ = "maintenance_dashboard_states"
|
|
|
|
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)
|
|
event_id = Column(
|
|
String, ForeignKey("maintenance_events.id"), nullable=False, index=True
|
|
)
|
|
dashboard_id = Column(Integer, nullable=False, index=True)
|
|
banner_id = Column(
|
|
String,
|
|
ForeignKey("maintenance_dashboard_banners.id"),
|
|
nullable=True,
|
|
)
|
|
status = Column(
|
|
SQLEnum(MaintenanceDashboardStateStatus),
|
|
nullable=False,
|
|
default=MaintenanceDashboardStateStatus.PENDING_APPLY,
|
|
)
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
maintenance_event = relationship(
|
|
"MaintenanceEvent", back_populates="dashboard_states"
|
|
)
|
|
banner = relationship(
|
|
"MaintenanceDashboardBanner", back_populates="dashboard_states"
|
|
)
|
|
|
|
__table_args__ = (
|
|
Index("ix_mds_dashboard_status", "dashboard_id", "status"),
|
|
)
|
|
# #endregion MaintenanceDashboardState
|
|
|
|
|
|
# #region MaintenanceSettings [C:1] [TYPE Class]
|
|
# @BRIEF Single-row maintenance mode configuration. Enforces singleton via CheckConstraint(id='default').
|
|
# @INVARIANT id must always be 'default' — enforced by CheckConstraint
|
|
class MaintenanceSettings(Base):
|
|
__tablename__ = "maintenance_settings"
|
|
|
|
id = Column(String, primary_key=True, default="default")
|
|
target_environment_id = Column(String, nullable=False)
|
|
display_timezone = Column(String, nullable=False, default="UTC")
|
|
banner_template = Column(
|
|
Text,
|
|
nullable=False,
|
|
default=(
|
|
'<div style="background:#FFF3E0;padding:16px;border-left:4px solid #FF9800;border-radius:4px">\n\n'
|
|
"## ⚠️ Технические работы\n\n"
|
|
"{message}\n\n"
|
|
"**Начало:** {start_time}\n"
|
|
"**Конец:** {end_time}\n\n"
|
|
"*Данные могут быть неполными или временно недоступны.*\n\n"
|
|
"</div>"
|
|
),
|
|
)
|
|
dashboard_scope = Column(
|
|
SQLEnum(DashboardScope),
|
|
nullable=False,
|
|
default=DashboardScope.PUBLISHED_ONLY,
|
|
)
|
|
excluded_dashboard_ids = Column(JSON, nullable=False, default=list)
|
|
forced_dashboard_ids = Column(JSON, nullable=False, default=list)
|
|
updated_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
__table_args__ = (
|
|
CheckConstraint("id = 'default'", name="ck_settings_singleton"),
|
|
)
|
|
# #endregion MaintenanceSettings
|
|
|
|
# #endregion MaintenanceModels
|