chore(lint): apply ruff --fix (4443 auto-fixes)
Auto-fixed categories: - F401: unused imports removed - I001: import blocks sorted - W293: trailing whitespace stripped - UP035: deprecated typing imports replaced - SIM: simplify suggestions applied - ARG: unused args prefixed with underscore - T201: print statements removed - F841: unused variables removed - RUF059: unpacked variables prefixed Remaining ~1500 unfixable errors (C901, B904, N806, E402) require manual work. Backend smoke tests: 13/13 passed.
This commit is contained in:
@@ -2,26 +2,29 @@
|
||||
# @RELATION VERIFIES -> [CleanReleaseModels]
|
||||
# @BRIEF Contract testing for Clean Release models
|
||||
# #endregion TestCleanReleaseModels
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
from pydantic import ValidationError
|
||||
|
||||
import pytest
|
||||
|
||||
from src.models.clean_release import (
|
||||
ReleaseCandidate,
|
||||
ReleaseCandidateStatus,
|
||||
ProfileType,
|
||||
CheckFinalStatus,
|
||||
CheckStageName,
|
||||
CheckStageResult,
|
||||
CheckStageStatus,
|
||||
ClassificationType,
|
||||
CleanProfilePolicy,
|
||||
ComplianceCheckRun,
|
||||
ComplianceReport,
|
||||
DistributionManifest,
|
||||
ExecutionMode,
|
||||
ManifestItem,
|
||||
ManifestSummary,
|
||||
ClassificationType,
|
||||
ComplianceCheckRun,
|
||||
CheckFinalStatus,
|
||||
CheckStageResult,
|
||||
CheckStageName,
|
||||
CheckStageStatus,
|
||||
ComplianceReport,
|
||||
ExecutionMode,
|
||||
ProfileType,
|
||||
ReleaseCandidate,
|
||||
ReleaseCandidateStatus,
|
||||
)
|
||||
|
||||
|
||||
# @TEST_FIXTURE: valid_enterprise_candidate
|
||||
@pytest.fixture
|
||||
def valid_candidate_data():
|
||||
@@ -204,4 +207,4 @@ def test_report_validation():
|
||||
violations_count=2,
|
||||
blocking_violations_count=0,
|
||||
)
|
||||
# #endregion test_report_validation
|
||||
# #endregion test_report_validation
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
# @RELATION VERIFIES -> [ModelsPackage]
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add src to path
|
||||
sys.path.append(str(Path(__file__).parent.parent.parent.parent / "src"))
|
||||
from src.core.config_models import Environment
|
||||
from src.core.logger import belief_scope
|
||||
|
||||
|
||||
# #region test_environment_model [TYPE Function]
|
||||
# @RELATION BINDS_TO -> test_models
|
||||
# @BRIEF Tests that Environment model correctly stores values.
|
||||
@@ -26,4 +29,4 @@ def test_environment_model():
|
||||
assert env.name == "test-env"
|
||||
assert env.url == "http://localhost:8088/api/v1"
|
||||
# #endregion test_environment_model
|
||||
# #endregion test_models
|
||||
# #endregion test_models
|
||||
|
||||
@@ -4,9 +4,13 @@
|
||||
# @LAYER: Domain
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
||||
import pytest
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestTaskType:
|
||||
"""Tests for the TaskType enum."""
|
||||
def test_enum_values(self):
|
||||
@@ -40,7 +44,7 @@ class TestErrorContext:
|
||||
class TestTaskReport:
|
||||
"""Tests for TaskReport model and its validators."""
|
||||
def _make_report(self, **overrides):
|
||||
from src.models.report import TaskReport, TaskType, ReportStatus
|
||||
from src.models.report import ReportStatus, TaskReport, TaskType
|
||||
defaults = {
|
||||
"report_id": "rpt-001",
|
||||
"task_id": "task-001",
|
||||
@@ -146,7 +150,7 @@ class TestReportCollection:
|
||||
assert col.total == 0
|
||||
assert col.has_next is False
|
||||
def test_with_items(self):
|
||||
from src.models.report import ReportCollection, ReportQuery, TaskReport, TaskType, ReportStatus
|
||||
from src.models.report import ReportCollection, ReportQuery, ReportStatus, TaskReport, TaskType
|
||||
report = TaskReport(
|
||||
report_id="r1", task_id="t1", task_type=TaskType.BACKUP,
|
||||
status=ReportStatus.SUCCESS, updated_at=datetime.utcnow(),
|
||||
@@ -161,7 +165,7 @@ class TestReportCollection:
|
||||
class TestReportDetailView:
|
||||
"""Tests for ReportDetailView model."""
|
||||
def test_valid_creation(self):
|
||||
from src.models.report import ReportDetailView, TaskReport, TaskType, ReportStatus
|
||||
from src.models.report import ReportDetailView, ReportStatus, TaskReport, TaskType
|
||||
report = TaskReport(
|
||||
report_id="r1", task_id="t1", task_type=TaskType.BACKUP,
|
||||
status=ReportStatus.SUCCESS, updated_at=datetime.utcnow(),
|
||||
@@ -173,7 +177,7 @@ class TestReportDetailView:
|
||||
assert detail.diagnostics is None
|
||||
assert detail.next_actions == []
|
||||
def test_with_all_fields(self):
|
||||
from src.models.report import ReportDetailView, TaskReport, TaskType, ReportStatus
|
||||
from src.models.report import ReportDetailView, ReportStatus, TaskReport, TaskType
|
||||
report = TaskReport(
|
||||
report_id="r1", task_id="t1", task_type=TaskType.MIGRATION,
|
||||
status=ReportStatus.FAILED, updated_at=datetime.utcnow(),
|
||||
@@ -188,4 +192,4 @@ class TestReportDetailView:
|
||||
assert len(detail.timeline) == 1
|
||||
assert detail.diagnostics["cause"] == "timeout"
|
||||
assert "Retry" in detail.next_actions
|
||||
# #endregion test_report_models
|
||||
# #endregion test_report_models
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import Column, String, DateTime, JSON, Text
|
||||
from sqlalchemy import JSON, Column, DateTime, String, Text
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, Table
|
||||
|
||||
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, String, Table
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
|
||||
@@ -9,19 +9,17 @@
|
||||
# @INVARIANT: Immutable snapshots are never mutated; forbidden lifecycle transitions are rejected.
|
||||
|
||||
from datetime import datetime
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import List, Optional, Dict, Any
|
||||
from pydantic import ConfigDict, Field, model_validator
|
||||
from typing import Any
|
||||
|
||||
from pydantic import ConfigDict, model_validator
|
||||
from pydantic.dataclasses import dataclass as pydantic_dataclass
|
||||
from sqlalchemy import Column, String, DateTime, JSON, ForeignKey, Integer, Boolean
|
||||
from sqlalchemy.orm import relationship
|
||||
from .mapping import Base
|
||||
from ..services.clean_release.enums import (
|
||||
CandidateStatus, RunStatus, ComplianceDecision,
|
||||
ApprovalDecisionType, PublicationStatus, ClassificationType
|
||||
)
|
||||
from sqlalchemy import JSON, Boolean, Column, DateTime, ForeignKey, Integer, String
|
||||
|
||||
from ..services.clean_release.enums import CandidateStatus, ClassificationType, ComplianceDecision, PublicationStatus, RunStatus
|
||||
from ..services.clean_release.exceptions import IllegalTransitionError
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
# #region ExecutionMode [TYPE Class]
|
||||
# @BRIEF Backward-compatible execution mode enum for legacy TUI/orchestrator tests.
|
||||
@@ -114,14 +112,14 @@ class ResourceSourceEntry:
|
||||
class ResourceSourceRegistry:
|
||||
registry_id: str
|
||||
name: str
|
||||
entries: List[ResourceSourceEntry]
|
||||
entries: list[ResourceSourceEntry]
|
||||
updated_at: datetime
|
||||
updated_by: str
|
||||
status: str = "ACTIVE"
|
||||
immutable: bool = True
|
||||
allowed_hosts: Optional[List[str]] = None
|
||||
allowed_schemes: Optional[List[str]] = None
|
||||
allowed_source_types: Optional[List[str]] = None
|
||||
allowed_hosts: list[str] | None = None
|
||||
allowed_schemes: list[str] | None = None
|
||||
allowed_source_types: list[str] | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def populate_legacy_allowlists(self):
|
||||
@@ -148,12 +146,12 @@ class CleanProfilePolicy:
|
||||
profile: ProfileType
|
||||
active: bool
|
||||
internal_source_registry_ref: str
|
||||
prohibited_artifact_categories: List[str]
|
||||
prohibited_artifact_categories: list[str]
|
||||
effective_from: datetime
|
||||
required_system_categories: Optional[List[str]] = None
|
||||
required_system_categories: list[str] | None = None
|
||||
external_source_forbidden: bool = True
|
||||
immutable: bool = True
|
||||
content_json: Optional[Dict[str, Any]] = None
|
||||
content_json: dict[str, Any] | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_enterprise_policy(self):
|
||||
@@ -191,8 +189,8 @@ class ComplianceCheckRun:
|
||||
triggered_by: str
|
||||
execution_mode: ExecutionMode
|
||||
final_status: CheckFinalStatus
|
||||
checks: List[CheckStageResult]
|
||||
finished_at: Optional[datetime] = None
|
||||
checks: list[CheckStageResult]
|
||||
finished_at: datetime | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_final_status_alignment(self):
|
||||
@@ -233,7 +231,7 @@ class ComplianceCheckRun:
|
||||
# @POST: status advances only through legal transitions.
|
||||
class ReleaseCandidate(Base):
|
||||
__tablename__ = "clean_release_candidates"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
name = Column(String, nullable=True) # Added back for backward compatibility with some legacy DTOs
|
||||
version = Column(String, nullable=False)
|
||||
@@ -251,9 +249,7 @@ class ReleaseCandidate(Base):
|
||||
status = kwargs.get("status")
|
||||
if status is None:
|
||||
kwargs["status"] = CandidateStatus.DRAFT.value
|
||||
elif isinstance(status, ReleaseCandidateStatus):
|
||||
kwargs["status"] = status.value
|
||||
elif isinstance(status, CandidateStatus):
|
||||
elif isinstance(status, ReleaseCandidateStatus) or isinstance(status, CandidateStatus):
|
||||
kwargs["status"] = status.value
|
||||
if not str(kwargs.get("id", "")).strip():
|
||||
raise ValueError("candidate_id must be non-empty")
|
||||
@@ -274,8 +270,8 @@ class ReleaseCandidate(Base):
|
||||
CandidateStatus.MANIFEST_BUILT: [CandidateStatus.CHECK_PENDING],
|
||||
CandidateStatus.CHECK_PENDING: [CandidateStatus.CHECK_RUNNING],
|
||||
CandidateStatus.CHECK_RUNNING: [
|
||||
CandidateStatus.CHECK_PASSED,
|
||||
CandidateStatus.CHECK_BLOCKED,
|
||||
CandidateStatus.CHECK_PASSED,
|
||||
CandidateStatus.CHECK_BLOCKED,
|
||||
CandidateStatus.CHECK_ERROR
|
||||
],
|
||||
CandidateStatus.CHECK_PASSED: [CandidateStatus.APPROVED, CandidateStatus.CHECK_PENDING],
|
||||
@@ -295,7 +291,7 @@ class ReleaseCandidate(Base):
|
||||
# @BRIEF Represents one artifact associated with a release candidate.
|
||||
class CandidateArtifact(Base):
|
||||
__tablename__ = "clean_release_artifacts"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
candidate_id = Column(String, ForeignKey("clean_release_candidates.id"), nullable=False)
|
||||
path = Column(String, nullable=False)
|
||||
@@ -315,7 +311,7 @@ class ManifestItem:
|
||||
category: str
|
||||
classification: ClassificationType
|
||||
reason: str
|
||||
checksum: Optional[str] = None
|
||||
checksum: str | None = None
|
||||
# #endregion ManifestItem
|
||||
|
||||
# #region ManifestSummary [TYPE Class]
|
||||
@@ -331,7 +327,7 @@ class ManifestSummary:
|
||||
# @INVARIANT: Immutable after creation.
|
||||
class DistributionManifest(Base):
|
||||
__tablename__ = "clean_release_manifests"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
candidate_id = Column(String, ForeignKey("clean_release_candidates.id"), nullable=False)
|
||||
manifest_version = Column(Integer, nullable=False)
|
||||
@@ -364,7 +360,7 @@ class DistributionManifest(Base):
|
||||
expected_count = int(summary.included_count) + int(summary.excluded_count)
|
||||
if expected_count != len(items):
|
||||
raise ValueError("manifest summary counts must match items size")
|
||||
|
||||
|
||||
# Ensure required DB fields have defaults if missing
|
||||
if "manifest_version" not in kwargs:
|
||||
kwargs["manifest_version"] = 1
|
||||
@@ -372,7 +368,7 @@ class DistributionManifest(Base):
|
||||
kwargs["artifacts_digest"] = kwargs.get("manifest_digest", "pending")
|
||||
if "source_snapshot_ref" not in kwargs:
|
||||
kwargs["source_snapshot_ref"] = "pending"
|
||||
|
||||
|
||||
# Pack items and summary into content_json if provided
|
||||
if items is not None or summary is not None:
|
||||
content = dict(kwargs.get("content_json") or {})
|
||||
@@ -418,7 +414,7 @@ class DistributionManifest(Base):
|
||||
# @BRIEF Immutable registry snapshot for allowed sources.
|
||||
class SourceRegistrySnapshot(Base):
|
||||
__tablename__ = "clean_release_registry_snapshots"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
registry_id = Column(String, nullable=False)
|
||||
registry_version = Column(String, nullable=False)
|
||||
@@ -433,7 +429,7 @@ class SourceRegistrySnapshot(Base):
|
||||
# @BRIEF Immutable policy snapshot used to evaluate a run.
|
||||
class CleanPolicySnapshot(Base):
|
||||
__tablename__ = "clean_release_policy_snapshots"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
policy_id = Column(String, nullable=False)
|
||||
policy_version = Column(String, nullable=False)
|
||||
@@ -447,7 +443,7 @@ class CleanPolicySnapshot(Base):
|
||||
# @BRIEF Operational record for one compliance execution.
|
||||
class ComplianceRun(Base):
|
||||
__tablename__ = "clean_release_compliance_runs"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
candidate_id = Column(String, ForeignKey("clean_release_candidates.id"), nullable=False)
|
||||
manifest_id = Column(String, ForeignKey("clean_release_manifests.id"), nullable=False)
|
||||
@@ -472,7 +468,7 @@ class ComplianceRun(Base):
|
||||
# @BRIEF Stage-level execution record inside a run.
|
||||
class ComplianceStageRun(Base):
|
||||
__tablename__ = "clean_release_compliance_stage_runs"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
run_id = Column(String, ForeignKey("clean_release_compliance_runs.id"), nullable=False)
|
||||
stage_name = Column(String, nullable=False)
|
||||
@@ -505,7 +501,7 @@ class ViolationCategory(str, Enum):
|
||||
# @BRIEF Violation produced by a stage.
|
||||
class ComplianceViolation(Base):
|
||||
__tablename__ = "clean_release_compliance_violations"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
run_id = Column(String, ForeignKey("clean_release_compliance_runs.id"), nullable=False)
|
||||
stage_name = Column(String, nullable=False)
|
||||
@@ -565,11 +561,11 @@ class ComplianceViolation(Base):
|
||||
self.stage_name = value.value if isinstance(value, ViolationCategory) else str(value)
|
||||
|
||||
@property
|
||||
def location(self) -> Optional[str]:
|
||||
def location(self) -> str | None:
|
||||
return self.artifact_path
|
||||
|
||||
@property
|
||||
def remediation(self) -> Optional[str]:
|
||||
def remediation(self) -> str | None:
|
||||
return (self.evidence_json or {}).get("remediation")
|
||||
|
||||
@property
|
||||
@@ -582,7 +578,7 @@ class ComplianceViolation(Base):
|
||||
# @INVARIANT: Immutable after creation.
|
||||
class ComplianceReport(Base):
|
||||
__tablename__ = "clean_release_compliance_reports"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
run_id = Column(String, ForeignKey("clean_release_compliance_runs.id"), nullable=False)
|
||||
candidate_id = Column(String, ForeignKey("clean_release_candidates.id"), nullable=False)
|
||||
@@ -639,7 +635,7 @@ class ComplianceReport(Base):
|
||||
return (self.summary_json or {}).get("operator_summary", "")
|
||||
|
||||
@property
|
||||
def structured_payload_ref(self) -> Optional[str]:
|
||||
def structured_payload_ref(self) -> str | None:
|
||||
return (self.summary_json or {}).get("structured_payload_ref")
|
||||
|
||||
@property
|
||||
@@ -655,7 +651,7 @@ class ComplianceReport(Base):
|
||||
# @BRIEF Approval or rejection bound to a candidate and report.
|
||||
class ApprovalDecision(Base):
|
||||
__tablename__ = "clean_release_approval_decisions"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
candidate_id = Column(String, ForeignKey("clean_release_candidates.id"), nullable=False)
|
||||
report_id = Column(String, ForeignKey("clean_release_compliance_reports.id"), nullable=False)
|
||||
@@ -669,7 +665,7 @@ class ApprovalDecision(Base):
|
||||
# @BRIEF Publication or revocation record.
|
||||
class PublicationRecord(Base):
|
||||
__tablename__ = "clean_release_publication_records"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True)
|
||||
candidate_id = Column(String, ForeignKey("clean_release_candidates.id"), nullable=False)
|
||||
report_id = Column(String, ForeignKey("clean_release_compliance_reports.id"), nullable=False)
|
||||
@@ -683,9 +679,11 @@ class PublicationRecord(Base):
|
||||
# #region CleanReleaseAuditLog [TYPE Class]
|
||||
# @BRIEF Represents a persistent audit log entry for clean release actions.
|
||||
import uuid
|
||||
|
||||
|
||||
class CleanReleaseAuditLog(Base):
|
||||
__tablename__ = "clean_release_audit_logs"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
|
||||
candidate_id = Column(String, index=True, nullable=True)
|
||||
action = Column(String, nullable=False) # e.g. "TRANSITION", "APPROVE", "PUBLISH"
|
||||
@@ -694,4 +692,4 @@ class CleanReleaseAuditLog(Base):
|
||||
details_json = Column(JSON, default=dict)
|
||||
# #endregion CleanReleaseAuditLog
|
||||
|
||||
# #endregion CleanReleaseModels
|
||||
# #endregion CleanReleaseModels
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# @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
|
||||
from sqlalchemy import JSON, Boolean, Column, DateTime, String
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
#
|
||||
# @INVARIANT: All primary keys are UUID strings.
|
||||
|
||||
from sqlalchemy import Column, String, Integer, DateTime
|
||||
from sqlalchemy.sql import func
|
||||
from .mapping import Base
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Column, DateTime, Integer, String
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
# #region ConnectionConfig [C:1] [TYPE Class]
|
||||
# @BRIEF Stores credentials for external databases used for column mapping.
|
||||
class ConnectionConfig(Base):
|
||||
@@ -28,4 +31,4 @@ class ConnectionConfig(Base):
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
# #endregion ConnectionConfig
|
||||
|
||||
# #endregion ConnectionModels
|
||||
# #endregion ConnectionModels
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# @LAYER: Model
|
||||
# @RELATION USED_BY -> MigrationApi
|
||||
|
||||
|
||||
from pydantic import BaseModel
|
||||
from typing import List
|
||||
|
||||
|
||||
# #region DashboardMetadata [C:1] [TYPE Class]
|
||||
# @BRIEF Represents a dashboard available for migration.
|
||||
@@ -18,11 +19,11 @@ class DashboardMetadata(BaseModel):
|
||||
# #region DashboardSelection [C:1] [TYPE Class]
|
||||
# @BRIEF Represents the user's selection of dashboards to migrate.
|
||||
class DashboardSelection(BaseModel):
|
||||
selected_ids: List[int]
|
||||
selected_ids: list[int]
|
||||
source_env_id: str
|
||||
target_env_id: str
|
||||
replace_db_config: bool = False
|
||||
fix_cross_filters: bool = True
|
||||
# #endregion DashboardSelection
|
||||
|
||||
# #endregion DashboardModels
|
||||
# #endregion DashboardModels
|
||||
|
||||
@@ -14,66 +14,66 @@
|
||||
# @RATIONALE: Original 984-line monolith violated INV_7 (400-line module limit). Decomposed into domain-focused sub-modules while preserving backward-compatible import paths.
|
||||
# @REJECTED: Keeping all models in a single file because it exceeded the fractal limit by 2.5x and accumulated structural erosion risk.
|
||||
|
||||
from src.models.dataset_review_pkg._clarification_models import ( # noqa: F401
|
||||
ClarificationAnswer,
|
||||
ClarificationOption,
|
||||
ClarificationQuestion,
|
||||
ClarificationSession,
|
||||
)
|
||||
from src.models.dataset_review_pkg._enums import ( # noqa: F401
|
||||
SessionStatus,
|
||||
SessionPhase,
|
||||
ReadinessState,
|
||||
RecommendedAction,
|
||||
SessionCollaboratorRole,
|
||||
AnswerKind,
|
||||
ApprovalState,
|
||||
ArtifactFormat,
|
||||
ArtifactType,
|
||||
BusinessSummarySource,
|
||||
ConfidenceState,
|
||||
FindingArea,
|
||||
FindingSeverity,
|
||||
ResolutionState,
|
||||
SemanticSourceType,
|
||||
TrustLevel,
|
||||
SemanticSourceStatus,
|
||||
FieldKind,
|
||||
FieldProvenance,
|
||||
CandidateMatchType,
|
||||
CandidateStatus,
|
||||
FilterSource,
|
||||
ClarificationStatus,
|
||||
ConfidenceState,
|
||||
FieldKind,
|
||||
FieldProvenance,
|
||||
FilterConfidenceState,
|
||||
FilterRecoveryStatus,
|
||||
VariableKind,
|
||||
MappingStatus,
|
||||
MappingMethod,
|
||||
MappingWarningLevel,
|
||||
ApprovalState,
|
||||
ClarificationStatus,
|
||||
QuestionState,
|
||||
AnswerKind,
|
||||
PreviewStatus,
|
||||
FilterSource,
|
||||
FindingArea,
|
||||
FindingSeverity,
|
||||
LaunchStatus,
|
||||
ArtifactType,
|
||||
ArtifactFormat,
|
||||
MappingMethod,
|
||||
MappingStatus,
|
||||
MappingWarningLevel,
|
||||
PreviewStatus,
|
||||
QuestionState,
|
||||
ReadinessState,
|
||||
RecommendedAction,
|
||||
ResolutionState,
|
||||
SemanticSourceStatus,
|
||||
SemanticSourceType,
|
||||
SessionCollaboratorRole,
|
||||
SessionPhase,
|
||||
SessionStatus,
|
||||
TrustLevel,
|
||||
VariableKind,
|
||||
)
|
||||
from src.models.dataset_review_pkg._session_models import ( # noqa: F401
|
||||
SessionCollaborator,
|
||||
DatasetReviewSession,
|
||||
)
|
||||
from src.models.dataset_review_pkg._profile_models import DatasetProfile # noqa: F401
|
||||
from src.models.dataset_review_pkg._finding_models import ValidationFinding # noqa: F401
|
||||
from src.models.dataset_review_pkg._semantic_models import ( # noqa: F401
|
||||
SemanticSource,
|
||||
SemanticFieldEntry,
|
||||
SemanticCandidate,
|
||||
from src.models.dataset_review_pkg._execution_models import ( # noqa: F401
|
||||
CompiledPreview,
|
||||
DatasetRunContext,
|
||||
ExportArtifact,
|
||||
SessionEvent,
|
||||
)
|
||||
from src.models.dataset_review_pkg._filter_models import ( # noqa: F401
|
||||
ImportedFilter,
|
||||
TemplateVariable,
|
||||
)
|
||||
from src.models.dataset_review_pkg._finding_models import ValidationFinding # noqa: F401
|
||||
from src.models.dataset_review_pkg._mapping_models import ExecutionMapping # noqa: F401
|
||||
from src.models.dataset_review_pkg._clarification_models import ( # noqa: F401
|
||||
ClarificationSession,
|
||||
ClarificationQuestion,
|
||||
ClarificationOption,
|
||||
ClarificationAnswer,
|
||||
from src.models.dataset_review_pkg._profile_models import DatasetProfile # noqa: F401
|
||||
from src.models.dataset_review_pkg._semantic_models import ( # noqa: F401
|
||||
SemanticCandidate,
|
||||
SemanticFieldEntry,
|
||||
SemanticSource,
|
||||
)
|
||||
from src.models.dataset_review_pkg._execution_models import ( # noqa: F401
|
||||
CompiledPreview,
|
||||
DatasetRunContext,
|
||||
SessionEvent,
|
||||
ExportArtifact,
|
||||
from src.models.dataset_review_pkg._session_models import ( # noqa: F401
|
||||
DatasetReviewSession,
|
||||
SessionCollaborator,
|
||||
)
|
||||
# #endregion DatasetReviewModels
|
||||
|
||||
@@ -2,119 +2,119 @@
|
||||
# @BRIEF Re-export all dataset review domain models from decomposed sub-modules for backward-compatible imports.
|
||||
# @LAYER: Domain
|
||||
|
||||
from src.models.dataset_review_pkg._clarification_models import (
|
||||
ClarificationAnswer,
|
||||
ClarificationOption,
|
||||
ClarificationQuestion,
|
||||
ClarificationSession,
|
||||
)
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
SessionStatus,
|
||||
SessionPhase,
|
||||
ReadinessState,
|
||||
RecommendedAction,
|
||||
SessionCollaboratorRole,
|
||||
AnswerKind,
|
||||
ApprovalState,
|
||||
ArtifactFormat,
|
||||
ArtifactType,
|
||||
BusinessSummarySource,
|
||||
ConfidenceState,
|
||||
FindingArea,
|
||||
FindingSeverity,
|
||||
ResolutionState,
|
||||
SemanticSourceType,
|
||||
TrustLevel,
|
||||
SemanticSourceStatus,
|
||||
FieldKind,
|
||||
FieldProvenance,
|
||||
CandidateMatchType,
|
||||
CandidateStatus,
|
||||
FilterSource,
|
||||
ClarificationStatus,
|
||||
ConfidenceState,
|
||||
FieldKind,
|
||||
FieldProvenance,
|
||||
FilterConfidenceState,
|
||||
FilterRecoveryStatus,
|
||||
VariableKind,
|
||||
MappingStatus,
|
||||
MappingMethod,
|
||||
MappingWarningLevel,
|
||||
ApprovalState,
|
||||
ClarificationStatus,
|
||||
QuestionState,
|
||||
AnswerKind,
|
||||
PreviewStatus,
|
||||
FilterSource,
|
||||
FindingArea,
|
||||
FindingSeverity,
|
||||
LaunchStatus,
|
||||
ArtifactType,
|
||||
ArtifactFormat,
|
||||
MappingMethod,
|
||||
MappingStatus,
|
||||
MappingWarningLevel,
|
||||
PreviewStatus,
|
||||
QuestionState,
|
||||
ReadinessState,
|
||||
RecommendedAction,
|
||||
ResolutionState,
|
||||
SemanticSourceStatus,
|
||||
SemanticSourceType,
|
||||
SessionCollaboratorRole,
|
||||
SessionPhase,
|
||||
SessionStatus,
|
||||
TrustLevel,
|
||||
VariableKind,
|
||||
)
|
||||
from src.models.dataset_review_pkg._session_models import (
|
||||
SessionCollaborator,
|
||||
DatasetReviewSession,
|
||||
)
|
||||
from src.models.dataset_review_pkg._profile_models import DatasetProfile
|
||||
from src.models.dataset_review_pkg._finding_models import ValidationFinding
|
||||
from src.models.dataset_review_pkg._semantic_models import (
|
||||
SemanticSource,
|
||||
SemanticFieldEntry,
|
||||
SemanticCandidate,
|
||||
from src.models.dataset_review_pkg._execution_models import (
|
||||
CompiledPreview,
|
||||
DatasetRunContext,
|
||||
ExportArtifact,
|
||||
SessionEvent,
|
||||
)
|
||||
from src.models.dataset_review_pkg._filter_models import (
|
||||
ImportedFilter,
|
||||
TemplateVariable,
|
||||
)
|
||||
from src.models.dataset_review_pkg._finding_models import ValidationFinding
|
||||
from src.models.dataset_review_pkg._mapping_models import ExecutionMapping
|
||||
from src.models.dataset_review_pkg._clarification_models import (
|
||||
ClarificationSession,
|
||||
ClarificationQuestion,
|
||||
ClarificationOption,
|
||||
ClarificationAnswer,
|
||||
from src.models.dataset_review_pkg._profile_models import DatasetProfile
|
||||
from src.models.dataset_review_pkg._semantic_models import (
|
||||
SemanticCandidate,
|
||||
SemanticFieldEntry,
|
||||
SemanticSource,
|
||||
)
|
||||
from src.models.dataset_review_pkg._execution_models import (
|
||||
CompiledPreview,
|
||||
DatasetRunContext,
|
||||
SessionEvent,
|
||||
ExportArtifact,
|
||||
from src.models.dataset_review_pkg._session_models import (
|
||||
DatasetReviewSession,
|
||||
SessionCollaborator,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"SessionStatus",
|
||||
"SessionPhase",
|
||||
"ReadinessState",
|
||||
"RecommendedAction",
|
||||
"SessionCollaboratorRole",
|
||||
"AnswerKind",
|
||||
"ApprovalState",
|
||||
"ArtifactFormat",
|
||||
"ArtifactType",
|
||||
"BusinessSummarySource",
|
||||
"ConfidenceState",
|
||||
"FindingArea",
|
||||
"FindingSeverity",
|
||||
"ResolutionState",
|
||||
"SemanticSourceType",
|
||||
"TrustLevel",
|
||||
"SemanticSourceStatus",
|
||||
"FieldKind",
|
||||
"FieldProvenance",
|
||||
"CandidateMatchType",
|
||||
"CandidateStatus",
|
||||
"FilterSource",
|
||||
"ClarificationAnswer",
|
||||
"ClarificationOption",
|
||||
"ClarificationQuestion",
|
||||
"ClarificationSession",
|
||||
"ClarificationStatus",
|
||||
"CompiledPreview",
|
||||
"ConfidenceState",
|
||||
"DatasetProfile",
|
||||
"DatasetReviewSession",
|
||||
"DatasetRunContext",
|
||||
"ExecutionMapping",
|
||||
"ExportArtifact",
|
||||
"FieldKind",
|
||||
"FieldProvenance",
|
||||
"FilterConfidenceState",
|
||||
"FilterRecoveryStatus",
|
||||
"VariableKind",
|
||||
"MappingStatus",
|
||||
"MappingMethod",
|
||||
"MappingWarningLevel",
|
||||
"ApprovalState",
|
||||
"ClarificationStatus",
|
||||
"QuestionState",
|
||||
"AnswerKind",
|
||||
"PreviewStatus",
|
||||
"LaunchStatus",
|
||||
"ArtifactType",
|
||||
"ArtifactFormat",
|
||||
"SessionCollaborator",
|
||||
"DatasetReviewSession",
|
||||
"DatasetProfile",
|
||||
"ValidationFinding",
|
||||
"SemanticSource",
|
||||
"SemanticFieldEntry",
|
||||
"SemanticCandidate",
|
||||
"FilterSource",
|
||||
"FindingArea",
|
||||
"FindingSeverity",
|
||||
"ImportedFilter",
|
||||
"TemplateVariable",
|
||||
"ExecutionMapping",
|
||||
"ClarificationSession",
|
||||
"ClarificationQuestion",
|
||||
"ClarificationOption",
|
||||
"ClarificationAnswer",
|
||||
"CompiledPreview",
|
||||
"DatasetRunContext",
|
||||
"LaunchStatus",
|
||||
"MappingMethod",
|
||||
"MappingStatus",
|
||||
"MappingWarningLevel",
|
||||
"PreviewStatus",
|
||||
"QuestionState",
|
||||
"ReadinessState",
|
||||
"RecommendedAction",
|
||||
"ResolutionState",
|
||||
"SemanticCandidate",
|
||||
"SemanticFieldEntry",
|
||||
"SemanticSource",
|
||||
"SemanticSourceStatus",
|
||||
"SemanticSourceType",
|
||||
"SessionCollaborator",
|
||||
"SessionCollaboratorRole",
|
||||
"SessionEvent",
|
||||
"ExportArtifact",
|
||||
"SessionPhase",
|
||||
"SessionStatus",
|
||||
"TemplateVariable",
|
||||
"TrustLevel",
|
||||
"ValidationFinding",
|
||||
"VariableKind",
|
||||
]
|
||||
# #endregion DatasetReviewModels
|
||||
|
||||
@@ -11,21 +11,23 @@ from datetime import datetime
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
Column,
|
||||
String,
|
||||
Integer,
|
||||
Text,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
String,
|
||||
Text,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
AnswerKind,
|
||||
ClarificationStatus,
|
||||
QuestionState,
|
||||
AnswerKind,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region ClarificationSession [C:2] [TYPE Class]
|
||||
|
||||
@@ -8,23 +8,25 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
JSON,
|
||||
Column,
|
||||
String,
|
||||
Text,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
JSON,
|
||||
String,
|
||||
Text,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
PreviewStatus,
|
||||
LaunchStatus,
|
||||
ArtifactType,
|
||||
ArtifactFormat,
|
||||
ArtifactType,
|
||||
LaunchStatus,
|
||||
PreviewStatus,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region CompiledPreview [C:2] [TYPE Class]
|
||||
|
||||
@@ -8,25 +8,27 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
String,
|
||||
Text,
|
||||
JSON,
|
||||
Boolean,
|
||||
Column,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
JSON,
|
||||
String,
|
||||
Text,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
FilterSource,
|
||||
FilterConfidenceState,
|
||||
FilterRecoveryStatus,
|
||||
VariableKind,
|
||||
FilterSource,
|
||||
MappingStatus,
|
||||
VariableKind,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region ImportedFilter [C:2] [TYPE Class]
|
||||
|
||||
@@ -9,20 +9,22 @@ from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
String,
|
||||
Text,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
String,
|
||||
Text,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
FindingArea,
|
||||
FindingSeverity,
|
||||
ResolutionState,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region ValidationFinding [C:2] [TYPE Class]
|
||||
|
||||
@@ -8,23 +8,25 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
String,
|
||||
Text,
|
||||
JSON,
|
||||
Boolean,
|
||||
Column,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
JSON,
|
||||
String,
|
||||
Text,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
ApprovalState,
|
||||
MappingMethod,
|
||||
MappingWarningLevel,
|
||||
ApprovalState,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region ExecutionMapping [C:2] [TYPE Class]
|
||||
|
||||
@@ -8,22 +8,24 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
Column,
|
||||
DateTime,
|
||||
Float,
|
||||
ForeignKey,
|
||||
String,
|
||||
Text,
|
||||
Float,
|
||||
Boolean,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
BusinessSummarySource,
|
||||
ConfidenceState,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region DatasetProfile [C:2] [TYPE Class]
|
||||
|
||||
@@ -9,28 +9,30 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
String,
|
||||
Integer,
|
||||
Text,
|
||||
Float,
|
||||
Boolean,
|
||||
Column,
|
||||
DateTime,
|
||||
Float,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
String,
|
||||
Text,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
SemanticSourceType,
|
||||
TrustLevel,
|
||||
SemanticSourceStatus,
|
||||
FieldKind,
|
||||
FieldProvenance,
|
||||
CandidateMatchType,
|
||||
CandidateStatus,
|
||||
FieldKind,
|
||||
FieldProvenance,
|
||||
SemanticSourceStatus,
|
||||
SemanticSourceType,
|
||||
TrustLevel,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region SemanticSource [C:2] [TYPE Class]
|
||||
|
||||
@@ -10,22 +10,24 @@ from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
String,
|
||||
Integer,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
String,
|
||||
)
|
||||
from sqlalchemy import (
|
||||
Enum as SQLEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from src.models.mapping import Base
|
||||
from src.models.dataset_review_pkg._enums import (
|
||||
SessionStatus,
|
||||
SessionPhase,
|
||||
ReadinessState,
|
||||
RecommendedAction,
|
||||
SessionCollaboratorRole,
|
||||
SessionPhase,
|
||||
SessionStatus,
|
||||
)
|
||||
from src.models.mapping import Base
|
||||
|
||||
|
||||
# #region SessionCollaborator [C:2] [TYPE Class]
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
# @LAYER: Models
|
||||
# @RELATION DEPENDS_ON -> [pydantic]
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
@@ -13,12 +14,12 @@ from pydantic import BaseModel, ConfigDict, Field
|
||||
# @DATA_CONTRACT: Input[extraFormData: Dict, filterState: Dict, ownState: Optional[Dict]] -> Model[FilterState]
|
||||
class FilterState(BaseModel):
|
||||
"""Single native filter state with extraFormData, filterState, and ownState."""
|
||||
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
extraFormData: Dict[str, Any] = Field(default_factory=dict, description="Extra form data for the filter")
|
||||
filterState: Dict[str, Any] = Field(default_factory=dict, description="Current filter state")
|
||||
ownState: Dict[str, Any] = Field(default_factory=dict, description="Own state of the filter")
|
||||
|
||||
extraFormData: dict[str, Any] = Field(default_factory=dict, description="Extra form data for the filter")
|
||||
filterState: dict[str, Any] = Field(default_factory=dict, description="Current filter state")
|
||||
ownState: dict[str, Any] = Field(default_factory=dict, description="Own state of the filter")
|
||||
# #endregion FilterState
|
||||
|
||||
|
||||
@@ -27,16 +28,16 @@ class FilterState(BaseModel):
|
||||
# @DATA_CONTRACT: Input[Dict[filter_id, FilterState]] -> Model[NativeFilterDataMask]
|
||||
class NativeFilterDataMask(BaseModel):
|
||||
"""Container for all native filter states in a dashboard."""
|
||||
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
filters: Dict[str, Any] = Field(default_factory=dict, description="Map of filter ID to filter state data")
|
||||
|
||||
def get_filter_ids(self) -> List[str]:
|
||||
|
||||
filters: dict[str, Any] = Field(default_factory=dict, description="Map of filter ID to filter state data")
|
||||
|
||||
def get_filter_ids(self) -> list[str]:
|
||||
"""Return list of all filter IDs."""
|
||||
return list(self.filters.keys())
|
||||
|
||||
def get_extra_form_data(self, filter_id: str) -> Dict[str, Any]:
|
||||
|
||||
def get_extra_form_data(self, filter_id: str) -> dict[str, Any]:
|
||||
"""Get extraFormData for a specific filter."""
|
||||
filter_state = self.filters.get(filter_id)
|
||||
if filter_state:
|
||||
@@ -50,22 +51,22 @@ class NativeFilterDataMask(BaseModel):
|
||||
# @DATA_CONTRACT: Input[dataMask: Dict, metadata: Dict] -> Model[ParsedNativeFilters]
|
||||
class ParsedNativeFilters(BaseModel):
|
||||
"""Result of extracting native filters from a Superset URL."""
|
||||
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
dataMask: Dict[str, Any] = Field(default_factory=dict, description="Extracted dataMask from filters")
|
||||
filter_type: Optional[str] = Field(default=None, description="Type of filter: permalink, native_filters_key, or native_filters")
|
||||
dashboard_id: Optional[str] = Field(default=None, description="Dashboard ID if available")
|
||||
permalink_key: Optional[str] = Field(default=None, description="Permalink key if used")
|
||||
filter_state_key: Optional[str] = Field(default=None, description="Filter state key if used")
|
||||
active_tabs: List[str] = Field(default_factory=list, description="Active tabs in dashboard")
|
||||
anchor: Optional[str] = Field(default=None, description="Anchor position in dashboard")
|
||||
chart_states: Dict[str, Any] = Field(default_factory=dict, description="Chart states in dashboard")
|
||||
|
||||
|
||||
dataMask: dict[str, Any] = Field(default_factory=dict, description="Extracted dataMask from filters")
|
||||
filter_type: str | None = Field(default=None, description="Type of filter: permalink, native_filters_key, or native_filters")
|
||||
dashboard_id: str | None = Field(default=None, description="Dashboard ID if available")
|
||||
permalink_key: str | None = Field(default=None, description="Permalink key if used")
|
||||
filter_state_key: str | None = Field(default=None, description="Filter state key if used")
|
||||
active_tabs: list[str] = Field(default_factory=list, description="Active tabs in dashboard")
|
||||
anchor: str | None = Field(default=None, description="Anchor position in dashboard")
|
||||
chart_states: dict[str, Any] = Field(default_factory=dict, description="Chart states in dashboard")
|
||||
|
||||
def has_filters(self) -> bool:
|
||||
"""Check if any filters were extracted."""
|
||||
return bool(self.dataMask)
|
||||
|
||||
|
||||
def get_filter_count(self) -> int:
|
||||
"""Get the number of filters extracted."""
|
||||
return len(self.dataMask)
|
||||
@@ -77,15 +78,15 @@ class ParsedNativeFilters(BaseModel):
|
||||
# @DATA_CONTRACT: Input[url: str, dashboard_id: Optional, filter_type: Optional, filters: Dict] -> Model[DashboardURLFilterExtraction]
|
||||
class DashboardURLFilterExtraction(BaseModel):
|
||||
"""Result of parsing a Superset dashboard URL to extract filter state."""
|
||||
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
url: str = Field(..., description="Original dashboard URL")
|
||||
dashboard_id: Optional[str] = Field(default=None, description="Extracted dashboard ID")
|
||||
filter_type: Optional[str] = Field(default=None, description="Type of filter found")
|
||||
dashboard_id: str | None = Field(default=None, description="Extracted dashboard ID")
|
||||
filter_type: str | None = Field(default=None, description="Type of filter found")
|
||||
filters: ParsedNativeFilters = Field(default_factory=ParsedNativeFilters, description="Extracted filter data")
|
||||
success: bool = Field(default=True, description="Whether extraction was successful")
|
||||
error: Optional[str] = Field(default=None, description="Error message if extraction failed")
|
||||
error: str | None = Field(default=None, description="Error message if extraction failed")
|
||||
# #endregion DashboardURLFilterExtraction
|
||||
|
||||
|
||||
@@ -94,19 +95,19 @@ class DashboardURLFilterExtraction(BaseModel):
|
||||
# @DATA_CONTRACT: Input[append_keys: List[str], override_keys: List[str]] -> Model[ExtraFormDataMerge]
|
||||
class ExtraFormDataMerge(BaseModel):
|
||||
"""Configuration for merging extraFormData between original and new filter values."""
|
||||
|
||||
|
||||
# Keys that should be appended (arrays, filters)
|
||||
append_keys: List[str] = Field(
|
||||
append_keys: list[str] = Field(
|
||||
default_factory=lambda: ["filters", "extras", "columns", "metrics"],
|
||||
description="Keys that should be merged by appending"
|
||||
)
|
||||
# Keys that should be overridden (single values)
|
||||
override_keys: List[str] = Field(
|
||||
override_keys: list[str] = Field(
|
||||
default_factory=lambda: ["time_range", "time_grain_sqla", "time_column", "granularity"],
|
||||
description="Keys that should be overridden by new values"
|
||||
)
|
||||
|
||||
def merge(self, original: Dict[str, Any], new: Dict[str, Any]) -> Dict[str, Any]:
|
||||
|
||||
def merge(self, original: dict[str, Any], new: dict[str, Any]) -> dict[str, Any]:
|
||||
"""
|
||||
Merge two extraFormData dictionaries.
|
||||
|
||||
@@ -115,11 +116,11 @@ class ExtraFormDataMerge(BaseModel):
|
||||
@return: Merged extraFormData dictionary
|
||||
"""
|
||||
result = {}
|
||||
|
||||
|
||||
# Start with original
|
||||
for key, value in original.items():
|
||||
result[key] = value
|
||||
|
||||
|
||||
# Apply overrides and appends from new
|
||||
for key, new_value in new.items():
|
||||
if key in self.override_keys:
|
||||
@@ -134,9 +135,9 @@ class ExtraFormDataMerge(BaseModel):
|
||||
result[key] = new_value
|
||||
else:
|
||||
result[key] = new_value
|
||||
|
||||
|
||||
return result
|
||||
# #endregion ExtraFormDataMerge
|
||||
|
||||
|
||||
# #endregion FilterStateModels
|
||||
# #endregion FilterStateModels
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
# #region GitModels [TYPE Module] [SEMANTICS sqlalchemy, git, model, config, sync]
|
||||
|
||||
import enum
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, String, Integer, DateTime, Enum, ForeignKey, Boolean
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import Boolean, Column, DateTime, Enum, ForeignKey, Integer, String
|
||||
|
||||
from src.core.database import Base
|
||||
|
||||
|
||||
class GitProvider(str, enum.Enum):
|
||||
GITHUB = "GITHUB"
|
||||
GITLAB = "GITLAB"
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
# @LAYER: Domain
|
||||
# @RELATION INHERITS_FROM -> MappingModels:Base
|
||||
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, JSON, Text, Time, ForeignKey
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import JSON, Boolean, Column, DateTime, String, Text, Time
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
def generate_uuid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
@@ -35,7 +38,7 @@ class ValidationPolicy(Base):
|
||||
# @BRIEF SQLAlchemy model for LLM provider configuration.
|
||||
class LLMProvider(Base):
|
||||
__tablename__ = "llm_providers"
|
||||
|
||||
|
||||
id = Column(String, primary_key=True, default=generate_uuid)
|
||||
provider_type = Column(String, nullable=False) # openai, openrouter, kilo
|
||||
name = Column(String, nullable=False)
|
||||
@@ -50,7 +53,7 @@ class LLMProvider(Base):
|
||||
# @BRIEF SQLAlchemy model for dashboard validation history.
|
||||
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)
|
||||
@@ -63,4 +66,4 @@ class ValidationRecord(Base):
|
||||
raw_response = Column(Text, nullable=True)
|
||||
# #endregion ValidationRecord
|
||||
|
||||
# #endregion LlmModels
|
||||
# #endregion LlmModels
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
# @INVARIANT: All primary keys are UUID strings.
|
||||
# @CONSTRAINT: source_env_id and target_env_id must be valid environment IDs.
|
||||
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, Enum as SQLEnum
|
||||
import enum
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, String
|
||||
from sqlalchemy import Enum as SQLEnum
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.sql import func
|
||||
import uuid
|
||||
import enum
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey
|
||||
|
||||
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, String
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator, model_validator
|
||||
|
||||
@@ -63,9 +63,9 @@ class ReportStatus(str, Enum):
|
||||
# @TEST_EDGE: missing_message -> {"code": "ERR_504"}
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ErrorContext(BaseModel):
|
||||
code: Optional[str] = None
|
||||
code: str | None = None
|
||||
message: str
|
||||
next_actions: List[str] = Field(default_factory=list)
|
||||
next_actions: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
# #endregion ErrorContext
|
||||
@@ -110,13 +110,13 @@ class TaskReport(BaseModel):
|
||||
task_id: str
|
||||
task_type: TaskType
|
||||
status: ReportStatus
|
||||
started_at: Optional[datetime] = None
|
||||
started_at: datetime | None = None
|
||||
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
|
||||
details: dict[str, Any] | None = None
|
||||
validation_record: dict[str, Any] | None = None # Extended for US2
|
||||
error_context: ErrorContext | None = None
|
||||
source_ref: dict[str, Any] | None = None
|
||||
|
||||
@field_validator("report_id", "task_id", "summary")
|
||||
@classmethod
|
||||
@@ -155,11 +155,11 @@ class TaskReport(BaseModel):
|
||||
class ReportQuery(BaseModel):
|
||||
page: int = Field(default=1, ge=1)
|
||||
page_size: int = Field(default=20, ge=1, le=100)
|
||||
task_types: List[TaskType] = Field(default_factory=list)
|
||||
statuses: List[ReportStatus] = Field(default_factory=list)
|
||||
time_from: Optional[datetime] = None
|
||||
time_to: Optional[datetime] = None
|
||||
search: Optional[str] = Field(default=None, max_length=200)
|
||||
task_types: list[TaskType] = Field(default_factory=list)
|
||||
statuses: list[ReportStatus] = Field(default_factory=list)
|
||||
time_from: datetime | None = None
|
||||
time_to: datetime | None = None
|
||||
search: str | None = Field(default=None, max_length=200)
|
||||
sort_by: str = Field(default="updated_at")
|
||||
sort_order: str = Field(default="desc")
|
||||
|
||||
@@ -203,7 +203,7 @@ class ReportQuery(BaseModel):
|
||||
# @TEST_EDGE: negative_total -> {"items": [], "total": -5, "page": 1, "page_size": 20, "has_next": False, "applied_filters": {}}
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ReportCollection(BaseModel):
|
||||
items: List[TaskReport]
|
||||
items: list[TaskReport]
|
||||
total: int = Field(ge=0)
|
||||
page: int = Field(ge=1)
|
||||
page_size: int = Field(ge=1)
|
||||
@@ -228,9 +228,9 @@ class ReportCollection(BaseModel):
|
||||
# @RELATION DEPENDS_ON -> ReportModels
|
||||
class ReportDetailView(BaseModel):
|
||||
report: TaskReport
|
||||
timeline: List[Dict[str, Any]] = Field(default_factory=list)
|
||||
diagnostics: Optional[Dict[str, Any]] = None
|
||||
next_actions: List[str] = Field(default_factory=list)
|
||||
timeline: list[dict[str, Any]] = Field(default_factory=list)
|
||||
diagnostics: dict[str, Any] | None = None
|
||||
next_actions: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
# #endregion ReportDetailView
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
# #region FileCategory [C:1] [TYPE Class]
|
||||
# @BRIEF Enumeration of supported file categories in the storage system.
|
||||
class FileCategory(str, Enum):
|
||||
@@ -31,7 +32,7 @@ class StoredFile(BaseModel):
|
||||
size: int = Field(..., ge=0, description="Size of the file in bytes.")
|
||||
created_at: datetime = Field(..., description="Creation timestamp.")
|
||||
category: FileCategory = Field(..., description="Category of the file.")
|
||||
mime_type: Optional[str] = Field(None, description="MIME type of the file.")
|
||||
mime_type: str | None = Field(None, description="MIME type of the file.")
|
||||
# #endregion StoredFile
|
||||
|
||||
# #endregion StorageModels
|
||||
# #endregion StorageModels
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
#
|
||||
# @INVARIANT: All primary keys are UUID strings.
|
||||
|
||||
from sqlalchemy import Column, String, DateTime, JSON, ForeignKey, Text, Integer, Index
|
||||
from sqlalchemy.sql import func
|
||||
from .mapping import Base
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import JSON, Column, DateTime, ForeignKey, Index, Integer, String, Text
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
# #region TaskRecord [C:1] [TYPE Class]
|
||||
# @BRIEF Represents a persistent record of a task execution.
|
||||
class TaskRecord(Base):
|
||||
@@ -107,4 +110,4 @@ class TaskLogRecord(Base):
|
||||
)
|
||||
# #endregion TaskLogRecord
|
||||
|
||||
# #endregion TaskModels
|
||||
# #endregion TaskModels
|
||||
|
||||
@@ -3,14 +3,11 @@
|
||||
# @LAYER: Domain
|
||||
# @RELATION INHERITS_FROM -> MappingModels:Base
|
||||
|
||||
from sqlalchemy import (
|
||||
Column, String, Boolean, DateTime, JSON, Text,
|
||||
ForeignKey, Integer, UniqueConstraint, Index
|
||||
)
|
||||
from sqlalchemy.dialects.postgresql import JSON as PG_JSON
|
||||
from datetime import datetime, timezone
|
||||
import uuid
|
||||
import hashlib
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from sqlalchemy import JSON, Boolean, Column, DateTime, ForeignKey, Index, Integer, String, Text, UniqueConstraint
|
||||
|
||||
from .mapping import Base
|
||||
|
||||
|
||||
@@ -57,8 +54,8 @@ class TranslationJob(Base):
|
||||
target_database_id = Column(String, nullable=True, comment="Superset database ID for SQL Lab insert target")
|
||||
|
||||
created_by = Column(String, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
|
||||
# #endregion TranslationJob
|
||||
|
||||
|
||||
@@ -86,7 +83,7 @@ class TranslationRun(Base):
|
||||
config_hash = Column(String, nullable=True, comment="Hash of translation configuration state")
|
||||
dict_snapshot_hash = Column(String, nullable=True, comment="Hash of dictionary state at run time")
|
||||
created_by = Column(String, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
# #endregion TranslationRun
|
||||
|
||||
|
||||
@@ -104,7 +101,7 @@ class TranslationBatch(Base):
|
||||
failed_records = Column(Integer, default=0)
|
||||
started_at = Column(DateTime, nullable=True)
|
||||
completed_at = Column(DateTime, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
# #endregion TranslationBatch
|
||||
|
||||
|
||||
@@ -127,7 +124,7 @@ class TranslationRecord(Base):
|
||||
token_count_input = Column(Integer, nullable=True)
|
||||
token_count_output = Column(Integer, nullable=True)
|
||||
translation_duration_ms = Column(Integer, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_translation_records_run_status", "run_id", "status"),
|
||||
@@ -146,7 +143,7 @@ class TranslationEvent(Base):
|
||||
event_type = Column(String, nullable=False) # JOB_CREATED, JOB_STARTED, JOB_COMPLETED, JOB_FAILED, etc.
|
||||
event_data = Column(JSON, nullable=True)
|
||||
created_by = Column(String, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
# #endregion TranslationEvent
|
||||
|
||||
|
||||
@@ -160,7 +157,7 @@ class TranslationPreviewSession(Base):
|
||||
run_id = Column(String, ForeignKey("translation_runs.id"), nullable=True)
|
||||
status = Column(String, nullable=False, default="ACTIVE") # ACTIVE, APPLIED, DISCARDED, EXPIRED
|
||||
created_by = Column(String, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
expires_at = Column(DateTime, nullable=True)
|
||||
# #endregion TranslationPreviewSession
|
||||
|
||||
@@ -180,7 +177,7 @@ class TranslationPreviewRecord(Base):
|
||||
source_data = Column(JSON, nullable=True, comment="Original source row key columns for upsert matching")
|
||||
status = Column(String, nullable=False, default="PENDING") # PENDING, APPROVED, REJECTED
|
||||
feedback = Column(Text, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
# #endregion TranslationPreviewRecord
|
||||
|
||||
|
||||
@@ -196,8 +193,8 @@ class TerminologyDictionary(Base):
|
||||
target_dialect = Column(String, nullable=False)
|
||||
is_active = Column(Boolean, default=True)
|
||||
created_by = Column(String, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
|
||||
# #endregion TerminologyDictionary
|
||||
|
||||
|
||||
@@ -215,8 +212,8 @@ class DictionaryEntry(Base):
|
||||
origin_run_id = Column(String, nullable=True, comment="Run ID from which this correction originated")
|
||||
origin_row_key = Column(String, nullable=True, comment="Row key within the run that triggered this correction")
|
||||
origin_user_id = Column(String, nullable=True, comment="User who submitted the correction")
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
@@ -241,8 +238,8 @@ class TranslationSchedule(Base):
|
||||
next_run_at = Column(DateTime, nullable=True)
|
||||
execution_mode = Column(String, nullable=False, default="full", comment="full, new_key_only")
|
||||
created_by = Column(String, nullable=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
|
||||
# #endregion TranslationSchedule
|
||||
|
||||
|
||||
@@ -254,7 +251,7 @@ class TranslationJobDictionary(Base):
|
||||
id = Column(String, primary_key=True, default=generate_uuid)
|
||||
job_id = Column(String, ForeignKey("translation_jobs.id"), nullable=False, index=True)
|
||||
dictionary_id = Column(String, ForeignKey("terminology_dictionaries.id"), nullable=False, index=True)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
@@ -287,8 +284,8 @@ class MetricSnapshot(Base):
|
||||
p50_duration_ms = Column(Integer, nullable=True)
|
||||
p95_duration_ms = Column(Integer, nullable=True)
|
||||
p99_duration_ms = Column(Integer, nullable=True)
|
||||
snapshot_date = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
snapshot_date = Column(DateTime, nullable=False, default=lambda: datetime.now(UTC))
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(UTC))
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_metric_snapshots_job_date", "job_id", "snapshot_date"),
|
||||
|
||||
Reference in New Issue
Block a user