fix error

This commit is contained in:
2026-01-22 23:18:48 +03:00
parent d99a13d91f
commit 49129d3e86
12 changed files with 1932 additions and 3644 deletions

1
.gitignore vendored
View File

@@ -65,3 +65,4 @@ dashboards
backend/mappings.db backend/mappings.db
backend/tasks.db

View File

@@ -13,6 +13,7 @@
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from typing import List, Optional from typing import List, Optional
from ...core.logger import belief_scope
from ...dependencies import get_config_manager from ...dependencies import get_config_manager
from ...core.database import get_db from ...core.database import get_db
from ...models.mapping import DatabaseMapping from ...models.mapping import DatabaseMapping

View File

@@ -10,6 +10,7 @@ from typing import List, Dict
from ...dependencies import get_config_manager, get_task_manager from ...dependencies import get_config_manager, get_task_manager
from ...models.dashboard import DashboardMetadata, DashboardSelection from ...models.dashboard import DashboardMetadata, DashboardSelection
from ...core.superset_client import SupersetClient from ...core.superset_client import SupersetClient
from ...core.logger import belief_scope
router = APIRouter(prefix="/api", tags=["migration"]) router = APIRouter(prefix="/api", tags=["migration"])
@@ -21,7 +22,8 @@ router = APIRouter(prefix="/api", tags=["migration"])
# @RETURN: List[DashboardMetadata] # @RETURN: List[DashboardMetadata]
@router.get("/environments/{env_id}/dashboards", response_model=List[DashboardMetadata]) @router.get("/environments/{env_id}/dashboards", response_model=List[DashboardMetadata])
async def get_dashboards(env_id: str, config_manager=Depends(get_config_manager)): async def get_dashboards(env_id: str, config_manager=Depends(get_config_manager)):
environments = config_manager.get_environments() with belief_scope("get_dashboards", f"env_id={env_id}"):
environments = config_manager.get_environments()
env = next((e for e in environments if e.id == env_id), None) env = next((e for e in environments if e.id == env_id), None)
if not env: if not env:
raise HTTPException(status_code=404, detail="Environment not found") raise HTTPException(status_code=404, detail="Environment not found")
@@ -39,8 +41,9 @@ async def get_dashboards(env_id: str, config_manager=Depends(get_config_manager)
# @RETURN: Dict - {"task_id": str, "message": str} # @RETURN: Dict - {"task_id": str, "message": str}
@router.post("/migration/execute") @router.post("/migration/execute")
async def execute_migration(selection: DashboardSelection, config_manager=Depends(get_config_manager), task_manager=Depends(get_task_manager)): async def execute_migration(selection: DashboardSelection, config_manager=Depends(get_config_manager), task_manager=Depends(get_task_manager)):
# Validate environments exist with belief_scope("execute_migration"):
environments = config_manager.get_environments() # Validate environments exist
environments = config_manager.get_environments()
env_ids = {e.id for e in environments} env_ids = {e.id for e in environments}
if selection.source_env_id not in env_ids or selection.target_env_id not in env_ids: if selection.source_env_id not in env_ids or selection.target_env_id not in env_ids:
raise HTTPException(status_code=400, detail="Invalid source or target environment") raise HTTPException(status_code=400, detail="Invalid source or target environment")

Binary file not shown.

View File

@@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>frontend</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -1,4 +1,5 @@
{ {
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"moduleResolution": "bundler", "moduleResolution": "bundler",
"target": "ESNext", "target": "ESNext",

View File

@@ -1,117 +0,0 @@
<!-- [DEF:App:Component] -->
<!--
@SEMANTICS: main, entrypoint, layout, navigation
@PURPOSE: The root component of the frontend application. Manages navigation and layout.
@LAYER: UI
@RELATION: DEPENDS_ON -> frontend/src/pages/Dashboard.svelte
@RELATION: DEPENDS_ON -> frontend/src/pages/Settings.svelte
@RELATION: DEPENDS_ON -> frontend/src/lib/stores.js
@INVARIANT: Navigation state must be persisted in the currentPage store.
-->
<script>
// [SECTION: IMPORTS]
import { get } from 'svelte/store';
import Dashboard from './pages/Dashboard.svelte';
import Settings from './pages/Settings.svelte';
import { selectedPlugin, selectedTask, currentPage } from './lib/stores.js';
import TaskRunner from './components/TaskRunner.svelte';
import DynamicForm from './components/DynamicForm.svelte';
import { api } from './lib/api.js';
import Toast from './components/Toast.svelte';
// [/SECTION]
// [DEF:handleFormSubmit:Function]
/**
* @purpose Handles form submission for task creation.
* @pre event.detail contains form parameters.
* @post Task is created and selectedTask is updated.
* @param {CustomEvent} event - The submit event from DynamicForm.
*/
async function handleFormSubmit(event) {
console.log("[App.handleFormSubmit][Action] Handling form submission for task creation.");
const params = event.detail;
try {
const plugin = get(selectedPlugin);
const task = await api.createTask(plugin.id, params);
selectedTask.set(task);
selectedPlugin.set(null);
console.log(`[App.handleFormSubmit][Coherence:OK] Task created id=${task.id}`);
} catch (error) {
console.error(`[App.handleFormSubmit][Coherence:Failed] Task creation failed error=${error}`);
}
}
// [/DEF:handleFormSubmit:Function]
// [DEF:navigate:Function]
/**
* @purpose Changes the current page and resets state.
* @pre Target page name is provided.
* @post currentPage store is updated and selection state is reset.
* @param {string} page - Target page name.
*/
function navigate(page) {
console.log(`[App.navigate][Action] Navigating to ${page}.`);
// Reset selection first
if (page !== get(currentPage)) {
selectedPlugin.set(null);
selectedTask.set(null);
}
// Then set page
currentPage.set(page);
}
// [/DEF:navigate:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
<Toast />
<main class="bg-gray-50 min-h-screen">
<header class="bg-white shadow-md p-4 flex justify-between items-center">
<button
type="button"
class="text-3xl font-bold text-gray-800 focus:outline-none"
on:click={() => navigate('dashboard')}
>
Superset Tools
</button>
<nav class="space-x-4">
<button
type="button"
on:click={() => navigate('dashboard')}
class="text-gray-600 hover:text-blue-600 font-medium {$currentPage === 'dashboard' ? 'text-blue-600 border-b-2 border-blue-600' : ''}"
>
Dashboard
</button>
<button
type="button"
on:click={() => navigate('settings')}
class="text-gray-600 hover:text-blue-600 font-medium {$currentPage === 'settings' ? 'text-blue-600 border-b-2 border-blue-600' : ''}"
>
Settings
</button>
</nav>
</header>
<div class="p-4">
{#if $currentPage === 'settings'}
<Settings />
{:else if $selectedTask}
<TaskRunner />
<button on:click={() => selectedTask.set(null)} class="mt-4 bg-blue-500 text-white p-2 rounded">
Back to Task List
</button>
{:else if $selectedPlugin}
<h2 class="text-2xl font-bold mb-4">{$selectedPlugin.name}</h2>
<DynamicForm schema={$selectedPlugin.schema} on:submit={handleFormSubmit} />
<button on:click={() => selectedPlugin.set(null)} class="mt-4 bg-gray-500 text-white p-2 rounded">
Back to Dashboard
</button>
{:else}
<Dashboard />
{/if}
</div>
</main>
<!-- [/SECTION] -->
<!-- [/DEF:App:Component] -->

View File

@@ -1,18 +0,0 @@
// [DEF:main:Module]
// @SEMANTICS: entrypoint, svelte, init
// @PURPOSE: Entry point for the Svelte application.
// @LAYER: UI-Entry
import './app.css'
import App from './App.svelte'
// [DEF:app_instance:Data]
// @PURPOSE: Initialized Svelte app instance.
const app = new App({
target: document.getElementById('app'),
props: {}
})
// [/DEF:app_instance:Data]
export default app
// [/DEF:main:Module]

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
**Feature Branch**: `012-remove-superset-tool` **Feature Branch**: `012-remove-superset-tool`
**Created**: 2026-01-22 **Created**: 2026-01-22
**Status**: Draft **Status**: Completed
**Input**: User description: "нужен рефакторинг бека - я хочу исключить модуль superset_tool, пусть останется только backend" **Input**: User description: "нужен рефакторинг бека - я хочу исключить модуль superset_tool, пусть останется только backend"
## Clarifications ## Clarifications

View File

@@ -51,350 +51,6 @@
- 📝 Generates the token-optimized project map. - 📝 Generates the token-optimized project map.
- ƒ **_write_entity_md** (`Function`) - ƒ **_write_entity_md** (`Function`)
- 📝 Recursive helper to write entity tree to Markdown. - 📝 Recursive helper to write entity tree to Markdown.
- 📦 **migration_script** (`Module`)
- 📝 Предоставляет интерактивный CLI для миграции дашбордов Superset между окружениями с возможностью восстановления после ошибок.
- 🏗️ Layer: App
- 🔗 DEPENDS_ON -> `superset_tool.client`
- 🔗 DEPENDS_ON -> `superset_tool.utils`
- **Migration** (`Class`)
- 📝 Инкапсулирует логику интерактивной миграции дашбордов с возможностью «удалить‑и‑перезаписать» при ошибке импорта.
- ƒ **__init__** (`Function`)
- 📝 Инициализирует сервис миграции, настраивает логгер и начальные состояния.
- ƒ **run** (`Function`)
- 📝 Точка входа последовательный запуск всех шагов миграции.
- 🔗 CALLS -> `self.ask_delete_on_failure`
- 🔗 CALLS -> `self.select_environments`
- 🔗 CALLS -> `self.select_dashboards`
- 🔗 CALLS -> `self.confirm_db_config_replacement`
- 🔗 CALLS -> `self.execute_migration`
- ƒ **ask_delete_on_failure** (`Function`)
- 📝 Запрашивает у пользователя, следует ли удалять дашборд при ошибке импорта.
- 🔗 CALLS -> `yesno`
- ƒ **select_environments** (`Function`)
- 📝 Позволяет пользователю выбрать исходное и целевое окружения Superset.
- 🔗 CALLS -> `setup_clients`
- 🔗 CALLS -> `menu`
- ƒ **select_dashboards** (`Function`)
- 📝 Позволяет пользователю выбрать набор дашбордов для миграции.
- 🔗 CALLS -> `self.from_c.get_dashboards`
- 🔗 CALLS -> `checklist`
- ƒ **confirm_db_config_replacement** (`Function`)
- 📝 Запрашивает у пользователя, требуется ли заменить имена БД в YAML-файлах.
- 🔗 CALLS -> `yesno`
- 🔗 CALLS -> `self._select_databases`
- ƒ **_select_databases** (`Function`)
- 📝 Позволяет пользователю выбрать исходную и целевую БД через API.
- 🔗 CALLS -> `self.from_c.get_databases`
- 🔗 CALLS -> `self.to_c.get_databases`
- 🔗 CALLS -> `self.from_c.get_database`
- 🔗 CALLS -> `self.to_c.get_database`
- 🔗 CALLS -> `menu`
- ƒ **_batch_delete_by_ids** (`Function`)
- 📝 Удаляет набор дашбордов по их ID единым запросом.
- 🔗 CALLS -> `self.to_c.network.request`
- ƒ **execute_migration** (`Function`)
- 📝 Выполняет экспорт-импорт дашбордов, обрабатывает ошибки и, при необходимости, выполняет процедуру восстановления.
- 🔗 CALLS -> `self.from_c.export_dashboard`
- 🔗 CALLS -> `create_temp_file`
- 🔗 CALLS -> `update_yamls`
- 🔗 CALLS -> `create_dashboard_export`
- 🔗 CALLS -> `self.to_c.import_dashboard`
- 🔗 CALLS -> `self._batch_delete_by_ids`
- 📦 **superset_tool.exceptions** (`Module`)
- 📝 Определяет иерархию пользовательских исключений для всего инструмента, обеспечивая единую точку обработки ошибок.
- 🏗️ Layer: Infra
- **SupersetToolError** (`Class`)
- 📝 Базовый класс для всех ошибок, генерируемых инструментом.
- 🔗 INHERITS_FROM -> `Exception`
- ƒ **__init__** (`Function`)
- 📝 Initializes the base tool error.
- **AuthenticationError** (`Class`)
- 📝 Ошибки, связанные с аутентификацией или авторизацией.
- 🔗 INHERITS_FROM -> `SupersetToolError`
- ƒ **__init__** (`Function`)
- 📝 Initializes an authentication error.
- **PermissionDeniedError** (`Class`)
- 📝 Ошибка, возникающая при отказе в доступе к ресурсу.
- 🔗 INHERITS_FROM -> `AuthenticationError`
- ƒ **__init__** (`Function`)
- 📝 Initializes a permission denied error.
- **SupersetAPIError** (`Class`)
- 📝 Общие ошибки при взаимодействии с Superset API.
- 🔗 INHERITS_FROM -> `SupersetToolError`
- ƒ **__init__** (`Function`)
- 📝 Initializes a Superset API error.
- **ExportError** (`Class`)
- 📝 Ошибки, специфичные для операций экспорта.
- 🔗 INHERITS_FROM -> `SupersetAPIError`
- ƒ **__init__** (`Function`)
- 📝 Initializes an export error.
- **DashboardNotFoundError** (`Class`)
- 📝 Ошибка, когда запрошенный дашборд или ресурс не найден (404).
- 🔗 INHERITS_FROM -> `SupersetAPIError`
- ƒ **__init__** (`Function`)
- 📝 Initializes a dashboard not found error.
- **DatasetNotFoundError** (`Class`)
- 📝 Ошибка, когда запрашиваемый набор данных не существует (404).
- 🔗 INHERITS_FROM -> `SupersetAPIError`
- ƒ **__init__** (`Function`)
- 📝 Initializes a dataset not found error.
- **InvalidZipFormatError** (`Class`)
- 📝 Ошибка, указывающая на некорректный формат или содержимое ZIP-архива.
- 🔗 INHERITS_FROM -> `SupersetToolError`
- ƒ **__init__** (`Function`)
- 📝 Initializes an invalid ZIP format error.
- **NetworkError** (`Class`)
- 📝 Ошибки, связанные с сетевым соединением.
- 🔗 INHERITS_FROM -> `SupersetToolError`
- ƒ **__init__** (`Function`)
- 📝 Initializes a network error.
- **FileOperationError** (`Class`)
- 📝 Общие ошибки файловых операций (I/O).
- 🔗 INHERITS_FROM -> `SupersetToolError`
- **InvalidFileStructureError** (`Class`)
- 📝 Ошибка, указывающая на некорректную структуру файлов или директорий.
- 🔗 INHERITS_FROM -> `FileOperationError`
- **ConfigurationError** (`Class`)
- 📝 Ошибки, связанные с неверной конфигурацией инструмента.
- 🔗 INHERITS_FROM -> `SupersetToolError`
- 📦 **superset_tool.models** (`Module`)
- 📝 Определяет Pydantic-модели для конфигурации инструмента, обеспечивая валидацию данных.
- 🏗️ Layer: Infra
- 🔗 DEPENDS_ON -> `pydantic`
- 🔗 DEPENDS_ON -> `superset_tool.utils.logger`
- **SupersetConfig** (`Class`)
- 📝 Модель конфигурации для подключения к одному экземпляру Superset API.
- 🔗 INHERITS_FROM -> `pydantic.BaseModel`
- ƒ **validate_auth** (`Function`)
- 📝 Проверяет, что словарь `auth` содержит все необходимые для аутентификации поля.
- ƒ **normalize_base_url** (`Function`)
- 📝 Нормализует `base_url`, добавляя `/api/v1`, если он отсутствует.
- **DatabaseConfig** (`Class`)
- 📝 Модель для параметров трансформации баз данных при миграции дашбордов.
- 🔗 INHERITS_FROM -> `pydantic.BaseModel`
- ƒ **validate_config** (`Function`)
- 📝 Проверяет, что словарь `database_config` содержит ключи 'old' и 'new'.
- 📦 **superset_tool.client** (`Module`)
- 📝 Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию.
- 🏗️ Layer: Domain
- 🔗 DEPENDS_ON -> `superset_tool.models`
- 🔗 DEPENDS_ON -> `superset_tool.exceptions`
- 🔗 DEPENDS_ON -> `superset_tool.utils`
- **SupersetClient** (`Class`)
- 📝 Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами.
- ƒ **__init__** (`Function`)
- 📝 Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент.
- ƒ **_validate_config** (`Function`)
- 📝 Проверяет, что переданный объект конфигурации имеет корректный тип.
- ƒ **headers** (`Function`)
- 📝 Возвращает базовые HTTP-заголовки, используемые сетевым клиентом.
- ƒ **get_dashboards** (`Function`)
- 📝 Получает полный список дашбордов, автоматически обрабатывая пагинацию.
- 🔗 CALLS -> `self._fetch_total_object_count`
- 🔗 CALLS -> `self._fetch_all_pages`
- ƒ **export_dashboard** (`Function`)
- 📝 Экспортирует дашборд в виде ZIP-архива.
- 🔗 CALLS -> `self.network.request`
- ƒ **import_dashboard** (`Function`)
- 📝 Импортирует дашборд из ZIP-файла с возможностью автоматического удаления и повторной попытки при ошибке.
- 🔗 CALLS -> `self._do_import`
- 🔗 CALLS -> `self.delete_dashboard`
- 🔗 CALLS -> `self.get_dashboards`
- ƒ **_resolve_target_id_for_delete** (`Function`)
- 📝 Определяет ID дашборда для удаления, используя ID или slug.
- ƒ **_do_import** (`Function`)
- 📝 Выполняет один запрос на импорт без обработки исключений.
- ƒ **delete_dashboard** (`Function`)
- 📝 Удаляет дашборд по его ID или slug.
- 🔗 CALLS -> `self.network.request`
- ƒ **_extract_dashboard_id_from_zip** (`Function`)
- 📝 Извлекает ID дашборда из `metadata.yaml` внутри ZIP-архива.
- ƒ **_extract_dashboard_slug_from_zip** (`Function`)
- 📝 Извлекает slug дашборда из `metadata.yaml` внутри ZIP-архива.
- ƒ **_validate_export_response** (`Function`)
- 📝 Проверяет, что HTTP-ответ на экспорт является валидным ZIP-архивом.
- ƒ **_resolve_export_filename** (`Function`)
- 📝 Определяет имя файла для экспорта из заголовков или генерирует его.
- ƒ **_validate_query_params** (`Function`)
- 📝 Формирует корректный набор параметров запроса с пагинацией.
- ƒ **_fetch_total_object_count** (`Function`)
- 📝 Получает общее количество объектов по указанному эндпоинту для пагинации.
- ƒ **_fetch_all_pages** (`Function`)
- 📝 Итерируется по всем страницам пагинированного API и собирает все данные.
- ƒ **_validate_import_file** (`Function`)
- 📝 Проверяет, что файл существует, является ZIP-архивом и содержит `metadata.yaml`.
- ƒ **get_datasets** (`Function`)
- 📝 Получает полный список датасетов, автоматически обрабатывая пагинацию.
- 🔗 CALLS -> `self._fetch_total_object_count`
- 🔗 CALLS -> `self._fetch_all_pages`
- ƒ **get_databases** (`Function`)
- 📝 Получает полный список баз данных, автоматически обрабатывая пагинацию.
- 🔗 CALLS -> `self._fetch_total_object_count`
- 🔗 CALLS -> `self._fetch_all_pages`
- ƒ **get_dataset** (`Function`)
- 📝 Получает информацию о конкретном датасете по его ID.
- 🔗 CALLS -> `self.network.request`
- ƒ **get_database** (`Function`)
- 📝 Получает информацию о конкретной базе данных по её ID.
- 🔗 CALLS -> `self.network.request`
- ƒ **update_dataset** (`Function`)
- 📝 Обновляет данные датасета по его ID.
- 🔗 CALLS -> `self.network.request`
- 📦 **superset_tool** (`Module`)
- 📝 Root package for superset_tool.
- 🏗️ Layer: Domain
- 📦 **superset_tool.utils.init_clients** (`Module`)
- 📝 Централизованно инициализирует клиенты Superset для различных окружений (DEV, PROD, SBX, PREPROD), используя `keyring` для безопасного доступа к паролям.
- 🏗️ Layer: Infra
- 🔗 DEPENDS_ON -> `superset_tool.models`
- 🔗 DEPENDS_ON -> `superset_tool.client`
- 🔗 DEPENDS_ON -> `keyring`
- ƒ **setup_clients** (`Function`)
- 📝 Инициализирует и возвращает словарь клиентов `SupersetClient`.
- 📦 **superset_tool.utils.logger** (`Module`)
- 📝 Предоставляет универсальную обёртку над стандартным `logging.Logger` для унифицированного создания и управления логгерами с выводом в консоль и/или файл.
- 🏗️ Layer: Infra
- ƒ **belief_scope** (`Function`)
- 📝 Context manager for belief state logging to maintain execution coherence.
- **SupersetLogger** (`Class`)
- 📝 Обёртка над `logging.Logger`, которая упрощает конфигурацию и использование логгеров.
- ƒ **__init__** (`Function`)
- 📝 Конфигурирует и инициализирует логгер, добавляя обработчики для файла и/или консоли.
- ƒ **_log** (`Function`)
- 📝 (Helper) Универсальный метод для вызова соответствующего уровня логирования.
- ƒ **info** (`Function`)
- 📝 Записывает сообщение уровня INFO.
- ƒ **debug** (`Function`)
- 📝 Записывает сообщение уровня DEBUG.
- ƒ **warning** (`Function`)
- 📝 Записывает сообщение уровня WARNING.
- ƒ **error** (`Function`)
- 📝 Записывает сообщение уровня ERROR.
- ƒ **critical** (`Function`)
- 📝 Записывает сообщение уровня CRITICAL.
- ƒ **exception** (`Function`)
- 📝 Записывает сообщение уровня ERROR вместе с трассировкой стека текущего исключения.
- 📦 **belief_scope** (`Method`)
- 📝 Instance method wrapper for belief_scope context manager.
- 📦 **superset_tool.utils.fileio** (`Module`)
- 📝 Предоставляет набор утилит для управления файловыми операциями, включая работу с временными файлами, архивами ZIP, файлами YAML и очистку директорий.
- 🏗️ Layer: Infra
- 🔗 DEPENDS_ON -> `superset_tool.exceptions`
- 🔗 DEPENDS_ON -> `superset_tool.utils.logger`
- 🔗 DEPENDS_ON -> `pyyaml`
- ƒ **create_temp_file** (`Function`)
- 📝 Контекстный менеджер для создания временного файла или директории с гарантированным удалением.
- ƒ **remove_empty_directories** (`Function`)
- 📝 Рекурсивно удаляет все пустые поддиректории, начиная с указанного пути.
- ƒ **read_dashboard_from_disk** (`Function`)
- 📝 Читает бинарное содержимое файла с диска.
- ƒ **calculate_crc32** (`Function`)
- 📝 Вычисляет контрольную сумму CRC32 для файла.
- 📦 **RetentionPolicy** (`DataClass`)
- 📝 Определяет политику хранения для архивов (ежедневные, еженедельные, ежемесячные).
- ƒ **archive_exports** (`Function`)
- 📝 Управляет архивом экспортированных файлов, применяя политику хранения и дедупликацию.
- 🔗 CALLS -> `apply_retention_policy`
- 🔗 CALLS -> `calculate_crc32`
- ƒ **apply_retention_policy** (`Function`)
- 📝 (Helper) Применяет политику хранения к списку файлов, возвращая те, что нужно сохранить.
- ƒ **save_and_unpack_dashboard** (`Function`)
- 📝 Сохраняет бинарное содержимое ZIP-архива на диск и опционально распаковывает его.
- ƒ **update_yamls** (`Function`)
- 📝 Обновляет конфигурации в YAML-файлах, заменяя значения или применяя regex.
- 🔗 CALLS -> `_update_yaml_file`
- ƒ **_update_yaml_file** (`Function`)
- 📝 (Helper) Обновляет один YAML файл.
- ƒ **replacer** (`Function`)
- 📝 Функция замены, сохраняющая кавычки если они были.
- ƒ **create_dashboard_export** (`Function`)
- 📝 Создает ZIP-архив из указанных исходных путей.
- ƒ **sanitize_filename** (`Function`)
- 📝 Очищает строку от символов, недопустимых в именах файлов.
- ƒ **get_filename_from_headers** (`Function`)
- 📝 Извлекает имя файла из HTTP заголовка 'Content-Disposition'.
- ƒ **consolidate_archive_folders** (`Function`)
- 📝 Консолидирует директории архивов на основе общего слага в имени.
- 📦 **superset_tool.utils.network** (`Module`)
- 📝 Инкапсулирует низкоуровневую HTTP-логику для взаимодействия с Superset API, включая аутентификацию, управление сессией, retry-логику и обработку ошибок.
- 🏗️ Layer: Infra
- 🔗 DEPENDS_ON -> `superset_tool.exceptions`
- 🔗 DEPENDS_ON -> `superset_tool.utils.logger`
- 🔗 DEPENDS_ON -> `requests`
- **APIClient** (`Class`)
- 📝 Инкапсулирует HTTP-логику для работы с API, включая сессии, аутентификацию, и обработку запросов.
- ƒ **__init__** (`Function`)
- 📝 Инициализирует API клиент с конфигурацией, сессией и логгером.
- ƒ **_init_session** (`Function`)
- 📝 Создает и настраивает `requests.Session` с retry-логикой.
- ƒ **authenticate** (`Function`)
- 📝 Выполняет аутентификацию в Superset API и получает access и CSRF токены.
- ƒ **headers** (`Function`)
- 📝 Возвращает HTTP-заголовки для аутентифицированных запросов.
- ƒ **request** (`Function`)
- 📝 Выполняет универсальный HTTP-запрос к API.
- ƒ **_handle_http_error** (`Function`)
- 📝 (Helper) Преобразует HTTP ошибки в кастомные исключения.
- ƒ **_handle_network_error** (`Function`)
- 📝 (Helper) Преобразует сетевые ошибки в `NetworkError`.
- ƒ **upload_file** (`Function`)
- 📝 Загружает файл на сервер через multipart/form-data.
- ƒ **_perform_upload** (`Function`)
- 📝 (Helper) Выполняет POST запрос с файлом.
- ƒ **fetch_paginated_count** (`Function`)
- 📝 Получает общее количество элементов для пагинации.
- ƒ **fetch_paginated_data** (`Function`)
- 📝 Автоматически собирает данные со всех страниц пагинированного эндпоинта.
- 📦 **superset_tool.utils.whiptail_fallback** (`Module`)
- 📝 Предоставляет плотный консольный UI-fallback для интерактивных диалогов, имитируя `whiptail` для систем, где он недоступен.
- 🏗️ Layer: UI
- ƒ **menu** (`Function`)
- 📝 Отображает меню выбора и возвращает выбранный элемент.
- ƒ **checklist** (`Function`)
- 📝 Отображает список с возможностью множественного выбора.
- ƒ **yesno** (`Function`)
- 📝 Задает вопрос с ответом да/нет.
- ƒ **msgbox** (`Function`)
- 📝 Отображает информационное сообщение.
- ƒ **inputbox** (`Function`)
- 📝 Запрашивает у пользователя текстовый ввод.
- **_ConsoleGauge** (`Class`)
- 📝 Контекстный менеджер для имитации `whiptail gauge` в консоли.
- ƒ **__init__** (`Function`)
- 📝 Initializes the gauge.
- ƒ **__enter__** (`Function`)
- 📝 Enters the context.
- ƒ **__exit__** (`Function`)
- 📝 Exits the context.
- ƒ **set_text** (`Function`)
- 📝 Sets the gauge text.
- ƒ **set_percent** (`Function`)
- 📝 Sets the gauge percentage.
- ƒ **gauge** (`Function`)
- 📝 Создает и возвращает экземпляр `_ConsoleGauge`.
- 📦 **superset_tool.utils.dataset_mapper** (`Module`)
- 📝 Этот модуль отвечает за обновление метаданных (verbose_map) в датасетах Superset, извлекая их из PostgreSQL или XLSX-файлов.
- 🏗️ Layer: Domain
- 🔗 DEPENDS_ON -> `superset_tool.client`
- 🔗 DEPENDS_ON -> `pandas`
- 🔗 DEPENDS_ON -> `psycopg2`
- **DatasetMapper** (`Class`)
- 📝 Класс для меппинга и обновления verbose_map в датасетах Superset.
- ƒ **__init__** (`Function`)
- 📝 Initializes the mapper.
- ƒ **get_postgres_comments** (`Function`)
- 📝 Извлекает комментарии к колонкам из системного каталога PostgreSQL.
- ƒ **load_excel_mappings** (`Function`)
- 📝 Загружает меппинги 'column_name' -> 'column_comment' из XLSX файла.
- ƒ **run_mapping** (`Function`)
- 📝 Основная функция для выполнения меппинга и обновления verbose_map датасета в Superset.
- 🔗 CALLS -> `self.get_postgres_comments`
- 🔗 CALLS -> `self.load_excel_mappings`
- 🔗 CALLS -> `superset_client.get_dataset`
- 🔗 CALLS -> `superset_client.update_dataset`
- 📦 **superset_tool.utils** (`Module`)
- 📝 Utility package for superset_tool.
- 🏗️ Layer: Infra
- 📦 **main** (`Module`) - 📦 **main** (`Module`)
- 📝 Entry point for the Svelte application. - 📝 Entry point for the Svelte application.
- 🏗️ Layer: UI-Entry - 🏗️ Layer: UI-Entry
@@ -454,14 +110,17 @@
- 📝 Handles task creation from dynamic form submission. - 📝 Handles task creation from dynamic form submission.
- ƒ **load** (`Function`) - ƒ **load** (`Function`)
- 📝 Loads initial plugin data for the dashboard. - 📝 Loads initial plugin data for the dashboard.
- ƒ **loadInitialData** (`Function`) - 🧩 **TaskManagementPage** (`Component`)
- 📝 Loads tasks and environments on page initialization. - 📝 Page for managing and monitoring tasks.
- ƒ **refreshTasks** (`Function`) - 🏗️ Layer: Page
- 📝 Periodically refreshes the task list. - ƒ **loadInitialData** (`Function`)
- ƒ **handleSelectTask** (`Function`) - 📝 Loads tasks and environments on page initialization.
- 📝 Updates the selected task ID when a task is clicked. - ƒ **refreshTasks** (`Function`)
- ƒ **handleRunBackup** (`Function`) - 📝 Periodically refreshes the task list.
- 📝 Triggers a manual backup task for the selected environment. - ƒ **handleSelectTask** (`Function`)
- 📝 Updates the selected task ID when a task is clicked.
- ƒ **handleRunBackup** (`Function`)
- 📝 Triggers a manual backup task for the selected environment.
- 🧩 **MigrationDashboard** (`Component`) - 🧩 **MigrationDashboard** (`Component`)
- 📝 Main dashboard for configuring and starting migrations. - 📝 Main dashboard for configuring and starting migrations.
- 🏗️ Layer: Page - 🏗️ Layer: Page
@@ -579,7 +238,7 @@
- ƒ **getSuggestion** (`Function`) - ƒ **getSuggestion** (`Function`)
- 📝 Finds a suggestion for a source database. - 📝 Finds a suggestion for a source database.
- 🧩 **TaskLogViewer** (`Component`) - 🧩 **TaskLogViewer** (`Component`)
- 📝 Displays detailed logs for a specific task in a modal. - 📝 Displays detailed logs for a specific task in a modal or inline.
- 🏗️ Layer: UI - 🏗️ Layer: UI
- ƒ **fetchLogs** (`Function`) - ƒ **fetchLogs** (`Function`)
- 📝 Fetches logs for the current task. - 📝 Fetches logs for the current task.
@@ -745,21 +404,48 @@
- ƒ **get_scheduler_service** (`Function`) - ƒ **get_scheduler_service** (`Function`)
- 📝 Dependency injector for the SchedulerService. - 📝 Dependency injector for the SchedulerService.
- 📦 **backend.src.core.superset_client** (`Module`) - 📦 **backend.src.core.superset_client** (`Module`)
- 📝 Extends the base SupersetClient with database-specific metadata fetching. - 📝 Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию.
- 🏗️ Layer: Core - 🏗️ Layer: Core
- 🔗 INHERITS_FROM -> `superset_tool.client.SupersetClient`
- **SupersetClient** (`Class`) - **SupersetClient** (`Class`)
- 📝 Extended SupersetClient for migration-specific operations. - 📝 Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами.
- ƒ **__init__** (`Function`)
- 📝 Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент.
- ƒ **authenticate** (`Function`)
- 📝 Authenticates the client using the configured credentials.
- ƒ **headers** (`Function`)
- 📝 Возвращает базовые HTTP-заголовки, используемые сетевым клиентом.
- ƒ **get_dashboards** (`Function`)
- 📝 Получает полный список дашбордов, автоматически обрабатывая пагинацию.
- ƒ **get_dashboards_summary** (`Function`)
- 📝 Fetches dashboard metadata optimized for the grid.
- ƒ **export_dashboard** (`Function`)
- 📝 Экспортирует дашборд в виде ZIP-архива.
- ƒ **import_dashboard** (`Function`)
- 📝 Импортирует дашборд из ZIP-файла.
- ƒ **delete_dashboard** (`Function`)
- 📝 Удаляет дашборд по его ID или slug.
- ƒ **get_datasets** (`Function`)
- 📝 Получает полный список датасетов, автоматически обрабатывая пагинацию.
- ƒ **get_dataset** (`Function`)
- 📝 Получает информацию о конкретном датасете по его ID.
- ƒ **update_dataset** (`Function`)
- 📝 Обновляет данные датасета по его ID.
- ƒ **get_databases** (`Function`)
- 📝 Получает полный список баз данных.
- ƒ **get_database** (`Function`)
- 📝 Получает информацию о конкретной базе данных по её ID.
- ƒ **get_databases_summary** (`Function`) - ƒ **get_databases_summary** (`Function`)
- 📝 Fetch a summary of databases including uuid, name, and engine. - 📝 Fetch a summary of databases including uuid, name, and engine.
- ƒ **get_database_by_uuid** (`Function`) - ƒ **get_database_by_uuid** (`Function`)
- 📝 Find a database by its UUID. - 📝 Find a database by its UUID.
- ƒ **get_dashboards_summary** (`Function`) - ƒ **_resolve_target_id_for_delete** (`Function`)
- 📝 Fetches dashboard metadata optimized for the grid. - ƒ **_do_import** (`Function`)
- ƒ **get_dataset** (`Function`) - ƒ **_validate_export_response** (`Function`)
- 📝 Fetch full dataset structure including columns and metrics. - ƒ **_resolve_export_filename** (`Function`)
- ƒ **update_dataset** (`Function`) - ƒ **_validate_query_params** (`Function`)
- 📝 Update dataset metadata. - ƒ **_fetch_total_object_count** (`Function`)
- ƒ **_fetch_all_pages** (`Function`)
- ƒ **_validate_import_file** (`Function`)
- 📦 **ConfigManagerModule** (`Module`) - 📦 **ConfigManagerModule** (`Module`)
- 📝 Manages application configuration, including loading/saving to JSON and CRUD for environments. - 📝 Manages application configuration, including loading/saving to JSON and CRUD for environments.
- 🏗️ Layer: Core - 🏗️ Layer: Core
@@ -785,6 +471,8 @@
- 📝 Returns the list of configured environments. - 📝 Returns the list of configured environments.
- ƒ **has_environments** (`Function`) - ƒ **has_environments** (`Function`)
- 📝 Checks if at least one environment is configured. - 📝 Checks if at least one environment is configured.
- ƒ **get_environment** (`Function`)
- 📝 Returns a single environment by ID.
- ƒ **add_environment** (`Function`) - ƒ **add_environment** (`Function`)
- 📝 Adds a new environment to the configuration. - 📝 Adds a new environment to the configuration.
- ƒ **update_environment** (`Function`) - ƒ **update_environment** (`Function`)
@@ -862,6 +550,8 @@
- 📝 Returns a list of recent log entries from the buffer. - 📝 Returns a list of recent log entries from the buffer.
- 📦 **Logger** (`Global`) - 📦 **Logger** (`Global`)
- 📝 The global logger instance for the application, configured with both a console handler and the custom WebSocket handler. - 📝 The global logger instance for the application, configured with both a console handler and the custom WebSocket handler.
- ƒ **believed** (`Function`)
- 📝 A decorator that wraps a function in a belief scope.
- **PluginLoader** (`Class`) - **PluginLoader** (`Class`)
- 📝 Scans a specified directory for Python modules, dynamically loads them, and registers any classes that are valid implementations of the PluginBase interface. - 📝 Scans a specified directory for Python modules, dynamically loads them, and registers any classes that are valid implementations of the PluginBase interface.
- 🏗️ Layer: Core - 🏗️ Layer: Core
@@ -907,12 +597,76 @@
- **PluginConfig** (`Class`) - **PluginConfig** (`Class`)
- 📝 A Pydantic model used to represent the validated configuration and metadata of a loaded plugin. This object is what gets exposed to the API layer. - 📝 A Pydantic model used to represent the validated configuration and metadata of a loaded plugin. This object is what gets exposed to the API layer.
- 🏗️ Layer: Core - 🏗️ Layer: Core
- 📦 **backend.core.utils.fileio** (`Module`)
- 📝 Предоставляет набор утилит для управления файловыми операциями, включая работу с временными файлами, архивами ZIP, файлами YAML и очистку директорий.
- 🏗️ Layer: Infra
- 🔗 DEPENDS_ON -> `backend.src.core.logger`
- 🔗 DEPENDS_ON -> `pyyaml`
- **InvalidZipFormatError** (`Class`)
- ƒ **create_temp_file** (`Function`)
- 📝 Контекстный менеджер для создания временного файла или директории с гарантированным удалением.
- ƒ **remove_empty_directories** (`Function`)
- 📝 Рекурсивно удаляет все пустые поддиректории, начиная с указанного пути.
- ƒ **read_dashboard_from_disk** (`Function`)
- 📝 Читает бинарное содержимое файла с диска.
- ƒ **calculate_crc32** (`Function`)
- 📝 Вычисляет контрольную сумму CRC32 для файла.
- 📦 **RetentionPolicy** (`DataClass`)
- 📝 Определяет политику хранения для архивов (ежедневные, еженедельные, ежемесячные).
- ƒ **archive_exports** (`Function`)
- 📝 Управляет архивом экспортированных файлов, применяя политику хранения и дедупликацию.
- 🔗 CALLS -> `apply_retention_policy`
- 🔗 CALLS -> `calculate_crc32`
- ƒ **apply_retention_policy** (`Function`)
- 📝 (Helper) Применяет политику хранения к списку файлов, возвращая те, что нужно сохранить.
- ƒ **save_and_unpack_dashboard** (`Function`)
- 📝 Сохраняет бинарное содержимое ZIP-архива на диск и опционально распаковывает его.
- ƒ **update_yamls** (`Function`)
- 📝 Обновляет конфигурации в YAML-файлах, заменяя значения или применяя regex.
- 🔗 CALLS -> `_update_yaml_file`
- ƒ **_update_yaml_file** (`Function`)
- 📝 (Helper) Обновляет один YAML файл.
- ƒ **create_dashboard_export** (`Function`)
- 📝 Создает ZIP-архив из указанных исходных путей.
- ƒ **sanitize_filename** (`Function`)
- 📝 Очищает строку от символов, недопустимых в именах файлов.
- ƒ **get_filename_from_headers** (`Function`)
- 📝 Извлекает имя файла из HTTP заголовка 'Content-Disposition'.
- ƒ **consolidate_archive_folders** (`Function`)
- 📝 Консолидирует директории архивов на основе общего слага в имени.
- 📦 **backend.core.utils.network** (`Module`)
- 📝 Инкапсулирует низкоуровневую HTTP-логику для взаимодействия с Superset API, включая аутентификацию, управление сессией, retry-логику и обработку ошибок.
- 🏗️ Layer: Infra
- 🔗 DEPENDS_ON -> `backend.src.core.logger`
- 🔗 DEPENDS_ON -> `requests`
- **SupersetAPIError** (`Class`)
- **AuthenticationError** (`Class`)
- 📦 **backend.src.core.utils.matching** (`Module`) - 📦 **backend.src.core.utils.matching** (`Module`)
- 📝 Provides utility functions for fuzzy matching database names. - 📝 Provides utility functions for fuzzy matching database names.
- 🏗️ Layer: Core - 🏗️ Layer: Core
- 🔗 DEPENDS_ON -> `rapidfuzz` - 🔗 DEPENDS_ON -> `rapidfuzz`
- ƒ **suggest_mappings** (`Function`) - ƒ **suggest_mappings** (`Function`)
- 📝 Suggests mappings between source and target databases using fuzzy matching. - 📝 Suggests mappings between source and target databases using fuzzy matching.
- 📦 **backend.core.utils.dataset_mapper** (`Module`)
- 📝 Этот модуль отвечает за обновление метаданных (verbose_map) в датасетах Superset, извлекая их из PostgreSQL или XLSX-файлов.
- 🏗️ Layer: Domain
- 🔗 DEPENDS_ON -> `backend.core.superset_client`
- 🔗 DEPENDS_ON -> `pandas`
- 🔗 DEPENDS_ON -> `psycopg2`
- **DatasetMapper** (`Class`)
- 📝 Класс для меппинга и обновления verbose_map в датасетах Superset.
- ƒ **__init__** (`Function`)
- 📝 Initializes the mapper.
- ƒ **get_postgres_comments** (`Function`)
- 📝 Извлекает комментарии к колонкам из системного каталога PostgreSQL.
- ƒ **load_excel_mappings** (`Function`)
- 📝 Загружает меппинги 'column_name' -> 'column_comment' из XLSX файла.
- ƒ **run_mapping** (`Function`)
- 📝 Основная функция для выполнения меппинга и обновления verbose_map датасета в Superset.
- 🔗 CALLS -> `self.get_postgres_comments`
- 🔗 CALLS -> `self.load_excel_mappings`
- 🔗 CALLS -> `superset_client.get_dataset`
- 🔗 CALLS -> `superset_client.update_dataset`
- 📦 **TaskPersistenceModule** (`Module`) - 📦 **TaskPersistenceModule** (`Module`)
- 📝 Handles the persistence of tasks using SQLAlchemy and the tasks.db database. - 📝 Handles the persistence of tasks using SQLAlchemy and the tasks.db database.
- 🏗️ Layer: Core - 🏗️ Layer: Core
@@ -1228,10 +982,8 @@
- 📝 Returns the JSON schema for migration plugin parameters. - 📝 Returns the JSON schema for migration plugin parameters.
- ƒ **execute** (`Function`) - ƒ **execute** (`Function`)
- 📝 Executes the dashboard migration logic. - 📝 Executes the dashboard migration logic.
- ƒ **test_superset_config_url_normalization** (`Function`) - ƒ **test_environment_model** (`Function`)
- 📝 Tests that SupersetConfig correctly normalizes the base URL. - 📝 Tests that Environment model correctly stores values.
- ƒ **test_superset_config_invalid_url** (`Function`)
- 📝 Tests that SupersetConfig raises ValueError for invalid URLs.
- ƒ **test_belief_scope_logs_entry_action_exit** (`Function`) - ƒ **test_belief_scope_logs_entry_action_exit** (`Function`)
- 📝 Test that belief_scope generates [ID][Entry], [ID][Action], and [ID][Exit] logs. - 📝 Test that belief_scope generates [ID][Entry], [ID][Action], and [ID][Exit] logs.
- ƒ **test_belief_scope_error_handling** (`Function`) - ƒ **test_belief_scope_error_handling** (`Function`)