{ "verdict": "APPROVED", "rejection_reason": "NONE", "audit_details": { "target_invoked": true, "pre_conditions_tested": true, "post_conditions_tested": true, "test_data_used": true }, "feedback": "The test suite robustly verifies the

MigrationEngine
 contracts. It avoids Tautologies by cleanly substituting IdMappingService without mocking the engine itself. Cross-filter parsing asserts against hard-coded, predefined validation dictionaries (no Logic Mirroring). It successfully addresses @PRE negative cases (e.g. invalid zip paths, missing YAMLs) and rigorously validates @POST file transformations (e.g. in-place UUID substitutions and archive reconstruction)." }
This commit is contained in:
2026-02-25 17:47:55 +03:00
parent 590ba49ddb
commit 99f19ac305
20 changed files with 1211 additions and 308 deletions

View File

@@ -16,6 +16,7 @@ import zipfile
from pathlib import Path
from typing import Dict, List, Optional, Tuple, Union, cast
from requests import Response
from datetime import datetime
from .logger import logger as app_logger, belief_scope
from .utils.network import APIClient, SupersetAPIError
from .utils.fileio import get_filename_from_headers
@@ -835,8 +836,8 @@ class SupersetClient:
# @PRE: Client is authenticated. resource_type is valid.
# @POST: Returns a list of resource dicts with at minimum id, uuid, and name fields.
# @RETURN: List[Dict]
def get_all_resources(self, resource_type: str) -> List[Dict]:
with belief_scope("SupersetClient.get_all_resources", f"type={resource_type}"):
def get_all_resources(self, resource_type: str, since_dttm: Optional[datetime] = None) -> List[Dict]:
with belief_scope("SupersetClient.get_all_resources", f"type={resource_type}, since={since_dttm}"):
column_map = {
"chart": {"endpoint": "/chart/", "columns": ["id", "uuid", "slice_name"]},
"dataset": {"endpoint": "/dataset/", "columns": ["id", "uuid", "table_name"]},
@@ -848,6 +849,25 @@ class SupersetClient:
return []
query = {"columns": config["columns"]}
if since_dttm:
# Format to ISO 8601 string for Superset filter
# e.g. "2026-02-25T13:24:32.186" or integer milliseconds.
# Assuming standard ISO string works:
# The user's example had value: 0 (which might imply ms or int) but often it accepts strings.
import math
# Use int milliseconds to be safe, as "0" was in the user example
timestamp_ms = math.floor(since_dttm.timestamp() * 1000)
query["filters"] = [
{
"col": "changed_on_dttm",
"opr": "gt",
"value": timestamp_ms
}
]
# Also we must request `changed_on_dttm` just in case, though API usually filters regardless of columns
validated = self._validate_query_params(query)
data = self._fetch_all_pages(
endpoint=config["endpoint"],