fix: commit semantic repair changes
This commit is contained in:
@@ -36,17 +36,27 @@ def valid_candidate_data():
|
||||
"source_snapshot_ref": "v1.0.0-snapshot"
|
||||
}
|
||||
|
||||
# [DEF:test_release_candidate_valid:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify that a valid release candidate can be instantiated.
|
||||
def test_release_candidate_valid(valid_candidate_data):
|
||||
rc = ReleaseCandidate(**valid_candidate_data)
|
||||
assert rc.candidate_id == "RC-001"
|
||||
assert rc.status == ReleaseCandidateStatus.DRAFT
|
||||
|
||||
# [/DEF:test_release_candidate_valid:Function]
|
||||
|
||||
# [DEF:test_release_candidate_empty_id:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify that a release candidate with an empty ID is rejected.
|
||||
def test_release_candidate_empty_id(valid_candidate_data):
|
||||
valid_candidate_data["candidate_id"] = " "
|
||||
with pytest.raises(ValueError, match="candidate_id must be non-empty"):
|
||||
ReleaseCandidate(**valid_candidate_data)
|
||||
|
||||
# @TEST_FIXTURE: valid_enterprise_policy
|
||||
# [/DEF:test_release_candidate_empty_id:Function]
|
||||
|
||||
@pytest.fixture
|
||||
def valid_policy_data():
|
||||
return {
|
||||
@@ -61,17 +71,30 @@ def valid_policy_data():
|
||||
}
|
||||
|
||||
# @TEST_INVARIANT: policy_purity
|
||||
# [DEF:test_enterprise_policy_valid:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify that a valid enterprise policy is accepted.
|
||||
def test_enterprise_policy_valid(valid_policy_data):
|
||||
policy = CleanProfilePolicy(**valid_policy_data)
|
||||
assert policy.external_source_forbidden is True
|
||||
|
||||
# @TEST_EDGE: enterprise_policy_missing_prohibited
|
||||
# [/DEF:test_enterprise_policy_valid:Function]
|
||||
|
||||
# [DEF:test_enterprise_policy_missing_prohibited:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify that an enterprise policy without prohibited categories is rejected.
|
||||
def test_enterprise_policy_missing_prohibited(valid_policy_data):
|
||||
valid_policy_data["prohibited_artifact_categories"] = []
|
||||
with pytest.raises(ValueError, match="enterprise-clean policy requires prohibited_artifact_categories"):
|
||||
CleanProfilePolicy(**valid_policy_data)
|
||||
|
||||
# @TEST_EDGE: enterprise_policy_external_allowed
|
||||
# [/DEF:test_enterprise_policy_missing_prohibited:Function]
|
||||
|
||||
# [DEF:test_enterprise_policy_external_allowed:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify that an enterprise policy allowing external sources is rejected.
|
||||
def test_enterprise_policy_external_allowed(valid_policy_data):
|
||||
valid_policy_data["external_source_forbidden"] = False
|
||||
with pytest.raises(ValueError, match="enterprise-clean policy requires external_source_forbidden=true"):
|
||||
@@ -79,6 +102,11 @@ def test_enterprise_policy_external_allowed(valid_policy_data):
|
||||
|
||||
# @TEST_INVARIANT: manifest_consistency
|
||||
# @TEST_EDGE: manifest_count_mismatch
|
||||
# [/DEF:test_enterprise_policy_external_allowed:Function]
|
||||
|
||||
# [DEF:test_manifest_count_mismatch:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify that a manifest with count mismatches is rejected.
|
||||
def test_manifest_count_mismatch():
|
||||
summary = ManifestSummary(included_count=1, excluded_count=0, prohibited_detected_count=0)
|
||||
item = ManifestItem(path="p", category="c", classification=ClassificationType.ALLOWED, reason="r")
|
||||
@@ -101,6 +129,11 @@ def test_manifest_count_mismatch():
|
||||
|
||||
# @TEST_INVARIANT: run_integrity
|
||||
# @TEST_EDGE: compliant_run_stage_fail
|
||||
# [/DEF:test_manifest_count_mismatch:Function]
|
||||
|
||||
# [DEF:test_compliant_run_validation:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify compliant run validation logic and mandatory stage checks.
|
||||
def test_compliant_run_validation():
|
||||
base_run = {
|
||||
"check_run_id": "run1",
|
||||
@@ -130,6 +163,11 @@ def test_compliant_run_validation():
|
||||
with pytest.raises(ValueError, match="compliant run requires all mandatory stages"):
|
||||
ComplianceCheckRun(**base_run)
|
||||
|
||||
# [/DEF:test_compliant_run_validation:Function]
|
||||
|
||||
# [DEF:test_report_validation:Function]
|
||||
# @RELATION: BINDS_TO -> __tests__/test_clean_release
|
||||
# @PURPOSE: Verify compliance report validation based on status and violation counts.
|
||||
def test_report_validation():
|
||||
# Valid blocked report
|
||||
ComplianceReport(
|
||||
@@ -147,3 +185,4 @@ def test_report_validation():
|
||||
operator_summary="Blocked", structured_payload_ref="ref",
|
||||
violations_count=2, blocking_violations_count=0
|
||||
)
|
||||
# [/DEF:test_report_validation:Function]
|
||||
|
||||
@@ -15,6 +15,7 @@ from src.core.logger import belief_scope
|
||||
|
||||
|
||||
# [DEF:test_environment_model:Function]
|
||||
# @RELATION: BINDS_TO -> test_models
|
||||
# @PURPOSE: Tests that Environment model correctly stores values.
|
||||
# @PRE: Environment class is available.
|
||||
# @POST: Values are verified.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# [DEF:test_report_models:Module]
|
||||
# @RELATION: BELONGS_TO -> SrcRoot
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Unit tests for report Pydantic models and their validators
|
||||
# @LAYER: Domain
|
||||
# @RELATION: TESTS -> backend.src.models.report
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# [DEF:backend.src.models.assistant:Module]
|
||||
# [DEF:AssistantModels:Module]
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: assistant, audit, confirmation, chat
|
||||
# @PURPOSE: SQLAlchemy models for assistant audit trail and confirmation tokens.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: DEPENDS_ON -> backend.src.models.mapping
|
||||
# @RELATION: DEPENDS_ON -> MappingModels
|
||||
# @INVARIANT: Assistant records preserve immutable ids and creation timestamps.
|
||||
|
||||
from datetime import datetime
|
||||
@@ -16,6 +16,7 @@ from .mapping import Base
|
||||
# [DEF:AssistantAuditRecord:Class]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Store audit decisions and outcomes produced by assistant command handling.
|
||||
# @RELATION: INHERITS -> MappingModels
|
||||
# @PRE: user_id must identify the actor for every record.
|
||||
# @POST: Audit payload remains available for compliance and debugging.
|
||||
class AssistantAuditRecord(Base):
|
||||
@@ -29,12 +30,15 @@ class AssistantAuditRecord(Base):
|
||||
message = Column(Text, nullable=True)
|
||||
payload = Column(JSON, nullable=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
# [/DEF:AssistantAuditRecord:Class]
|
||||
|
||||
|
||||
# [DEF:AssistantMessageRecord:Class]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Persist chat history entries for assistant conversations.
|
||||
# @RELATION: INHERITS -> MappingModels
|
||||
# @PRE: user_id, conversation_id, role and text must be present.
|
||||
# @POST: Message row can be queried in chronological order.
|
||||
class AssistantMessageRecord(Base):
|
||||
@@ -50,12 +54,15 @@ class AssistantMessageRecord(Base):
|
||||
confirmation_id = Column(String, nullable=True)
|
||||
payload = Column(JSON, nullable=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
|
||||
# [/DEF:AssistantMessageRecord:Class]
|
||||
|
||||
|
||||
# [DEF:AssistantConfirmationRecord:Class]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Persist risky operation confirmation tokens with lifecycle state.
|
||||
# @RELATION: INHERITS -> MappingModels
|
||||
# @PRE: intent/dispatch and expiry timestamp must be provided.
|
||||
# @POST: State transitions can be tracked and audited.
|
||||
class AssistantConfirmationRecord(Base):
|
||||
@@ -70,5 +77,7 @@ class AssistantConfirmationRecord(Base):
|
||||
expires_at = Column(DateTime, nullable=False)
|
||||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
consumed_at = Column(DateTime, nullable=True)
|
||||
|
||||
|
||||
# [/DEF:AssistantConfirmationRecord:Class]
|
||||
# [/DEF:backend.src.models.assistant:Module]
|
||||
# [/DEF:AssistantModels:Module]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# @SEMANTICS: auth, models, user, role, permission, sqlalchemy
|
||||
# @PURPOSE: SQLAlchemy models for multi-user authentication and authorization.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: INHERITS_FROM -> [Base]
|
||||
# @RELATION: INHERITS_FROM -> [MappingModels:Base]
|
||||
#
|
||||
# @INVARIANT: Usernames and emails must be unique.
|
||||
|
||||
@@ -20,12 +20,16 @@ from .mapping import Base
|
||||
# [DEF:generate_uuid:Function]
|
||||
# @PURPOSE: Generates a unique UUID string.
|
||||
# @POST: Returns a string representation of a new UUID.
|
||||
# @RELATION: DEPENDS_ON -> uuid
|
||||
def generate_uuid():
|
||||
return str(uuid.uuid4())
|
||||
# [/DEF:generate_uuid:Function]
|
||||
|
||||
# [DEF:user_roles:Table]
|
||||
# @PURPOSE: Association table for many-to-many relationship between Users and Roles.
|
||||
# @RELATION: DEPENDS_ON -> Base.metadata
|
||||
# @RELATION: DEPENDS_ON -> User
|
||||
# @RELATION: DEPENDS_ON -> Role
|
||||
user_roles = Table(
|
||||
"user_roles",
|
||||
Base.metadata,
|
||||
@@ -36,6 +40,9 @@ user_roles = Table(
|
||||
|
||||
# [DEF:role_permissions:Table]
|
||||
# @PURPOSE: Association table for many-to-many relationship between Roles and Permissions.
|
||||
# @RELATION: DEPENDS_ON -> Base.metadata
|
||||
# @RELATION: DEPENDS_ON -> Role
|
||||
# @RELATION: DEPENDS_ON -> Permission
|
||||
role_permissions = Table(
|
||||
"role_permissions",
|
||||
Base.metadata,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# [DEF:backend.src.models.clean_release:Module]
|
||||
# @COMPLEXITY: 5
|
||||
# [DEF:CleanReleaseModels:Module]
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: clean-release, models, lifecycle, compliance, evidence, immutability
|
||||
# @PURPOSE: Define canonical clean release domain entities and lifecycle guards.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: DEPENDS_ON -> MappingModels
|
||||
# @PRE: Base mapping model and release enums are available.
|
||||
# @POST: Provides SQLAlchemy and dataclass definitions for governance domain.
|
||||
# @SIDE_EFFECT: None (schema definition).
|
||||
@@ -695,4 +696,4 @@ class CleanReleaseAuditLog(Base):
|
||||
details_json = Column(JSON, default=dict)
|
||||
# [/DEF:CleanReleaseAuditLog:Class]
|
||||
|
||||
# [/DEF:backend.src.models.clean_release:Module]
|
||||
# [/DEF:CleanReleaseModels:Module]
|
||||
@@ -1,11 +1,11 @@
|
||||
# [DEF:backend.src.models.config:Module]
|
||||
# [DEF:ConfigModels:Module]
|
||||
#
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: database, config, settings, sqlalchemy, notification
|
||||
# @PURPOSE: Defines SQLAlchemy persistence models for application and notification configuration records.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: [DEPENDS_ON] ->[sqlalchemy]
|
||||
# @RELATION: [DEPENDS_ON] ->[backend.src.models.mapping:Base]
|
||||
|
||||
# @RELATION: [DEPENDS_ON] -> [MappingModels:Base]
|
||||
# @INVARIANT: Configuration payload and notification credentials must remain persisted as non-null JSON documents.
|
||||
|
||||
from sqlalchemy import Column, String, DateTime, JSON, Boolean
|
||||
@@ -50,4 +50,4 @@ class NotificationConfig(Base):
|
||||
|
||||
import uuid
|
||||
|
||||
# [/DEF:backend.src.models.config:Module]
|
||||
# [/DEF:ConfigModels:Module]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# [DEF:backend.src.models.connection:Module]
|
||||
# [DEF:ConnectionModels:Module]
|
||||
#
|
||||
# @COMPLEXITY: 1
|
||||
# @SEMANTICS: database, connection, configuration, sqlalchemy, sqlite
|
||||
@@ -33,4 +33,4 @@ class ConnectionConfig(Base):
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
# [/DEF:ConnectionConfig:Class]
|
||||
|
||||
# [/DEF:backend.src.models.connection:Module]
|
||||
# [/DEF:ConnectionModels:Module]
|
||||
@@ -1,9 +1,9 @@
|
||||
# [DEF:backend.src.models.dashboard:Module]
|
||||
# [DEF:DashboardModels:Module]
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: dashboard, model, metadata, migration
|
||||
# @PURPOSE: Defines data models for dashboard metadata and selection.
|
||||
# @LAYER: Model
|
||||
# @RELATION: USED_BY -> backend.src.api.routes.migration
|
||||
# @RELATION: USED_BY -> MigrationApi
|
||||
|
||||
from pydantic import BaseModel
|
||||
from typing import List
|
||||
@@ -29,4 +29,4 @@ class DashboardSelection(BaseModel):
|
||||
fix_cross_filters: bool = True
|
||||
# [/DEF:DashboardSelection:Class]
|
||||
|
||||
# [/DEF:backend.src.models.dashboard:Module]
|
||||
# [/DEF:DashboardModels:Module]
|
||||
@@ -1,9 +1,9 @@
|
||||
# [DEF:backend.src.models.llm:Module]
|
||||
# [DEF:LlmModels:Module]
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: llm, models, sqlalchemy, persistence
|
||||
# @PURPOSE: SQLAlchemy models for LLM provider configuration and validation results.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: INHERITS_FROM -> backend.src.models.mapping.Base
|
||||
# @RELATION: INHERITS_FROM -> MappingModels:Base
|
||||
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, JSON, Text, Time, ForeignKey
|
||||
from datetime import datetime
|
||||
@@ -65,4 +65,4 @@ class ValidationRecord(Base):
|
||||
raw_response = Column(Text, nullable=True)
|
||||
# [/DEF:ValidationRecord:Class]
|
||||
|
||||
# [/DEF:backend.src.models.llm:Module]
|
||||
# [/DEF:LlmModels:Module]
|
||||
@@ -5,7 +5,8 @@
|
||||
# @SEMANTICS: database, mapping, environment, migration, sqlalchemy, sqlite
|
||||
# @PURPOSE: Defines the database schema for environment metadata and database mappings using SQLAlchemy.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: DEPENDS_ON -> [sqlalchemy]
|
||||
# @RELATION: DEPENDS_ON -> sqlalchemy
|
||||
|
||||
#
|
||||
# @INVARIANT: All primary keys are UUID strings.
|
||||
# @CONSTRAINT: source_env_id and target_env_id must be valid environment IDs.
|
||||
@@ -44,6 +45,7 @@ class MigrationStatus(enum.Enum):
|
||||
# [DEF:Environment:Class]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Represents a Superset instance environment.
|
||||
# @RELATION: DEPENDS_ON -> MappingModels
|
||||
class Environment(Base):
|
||||
__tablename__ = "environments"
|
||||
|
||||
@@ -87,6 +89,7 @@ class MigrationJob(Base):
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Maps a universal UUID for a resource to its actual ID on a specific environment.
|
||||
# @TEST_DATA: resource_mapping_record -> {'environment_id': 'prod-env-1', 'resource_type': 'chart', 'uuid': '123e4567-e89b-12d3-a456-426614174000', 'remote_integer_id': '42'}
|
||||
# @RELATION: DEPENDS_ON -> MappingModels
|
||||
class ResourceMapping(Base):
|
||||
__tablename__ = "resource_mappings"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# @PURPOSE: Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: DEPENDS_ON -> [AuthModels]
|
||||
# @RELATION: INHERITS_FROM -> [Base]
|
||||
# @RELATION: INHERITS_FROM -> [MappingModels:Base]
|
||||
#
|
||||
# @INVARIANT: Exactly one preference row exists per user_id.
|
||||
# @INVARIANT: Sensitive Git token is stored encrypted and never returned in plaintext.
|
||||
@@ -23,6 +23,7 @@ from .mapping import Base
|
||||
# [DEF:UserDashboardPreference:Class]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Stores Superset username binding and default "my dashboards" toggle for one authenticated user.
|
||||
# @RELATION: INHERITS -> MappingModels:Base
|
||||
class UserDashboardPreference(Base):
|
||||
__tablename__ = "user_dashboard_preferences"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# [DEF:backend.src.models.report:Module]
|
||||
# @COMPLEXITY: 5
|
||||
# [DEF:ReportModels:Module]
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: reports, models, pydantic, normalization, pagination
|
||||
# @PURPOSE: Canonical report schemas for unified task reporting across heterogeneous task types.
|
||||
# @LAYER: Domain
|
||||
@@ -7,7 +7,7 @@
|
||||
# @POST: Provides validated schemas for cross-plugin reporting and UI consumption.
|
||||
# @SIDE_EFFECT: None (schema definition).
|
||||
# @DATA_CONTRACT: Model[TaskReport, ReportCollection, ReportDetailView]
|
||||
# @RELATION: [DEPENDS_ON] ->[backend.src.core.task_manager.models]
|
||||
# @RELATION: [DEPENDS_ON] -> [TaskModels]
|
||||
# @INVARIANT: Canonical report fields are always present for every report item.
|
||||
|
||||
# [SECTION: IMPORTS]
|
||||
@@ -20,8 +20,9 @@ from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
|
||||
|
||||
# [DEF:TaskType:Class]
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @INVARIANT: Must contain valid generic task type mappings.
|
||||
# @RELATION: DEPENDS_ON -> ReportModels
|
||||
# @SEMANTICS: enum, type, task
|
||||
# @PURPOSE: Supported normalized task report types.
|
||||
class TaskType(str, Enum):
|
||||
@@ -31,11 +32,13 @@ class TaskType(str, Enum):
|
||||
DOCUMENTATION = "documentation"
|
||||
CLEAN_RELEASE = "clean_release"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
# [/DEF:TaskType:Class]
|
||||
|
||||
|
||||
# [DEF:ReportStatus:Class]
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @INVARIANT: TaskStatus enum mapping logic holds.
|
||||
# @SEMANTICS: enum, status, task
|
||||
# @PURPOSE: Supported normalized report status values.
|
||||
@@ -44,11 +47,13 @@ class ReportStatus(str, Enum):
|
||||
FAILED = "failed"
|
||||
IN_PROGRESS = "in_progress"
|
||||
PARTIAL = "partial"
|
||||
|
||||
|
||||
# [/DEF:ReportStatus:Class]
|
||||
|
||||
|
||||
# [DEF:ErrorContext:Class]
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @INVARIANT: The properties accurately describe error state.
|
||||
# @SEMANTICS: error, context, payload
|
||||
# @PURPOSE: Error and recovery context for failed/partial reports.
|
||||
@@ -69,11 +74,13 @@ class ErrorContext(BaseModel):
|
||||
code: Optional[str] = None
|
||||
message: str
|
||||
next_actions: List[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
# [/DEF:ErrorContext:Class]
|
||||
|
||||
|
||||
# [DEF:TaskReport:Class]
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @INVARIANT: Must represent canonical task record attributes.
|
||||
# @SEMANTICS: report, model, summary
|
||||
# @PURPOSE: Canonical normalized report envelope for one task execution.
|
||||
@@ -116,7 +123,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
|
||||
validation_record: Optional[Dict[str, Any]] = None # Extended for US2
|
||||
error_context: Optional[ErrorContext] = None
|
||||
source_ref: Optional[Dict[str, Any]] = None
|
||||
|
||||
@@ -126,11 +133,13 @@ class TaskReport(BaseModel):
|
||||
if not isinstance(value, str) or not value.strip():
|
||||
raise ValueError("Value must be a non-empty string")
|
||||
return value.strip()
|
||||
|
||||
|
||||
# [/DEF:TaskReport:Class]
|
||||
|
||||
|
||||
# [DEF:ReportQuery:Class]
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @INVARIANT: Time and pagination queries are mutually consistent.
|
||||
# @SEMANTICS: query, filter, search
|
||||
# @PURPOSE: Query object for server-side report filtering, sorting, and pagination.
|
||||
@@ -184,11 +193,13 @@ class ReportQuery(BaseModel):
|
||||
if self.time_from and self.time_to and self.time_from > self.time_to:
|
||||
raise ValueError("time_from must be less than or equal to time_to")
|
||||
return self
|
||||
|
||||
|
||||
# [/DEF:ReportQuery:Class]
|
||||
|
||||
|
||||
# [DEF:ReportCollection:Class]
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @INVARIANT: Represents paginated data correctly.
|
||||
# @SEMANTICS: collection, pagination
|
||||
# @PURPOSE: Paginated collection of normalized task reports.
|
||||
@@ -209,11 +220,13 @@ class ReportCollection(BaseModel):
|
||||
page_size: int = Field(ge=1)
|
||||
has_next: bool
|
||||
applied_filters: ReportQuery
|
||||
|
||||
|
||||
# [/DEF:ReportCollection:Class]
|
||||
|
||||
|
||||
# [DEF:ReportDetailView:Class]
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @INVARIANT: Incorporates a report and logs correctly.
|
||||
# @SEMANTICS: view, detail, logs
|
||||
# @PURPOSE: Detailed report representation including diagnostics and recovery actions.
|
||||
@@ -230,6 +243,8 @@ class ReportDetailView(BaseModel):
|
||||
timeline: List[Dict[str, Any]] = Field(default_factory=list)
|
||||
diagnostics: Optional[Dict[str, Any]] = None
|
||||
next_actions: List[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
# [/DEF:ReportDetailView:Class]
|
||||
|
||||
# [/DEF:backend.src.models.report:Module]
|
||||
# [/DEF:ReportModels:Module]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# [DEF:backend.src.models.storage:Module]
|
||||
# [DEF:StorageModels:Module]
|
||||
# @COMPLEXITY: 1
|
||||
# @SEMANTICS: storage, file, model, pydantic
|
||||
# @PURPOSE: Data models for the storage system.
|
||||
@@ -41,4 +41,4 @@ class StoredFile(BaseModel):
|
||||
mime_type: Optional[str] = Field(None, description="MIME type of the file.")
|
||||
# [/DEF:StoredFile:Class]
|
||||
|
||||
# [/DEF:backend.src.models.storage:Module]
|
||||
# [/DEF:StorageModels:Module]
|
||||
@@ -1,4 +1,4 @@
|
||||
# [DEF:backend.src.models.task:Module]
|
||||
# [DEF:TaskModels:Module]
|
||||
#
|
||||
# @COMPLEXITY: 1
|
||||
# @SEMANTICS: database, task, record, sqlalchemy, sqlite
|
||||
@@ -36,7 +36,7 @@ class TaskRecord(Base):
|
||||
|
||||
# [DEF:TaskLogRecord:Class]
|
||||
# @PURPOSE: Represents a single persistent log entry for a task.
|
||||
# @COMPLEXITY: 5
|
||||
# @COMPLEXITY: 3
|
||||
# @RELATION: DEPENDS_ON -> TaskRecord
|
||||
# @INVARIANT: Each log entry belongs to exactly one task.
|
||||
#
|
||||
@@ -113,4 +113,4 @@ class TaskLogRecord(Base):
|
||||
)
|
||||
# [/DEF:TaskLogRecord:Class]
|
||||
|
||||
# [/DEF:backend.src.models.task:Module]
|
||||
# [/DEF:TaskModels:Module]
|
||||
Reference in New Issue
Block a user