код написан

This commit is contained in:
2026-03-10 12:00:18 +03:00
parent 82435822eb
commit 31717870e3
57 changed files with 53951 additions and 4909 deletions

View File

@@ -6,7 +6,7 @@
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> sqlalchemy
from sqlalchemy import Column, String, DateTime, JSON
from sqlalchemy import Column, String, DateTime, JSON, Boolean
from sqlalchemy.sql import func
from .mapping import Base
@@ -23,4 +23,21 @@ class AppConfigRecord(Base):
# [/DEF:AppConfigRecord:Class]
# [DEF:NotificationConfig:Class]
# @PURPOSE: Global settings for external notification providers.
class NotificationConfig(Base):
__tablename__ = "notification_configs"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
type = Column(String, nullable=False) # SMTP, SLACK, TELEGRAM
name = Column(String, nullable=False)
credentials = Column(JSON, nullable=False) # Encrypted connection details
is_active = Column(Boolean, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
# [/DEF:NotificationConfig:Class]
import uuid
# [/DEF:backend.src.models.config:Module]

View File

@@ -5,7 +5,7 @@
# @LAYER: Domain
# @RELATION: INHERITS_FROM -> backend.src.models.mapping.Base
from sqlalchemy import Column, String, Boolean, DateTime, JSON, Text
from sqlalchemy import Column, String, Boolean, DateTime, JSON, Text, Time, ForeignKey
from datetime import datetime
import uuid
from .mapping import Base
@@ -13,6 +13,26 @@ from .mapping import Base
def generate_uuid():
return str(uuid.uuid4())
# [DEF:ValidationPolicy:Class]
# @PURPOSE: Defines a scheduled rule for validating a group of dashboards within an execution window.
class ValidationPolicy(Base):
__tablename__ = "validation_policies"
id = Column(String, primary_key=True, default=generate_uuid)
name = Column(String, nullable=False)
environment_id = Column(String, nullable=False)
is_active = Column(Boolean, default=True)
dashboard_ids = Column(JSON, nullable=False) # Array of dashboard IDs
schedule_days = Column(JSON, nullable=False) # Array of integers (0-6)
window_start = Column(Time, nullable=False)
window_end = Column(Time, nullable=False)
notify_owners = Column(Boolean, default=True)
custom_channels = Column(JSON, nullable=True) # List of external channels
alert_condition = Column(String, default="FAIL_ONLY") # FAIL_ONLY, WARN_AND_FAIL, ALWAYS
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# [/DEF:ValidationPolicy:Class]
# [DEF:LLMProvider:Class]
# @PURPOSE: SQLAlchemy model for LLM provider configuration.
class LLMProvider(Base):
@@ -34,9 +54,11 @@ class ValidationRecord(Base):
__tablename__ = "llm_validation_results"
id = Column(String, primary_key=True, default=generate_uuid)
task_id = Column(String, nullable=True, index=True) # Reference to TaskRecord
dashboard_id = Column(String, nullable=False, index=True)
environment_id = Column(String, nullable=True, index=True)
timestamp = Column(DateTime, default=datetime.utcnow)
status = Column(String, nullable=False) # PASS, WARN, FAIL
status = Column(String, nullable=False) # PASS, WARN, FAIL, UNKNOWN
screenshot_path = Column(String, nullable=True)
issues = Column(JSON, nullable=False)
summary = Column(Text, nullable=False)

View File

@@ -41,6 +41,10 @@ class UserDashboardPreference(Base):
auto_open_task_drawer = Column(Boolean, nullable=False, default=True)
dashboards_table_density = Column(String, nullable=False, default="comfortable")
telegram_id = Column(String, nullable=True)
email_address = Column(String, nullable=True)
notify_on_fail = Column(Boolean, nullable=False, default=True)
created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
updated_at = Column(
DateTime,

View File

@@ -112,6 +112,7 @@ class TaskReport(BaseModel):
updated_at: datetime
summary: str
details: Optional[Dict[str, Any]] = None
validation_record: Optional[Dict[str, Any]] = None # Extended for US2
error_context: Optional[ErrorContext] = None
source_ref: Optional[Dict[str, Any]] = None