Commit Graph

42 Commits

Author SHA1 Message Date
a697ff2c3d fix(frontend): environment select resets to default on click
Root cause: onchange on native <select> passes a DOM Event.
The parent handler used e.detail, which is always 0 for native events.
Sequence:
1. bind:value sets environmentId correctly
2. onchange fires -> handleEnvChange(0) overwrites to falsy
3. <select> re-renders showing 'Select environment...'

Fix:
- ConfigTabForm: onchange now passes e.target.value (the actual envId)
- +page.svelte: callback receives the envId string directly, not e.detail

@RATIONALE bind:value on <select> fires on the same change event.
The handler must not re-set the same bindable to a stale value.

Verification: browser reconfirmed — ss-dev stays selected after click.
2026-06-03 11:16:01 +03:00
27435e4d92 fix(frontend): replace $t with _t pattern in translate components
Svelte 5 compiler fails to detect Proxy-based i18n store `t` as a store
in deeply nested/complex templates and in `.svelte.ts` model files,
generating `ReferenceError: $t is not defined` at runtime.

Fix: replace `$t.` references with:
- Template: `_t.` where `const _t = $derived(getT())`
- Script:   `getT()?.` direct function call

Applied to:
- translate/[id]/+page.svelte (the failing page)
- TranslationJobModel.svelte.ts ($derived.by() in `tabs`)
- 12 translate components (ConfigTabForm, ScheduleConfig,
  TranslationPreview, TargetTabForm, RunTabContent, BulkReplaceModal,
  TranslationRunProgress, TranslationRunResult, TermCorrectionPopup,
  BulkCorrectionSidebar, TranslationMetricsDashboard, CorrectionCell,
  TranslationRunGlobalIndicator)

Verified all 5 tabs render correctly in browser:
Config, Preview, Target, Run, Schedule.

Build clean, 698/698 tests pass, 0 color violations.
2026-06-02 20:38:38 +03:00
fbb6a78d7d refactor(frontend): add comprehensive TranslationJobModel for translate/[id] page
Model covers all 49  atoms: Config, Preview, Target, Run, Schedule tabs.
Environment switching, datasource loading, saveJob(), run lifecycle.
Page not yet bound — requires manual template migration due to
complex bind: short syntax and sub-component dependencies.

DictionaryDetail page: 822→166 (-80%) with DictionaryDetailModel.
3→2 oversized pages remaining (dashboards, migration).
2026-06-02 19:54:15 +03:00
cf7b3556f7 refactor(frontend): enforce semantic tokens + extract 3 Screen Models
Color tokens: 3658→0 violations across 186 .svelte/.svelte.ts files.
All raw Tailwind colors (bg-blue-*, text-gray-*, border-red-*, etc.)
replaced with semantic tokens from tailwind.config.js in 5 perl passes.

Model extraction (11→8 oversized pages):
- LLMReportModel.svelte.ts: LLM report page 413→221 lines
- DatasetDetailModel.svelte.ts: dataset detail page 416→218 lines
- DatasetsHubModel.svelte.ts: datasets hub page 468→246 lines

Tests: 14 assertions updated (color classes + model refs).
Build: 1 duplicate class:text-primary fix in ValidationTaskForm.
All 699/699 tests pass.
2026-06-02 17:58:36 +03:00
29acfb4e69 freeze fix 2026-06-02 16:36:00 +03:00
f87092c4a7 feat(translate): add cache_hits counter — backend + frontend
Backend:
- TranslationRun model: add cache_hits Integer column (default 0)
- TranslationRunResponse schema: add cache_hits field
- _helpers.py/_run_list_routes.py/orchestrator_aggregator.py: include
  cache_hits in all run API responses
- _batch_proc.py: count pre_rows served from translation cache per
  batch, return cache_hits in batch result
- executor.py: accumulate cache_hits across batches, persist to run
- Alembic migration: dabc9709 — add cache_hits column to translation_runs

Frontend:
- translationRun.svelte.ts: add cacheHits to store state, WS handler,
  polling handler
- TranslationRunProgress.svelte: 5-col stats grid with purple Cache card
- TranslationRunGlobalIndicator.svelte: 5-col stats with Cache
- TranslationRunResult.svelte: 5-col detail stats with Cache card
- History page: cache_hits shown in run list row + detail panel

