This commit is contained in:
2026-03-18 08:45:15 +03:00
parent 3094a2b58b
commit 6d64124e88
17 changed files with 1563 additions and 31159 deletions

View File

@@ -45,16 +45,25 @@ from src.models.dataset_review import (
DatasetProfile,
DatasetReviewSession,
DatasetRunContext,
ExecutionMapping,
FilterConfidenceState,
FilterRecoveryStatus,
FilterSource,
FindingArea,
FindingSeverity,
ImportedFilter,
LaunchStatus,
MappingMethod,
MappingStatus,
PreviewStatus,
RecommendedAction,
ReadinessState,
ResolutionState,
SessionPhase,
SessionStatus,
TemplateVariable,
ValidationFinding,
VariableKind,
)
from src.services.dataset_review.repositories.session_repository import (
DatasetReviewSessionRepository,
@@ -248,6 +257,17 @@ class DatasetReviewOrchestrator:
)
persisted_session = self.repository.create_session(session)
recovered_filters: List[ImportedFilter] = []
template_variables: List[TemplateVariable] = []
execution_mappings: List[ExecutionMapping] = []
if normalized_source_kind == "superset_link" and parsed_context is not None:
recovered_filters, template_variables, execution_mappings, findings = self._build_recovery_bootstrap(
environment=environment,
session=persisted_session,
parsed_context=parsed_context,
findings=findings,
)
profile = self._build_initial_profile(
session_id=persisted_session.session_id,
parsed_context=parsed_context,
@@ -276,6 +296,14 @@ class DatasetReviewOrchestrator:
profile,
findings,
)
if recovered_filters or template_variables or execution_mappings:
persisted_session = self.repository.save_recovery_state(
persisted_session.session_id,
command.user.id,
recovered_filters,
template_variables,
execution_mappings,
)
active_task_id = self._enqueue_recovery_task(
command=command,
@@ -644,6 +672,115 @@ class DatasetReviewOrchestrator:
return findings
# [/DEF:DatasetReviewOrchestrator._build_partial_recovery_findings:Function]
# [DEF:DatasetReviewOrchestrator._build_recovery_bootstrap:Function]
# @COMPLEXITY: 4
# @PURPOSE: Recover and materialize initial imported filters, template variables, and draft execution mappings after session creation.
def _build_recovery_bootstrap(
self,
environment,
session: DatasetReviewSession,
parsed_context: SupersetParsedContext,
findings: List[ValidationFinding],
) -> tuple[List[ImportedFilter], List[TemplateVariable], List[ExecutionMapping], List[ValidationFinding]]:
extractor = SupersetContextExtractor(environment)
imported_filters_payload = extractor.recover_imported_filters(parsed_context)
if imported_filters_payload is None:
imported_filters_payload = []
imported_filters = [
ImportedFilter(
session_id=session.session_id,
filter_name=str(item.get("filter_name") or f"imported_filter_{index}"),
display_name=item.get("display_name"),
raw_value=item.get("raw_value"),
normalized_value=item.get("normalized_value"),
source=FilterSource(str(item.get("source") or FilterSource.SUPERSET_URL.value)),
confidence_state=FilterConfidenceState(
str(item.get("confidence_state") or FilterConfidenceState.UNRESOLVED.value)
),
requires_confirmation=bool(item.get("requires_confirmation", False)),
recovery_status=FilterRecoveryStatus(
str(item.get("recovery_status") or FilterRecoveryStatus.PARTIAL.value)
),
notes=item.get("notes"),
)
for index, item in enumerate(imported_filters_payload)
]
template_variables: List[TemplateVariable] = []
execution_mappings: List[ExecutionMapping] = []
if session.dataset_id is not None:
try:
dataset_payload = extractor.client.get_dataset_detail(session.dataset_id)
discovered_variables = extractor.discover_template_variables(dataset_payload)
template_variables = [
TemplateVariable(
session_id=session.session_id,
variable_name=str(item.get("variable_name") or f"variable_{index}"),
expression_source=str(item.get("expression_source") or ""),
variable_kind=VariableKind(str(item.get("variable_kind") or VariableKind.UNKNOWN.value)),
is_required=bool(item.get("is_required", True)),
default_value=item.get("default_value"),
mapping_status=MappingStatus(str(item.get("mapping_status") or MappingStatus.UNMAPPED.value)),
)
for index, item in enumerate(discovered_variables)
]
except Exception as exc:
if "dataset_template_variable_discovery_failed" not in parsed_context.unresolved_references:
parsed_context.unresolved_references.append("dataset_template_variable_discovery_failed")
if not any(
finding.caused_by_ref == "dataset_template_variable_discovery_failed"
for finding in findings
):
findings.append(
ValidationFinding(
area=FindingArea.TEMPLATE_MAPPING,
severity=FindingSeverity.WARNING,
code="TEMPLATE_VARIABLE_DISCOVERY_FAILED",
title="Template variables could not be discovered",
message="Session remains usable, but dataset template variables still need review.",
resolution_state=ResolutionState.OPEN,
caused_by_ref="dataset_template_variable_discovery_failed",
)
)
logger.explore(
"Template variable discovery failed during session bootstrap",
extra={"session_id": session.session_id, "dataset_id": session.dataset_id, "error": str(exc)},
)
filter_lookup = {
str(imported_filter.filter_name or "").strip().lower(): imported_filter
for imported_filter in imported_filters
if str(imported_filter.filter_name or "").strip()
}
for template_variable in template_variables:
matched_filter = filter_lookup.get(str(template_variable.variable_name or "").strip().lower())
if matched_filter is None:
continue
requires_explicit_approval = bool(
matched_filter.requires_confirmation
or matched_filter.recovery_status != FilterRecoveryStatus.RECOVERED
)
execution_mappings.append(
ExecutionMapping(
session_id=session.session_id,
filter_id=matched_filter.filter_id,
variable_id=template_variable.variable_id,
mapping_method=MappingMethod.DIRECT_MATCH,
raw_input_value=matched_filter.raw_value,
effective_value=matched_filter.normalized_value if matched_filter.normalized_value is not None else matched_filter.raw_value,
transformation_note="Bootstrapped from Superset recovery context",
warning_level=None if not requires_explicit_approval else None,
requires_explicit_approval=requires_explicit_approval,
approval_state=ApprovalState.PENDING if requires_explicit_approval else ApprovalState.NOT_REQUIRED,
approved_by_user_id=None,
approved_at=None,
)
)
return imported_filters, template_variables, execution_mappings, findings
# [/DEF:DatasetReviewOrchestrator._build_recovery_bootstrap:Function]
# [DEF:DatasetReviewOrchestrator._build_execution_snapshot:Function]
# @COMPLEXITY: 4
# @PURPOSE: Build effective filters, template params, approvals, and fingerprint for preview and launch gating.