Files
ss-tools/backend/src/models/mapping.py
busya 274510fc38 refactor(semantics): migrate legacy @TIER to @COMPLEXITY annotations
- Replaced @TIER: TRIVIAL with @COMPLEXITY: 1
- Replaced @TIER: STANDARD with @COMPLEXITY: 3
- Replaced @TIER: CRITICAL with @COMPLEXITY: 5
- Manually elevated specific critical/complex components to levels 2 and 4
- Ignored legacy, specs, and node_modules directories
- Updated generated semantic map
2026-03-16 10:06:44 +03:00

103 lines
4.0 KiB
Python

# [DEF:backend.src.models.mapping:Module]
#
# @COMPLEXITY: 3
# @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
#
# @INVARIANT: All primary keys are UUID strings.
# @CONSTRAINT: source_env_id and target_env_id must be valid environment IDs.
# [SECTION: IMPORTS]
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, Enum as SQLEnum
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import func
import uuid
import enum
# [/SECTION]
Base = declarative_base()
# [DEF:ResourceType:Class]
# @COMPLEXITY: 1
# @PURPOSE: Enumeration of possible Superset resource types for ID mapping.
class ResourceType(str, enum.Enum):
CHART = "chart"
DATASET = "dataset"
DASHBOARD = "dashboard"
# [/DEF:ResourceType:Class]
# [DEF:MigrationStatus:Class]
# @COMPLEXITY: 1
# @PURPOSE: Enumeration of possible migration job statuses.
class MigrationStatus(enum.Enum):
PENDING = "PENDING"
RUNNING = "RUNNING"
COMPLETED = "COMPLETED"
FAILED = "FAILED"
AWAITING_MAPPING = "AWAITING_MAPPING"
# [/DEF:MigrationStatus:Class]
# [DEF:Environment:Class]
# @COMPLEXITY: 3
# @PURPOSE: Represents a Superset instance environment.
class Environment(Base):
__tablename__ = "environments"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
name = Column(String, nullable=False)
url = Column(String, nullable=False)
credentials_id = Column(String, nullable=False)
# [/DEF:Environment:Class]
# [DEF:DatabaseMapping:Class]
# @COMPLEXITY: 3
# @PURPOSE: Represents a mapping between source and target databases.
class DatabaseMapping(Base):
__tablename__ = "database_mappings"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
source_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
target_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
source_db_uuid = Column(String, nullable=False)
target_db_uuid = Column(String, nullable=False)
source_db_name = Column(String, nullable=False)
target_db_name = Column(String, nullable=False)
engine = Column(String, nullable=True)
# [/DEF:DatabaseMapping:Class]
# [DEF:MigrationJob:Class]
# @COMPLEXITY: 2
# @PURPOSE: Represents a single migration execution job.
class MigrationJob(Base):
__tablename__ = "migration_jobs"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
source_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
target_env_id = Column(String, ForeignKey("environments.id"), nullable=False)
status = Column(SQLEnum(MigrationStatus), default=MigrationStatus.PENDING)
replace_db = Column(Boolean, default=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
# [/DEF:MigrationJob:Class]
# [DEF:ResourceMapping:Class]
# @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'}
class ResourceMapping(Base):
__tablename__ = "resource_mappings"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
environment_id = Column(String, ForeignKey("environments.id"), nullable=False)
resource_type = Column(SQLEnum(ResourceType), nullable=False)
uuid = Column(String, nullable=False)
remote_integer_id = Column(String, nullable=False) # Stored as string to handle potentially large or composite IDs safely, though Superset usually uses integers.
resource_name = Column(String, nullable=True) # Used for UI display
last_synced_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
# [/DEF:ResourceMapping:Class]
# [/DEF:backend.src.models.mapping:Module]