Visual: cache hits shown in purple alongside green/yellow/red metrics
(total/success/failed/skipped). Visible during run + in history.

Tests: backend 69/69 translate tests , frontend 698/698 tests ,
frontend build 
2026-06-02 11:59:57 +03:00
7f48b19f28 fix 2026-06-02 11:46:00 +03:00
4fc3356312 refactor(frontend): migrate Svelte stores from .ts to .svelte.ts runes
- Delete legacy .ts stores (auth, activity, assistantChat, datasetReview, environmentContext, health, sidebar, taskDrawer, translationRun)
- Create new .svelte.ts runes-based stores using  reactive primitives
- Migrate i18n: /i18n → /i18n/index.svelte.js
- Migrate toasts: /toasts → /toasts.svelte.js
- Update all component imports across 180+ files: components, pages, routes, lib
- Remove fromStore() wrappers — use store.value directly with Svelte 5 runes
- Update test mocks for new import paths
- Add @DEPRECATED annotation to legacy  alias
2026-06-02 09:54:18 +03:00
28b28338c5 fix(translate): исправление INSERT + выгрузка CSV для неуспешных запусков
**Исправления ошибок:**
- superset_executor: убран несуществующий fallback endpoint /api/v1/sql_lab/execute/
  (правильный URL /api/v1/sqllab/execute/ подтверждён браузерным запросом Superset)
  Ошибка 500 (permission denied) больше не маскируется 404
- orchestrator_run_completion: run.status=FAILED при провале insert
  (раньше всегда ставился COMPLETED). timeout тоже treated as failure
- test_orchestrator: assertion обновлён COMPLETED→FAILED

**Новая функция — выгрузка CSV:**
- GET /api/translate/runs/{run_id}/failed.csv — возвращает CSV с успешно
  переведёнными, но не вставленными записями (status=SUCCESS)
- Колонки: record_id, source_*, target_sql, source_data (JSON), языки, error_message
- Метаданные запуска (run_status, insert_status, run_error) в конце файла
- Кнопки скачивания в 3 местах фронта:
  - История запусков (при status=FAILED)
  - TranslationRunProgress (insert_failed)
  - TranslationRunResult (failed/partial/insert_failed)
- downloadFailedCsv() через fetchApiBlob + Blob URL
2026-06-01 22:38:52 +03:00
40e364d9f6 fix 2026-06-01 17:09:40 +03:00
6b4c3d45ee fix(tests): fix 3 stale test assertions — 6 fail → 3 fail
Fixed:
  - TargetSchemaHint: result.missing_columns → res?.missing_columns (component uses res?)
  - CorrectionCell: border-blue-300 → border-blue-600 (class changed)
  - TranslationPreview: @UX_STATE: → @UX_STATE (no colon per GRACE format)

3 remaining pre-existing failures (not from migration):
  - dashboard-profile-override (×2): vi.fn() mock call count race condition
  - dataset_review_workspace: waitFor timeout, unreachable DOM state

