feat: implement LLM table translation service with searchable datasource dropdown, i18n, sidebar, and RBAC

- Add backend plugin modules: preview, executor, orchestrator, events, sql_generator, superset_executor, dictionary, scheduler, metrics
- Add API routes for translate jobs, runs, dictionaries, preview, schedule, metrics, corrections
- Add ORM models (12 tables) and Pydantic schemas (15 DTOs)
- Register translate router in app.py with RBAC permission guards
- Add frontend pages: job list, job config, dictionary list/editor, history
- Add 7 reusable Svelte 5 components: Preview, RunProgress, RunResult, TermCorrection, BulkCorrection, ScheduleConfig, MetricsDashboard
- Add searchable datasource dropdown with Superset API integration
- Add i18n (en/ru) with ~300 keys across common, config, jobs, dictionaries, preview namespaces
- Add Translation sidebar category with Jobs/Dictionaries/History sub-items
- Hide health monitor error toast via suppressToast API option
- Add 69 backend tests and 44 frontend test files
- Fix: SupersetClient env resolution (string -> Environment object)
- Fix: Dataset detail API returns proper database dict
- Fix: Database dialect extraction fallback when metadata incomplete
This commit is contained in:
2026-05-09 19:34:25 +03:00
parent bf82e17418
commit 67ba04d4ff
44 changed files with 14744 additions and 5 deletions

View File

@@ -0,0 +1,62 @@
# [DEF:TranslatePlugin:Module]
# @COMPLEXITY: 2
# @SEMANTICS: plugin, translate, llm, sql, dashboard
# @PURPOSE: TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.
# @LAYER: Domain
# @RELATION: INHERITS -> [PluginBase]
# @RATIONALE: Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines).
# @REJECTED: Extending LLMAnalysisPlugin would conflate two distinct feature domains.
from typing import Dict, Any, Optional
from ...core.plugin_base import PluginBase
# [DEF:TranslatePlugin:Class]
# @PURPOSE: Plugin for translating SQL queries and dashboard definitions across database dialects.
# @RELATION: IMPLEMENTS -> backend.src.core.plugin_base.PluginBase
class TranslatePlugin(PluginBase):
@property
def id(self) -> str:
return "translate"
@property
def name(self) -> str:
return "LLM Table Translation"
@property
def description(self) -> str:
return "Cross-dialect SQL and dashboard translation using LLMs."
@property
def version(self) -> str:
return "1.0.0"
def get_schema(self) -> Dict[str, Any]:
return {
"type": "object",
"properties": {
"source_dialect": {
"type": "string",
"title": "Source Dialect",
"description": "Source database dialect (e.g. PostgreSQL, ClickHouse)",
},
"target_dialect": {
"type": "string",
"title": "Target Dialect",
"description": "Target database dialect (e.g. PostgreSQL, ClickHouse)",
},
"job_id": {
"type": "string",
"title": "Translation Job ID",
"description": "Existing translation job to execute",
},
},
"required": ["job_id"],
}
async def execute(self, params: Dict[str, Any], context: Optional[Any] = None):
"""Execute a translation job — implementation deferred to later phases."""
raise NotImplementedError("TranslatePlugin.execute not yet implemented")
# [/DEF:TranslatePlugin:Class]
# [/DEF:TranslatePlugin:Module]