fix: finalize semantic repair and test updates

This commit is contained in:
2026-03-21 15:07:06 +03:00
parent c827c2f098
commit 2da548fd71
99 changed files with 2484 additions and 985 deletions

View File

@@ -1,4 +1,4 @@
# [DEF:backend.src.core.migration.__init__:Module]
# [DEF:MigrationPackage:Module]
# @COMPLEXITY: 1
# @SEMANTICS: migration, package, exports
# @PURPOSE: Namespace package for migration pre-flight orchestration components.
@@ -9,4 +9,4 @@ from .archive_parser import MigrationArchiveParser
__all__ = ["MigrationDryRunService", "MigrationArchiveParser"]
# [/DEF:backend.src.core.migration.__init__:Module]
# [/DEF:MigrationPackage:Module]

View File

@@ -1,9 +1,9 @@
# [DEF:backend.src.core.migration.archive_parser:Module]
# [DEF:MigrationArchiveParserModule:Module]
# @COMPLEXITY: 3
# @SEMANTICS: migration, zip, parser, yaml, metadata
# @PURPOSE: Parse Superset export ZIP archives into normalized object catalogs for diffing.
# @LAYER: Core
# @RELATION: DEPENDS_ON -> backend.src.core.logger
# @RELATION: DEPENDS_ON -> [LoggerModule]
# @INVARIANT: Parsing is read-only and never mutates archive files.
import json
@@ -19,11 +19,13 @@ from ..logger import logger, belief_scope
# [DEF:MigrationArchiveParser:Class]
# @PURPOSE: Extract normalized dashboards/charts/datasets metadata from ZIP archives.
# @RELATION: CONTAINS -> [extract_objects_from_zip, _collect_yaml_objects, _normalize_object_payload]
# @RELATION: CONTAINS -> [extract_objects_from_zip]
# @RELATION: CONTAINS -> [_collect_yaml_objects]
# @RELATION: CONTAINS -> [_normalize_object_payload]
class MigrationArchiveParser:
# [DEF:extract_objects_from_zip:Function]
# @PURPOSE: Extract object catalogs from Superset archive.
# @RELATION: DEPENDS_ON -> _collect_yaml_objects
# @RELATION: DEPENDS_ON -> [_collect_yaml_objects]
# @PRE: zip_path points to a valid readable ZIP.
# @POST: Returns object lists grouped by resource type.
# @RETURN: Dict[str, List[Dict[str, Any]]]
@@ -53,7 +55,7 @@ class MigrationArchiveParser:
# [DEF:_collect_yaml_objects:Function]
# @PURPOSE: Read and normalize YAML manifests for one object type.
# @RELATION: DEPENDS_ON -> _normalize_object_payload
# @RELATION: DEPENDS_ON -> [_normalize_object_payload]
# @PRE: object_type is one of dashboards/charts/datasets.
# @POST: Returns only valid normalized objects.
def _collect_yaml_objects(
@@ -153,4 +155,4 @@ class MigrationArchiveParser:
# [/DEF:MigrationArchiveParser:Class]
# [/DEF:backend.src.core.migration.archive_parser:Module]
# [/DEF:MigrationArchiveParserModule:Module]

View File

@@ -1,12 +1,12 @@
# [DEF:backend.src.core.migration.dry_run_orchestrator:Module]
# [DEF:MigrationDryRunOrchestratorModule:Module]
# @COMPLEXITY: 3
# @SEMANTICS: migration, dry_run, diff, risk, superset
# @PURPOSE: Compute pre-flight migration diff and risk scoring without apply.
# @LAYER: Core
# @RELATION: DEPENDS_ON ->[backend.src.core.superset_client.SupersetClient]
# @RELATION: DEPENDS_ON ->[backend.src.core.migration_engine.MigrationEngine]
# @RELATION: DEPENDS_ON ->[backend.src.core.migration.archive_parser.MigrationArchiveParser]
# @RELATION: DEPENDS_ON ->[backend.src.core.migration.risk_assessor]
# @RELATION: DEPENDS_ON -> [SupersetClient]
# @RELATION: DEPENDS_ON -> [MigrationEngine]
# @RELATION: DEPENDS_ON -> [MigrationArchiveParser]
# @RELATION: DEPENDS_ON -> [RiskAssessorModule]
# @INVARIANT: Dry run is informative only and must not mutate target environment.
from datetime import datetime, timezone
@@ -27,7 +27,14 @@ from ..utils.fileio import create_temp_file
# [DEF:MigrationDryRunService:Class]
# @PURPOSE: Build deterministic diff/risk payload for migration pre-flight.
# @RELATION: CONTAINS -> [__init__, run, _load_db_mapping, _accumulate_objects, _index_by_uuid, _build_object_diff, _build_target_signatures, _build_risks]
# @RELATION: CONTAINS -> [__init__]
# @RELATION: CONTAINS -> [run]
# @RELATION: CONTAINS -> [_load_db_mapping]
# @RELATION: CONTAINS -> [_accumulate_objects]
# @RELATION: CONTAINS -> [_index_by_uuid]
# @RELATION: CONTAINS -> [_build_object_diff]
# @RELATION: CONTAINS -> [_build_target_signatures]
# @RELATION: CONTAINS -> [_build_risks]
class MigrationDryRunService:
# [DEF:__init__:Function]
# @PURPOSE: Wire parser dependency for archive object extraction.
@@ -40,7 +47,11 @@ class MigrationDryRunService:
# [DEF:run:Function]
# @PURPOSE: Execute full dry-run computation for selected dashboards.
# @RELATION: DEPENDS_ON -> [_load_db_mapping, _accumulate_objects, _build_target_signatures, _build_object_diff, _build_risks]
# @RELATION: DEPENDS_ON -> [_load_db_mapping]
# @RELATION: DEPENDS_ON -> [_accumulate_objects]
# @RELATION: DEPENDS_ON -> [_build_target_signatures]
# @RELATION: DEPENDS_ON -> [_build_object_diff]
# @RELATION: DEPENDS_ON -> [_build_risks]
# @PRE: source/target clients are authenticated and selection validated by caller.
# @POST: Returns JSON-serializable pre-flight payload with summary, diff and risk.
# @SIDE_EFFECT: Reads source export archives and target metadata via network.
@@ -195,7 +206,7 @@ class MigrationDryRunService:
# [DEF:_build_object_diff:Function]
# @PURPOSE: Compute create/update/delete buckets by UUID+signature.
# @RELATION: DEPENDS_ON -> _index_by_uuid
# @RELATION: DEPENDS_ON -> [_index_by_uuid]
def _build_object_diff(
self, source_objects: List[Dict[str, Any]], target_objects: List[Dict[str, Any]]
) -> Dict[str, List[Dict[str, Any]]]:
@@ -349,4 +360,4 @@ class MigrationDryRunService:
# [/DEF:MigrationDryRunService:Class]
# [/DEF:backend.src.core.migration.dry_run_orchestrator:Module]
# [/DEF:MigrationDryRunOrchestratorModule:Module]

View File

@@ -1,12 +1,18 @@
# [DEF:backend.src.core.migration.risk_assessor:Module]
# [DEF:RiskAssessorModule:Module]
# @COMPLEXITY: 5
# @SEMANTICS: migration, dry_run, risk, scoring, preflight
# @PURPOSE: Compute deterministic migration risk items and aggregate score for dry-run reporting.
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> [backend.src.core.superset_client.SupersetClient]
# @RELATION: DISPATCHED_BY -> [backend.src.core.migration.dry_run_orchestrator.MigrationDryRunService.run]
# @RELATION: CONTAINS -> [index_by_uuid, extract_owner_identifiers, build_risks, score_risks]
# @RELATION: DEPENDS_ON -> [SupersetClient]
# @RELATION: CONTAINS -> [index_by_uuid]
# @RELATION: CONTAINS -> [extract_owner_identifiers]
# @RELATION: CONTAINS -> [build_risks]
# @RELATION: CONTAINS -> [score_risks]
# @INVARIANT: Risk scoring must remain bounded to [0,100] and preserve severity-to-weight mapping.
# @PRE: Risk assessor functions receive normalized migration object collections from dry-run orchestration.
# @POST: Risk scoring output preserves item list and provides bounded score with derived level.
# @SIDE_EFFECT: Emits diagnostic logs and performs read-only metadata requests via Superset client.
# @DATA_CONTRACT: Module[build_risks, score_risks]
# @TEST_CONTRACT: [source_objects,target_objects,diff,target_client] -> [List[RiskItem]]
# @TEST_SCENARIO: [overwrite_update_objects] -> [medium overwrite_existing risk is emitted for each update diff item]
# @TEST_SCENARIO: [missing_datasource_dataset] -> [high missing_datasource risk is emitted]
@@ -80,7 +86,8 @@ def extract_owner_identifiers(owners: Any) -> List[str]:
# [DEF:build_risks:Function]
# @PURPOSE: Build risk list from computed diffs and target catalog state.
# @RELATION: DEPENDS_ON -> [index_by_uuid, extract_owner_identifiers]
# @RELATION: DEPENDS_ON -> [index_by_uuid]
# @RELATION: DEPENDS_ON -> [extract_owner_identifiers]
# @PRE: source_objects/target_objects/diff contain dashboards/charts/datasets keys with expected list structures.
# @PRE: target_client is authenticated/usable for database list retrieval.
# @POST: Returns list of deterministic risk items derived from overwrite, missing datasource, reference, and owner mismatch checks.
@@ -192,4 +199,4 @@ def score_risks(risk_items: List[Dict[str, Any]]) -> Dict[str, Any]:
# [/DEF:score_risks:Function]
# [/DEF:backend.src.core.migration.risk_assessor:Module]
# [/DEF:RiskAssessorModule:Module]