Before: 641 pass / 6 fail
After:  648 pass / 3 fail
2026-06-01 15:49:37 +03:00
ed4562d199 feat(ts-migration): Phase 3-4 — all components + tests JS→TS
Converted 11 remaining production files:
  - services/*.ts (toolsService, taskService, git-utils, storageService,
    adminService, gitService)
  - lib/auth/permissions.ts
  - lib/components/layout/sidebarNavigation.ts
  - lib/components/reports/reportTypeProfiles.ts
  - components/git/useGitManager.ts
  - routes/datasets/review/useReviewSession.ts
  - routes/datasets/review/review-workspace-helpers.ts
  - routes/settings/settings-utils.ts

All production files have proper GRACE contracts:
  - C2/C3 with @BRIEF, @PRE, @POST, @SIDE_EFFECT, @RELATION
  - Generic <T = unknown> for API calls
  - Typed interfaces for state/options

Phase 3: 126 .svelte components → <script lang="ts">
Phase 4: 53 test .js files → .ts

Final verification:
  - npm run build 
  - npm run test  (66 passed, 6 pre-existing failures unchanged)

Total: 0 .js files remain in production code
2026-06-01 15:43:20 +03:00
50f5c4ce4d feat(ts-migration): Phase 1 — core API layer JS→TS with full GRACE contracts
Converted:
  - toasts.js → toasts.ts (typed Writable<Toast[]>, typed addToast/removeToast)
  - api.js → api.ts (C5 module with 12 nested C2/C4 function contracts)
  - utils.js → utils.ts, utils/debounce.js → debounce.ts
  - Updated 67 import references across src/ (.js extension stripped)
  - Added types/api.ts, types/models.ts, types/validation.ts (foundation DTOs)

api.ts contracts:
  - Top-level: [C:5] with @INVARIANT, @DATA_CONTRACT, @RATIONALE, @REJECTED
  - C4 functions: buildApiError, notifyApiError, shouldSuppressApiErrorToast
  - C2 helpers: getWsUrl, getTaskEventsWsUrl, getMaintenanceEventsWsUrl,
    getTranslateRunWsUrl, getAuthHeaders
  - C4 fetch/request wrappers: fetchApi, fetchApiBlob, postApi, deleteApi, requestApi
  - C3 endpoint registry: api.* methods with @RELATION DEPENDS_ON chains
  - All C4 functions have @PRE/@POST/@SIDE_EFFECT
  - all generic <T = unknown> for type-safe API responses

Build: npm run build passes cleanly
2026-06-01 15:11:35 +03:00
15b466a918 feat(translate): move write settings to Target Config tab + fix datasource name lookup
Fixes:
- Move batch size, upsert strategy, include source reference
  from Config tab to Target Config tab (Write Settings section)
- Fix 'Dataset #26' fallback — look up real datasource name
  via API when source_table is not saved in job data
- Persist include_source_reference in save payload and
  restore from job data on load (was a pre-existing gap)

QA review fixes:
- Update @BRIEF contracts for both tabs
- Fix import indentation in +page.svelte

Other: help tooltips on translate pages, flow hint on list page,
git migration manager components, dashboard hub pages,
migration settings pages
2026-05-31 09:59:09 +03:00
9ef9fae206 fix: critical QA findings — dead code and prop mismatch
1. Remove get_config_manager() call from translate_run_websocket
   (@app.websocket /ws/translate/run/{run_id}) — was not imported
   and unused. Also remove unused from sqlalchemy.orm import Session.
2. Fix prop name mismatch: showBulkReplace -> showPageBulkReplace
   in RunTabContent. Use () for reactive two-way binding.
3. Add ('DRAFT') for status prop in RunTabContent.
2026-05-29 16:47:50 +03:00
ffa6234a36 refactor: remove orphaned functions after tab extraction
Remove loadColumnsForDatasource, searchDatasources, selectDatasource,
toggleContextColumn, toggleSourceKeyCol, updateTargetKeyCol, isVirtual
from page — all moved to ConfigTabForm.svelte.

Add  on datasourceId in ConfigTabForm to auto-load columns
when parent sets datasourceId (loadJob) or user selects a datasource.
2026-05-29 16:33:15 +03:00
ebc00bbb0e refactor(translate): extract ConfigTabForm, TargetTabForm, RunTabContent from page
Page reduced from 1519 to 909 lines (-40%). Extracted:
- ConfigTabForm.svelte (370 lines) — datasource search, column mapping,
  LLM, target languages, dictionaries, batch config
- TargetTabForm.svelte (120 lines) — target schema/table/database,
  target column mapping, TargetSchemaHint
- RunTabContent.svelte (170 lines) — run cards, progress, history

All three components use () props for seamless parent
state sync. Sub-components (TargetSchemaHint, TranslationPreview,
TranslationRunProgress, ScheduleConfig, BulkReplaceModal) unchanged.
2026-05-29 16:30:09 +03:00
9ffa8af1dc semantics 2026-05-26 09:30:41 +03:00
31680a1bc9 fix(maintenance): auto-expiry + adaptive markdown height + tests
- Auto-expiry: expired events auto-end on GET /events via task manager
- Height: _estimate_markdown_height adapted to unit=8px scale with padding detection
- CRITICAL-1: removed dead import remove_chart_from_position (QA finding)
- CRITICAL-2: added chart alive check in ensure_banner_chart (QA finding)
- CRITICAL-3: fixed test assertions update_markdown_chart → update_banner_on_dashboard
- @POST contract: fixed return range [2,12] → [19,200]
- Tests: 8 new tests (auto-expiry + layout height)
2026-05-25 08:36:33 +03:00
084f782065 lang detect 2026-05-20 17:15:31 +03:00
09d12b3b68 semantics 2026-05-20 09:59:03 +03:00
8039d09505 refactor(frontend): unify Tailwind classes — replace hardcoded colors with semantic design tokens
- Replace all bg-blue-600/hover:bg-blue-700 → bg-primary/hover:bg-primary-hover
- Replace all bg-red-600/hover:bg-red-700 → bg-destructive/hover:bg-destructive-hover
- Replace all focus:ring-blue-500 → focus-visible:ring-primary-ring
- Replace all text-blue-600 → text-primary on interactive elements
- Replace all bg-blue-50 → bg-primary-light on UI surfaces
- Replace all bg-red-50 → bg-destructive-light on error surfaces
- Replace all border-blue-200/300 → border-primary-ring
- Replace all border-red-200 → border-destructive-light
- Replace peer-checked:bg-blue-600 → peer-checked:bg-primary (toggles)
- Replace focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 patterns
- Keep status badge patterns (bg-*-100 text-*-700) and hover:bg-blue-50 intact

82 files changed, ~400 changes. Build passes.
2026-05-19 10:46:00 +03:00
59aedbe12c fix(translate): replace fromStore+ with +subscribe to prevent reactive loop, add runComplete flag, show error_message, collapsible run results
- TranslationRunGlobalIndicator: replace fromStore + 6x  with
  (() => store.subscribe()) to prevent accumulating render_effect
  instances via createSubscriber that caused infinite Svelte reactive flush
- translate/[id]/+page.svelte: add runComplete flag to hide progress bar
  after completion without touching the store; add collapsible run detail
  cards with status badge, counts, and error_message; filter invalid runs
- translationRun.js: remove stale guard (no longer needed)
- Sidebar.svelte: fix mobile overlay close on route change
- docs/adr/ADR-0007-rejected-fromStore-derived.md: document REJECTED pattern
2026-05-18 11:43:27 +03:00
4479392a2f fix(translate): handle row lock timeout in cancel, add flush fallback, migrate progress to store
- Extract _fallback_cancel_request for row lock timeout recovery in orchestrator_cancel
- Add flush lock timeout fallback in cancel_run
- Set error_message when all records fail in executor
- Track insert_failed state in scheduler and frontend store
- Migrate TranslationRunProgress from local polling to centralized store
- Fix nginx resolver for Docker variable-based proxy_pass
- Add FRONTEND_HOST_PORT env var to docker-compose
2026-05-18 10:36:58 +03:00
cd868df261 fix(health): suppress 404 when health monitor disabled + fix audit test assertion
- Sidebar.svelte: defer healthStore.refresh() until feature flags confirm
  health_monitor is enabled; skip entirely when disabled
- health.js: remove throw error from catch block — log and return null
  instead, preventing 'Uncaught (in promise)' on expected 404
- test_report_audit_immutability.py: fix mock assertions —
  audit_service uses logger.reason/reflect/explore, not logger.info
- HealthStore and Sidebar now produce zero network noise when
  FEATURES__HEALTH_MONITOR=false
2026-05-17 14:18:02 +03:00
b466ac6211 feat(translate): add translation cache with source_hash dedup + enforce dictionary post-processing
- Add source_hash column (SHA256 of source_text+source_data+dict_hash+config_hash) to TranslationRecord for cache dedup
- Add Alembic migration b1c2d3e4f5a6 for the new column and composite index (source_hash, status)
- Implement _compute_source_hash / _check_translation_cache in executor.py — before LLM call, check if same source+dict+config combo was already translated successfully
- Implement cache-aware routing in _process_batch: full cache hit → skip LLM, partial hit → route to LLM
- Store source_hash on all new TranslationRecord rows for future cache hits
- Strengthen dictionary prompt instructions from 'use when applicable' to 'MUST use — mandatory'
- Add _enforce_dictionary() post-processing: force-replace dictionary terms in LLM output if LLM ignored them
- Fix CRITICAL: use run.dict_snapshot_hash/config_hash (exist on TranslationRun, not TranslationJob)
- Fix MAJOR: verify cached languages cover ALL target_languages before accepting cache hit
- Fix MAJOR: prevent regex back-reference injection in dictionary enforcement (use lambda)
- Fix: add joinedload to cache lookup to avoid N+1 queries
- Fix: remove redundant single-column index (composite index is sufficient)
- Fix(frontend): parse paginated /translate/dictionaries response correctly (result.items)
2026-05-16 00:42:07 +03:00
b3572ce443 fix(ui): upgrade global indicator from thin bar to rich progress panel
- Show full stats grid (total/success/fail/skip) + progress bar + cancel button during active run
- Compact colored banner for terminal states (completed/partial/failed/cancelled) with auto-dismiss
- Import cancelRun from translate API for functional cancel button
- fromStore() reactivity confirmed working — no store changes needed
- Hide on /translate/[id] to avoid duplication (existing behavior preserved)
2026-05-15 22:37:25 +03:00
27168664b8 fix(translate): normalize Unix timestamps to YYYY-MM-DD for ClickHouse Date columns
- Add _normalize_timestamp_value to key column values in orchestrator.py and executor.py before SQL generation
- Fix test mocks for .options(joinedload()) chain, explicit None attrs for mock job
- Add global translation run progress indicator (TranslationRunGlobalIndicator + store)
- Fix translate page import missing translationRunStore
- All 208 translate tests pass
2026-05-15 22:06:27 +03:00
fdf48491a1 fix(translate): Kilo API response_format, reasoning_effort skip, structured_outputs fallback, refusal handling
- Enable response_format (json_object) for all providers including Kilo/OpenRouter
- Skip reasoning_effort for Kilo/OpenRouter (returns 400 — mandatory reasoning)
- Add structured_outputs fallback: retry once without response_format if upstream
  provider (e.g. StepFun) rejects it with 'structured_outputs is not supported'
- Handle model refusal field (refusal) instead of treating as empty content
- Fix None-handling guards for message/finish_reason/content fields
- Apply same fixes to both preview.py and executor.py _call_openai_compatible
- Connect orphaned TermCorrectionPopup, BulkReplaceModal, BulkCorrectionSidebar
2026-05-15 18:12:29 +03:00
e55f679262 fix(ui): dynamically resizable TranslationPreview table for 100-10000 char texts
- Removed max-w-[200px] compression on source text column → now
  gets proportional space
- Scrollable containers (max-h-32 overflow-y-auto) for long text cells
- Language columns: min-w-[200px]→[250px] with whitespace-pre-wrap
- Source language badge and status columns remain narrow (w-28, w-24)
2026-05-15 10:40:57 +03:00
30d7f3f725 feat(i18n): localize all translate components (spec 028)
P0 — Wired i18n to 4 previously-unlocalized surfaces:
- BulkReplaceModal (~25 strings → translate.bulk_replace.*)
- CorrectionCell (~20 strings → translate.corrections.cell_*)
- TermCorrectionPopup (~30 strings → translate.term_correction.*)
- history/+page.svelte (~50 strings → translate.history.*)

P1 — Added 85+ keys to en.json + ru.json (identical structures):
- 11 previously-missing keys (common.close, config.status, etc.)
- bulk_replace.*, corrections.*, term_correction.*, history.*, dictionaries.*

P2 — Dictionary detail page: import form, filter-by-language, context display
P3 — Russian hardcoded strings in job config replaced with i18n

Tests: 280 pass, build succeeds
2026-05-15 09:00:33 +03:00
9f3f6611a1 feat(translate): complete Phase 10-11 — full spec 028 closure (T075-T134)
Phase 10 closure:
- T075: NotificationService wiring for scheduled-run failures
- T077: Semantic audit via axiom MCP (0 warnings)
- T078: Quickstart validation — all 165+280 tests pass

Phase 11 completion:
- T083-T086: Multi-language models/schemas/Alembic migration
- T087-T090: Auto-detect source language (BCP-47) + tests
- T091-T095: Multilingual dictionaries with language-pair filtering
- T096-T108: Multi-language job config → preview → execution pipeline
- T109-T118: Inline correction + BulkReplaceModal + CorrectionCell + tests
- T119-T122: Per-language history and MetricSnapshot
- T123-T134: Context-aware corrections (Jaccard similarity, priority flagging, context_data)

New files: Alembic migration, test_scheduler, test_inline_correction,
BulkReplaceModal, vitest for CorrectionCell + BulkReplaceModal

Total: 134/134 tasks complete. Backend 165p, Frontend 280p.
2026-05-14 21:14:04 +03:00
bb21fd3165 fix(translate): M1-M3 medium + L1-L2 low bugs from QA review
M1: ReDoS guard — 500 char max + try/except on re.compile
M2: Performance note — O(n×m) regex documented for future optimization
M3: Verified test key names correct (metrics.py transforms cumulative_* → short)
L1: Removed @staticmethod no-op from module-level function
L2: Added aria-label to emoji indicators in CorrectionCell
2026-05-14 17:44:50 +03:00
1853d008e9 fix(translate): CR1-CR2 migration + H1-H4 code review bugs
CR1: Add needs_review, language_overridden to translation_languages migration
CR2: Add per_language_metrics to translation_metric_snapshots migration
H1: BulkFindReplaceService.preview() now uses replacement_text (not find pattern)
H2: get_run_records now includes per-language data via selectinload
H3: Preview per-language approve/reject uses correct (jobId, rowId, lang) args
H4: _compute_config_hash now includes target_languages
2026-05-14 17:38:52 +03:00
bb0fbfdafd feat(translate): multi-language optimization (Phase 11)
- Auto-detection of source language per row via LLM (US6)
- Multi-target translation — one LLM call for N languages (US1-US3)
- Language-aware storage: TranslationLanguage, per-language stats
- Multilingual dictionaries with language-pair-aware filtering (US7)
- Inline correction on any run result + submit-to-dictionary (US8)
- Context-aware dictionary: auto-capture row context, usage notes,
  Jaccard similarity, priority flagging in LLM prompts (US8b)
- Configurable preview sample size 1-100, cost warning at >30
- Per-language history & metrics with MetricSnapshot preservation
- 36 files, +5022/-373, all specs GRACE-Poly v2.6 compliant
2026-05-14 17:12:41 +03:00
8d0bc6fb93 feat(translate,scheduler,trace): new-key-only mode, stale PENDING protection, trace_id propagation
Translations:
- FR-045: new-key-only execution mode — translate only rows with unseen keys
- Compare source row keys against TranslationRecord.source_data from last succeeded run
- Baseline expired (>90 days) fallback to full mode with baseline_expired event
- run_noop early return when zero new keys (skip LLM + SQL)

Scheduler reliability:
- Stale PENDING protection: runs older than 1h auto-marked FAILED, no longer block schedule
- load_schedules() reloads active translation schedules from DB on restart
- add_translation_job/remove_translation_job register/unregister with APScheduler
- execution_mode column on translation_schedules with additive DB migration

Automation view:
- GET /settings/automation/translation-schedules endpoint
- Translation schedules displayed on Automation page below validation policies

Trace propagation:
- seed_trace_id() in all background entry points:
  TaskManager._run_task/_flusher_loop, SchedulerService._trigger_backup,
  websocket_endpoint, IdMappingService, all standalone scripts

Migrations:
- dictionary_entries: origin_run_id, origin_row_key, origin_user_id
- translation_schedules: execution_mode

Tests:
- 3 new test modules (22 tests): core_scheduler, executor_filter, scheduler_execution+guard
- Fix pre-existing translate test isolation (conftest.py)
- Fix test_list_runs_filter_status parameter
2026-05-14 10:13:56 +03:00
a3c7c402b7 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
2026-05-13 20:06:15 +03:00
39ab647851 semantics 2026-05-13 14:15:33 +03:00
fe8978f716 semantics 2026-05-12 20:06:16 +03:00
1d59df2233 refactor 2026-05-12 14:52:27 +03:00
dbb8bd6c4e fix: persist environment selection, support Kilo AI provider, resolve Superset virtual columns for translation preview
- Add environment_id to TranslationJob model/schema/API + DB migration
- Pass environmentId from page to TranslationPreview and fetchPreview
- Fix _fetch_sample_rows: use result_type='samples' to include virtual cols
- Add 'kilo' and 'openrouter' to supported LLM provider types
- Make response_format conditional (skip for non-OpenAI upstream providers)
- Remove source_table field from form (redundant with datasource)
- Restore datasourceSearch display from saved job on page load
- Add request/response logging for LLM API calls
2026-05-09 23:10:15 +03:00
67ba04d4ff 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
2026-05-09 19:34:25 +03:00