fix(llm): add fetch-models endpoint, fix SQL Lab INSERT (client_id truncation, sync mode, target_column, timestamp normalization)
- Add POST /api/llm/providers/fetch-models route with LLMClient.fetch_models() - Add target_column to TranslationJob model/schema/service/orchestrator - Fix SQL Lab execute: truncate client_id to 11 chars (varchar(11)) - Switch SQL Lab to sync mode (runAsync: false) — no Celery workers - Fix polling: unwrap nested result from Superset query API - Fix ClickHouse timestamp: normalize float timestamps to YYYY-MM-DD
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
<!-- #region MigrationPage [C:4] [TYPE Page] [SEMANTICS sveltekit, migration, dashboard, dry-run, environment] -->
|
||||
<!--
|
||||
@COMPLEXITY: 3
|
||||
@SEMANTICS: migration, dashboard, environment, dry-run, task-resume
|
||||
@PURPOSE: Main migration dashboard page for environment selection, dry-run validation, and migration execution.
|
||||
@BRIEF: Main migration dashboard page for environment selection, dry-run validation, and migration execution.
|
||||
@LAYER: UI
|
||||
@RELATION: [DEPENDS_ON] ->[frontend/src/lib/api.js]
|
||||
@RELATION: [DEPENDS_ON] ->[stores]
|
||||
@@ -52,7 +51,7 @@
|
||||
<!-- @UX_FEEDBACK Modal dialogs for database mappings and password entry. -->
|
||||
<!-- @UX_RECOVERY User can adjust selection, refresh databases, retry dry-run/migration. -->
|
||||
<!--
|
||||
@PURPOSE: Orchestrate migration UI workflow and route user actions to backend APIs and task store.
|
||||
@BRIEF: Orchestrate migration UI workflow and route user actions to backend APIs and task store.
|
||||
@PRE: API client and component dependencies are available; i18n store is initialized.
|
||||
@POST: User can progress through selection, dry-run, migration start, and task resume flows.
|
||||
@SIDE_EFFECT: Performs HTTP requests, mutates local UI state, updates selectedTask store.
|
||||
@@ -114,7 +113,7 @@
|
||||
|
||||
const belief_scope = <T>(_id: string, fn: () => T): T => fn();
|
||||
|
||||
// [DEF:fetchEnvironments:Function]
|
||||
// #region fetchEnvironments:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Fetches the list of environments from the API.
|
||||
* @pre None.
|
||||
@@ -134,9 +133,9 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
// [/DEF:fetchEnvironments:Function]
|
||||
// #endregion fetchEnvironments:Function
|
||||
|
||||
// [DEF:fetchDashboards:Function]
|
||||
// #region fetchDashboards:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Fetches dashboards for the selected source environment.
|
||||
* @pre envId is a valid environment ID.
|
||||
@@ -157,13 +156,13 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
// [/DEF:fetchDashboards:Function]
|
||||
// #endregion fetchDashboards:Function
|
||||
|
||||
onMount(fetchEnvironments);
|
||||
|
||||
// [DEF:ReactiveDashboardFetch:Block]
|
||||
// #region ReactiveDashboardFetch:Block [TYPE Function]
|
||||
/**
|
||||
* @PURPOSE: Automatically fetch dashboards when the source environment is changed.
|
||||
* @BRIEF: Automatically fetch dashboards when the source environment is changed.
|
||||
* @PRE: sourceEnvId is not empty.
|
||||
* @POST: fetchDashboards is called with the new sourceEnvId.
|
||||
* @UX_STATE: [Loading] -> Triggered when sourceEnvId changes.
|
||||
@@ -173,9 +172,9 @@
|
||||
console.info("[ReactiveDashboardFetch][REASON] Source environment changed, fetching dashboards", { sourceEnvId });
|
||||
void fetchDashboards(sourceEnvId);
|
||||
});
|
||||
// [/DEF:ReactiveDashboardFetch:Block]
|
||||
// #endregion ReactiveDashboardFetch:Block
|
||||
|
||||
// [DEF:fetchDatabases:Function]
|
||||
// #region fetchDatabases:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Fetches databases from both environments and gets suggestions.
|
||||
* @pre sourceEnvId and targetEnvId must be set.
|
||||
@@ -221,9 +220,9 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
// [/DEF:fetchDatabases:Function]
|
||||
// #endregion fetchDatabases:Function
|
||||
|
||||
// [DEF:handleMappingUpdate:Function]
|
||||
// #region handleMappingUpdate:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Saves a mapping to the backend.
|
||||
* @pre event.detail contains sourceUuid and targetUuid.
|
||||
@@ -262,10 +261,10 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
// [/DEF:handleMappingUpdate:Function]
|
||||
// #endregion handleMappingUpdate:Function
|
||||
|
||||
// [DEF:handleViewLogs:Function]
|
||||
// @PURPOSE: Opens the log viewer for a specific task.
|
||||
// #region handleViewLogs:Function [TYPE Function]
|
||||
// @BRIEF: Opens the log viewer for a specific task.
|
||||
// @PRE: event.detail contains task object.
|
||||
// @POST: logViewer state updated and showLogViewer set to true.
|
||||
function handleViewLogs(event: CustomEvent) {
|
||||
@@ -276,10 +275,10 @@
|
||||
showLogViewer = true;
|
||||
});
|
||||
}
|
||||
// [/DEF:handleViewLogs:Function]
|
||||
// #endregion handleViewLogs:Function
|
||||
|
||||
// [DEF:handlePasswordPrompt:Function]
|
||||
// @PURPOSE: Reactive logic to show password prompt when a task is awaiting input.
|
||||
// #region handlePasswordPrompt:Function [TYPE Function]
|
||||
// @BRIEF: Reactive logic to show password prompt when a task is awaiting input.
|
||||
// @PRE: selectedTask status is AWAITING_INPUT.
|
||||
// @POST: showPasswordPrompt set to true with request data.
|
||||
// This is triggered by TaskRunner or TaskHistory when a task needs input
|
||||
@@ -287,9 +286,9 @@
|
||||
// Ideally, TaskHistory or TaskRunner emits an event when input is needed.
|
||||
// Or we watch selectedTask.
|
||||
|
||||
// [DEF:ReactivePasswordPrompt:Block]
|
||||
// #region ReactivePasswordPrompt:Block [TYPE Function]
|
||||
/**
|
||||
* @PURPOSE: Monitor selected task for input requests and trigger password prompt.
|
||||
* @BRIEF: Monitor selected task for input requests and trigger password prompt.
|
||||
* @PRE: $selectedTask is not null and status is AWAITING_INPUT.
|
||||
* @POST: showPasswordPrompt is set to true if input_request is database_password.
|
||||
* @UX_STATE: [AwaitingInput] -> Password prompt modal is displayed.
|
||||
@@ -311,11 +310,11 @@
|
||||
showPasswordPrompt = true;
|
||||
}
|
||||
});
|
||||
// [/DEF:ReactivePasswordPrompt:Block]
|
||||
// [/DEF:handlePasswordPrompt:Function]
|
||||
// #endregion ReactivePasswordPrompt:Block
|
||||
// #endregion handlePasswordPrompt:Function
|
||||
|
||||
// [DEF:handleResumeMigration:Function]
|
||||
// @PURPOSE: Resumes a migration task with provided passwords.
|
||||
// #region handleResumeMigration:Function [TYPE Function]
|
||||
// @BRIEF: Resumes a migration task with provided passwords.
|
||||
// @PRE: event.detail contains passwords.
|
||||
// @POST: resumeTask is called and showPasswordPrompt is hidden on success.
|
||||
async function handleResumeMigration(event: CustomEvent) {
|
||||
@@ -335,11 +334,11 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
// [/DEF:handleResumeMigration:Function]
|
||||
// #endregion handleResumeMigration:Function
|
||||
|
||||
// [DEF:startMigration:Function]
|
||||
// #region startMigration:Function [TYPE Function]
|
||||
/**
|
||||
* @PURPOSE: Initiates the migration process by sending the selection to the backend.
|
||||
* @BRIEF: Initiates the migration process by sending the selection to the backend.
|
||||
* @PRE: sourceEnvId and targetEnvId are set and different; at least one dashboard is selected.
|
||||
* @POST: A migration task is created and selectedTask store is updated.
|
||||
* @SIDE_EFFECT: Resets dryRunResult; updates error state on failure.
|
||||
@@ -412,11 +411,11 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
// [/DEF:startMigration:Function]
|
||||
// #endregion startMigration:Function
|
||||
|
||||
// [DEF:startDryRun:Function]
|
||||
// #region startDryRun:Function [TYPE Function]
|
||||
/**
|
||||
* @PURPOSE: Performs a dry-run migration to identify potential risks and changes.
|
||||
* @BRIEF: Performs a dry-run migration to identify potential risks and changes.
|
||||
* @PRE: source/target environments and selected dashboards are valid.
|
||||
* @POST: dryRunResult is populated with the pre-flight analysis.
|
||||
* @UX_STATE: [Loading] -> [Success] or [Error]
|
||||
@@ -469,13 +468,14 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
// [/DEF:startDryRun:Function]
|
||||
// [/DEF:MigrationDashboard:Component]
|
||||
// #endregion startDryRun:Function
|
||||
// #endregion MigrationDashboard:Component
|
||||
</script>
|
||||
|
||||
<!-- #region MigrationDashboardView [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region MigrationDashboardView [C:2] [TYPE Block] [SEMANTICS migration, dashboard, layout, config] -->
|
||||
<!-- @BRIEF Migration dashboard template wrapper: environment selector, dashboard grid, action buttons, dry-run results, and modals. -->
|
||||
<!--
|
||||
@PURPOSE: Render migration configuration controls, action CTAs, dry-run results, and modal entry points.
|
||||
@BRIEF: Render migration configuration controls, action CTAs, dry-run results, and modal entry points.
|
||||
@UX_STATE: Idle -> Configuration form is interactive.
|
||||
@UX_STATE: Loading -> Loading messages and disabled buttons prevent duplicate actions.
|
||||
@UX_STATE: Error -> Error banner is displayed without discarding current selection.
|
||||
@@ -485,15 +485,18 @@
|
||||
-->
|
||||
<!-- [SECTION: TEMPLATE] -->
|
||||
<div class="max-w-4xl mx-auto p-6">
|
||||
<!-- #region MigrationHeader [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region MigrationHeader [C:2] [TYPE Block] [SEMANTICS migration, page-header] -->
|
||||
<!-- @BRIEF Page header displaying the migration navigation title. -->
|
||||
<PageHeader title={$t.nav.migration} />
|
||||
<!-- #endregion MigrationHeader -->
|
||||
|
||||
<!-- #region TaskHistorySection [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region TaskHistorySection [C:2] [TYPE Block] [SEMANTICS migration, task-history] -->
|
||||
<!-- @BRIEF Section showing recent migration task history. -->
|
||||
<TaskHistory />
|
||||
<!-- #endregion TaskHistorySection -->
|
||||
|
||||
<!-- #region ActiveTaskSection [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region ActiveTaskSection [C:2] [TYPE Block] [SEMANTICS migration, active-task] -->
|
||||
<!-- @BRIEF Active task runner section shown when a migration task is selected. -->
|
||||
{#if $selectedTask}
|
||||
<div class="mt-6">
|
||||
<TaskRunner />
|
||||
@@ -518,7 +521,8 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- #region EnvironmentSelectionSection [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region EnvironmentSelectionSection [C:2] [TYPE Block] [SEMANTICS migration, environment-selection] -->
|
||||
<!-- @BRIEF Source and target environment selector grid. -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
|
||||
<EnvSelector
|
||||
label={$t.migration?.source_env }
|
||||
@@ -534,6 +538,7 @@
|
||||
<!-- #endregion EnvironmentSelectionSection -->
|
||||
|
||||
<!-- #region DashboardSelectionSection [C:2] [TYPE Component] [SEMANTICS migration, dashboard, selection, form] -->
|
||||
<!-- @BRIEF Dashboard multi-select grid for choosing which dashboards to migrate. -->
|
||||
<div class="mb-8">
|
||||
<h2 class="text-lg font-medium mb-4">
|
||||
{$t.migration?.select_dashboards_title }
|
||||
@@ -554,7 +559,8 @@
|
||||
</div>
|
||||
<!-- #endregion DashboardSelectionSection -->
|
||||
|
||||
<!-- #region MigrationOptionsSection [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region MigrationOptionsSection [C:2] [TYPE Block] [SEMANTICS migration, options, config] -->
|
||||
<!-- @BRIEF Migration options: cross-filter fix toggle and database replacement toggle. -->
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<input
|
||||
@@ -640,7 +646,8 @@
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<!-- #region DryRunResultsSection [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region DryRunResultsSection [C:2] [TYPE Block] [SEMANTICS migration, dry-run, results] -->
|
||||
<!-- @BRIEF Dry-run analysis results: diff summary cards, risk assessment, and full JSON details. -->
|
||||
{#if dryRunResult}
|
||||
<div class="mt-6 rounded-md border border-slate-200 bg-slate-50 p-4 space-y-3">
|
||||
<h3 class="text-base font-semibold">Pre-flight Diff</h3>
|
||||
@@ -685,9 +692,10 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- #region MigrationModals [C:2] [TYPE Block] [SEMANTICS ui,section] -->
|
||||
<!-- #region MigrationModals [C:2] [TYPE Block] [SEMANTICS migration, modals, overlay] -->
|
||||
<!-- @BRIEF Overlay modals for log viewer and password entry during migration. -->
|
||||
<!--
|
||||
@PURPOSE: Render overlay components for log viewing and password entry.
|
||||
@BRIEF: Render overlay components for log viewing and password entry.
|
||||
@UX_STATE: [LogViewing] -> TaskLogViewer is visible.
|
||||
@UX_STATE: [AwaitingInput] -> PasswordPrompt is visible.
|
||||
-->
|
||||
|
||||
Reference in New Issue
Block a user