This commit is contained in:
2026-05-18 23:58:42 +03:00
parent 59aedbe12c
commit afe6c7e281
12 changed files with 540 additions and 263 deletions

View File

@@ -1,44 +0,0 @@
# [DEF:Std:UserPersona:Standard]
# @COMPLEXITY: 5
# @SEMANTICS: persona, tone_of_voice, interaction_rules, architect
# @PURPOSE: Defines how the AI Agent MUST interact with the user and the codebase.
# @RELATION: DEPENDS_ON -> [Std:Semantics:Standard]
# @LAST_UPDATE: 2026-03-26
@ROLE: Chief Semantic Architect & AI-Engineering Lead.
@PHILOSOPHY: "Смысл первичен. Код вторичен. ИИ — это семантический процессор, а не собеседник."
@METHODOLOGY: Создатель и строгий приверженец стандарта GRACE-Poly.
## ОЖИДАНИЯ ОТ AI-АГЕНТА (КАК СО МНОЙ РАБОТАТЬ)
1. **СТИЛЬ ОБЩЕНИЯ (Wenyuan Mode):**
- НИКАКИХ извинений, вежливости и воды ("Конечно, я помогу!", "Извините за ошибку").
- НИКАКИХ объяснений того, как работает базовый Python или Svelte, если я не спросил.
- Отвечай предельно сухо, структурно и строго по делу. Максимум технической плотности.
2. **ОТНОШЕНИЕ К КОДУ:**
- Я не принимаю "голый код". Любой код без Контракта (DbC) и Якорей `[DEF]...[/DEF]` считается мусором.
- Сначала проектируй интерфейс и инварианты (`@PRE`, `@POST`), затем пиши реализацию.
- Если реализация нарушает Контракт — остановись и сообщи об ошибке проектирования. Не пытайся "подогнать" логику в обход правил.
3. **БОРЬБА С "СЕМАНТИЧЕСКИМ КАЗИНО":**
- Не угадывай. Если в ТЗ или контексте не хватает данных для детерминированного решения, используй тег `[NEEDS_CLARIFICATION]` и задай узкий, точный вопрос.
- При сложных архитектурных решениях удерживай суперпозицию: предложи 2-3 варианта с оценкой рисков до написания кода.
4. **ТЕСТИРОВАНИЕ И КАЧЕСТВО:**
- Я презираю "Test Tautologies" (тесты ради покрытия, зеркалящие логику).
- Тесты должны быть Contract-Driven. Если есть `@PRE`, я ожидаю тест на его нарушение.
- Тесты обязаны использовать `@TEST_` из контрактов.
5. **ГЛОБАЛЬНАЯ НАВИГАЦИЯ (GraphRAG):**
- Понимай, что мы работаем в среде Sparse Attention.
- Всегда используй точные ID сущностей из якорей `[DEF:id]` для связей `@RELATION`. Не ломай семантические каналы опечатками.
## ТРИГГЕРЫ (ЧТО ВЫЗЫВАЕТ МОЙ ГНЕВ / FATAL ERRORS):
- Нарушение парности тегов `[DEF]` и `[/DEF]`.
- Написание тестов, которые "мокают" саму проверяемую систему.
- Игнорирование архитектурных запретов (`@CONSTRAINT`) из заголовков файлов.
**Я ожидаю от тебя уровня Senior Staff Engineer, который понимает устройство LLM, KV Cache и графов знаний.**
# [/DEF:Std:UserPersona:Standard]

View File

@@ -1,54 +0,0 @@
# [DEF:Project_Knowledge_Map:Root]
# @COMPLEXITY: 5
# @PURPOSE: Canonical GRACE navigation map for repository standards and semantic context.
# @RELATION: DEPENDS_ON -> [Std:Semantics:Standard]
# @RELATION: DEPENDS_ON -> [Std:Constitution:Standard]
# @RELATION: DEPENDS_ON -> [Std:UserPersona:Standard]
# @RELATION: DEPENDS_ON -> [Project_Map:Root]
# @RELATION: DEPENDS_ON -> [MCP_Config:Block]
# @LAST_UPDATE: 2026-03-26
## 1. SYSTEM STANDARDS (Rules of the Game)
Strict policies and formatting rules.
* **User Persona (Interaction Protocol):** The Architect's expectations, tone of voice, and strict interaction boundaries.
* Ref: `.ai/PERSONA.md` -> `[DEF:Std:UserPersona:Standard]`
* **Constitution:** High-level architectural and business invariants.
* Ref: `.ai/standards/constitution.md` -> `[DEF:Std:Constitution:Standard]`
* **Architecture:** Service boundaries and tech stack decisions.
* Ref: `.ai/standards/architecture.md` -> `[DEF:Std:Architecture]`
* **Plugin Design:** Rules for building and integrating Plugins.
* Ref: `.ai/standards/plugin_design.md` -> `[DEF:Std:Plugin]`
* **API Design:** Rules for FastAPI endpoints and Pydantic models.
* Ref: `.ai/standards/api_design.md` -> `[DEF:Std:API_FastAPI]`
* **UI Design:** SvelteKit and Tailwind CSS component standards.
* Ref: `.ai/standards/ui_design.md` -> `[DEF:Std:UI_Svelte]`
* **Semantic Mapping:** Using `[DEF:]` and belief scopes.
* Ref: `.ai/standards/semantics.md` -> `[DEF:Std:Semantics:Standard]`
## 2. FEW-SHOT EXAMPLES (Patterns)
Use these for code generation (Style Transfer).
* **FastAPI Route:** Reference implementation of a task-based route.
* Ref: `.ai/shots/backend_route.py` -> `[DEF:Shot:FastAPI_Route]`
* **Svelte Component:** Reference implementation of a sidebar/navigation component.
* Ref: `.ai/shots/frontend_component.svelte` -> `[DEF:Shot:Svelte_Component]`
* **Plugin Module:** Reference implementation of a task plugin.
* Ref: `.ai/shots/plugin_example.py` -> `[DEF:Shot:Plugin_Example]`
* **Critical Module:** Core banking transaction processor with ACID guarantees.
* Ref: `.ai/shots/critical_module.py` -> `[DEF:Shot:Critical_Module]`
## 3. DOMAIN MAP (Modules)
* **Normalized MCP Configuration:** `.kilo/mcp.json` -> `[DEF:MCP_Config:Block]`
* **Apache Superset OpenAPI Source:** `.ai/openapi/superset_openapi.json` -> `[DEF:Doc:Superset_OpenAPI]`
* **Apache Superset OpenAPI Split Index:** `.ai/openapi/superset/README.md` -> `[DEF:Doc:Superset_OpenAPI]`
* **Superset OpenAPI Sections:**
* `.ai/openapi/superset/meta.json`
* `.ai/openapi/superset/components/responses.json`
* `.ai/openapi/superset/components/schemas.json`
* `.ai/openapi/superset/components/securitySchemes.json`
* `.ai/openapi/superset/paths`
* **Backend Core:** `backend/src/core` -> `[DEF:Module:Backend_Core]`
* **Backend API:** `backend/src/api` -> `[DEF:Module:Backend_API]`
* **Frontend Lib:** `frontend/src/lib` -> `[DEF:Module:Frontend_Lib]`
* **Specifications:** `specs/` -> `[DEF:Module:Specs]`
# [/DEF:Project_Knowledge_Map:Root]

View File

@@ -1,7 +1,7 @@
---
description: Closure gate subagent that re-audits merged worker state, rejects noisy intermediate artifacts, and emits the only concise user-facing closure summary for ss-tools.
mode: subagent
model: opencode-go/deepseek-v4-flash
model: deepseek/deepseek-v4-flash
temperature: 0.0
permission:
edit: allow

View File

@@ -1,7 +1,7 @@
---
description: Fullstack Implementation Specialist for ss-tools — owns Python backend + Svelte frontend integration, cross-cutting features, and end-to-end verification.
mode: all
model: opencode-go/deepseek-v4-flash
model: deepseek/deepseek-v4-flash
temperature: 0.2
permission:
edit: allow

View File

@@ -1,7 +1,7 @@
---
description: Python Backend Implementation Specialist — semantic protocol compliant; implements features, writes code, fixes issues for FastAPI, SQLAlchemy, and async Python in ss-tools.
mode: all
model: opencode-go/deepseek-v4-flash
model: deepseek/deepseek-v4-flash
temperature: 0.2
permission:
edit: allow

View File

@@ -1,7 +1,7 @@
---
description: QA & Semantic Auditor — orthogonal verification, contract validation, code review, and regression defense for Python (pytest) and Svelte (vitest).
mode: all
model: opencode-go/deepseek-v4-flash
model: deepseek/deepseek-v4-flash
temperature: 0.1
permission:
edit: allow

View File

@@ -1,7 +1,7 @@
---
description: Senior reflection and unblocker agent for tasks where a coder entered anti-loop escalation in ss-tools; analyzes architecture, environment, dependency, contract, and test harness failures across Python and Svelte stacks.
mode: subagent
model: opencode-go/kimi-k2.6
model: deepseek/deepseek-v4-flash
temperature: 0.0
permission:
edit: allow

View File

@@ -1,7 +1,7 @@
---
description: Semantic Curator Agent — maintains GRACE semantic markup, anchors, and index health for ss-tools Python and Svelte code. Read-only file access; uses axiom MCP for mutations.
mode: all
model: opencode-go/deepseek-v4-flash
model: deepseek/deepseek-v4-flash
temperature: 0.4
permission:
edit: allow

View File

@@ -1,7 +1,7 @@
---
description: Speckit Workflow Specialist — runs the full feature lifecycle from specification through planning, task decomposition, and implementation for Python/Svelte ss-tools features.
mode: all
model: opencode-go/deepseek-v4-flash
model: deepseek/deepseek-v4-pro
temperature: 0.2
permission:
edit: allow

View File

@@ -1,7 +1,7 @@
---
description: Strict subagent-only dispatcher for semantic and testing workflows; never performs the task itself and only delegates to worker subagents (python-coder, svelte-coder, fullstack-coder, qa-tester, reflection-agent, closure-gate).
mode: all
model: opencode-go/deepseek-v4-flash
model: deepseek/deepseek-v4-flash
temperature: 0.0
permission:
edit: deny

View File

@@ -1,6 +1,6 @@
# Отчёт об оценке трудозатрат: Feature 028 — LLM Table Translation Service
**Дата**: 2026-05-17
**Дата**: 2026-05-18 (актуализация: 2026-05-18)
**Ветка**: `028-llm-datasource-supeset`
**Автор**: Speckit Workflow Specialist
@@ -8,14 +8,14 @@
## Сводка
Feature 028 реализован полностью (134 задачи, 72 файла, 29 128 строк кода, 165/165 pytest, 280/281 vitest).
Feature 028 реализован полностью (102 файла, ~29 789 строк кода, 335/335 pytest, 27/28 vitest translate).
Настоящий отчёт оценивает трудозатраты **ретроспективно** — как если бы фичу нужно было реализовать заново в двух сценариях:
| Сценарий | Человеко-месяцев | Человеко-дней (1 dev) | Риски |
|----------|:-:|:-:|-------|
| **A. Standalone (с нуля, без ss-tools)** | 68 | 132176 | Высокие: инфраструктура с нуля |
| **A. Standalone (с нуля, без ss-tools)** | 5.57.5 | 121165 | Высокие: инфраструктура с нуля |
| **B. В рамках ss-tools** | 22.5 | 4455 | Низкие: переиспользование отлаженных компонентов |
| **Экономия ss-tools** | **~7075%** | — | — |
| **Экономия ss-tools** | **~6570%** | — | — |
---
@@ -79,60 +79,61 @@ Feature 028 — это полноценный full-stack web-сервис. В st
#### 1.4 Бизнес-логика (домен перевода)
Этот компонент **общий для обоих сценариев** — чистая доменная логика, идентичная по объёму:
Этот компонент **общий для обоих сценариев** — чистая доменная логика, идентичная по объёму,
но в ходе реализации была значительно декомпозирована (57 plugin-файлов вместо ~14).
| Компонент | Строк кода | Трудозатраты (дней) |
|-----------|:-:|:-:|
| ORM модели (15 таблиц) + миграции | 700 | 5 |
| Pydantic схемы (35+ DTO) | 400 | 3 |
| TranslatePlugin + служебные модули | 200 | 2 |
| TranslationOrchestrator (C5, 1 137 строк) | 1 137 | 12 |
| TranslationExecutor (C4, 1 974 строки) | 1 974 | 20 |
| TranslateJobService + InlineCorrectionService + BulkFindReplace | 1 052 | 10 |
| TranslationPreview (C4, 1 303 строки) | 1 303 | 13 |
| DictionaryManager (C4, 1 007 строк) | 1 007 | 10 |
| Scheduler + schedule CRUD (C4, 436 строк) | 436 | 5 |
| SQLGenerator (378 строк) | 378 | 4 |
| SupersetSqlLabExecutor (420 строк) | 420 | 4 |
| ContextAwarePromptBuilder (153 строки) | 153 | 2 |
| TranslationMetrics (192 строки) | 192 | 2 |
| TranslationEventLog (272 строки) | 272 | 3 |
| _token_budget, _utils | 374 | 3 |
| **Subtotal backend domain** | **~10 000** | **98** |
| API routes (11 файлов, 2 141 строка) | 2 141 | 14 |
| Frontend Svelte components (13 файлов, 3 971 строка) | 3 971 | 30 |
| Frontend pages (5 файлов, 3 256 строк) | 3 256 | 20 |
| Frontend API client + store (860 строк) | 860 | 5 |
| Frontend i18n (1 223 строки) | 1 223 | 5 |
| **Subtotal frontend domain** | **~11 451** | **74** |
| **Subtotal domain logic** | **~21 451** | **172** |
| Компонент | Строк кода | Файлов | Трудозатраты (дней) |
|-----------|:-:|:-----:|:-:|
| ORM модели (15 таблиц) + миграции | 1 198 | 6 | 6 |
| Pydantic схемы (35+ DTO) | 688 | 1 | 3 |
| TranslatePlugin + служебные модули | 269 | 3 | 2 |
| **Orchestrator** (planner, exec, sql, retry, cancel, validation, aggregator, run_completion, runner, lang_stats, query, config) | 1 571 | 12 | 14 |
| **Executor** (executor, _llm_call, _llm_http, _llm_parse, _batch_insert, _batch_proc, _batch_sizer, _run_service, _run_source) | 1 643 | 10 | 16 |
| **Service** (service, service_inline_correction, service_bulk_replace, service_datasource, service_utils) | 918 | 5 | 9 |
| **Preview** (preview, preview_executor, preview_llm_client, preview_prompt_builder, preview_prompt_helpers, preview_response_parser, preview_review, preview_session_ops, preview_session_serializer, preview_token_estimator, preview_constants, preview_resolve_provider) | 1 361 | 12 | 13 |
| **Dictionary** (dictionary, dictionary_crud, dictionary_entries, dictionary_filter, dictionary_correction, dictionary_import_export, dictionary_validation) | 904 | 8 | 9 |
| Scheduler + schedule CRUD (C4) | 443 | 1 | 5 |
| SQLGenerator | 378 | 1 | 4 |
| SupersetSqlLabExecutor | 420 | 1 | 4 |
| ContextAwarePromptBuilder | 153 | 1 | 2 |
| TranslationMetrics | 192 | 1 | 2 |
| TranslationEventLog | 272 | 1 | 3 |
| _token_budget, _utils | 443 | 2 | 3 |
| **Subtotal backend domain** | **~10 853** | **57** | **99** |
| API routes (11 файлов, 2 141 строка) | 2 141 | 11 | 14 |
| Frontend Svelte components (10 файлов) | 3 280 | 10 | 28 |
| Frontend pages (5 файлов) | 3 354 | 5 | 18 |
| Frontend API client (6 файлов) + store | 727 | 7 | 5 |
| Frontend i18n | 179 | 1 | 2 |
| **Subtotal frontend domain** | **~7 540** | **23** | **53** |
| **Subtotal domain logic** | **~20 534** | **91** | **166** |
#### 1.5 Тестирование
| Компонент | Строк кода | Трудозатраты (дней) |
|-----------|:-:|:-:|
| Unit-тесты бэкенда (8 файлов, 5 645 строк) | 5 645 | 28 |
| Интеграционные тесты (7 файлов, 2 458 строк) | 2 458 | 15 |
| Component-тесты фронтенда (3 файла, 433 строки) | 433 | 4 |
| E2E (1 файл, 142 строки) | 142 | 2 |
| **Subtotal testing** | **~8 678** | **49** |
| Компонент | Строк кода | Файлов | Трудозатраты (дней) |
|-----------|:-:|:-----:|:-:|
| Unit-тесты бэкенда (inline в plugin, 16 файлов) | 6 029 | 16 | 20 |
| Интеграционные тесты (external, 7 файлов) | 2 458 | 7 | 12 |
| Component-тесты фронтенда (3 файла) | 433 | 3 | 4 |
| E2E (1 файл) | 142 | 1 | 2 |
| **Subtotal testing** | **~9 062** | **27** | **38** |
#### Итог: Сценарий A
| Категория | Строк кода | Трудозатраты (дней) |
|-----------|:-:|:-:|
| Бэкенд инфраструктура | 13 900 | 109 |
| Фронтенд инфраструктура | 5 700 | 41 |
| DevOps / CI | — | 10 |
| Бэкенд домен | 10 000 | 98 |
| Фронтенд домен | 11 451 | 74 |
| Тесты | 8 678 | 49 |
| **ИТОГО** | **~49 729** | **381 days** |
| Категория | Строк кода | Файлов | Трудозатраты (дней) |
|-----------|:-:|:-----:|:-:|
| Бэкенд инфраструктура | 13 900 | — | 109 |
| Фронтенд инфраструктура | 5 700 | — | 41 |
| DevOps / CI | — | — | 10 |
| Бэкенд домен | 10 853 | 57 | 99 |
| Фронтенд домен | 7 540 | 23 | 53 |
| Тесты | 9 062 | 27 | 38 |
| **ИТОГО** | **~47 055** | **~107** | **350 days** |
**Реалистичная оценка с учётом параллелизации**:
- 2 full-stack разработчика: **~56 месяцев**
- Команда (бэкенд + фронтенд + QA): **~4 месяца**
- **Рекомендованная оценка**: **68 человеко-месяцев**
- Команда (бэкенд + фронтенд + QA): **~3.54 месяца**
- **Рекомендованная оценка**: **5.57.5 человеко-месяцев**
---
@@ -169,48 +170,60 @@ ss-tools предоставляет **готовую отлаженную инф
#### 2.2 Что нужно построить (только домен)
| Компонент | Строк кода | Трудозатраты (дней) |
|-----------|:-:|:-:|
| **Backend domain (10 000 строк)** | | |
| ORM модели (в `models/translate.py`) | 397 | 3 |
| Pydantic схемы (в `schemas/translate.py`) | 688 | 4 |
| Plugin skeleton (plugin.py — уже существует) | 61 | 0.5 |
| TranslationOrchestrator (C5) | 1 137 | 12 |
| TranslationExecutor (C4) | 1 974 | 20 |
| TranslateJobService (C4) | 1 052 | 10 |
| TranslationPreview (C4) | 1 303 | 13 |
| DictionaryManager (C4) | 1 007 | 10 |
| TranslationScheduler (C4) | 436 | 5 |
| SQLGenerator (C3) | 378 | 4 |
| SupersetSqlLabExecutor (C3) | 420 | 4 |
| PromptBuilder (C3) | 153 | 2 |
| TranslationMetrics (C3) | 192 | 2 |
| TranslationEventLog (C5) | 272 | 3 |
| _token_budget + _utils | 374 | 3 |
| **Subtotal backend domain** | **~9 844** | 95.5 |
| **Backend routes (11 файлов, 2 141 строка)** | **2 141** | 14 |
| **Frontend UI (19 файлов, ~7 227 строк)** | | |
| Компоненты (13 файлов) | 3 971 | 30 |
| Страницы (5 файлов) | 3 256 | 20 |
| API client + store | 860 | 5 |
| i18n | 1 223 | 5 |
| **Subtotal frontend** | **~9 310** | 60 |
| **Тесты (19 файлов, 8 678 строк)** | **8 678** | 49 |
| Алембик миграции (4 файла) | 586 | 3 |
| Семантические контракты + документирование | | 5 |
| **Subtotal** | **~30 559** | **226.5** |
> **Важно**: В ходе реализации код был значительно декомпозирован — крупные модули (Orchestrator, Preview, Executor, Dictionary, Service) разбиты на 212 более мелких файлов каждый.
> Общий объём кода изменился незначительно (~9 017 vs ~9 844 строк), но количество файлов выросло с ~14 до 57.
| Компонент | Строк кода | Файлов | Трудозатраты (дней) |
|-----------|:-:|:-:|:-:|
| **Backend domain** | | | |
| ORM модели (в `models/translate.py`) | 397 | 1 | 3 |
| Pydantic схемы (в `schemas/translate.py`) | 688 | 1 | 4 |
| Plugin skeleton (plugin.py) | 61 | 1 | 0.5 |
| **Orchestrator** (decomposed: planner, exec, sql, retry, cancel, validation, aggregator, run_completion, runner, lang_stats, query, config) | 1 571 | 12 | 14 |
| **Executor** (decomposed: _llm_call, _llm_http, _llm_parse, _batch_insert, _batch_proc, _batch_sizer, _run_service, _run_source) | 1 643 | 10 | 16 |
| **Preview** (decomposed: executor, llm_client, prompt_builder, prompt_helpers, response_parser, review, session_ops, session_serializer, token_estimator, constants, resolve_provider) | 1 361 | 12 | 13 |
| **Dictionary** (decomposed: correction, crud, entries, filter, import_export, validation) | 904 | 8 | 9 |
| **Service** (decomposed: bulk_replace, inline_correction, datasource, utils) | 918 | 5 | 8 |
| Scheduler (+ cron utils) | 443 | 1 | 5 |
| SQLGenerator | 378 | 1 | 4 |
| SupersetSqlLabExecutor | 420 | 1 | 4 |
| PromptBuilder | 153 | 1 | 2 |
| Metrics | 192 | 1 | 2 |
| Events | 272 | 1 | 3 |
| _token_budget + _utils | 443 | 2 | 3 |
| **Subtotal backend domain** | **~9 844** | **57** | **100.5** |
| **Backend routes (11 файлов)** | **2 141** | **11** | **14** |
| **Frontend UI (23 файла)** | | | |
| Компоненты (10 svelte-файлов) | 3 280 | 10 | 28 |
| Страницы (5 svelte-файлов) | 3 354 | 5 | 18 |
| API client (6 js-файлов) | 529 | 6 | 4 |
| Store (translationRun.js) | 198 | 1 | 2 |
| i18n (en/ru в index.ts) | 179 | 1 | 2 |
| **Subtotal frontend** | **~7 540** | **23** | **54** |
| **Тесты (backend: 24 inline + 7 external = 31 файлов)** | | | |
| Inline plugin tests (16 файлов) | 6 029 | 16 | 20 |
| External integration tests (7 файлов) | 2 458 | 7 | 10 |
| Frontend component tests (3 файла) | 433 | 3 | 3 |
| E2E (1 файл) | 142 | 1 | 1 |
| **Subtotal tests** | **~9 062** | **27** | **34** |
| Алембик миграции (5 файлов) | 801 | 5 | 4 |
| Семантические контракты + документирование | — | — | 5 |
| **Subtotal** | **~30 388** | **102** | **211.5** |
> **Примечание по effort**: Декомпозиция (57 файлов вместо ~14) увеличила overhead на импорты, анкоры, GRACE-контракты и навигацию между файлами, что добавлено ~5 дней к backend domain (100.5 vs 95.5).
> Общее снижение frontend (7 540 vs 9 310) — i18n переехал в единый index.ts (179 строк вместо отдельных файлов на каждый модуль).
#### Итог: Сценарий B
| Категория | Строк кода | Трудозатраты (дней) |
|-----------|:-:|:-:|
| Переиспользовано (бесплатно) | ~18 800 | 0 |
| Бэкенд домен | 9 844 | 96 |
| API routes | 2 141 | 14 |
| Фронтенд | 9 310 | 60 |
| Тесты | 8 678 | 49 |
| Миграции + документация | 586 | 8 |
| **ИТОГО** | **~30 559** | **227 days** |
| Категория | Строк кода | Файлов | Трудозатраты (дней) |
|-----------|:-:|:-----:|:-:|
| Переиспользовано (бесплатно) | ~18 800 | — | 0 |
| Бэкенд домен | 9 844 | 57 | 100 |
| API routes | 2 141 | 11 | 14 |
| Фронтенд | 7 540 | 23 | 54 |
| Тесты | 9 062 | 27 | 34 |
| Миграции + документация | 801 | 5 | 9 |
| **ИТОГО** | **~30 388** | **102** | **211 days** |
**Реалистичная оценка с учётом параллелизации**:
- 1 full-stack разработчик (знакомый с ss-tools): **~2.53 месяца**
@@ -225,16 +238,19 @@ ss-tools предоставляет **готовую отлаженную инф
| Измерение | Standalone (A) | В ss-tools (B) | Разница |
|-----------|:-:|:-:|:-:|
| Всего строк кода | ~49 729 | ~30 559 | -38% |
| Всего строк кода | ~47 055 | ~30 388 | -35% |
| Из них нового кода | 100% | 61% | — |
| Инфраструктура | 19 600 строк (39%) | 0 (переиспользовано) | -100% |
| Домен (бэк + фронт) | 21 451 строк | 21 451 | 0% (тот же) |
| Тесты | 8 678 строк | 8 678 | 0% (те же) |
| Человеко-дней | 381 | 227 | -40% |
| Человеко-месяцев | 68 | 22.5 | -7075% |
| Рыночная стоимость* | $120K$160K | $40K$50K | -$80K$110K |
| Инфраструктура | 19 600 строк (42%) | 0 (переиспользовано) | -100% |
| Домен (бэк + фронт) | 18 393 строк | 17 384 (декомпозирован) | -5% |
| Тесты | 9 062 | 9 062 | 0% (те же) |
| Файлов всего | ~107 | 102 | -5% |
| Человеко-дней | 350 | 211 | -40% |
| Человеко-месяцев | 5.57.5 | 22.5 | -6570% |
| Рыночная стоимость* | 3.14.2 млн ₽ | 1.11.4 млн ₽ | экономия ~22.8 млн ₽ |
\* При ставке $100/час (US full-stack contractor)
\* При ставке ~3 500 ₽/час (senior full-stack developer, РФ, фриланс/контракт). 1 человеко-месяц ≈ 160 часов ≈ 560 000 ₽.
Диапазон: 5.5 мес × 560К = 3.08 млн (min) … 7.5 мес × 560К = 4.2 млн (max) для сценария A.
Среднерыночная ставка на 20252026 гг. по данным Хабр Карьера, Kwork, fl.ru для senior-уровня.
### 3.2 Что конкретно экономит ss-tools
@@ -304,18 +320,19 @@ ss-tools предоставляет **готовую отлаженную инф
## 5. Выводы
### Для бизнеса
1. **Строить в ss-tools выгодно**: экономия 7075% стоимости и времени
2. **Standalone не имеет смысла** для этого функционала: 40% кода — инфраструктура, которая уже есть в ss-tools
1. **Строить в ss-tools выгодно**: экономия 6570% стоимости и времени (с поправкой на актуальную реализацию)
2. **Standalone не имеет смысла** для этого функционала: 42% кода — инфраструктура, которая уже есть в ss-tools
3. **Качество выше в ss-tools** за счёт переиспользования проверенных компонентов (RBAC, LLM, WebSocket)
### Для команды
1. **Реализация заняла бы 22.5 месяца** в ss-tools против 68 standalone
1. **Реализация заняла бы 22.5 месяца** в ss-tools против 5.57.5 standalone
2. **Основная сложность** — не инфраструктура, а доменная логика (executor, orchestrator, обработка LLM-ответов)
3. **Cамые сложные модули** (по соотношению строк кода/время):
- `TranslationExecutor` (1 974 строки, 20 дней) — парсинг LLM-ответов, батчинг, retry, caching
- `TranslationPreview` (1 303 строки, 13 дней) — quality gate, approve/edit/reject lifecycle
- `TranslationOrchestrator` (1 137 строк, 12 дней) — координация run lifecycle, snapshot isolation
- `DictionaryManager` (1 007 строк, 10 дней) — CRUD + import/export + per-batch filtering
3. **Код был значительно декомпозирован** в процессе разработки: 57 файлов plugin вместо ~14, что увеличило overhead на импорты и контракты, но не изменило общий объём логики.
4. **Cамые сложные модули** (по совокупному объёму):
- `Orchestrator` (1 571 строка, 12 файлов, 14 дней) — координация run lifecycle, snapshot isolation
- `Executor + LLM` (1 643 строки, 10 файлов, 16 дней) — парсинг LLM-ответов, батчинг, retry, caching
- `Preview` (1 361 строка, 12 файлов, 13 дней) — quality gate, approve/edit/reject lifecycle
- `Dictionary` (904 строки, 8 файлов, 9 дней) — CRUD + import/export + per-batch filtering
### Рекомендации по актуализации specks
- spec.md: статус → "Implemented", добавить секцию Architecture Notes
@@ -326,66 +343,208 @@ ss-tools предоставляет **готовую отлаженную инф
---
## Приложение A: Детальный breakdown по файлам
## Приложение A: Детальный breakdown по файлам (актуальная реализация)
### Бэкенд (31 файл, ~15 777 строк)
> В ходе реализации выполнена масштабная декомпозиция. Крупные модули (Orchestrator, Preview, Executor, Dictionary, Service) разбиты на 212 файлов каждый.
> Общий объём кода изменился незначительно, но количество файлов выросло с ~31 до 75 (backend source) + 23 (frontend) + 27 (tests) = 125 файлов.
### Бэкенд (75 файлов, ~13 187 строк source + ~8 487 строк тестов)
#### Plugin core (57 файлов, 9 017 строк source)
**Orchestrator (12 файлов, 1 571 строка)**
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `orchestrator.py` | 176 | Entry point / facade |
| `orchestrator_planner.py` | 128 | Run planning: target langs, batches |
| `orchestrator_exec.py` | 121 | Translation execution coordinator |
| `orchestrator_sql.py` | 118 | SQL generation stage |
| `orchestrator_sql_rows.py` | 116 | Row fetch + pagination |
| `orchestrator_aggregator.py` | 138 | Results aggregation |
| `orchestrator_retry.py` | 137 | Retry logic for failed batches |
| `orchestrator_cancel.py` | 120 | Run cancellation |
| `orchestrator_validation.py` | 61 | Post-run validation |
| `orchestrator_run_completion.py` | 132 | Run finalization (status, error_message) |
| `orchestrator_runner.py` | 76 | Background task runner |
| `orchestrator_lang_stats.py` | 88 | Per-language statistics |
| `orchestrator_query.py` | 113 | Query builder / data source queries |
| `orchestrator_config.py` | 47 | Configuration merging |
**Preview (12 файлов, 1 361 строка)**
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `preview.py` | 267 | Main facade: run, accept, reject |
| `preview_executor.py` | 149 | LLM call orchestration |
| `preview_llm_client.py` | 107 | Low-level LLM HTTP client |
| `preview_prompt_builder.py` | 133 | Prompt construction per language |
| `preview_prompt_helpers.py` | 113 | Prompt formatting utilities |
| `preview_response_parser.py` | 137 | Parse LLM responses |
| `preview_review.py` | 137 | Quality gate / approval logic |
| `preview_session_ops.py` | 94 | Preview session persistence |
| `preview_session_serializer.py` | 101 | Session serialize/deserialize |
| `preview_token_estimator.py` | 51 | Token budget estimation |
| `preview_constants.py` | 48 | Constants / defaults |
| `preview_resolve_provider.py` | 24 | LLM provider resolution |
**Executor / Batch / LLM (10 файлов, 1 643 строки)**
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `executor.py` | 256 | Main facade: batch dispatch, caching |
| `_llm_call.py` | 272 | Centralized LLM call with retry + fallback |
| `_llm_http.py` | 187 | HTTP transport for LLM APIs |
| `_llm_parse.py` | 117 | Parse LLM streamed responses |
| `_batch_insert.py` | 233 | Insert results to Superset datasource |
| `_batch_proc.py` | 189 | Batch processing coordination |
| `_batch_sizer.py` | 223 | Dynamic batch sizing by token budget |
| `_run_service.py` | 176 | Run create/update/status queries |
| `_run_source.py` | 141 | Source row fetching + pagination |
**Dictionary (8 файлов, 904 строки)**
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `dictionary.py` | 68 | Facade / re-exports |
| `dictionary_crud.py` | 136 | Create, read, update entries |
| `dictionary_entries.py` | 164 | Entry query + filtering |
| `dictionary_filter.py` | 131 | Per-batch dynamic filter construction |
| `dictionary_correction.py` | 192 | Correction CRUD + batch apply |
| `dictionary_import_export.py` | 196 | CSV import/export |
| `dictionary_validation.py` | 17 | Entry validation rules |
**Service (5 файлов, 918 строк)**
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `service.py` | 276 | Job CRUD + run coordination |
| `service_inline_correction.py` | 222 | Inline correction orchestration |
| `service_bulk_replace.py` | 189 | Bulk find-and-replace |
| `service_datasource.py` | 171 | Datasource metadata service |
| `service_utils.py` | 60 | Shared service utilities |
**Standalone modules (12 файлов, 2 620 строк)**
| Файл | Строк | Сложность | Назначение |
|------|:-----:|:---------:|------------|
| `plugins/translate/plugin.py` | 61 | C2 | Plugin skeleton (NotImplementedError) |
| `plugins/translate/orchestrator.py` | 1 137 | C5 | Run lifecycle coordinator |
| `plugins/translate/executor.py` | 1 974 | C4 | Batch LLM processing + caching |
| `plugins/translate/service.py` | 1 052 | C4 | Job CRUD + InlineCorrection + BulkReplace |
| `plugins/translate/preview.py` | 1 303 | C4 | Preview engine with quality gate |
| `plugins/translate/dictionary.py` | 1 007 | C4 | Dictionary CRUD + import + filtering |
| `plugins/translate/scheduler.py` | 436 | C4 | Schedule CRUD + APScheduler dispatch |
| `plugins/translate/sql_generator.py` | 378 | C3 | Dialect-aware SQL generation |
| `plugins/translate/superset_executor.py` | 420 | C3 | Superset SQL Lab API client |
| `plugins/translate/prompt_builder.py` | 153 | C3 | Context-aware prompt construction |
| `plugins/translate/metrics.py` | 192 | C3 | Metrics aggregation |
| `plugins/translate/events.py` | 272 | C5 | Structured event log + pruning |
| `plugins/translate/_token_budget.py` | 341 | C2 | Token estimation |
| `plugins/translate/_utils.py` | 33 | C1 | Term normalization |
| `api/routes/translate/_router.py` | 13 | C1 | APIRouter instance |
| `api/routes/translate/__init__.py` | 40 | C4 | Route package init |
| `api/routes/translate/_job_routes.py` | 249 | C3 | Job CRUD endpoints |
| `api/routes/translate/_run_routes.py` | 554 | C4 | Run execution endpoints |
| `api/routes/translate/_run_list_routes.py` | 225 | C3 | Run list/detail/CSV |
| `api/routes/translate/_preview_routes.py` | 194 | C3 | Preview endpoints |
| `api/routes/translate/_dictionary_routes.py` | 391 | C3 | Dictionary endpoints |
| `api/routes/translate/_correction_routes.py` | 100 | C2 | Correction endpoints |
| `api/routes/translate/_schedule_routes.py` | 239 | C3 | Schedule endpoints |
| `api/routes/translate/_metrics_routes.py` | 65 | C2 | Metrics endpoints |
| `api/routes/translate/_helpers.py` | 71 | C1 | Response helpers |
| `models/translate.py` | 397 | C2 | 15 ORM models |
| `schemas/translate.py` | 688 | C2 | 35+ Pydantic schemas |
| Тесты (19 файлов) | 8 678 | — | Unit + integration tests |
| Алембик (4 файла) | 586 | — | Migrations |
| `scheduler.py` | 443 | C4 | Schedule CRUD + APScheduler dispatch |
| `superset_executor.py` | 420 | C3 | Superset SQL Lab API client |
| `sql_generator.py` | 378 | C3 | Dialect-aware SQL generation |
| `_token_budget.py` | 342 | C2 | Token estimation |
| `events.py` | 272 | C3 | Structured event log + pruning |
| `_utils.py` | 206 | C1 | Shared utilities |
| `scheduler.py` | 443 | C4 | Schedule CRUD + APScheduler dispatch |
| `metrics.py` | 192 | C2 | Metrics aggregation |
| `prompt_builder.py` | 153 | C3 | Context-aware prompt construction |
| `plugin.py` | 61 | C2 | Plugin skeleton |
| `__init__.py` | 2 | | Package marker |
### Фронтенд (19 файлов, ~9 976 строк)
#### Routes (11 файлов, 2 141 строка)
| Файл | Строк | Сложность | Назначение |
|------|:-----:|:---------:|------------|
| API client (translate.js) | 664 | C2 | API wrapper |
| Store (translationRun.js) | 196 | C3 | Svelte 5 rune store |
| TranslationPreview.svelte | 561 | C4 | Preview component |
| TranslationRunResult.svelte | 464 | C4 | Run result display |
| BulkReplaceModal.svelte | 396 | C3 | Find-and-replace modal |
| TranslationRunProgress.svelte | 310 | C4 | Live progress |
| ScheduleConfig.svelte | 286 | C3 | Schedule editor |
| BulkCorrectionSidebar.svelte | 285 | C3 | Bulk correction |
| TermCorrectionPopup.svelte | 342 | C3 | Single correction popup |
| CorrectionCell.svelte | 326 | C3 | Inline editable cell |
| TranslationRunGlobalIndicator.svelte | 198 | C2 | Run indicator |
| TranslationMetricsDashboard.svelte | 184 | C2 | Metrics dashboard |
| +page.svelte (job list) | 279 | C3 | Job list page |
| [id]/+page.svelte (job detail) | 1 363 | C4 | Job config + run |
| history/+page.svelte | 523 | C3 | History page |
| dictionaries/+page.svelte | 270 | C3 | Dictionary list |
| dictionaries/[id]/+page.svelte | 821 | C3 | Dictionary editor |
| Тесты компонентов (3 файла) | 433 | — | Component tests |
| i18n (2 файла) | 1 223 | — | en + ru translation |
| E2E (1 файл) | 142 | — | End-to-end test |
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `__init__.py` | 40 | Package init + router registration |
| `_router.py` | 13 | APIRouter instance |
| `_job_routes.py` | 249 | Job CRUD endpoints |
| `_run_routes.py` | 554 | Run execution endpoints |
| `_run_list_routes.py` | 225 | Run list/detail/CSV |
| `_preview_routes.py` | 194 | Preview endpoints |
| `_dictionary_routes.py` | 391 | Dictionary endpoints |
| `_correction_routes.py` | 100 | Correction endpoints |
| `_schedule_routes.py` | 239 | Schedule endpoints |
| `_metrics_routes.py` | 65 | Metrics endpoints |
| `_helpers.py` | 71 | Response helpers |
#### Models + Schemas (2 файла, 1 085 строк)
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `models/translate.py` | 397 | 15 ORM моделей |
| `schemas/translate.py` | 688 | 35+ Pydantic схем |
#### Миграции (5 файлов, ~944 строк)
#### Тесты бэкенда
**Inline plugin tests (16 файлов, 6 029 строк)**
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `test_orchestrator.py` | 880 | Orchestrator unit tests |
| `test_inline_correction.py` | 792 | Inline correction tests |
| `test_executor.py` | 698 | Executor + LLM call tests |
| `test_orthogonal_fixes.py` | 616 | Edge case + regression tests |
| `test_preview.py` | 610 | Preview engine tests |
| `test_clickhouse_insert_integration.py` | 546 | CH insert integration |
| `test_scheduler.py` | 407 | Scheduler unit tests |
| `test_sql_generator.py` | 368 | SQL generation tests |
| `test_dictionary_filter.py` | 228 | Dynamic filter tests |
| `test_dictionary_crud.py` | 218 | Dictionary CRUD tests |
| `test_token_budget.py` | 195 | Token estimation tests |
| `test_dictionary_import.py` | 177 | Import/export tests |
| `test_dictionary_correction.py` | 124 | Correction tests |
| `test_dictionary_prompt_builder.py` | 111 | Prompt builder tests |
| `test_dictionary_utils.py` | 36 | Dictionary utility tests |
| `test_dictionary.py` | 20 | Dictionary facade tests |
**External integration tests (7 файлов, 2 458 строк)**
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `test_translate_jobs.py` | — | API job lifecycle |
| `test_translate_scheduler.py` | — | Scheduler integration |
| `test_translate_scheduler_execution.py` | — | Execution integration |
| `test_translate_scheduler_guard.py` | — | Guard/validation |
| `test_translate_corrections.py` | — | Correction API |
| `test_translate_history.py` | — | History API |
| `test_translate_executor_filter.py` | — | Executor filter logic |
### Фронтенд (23 файла source + 4 файла тестов, ~7 540 source + 575 тестов)
#### Компоненты (10 файлов, 3 280 строк)
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `TranslationPreview.svelte` | 561 | Preview component (quality gate) |
| `TranslationRunResult.svelte` | 464 | Run result display |
| `BulkReplaceModal.svelte` | 396 | Find-and-replace modal |
| `TermCorrectionPopup.svelte` | 342 | Single correction popup |
| `CorrectionCell.svelte` | 326 | Inline editable cell |
| `TranslationRunProgress.svelte` | 310 | Live progress with retry |
| `ScheduleConfig.svelte` | 286 | Schedule editor |
| `BulkCorrectionSidebar.svelte` | 285 | Bulk correction panel |
| `TranslationRunGlobalIndicator.svelte` | 198 | Global run indicator |
| `TranslationMetricsDashboard.svelte` | 184 | Metrics dashboard |
#### Страницы (5 файлов, 3 354 строки)
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `[id]/+page.svelte` | 1 363 | Job detail (config + run + results) |
| `dictionaries/[id]/+page.svelte` | 821 | Dictionary editor |
| `history/+page.svelte` | 523 | Run history |
| `dictionaries/+page.svelte` | 270 | Dictionary list |
| `+page.svelte` | 279 | Job list |
#### API client (6 файлов, 529 строк)
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `runs.js` | — | Run status/control API |
| `jobs.js` | — | Job CRUD API |
| `dictionaries.js` | — | Dictionary CRUD API |
| `corrections.js` | — | Correction API |
| `schedules.js` | — | Schedule API |
| `datasources.js` | — | Datasource API |
#### Store + i18n (2 файла, 377 строк)
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `translationRun.js` | 198 | Run state store |
| `i18n/index.ts` | 179 | en + ru translation keys |
#### Frontend-тесты (4 файла, 575 строк)
| Файл | Строк | Назначение |
|------|:-----:|------------|
| `test_bulk_replace_modal.svelte.js` | — | BulkReplace modal tests |
| `test_correction_cell.svelte.js` | — | CorrectionCell tests |
| `test_translation_preview.svelte.js` | 433 (все 3) | Preview component tests |
| `translation.e2e.js` | 142 | E2E: create run, check progress |
---

View File

@@ -0,0 +1,216 @@
# Спецификация: Сервис LLM-перевода табличных данных
**Дата**: 2026-05-18
**Назначение**: Передача сторонней команде для оценки трудозатрат
**Фокус**: только требования к конечному результату, без технологий
---
## 1. Фронтенд (Web-интерфейс)
### 1.1 Управление задачами перевода (Jobs)
- Список всех задач перевода с фильтрацией по датасорсу, целевой таблице, статусу.
- Создание новой задачи перевода:
- Выбор Superset-датасорса (источник данных).
- Выбор колонки для перевода (одна, обязательная).
- Выбор колонок контекста (ноль или более) — их значения передаются LLM для повышения качества.
- Выбор ключевых колонок (одна или более, composite key) — по ним данные будут сопоставляться при вставке в целевую таблицу.
- Указание целевой таблицы и целевой колонки.
- Выбор одного или нескольких языков перевода.
- Редактирование системного промпта (шаблон сообщения LLM).
- Выбор LLM-провайдера и модели.
- Прикрепление одного или нескольких справочников терминов.
- Указание стратегии UPSERT (skip_existing / overwrite / insert).
- Редактирование, копирование, удаление задачи.
### 1.2 Превью (Quality Gate)
- Запуск превью на ограниченной выборке строк (1100, по умолчанию 10).
- Отображение source-строк, контекста, обнаруженного языка оригинала и перевода на каждый целевой язык — рядом, в табличном виде.
- Approve / Edit / Reject для каждой строки превью.
- Повторный запуск превью с изменёнными настройками (промпт, язык, провайдер).
- Подтверждение превью (accept) — открывает возможность полного прогона.
- Предупреждение о стоимости перед запуском полного прогона (оценка токенов и цены).
### 1.3 Выполнение (Run)
- Запуск полного прогона (только после accepted превью).
- Живой индикатор прогресса: сколько строк обработано, успешно, с ошибками, процент выполнения.
- Возможность отмены прогона.
- Построчный просмотр результатов после завершения:
- Исходный текст, контекст, перевод по каждому языку.
- Статус каждой строки (OK / ошибка / пропущена).
- Сгенерированный SQL (для аудита).
- Статус вставки в Superset.
- Повтор проблемных batch-ей (retry failed).
- Inline-редактирование любой переведённой строки в результатах.
- Bulk Find & Replace по результатам прогона (с превью замен).
### 1.4 Очередь и планировщик
- Возможность настроить расписание для задачи:
- Одноразовый запуск в будущем.
- Интервальный (каждые N минут/часов/дней).
- Cron-выражение с выбором часового пояса.
- Scheduled-прогон создаёт новый Run и выполняет полный цикл.
- Для scheduled-прогонов: new-key-only (только новые строки, которых нет в последнем успешном прогоне).
- Если последний успешный прогон старше 90 дней — fallback на полный прогон.
- Защита от overlap: если предыдущий scheduled-прогон ещё выполняется — пропуск или очередь (1 в очереди).
- После N последовательных ошибок (по умолч. 3) — автоотключение расписания и уведомление.
### 1.5 История и аудит
- Список всех прогонов с деталями: датасорс, целевая таблица, кол-во строк, статус, кто запустил.
- Детальный просмотр прогона: configuration snapshot, промпт, результаты по строкам, сгенерированный SQL, Superset execution reference.
- Фильтрация по датасорсу, целевой таблице, дате, статусу.
### 1.6 Справочники терминов (Dictionaries)
- Создание справочника.
- Добавление пар «термин оригинала → перевод» с указанием языка оригинала и языка перевода.
- Импорт из CSV/TSV с превью, разрешением конфликтов (overwrite / keep / skip).
- Inline-редактирование, удаление записей.
- Прикрепление справочника к задаче перевода.
- Приоритет справочников (низкий номер = выше приоритет).
### 1.7 Коррекция и обратная связь
- Из любого завершённого прогона: клик на ячейку перевода → inline-редактирование.
- После редактирования: кнопка «Отправить в справочник».
- Popup с предзаполненными: исходный термин, старый перевод, новый перевод, язык оригинала (из строки), язык перевода (из колонки), context_data (из строк, автоматически), usage notes (вручную).
- Выбор целевого справочника (фильтр по языковой паре).
- Bulk-режим: массовое редактирование и отправка нескольких терминов за раз.
- Конфликт при повторной отправке: overwrite / keep existing / cancel.
---
## 2. Оркестратор (Run Lifecycle)
### 2.1 Жизненный цикл прогона
1. **Создание**: формируется snapshot конфигурации задачи + snapshot прикреплённых справочников.
2. **Планирование**: определяются целевые языки, размер batch-ей (динамически, по token budget), порядок обработки.
3. **Выполнение**:
- Выборка source-строк: для scheduled new-key-only — только новые ключи; для manual — все строки.
- Разбивка на batch-и.
- Для каждого batch:
a. Запрос к LLM с промптом, контекстом, отфильтрованными записями справочников.
b. Парсинг структурированного JSON-ответа.
c. Валидация: все ли строки batch переведены, нет ли дубликатов.
d. Если ошибка — запись в TranslationBatch как failed.
- После всех batch-ей: финализация (статус, error_message если все строки упали).
4. **Вставка (Insert phase)**:
- Генерация UPSERT SQL под диалект БД (определяется динамически из Superset connection).
- Отправка SQL через Superset SQL Lab API.
- Polling статуса выполнения.
- Запись результата (query reference, статус, ошибка).
5. **Завершение**: запись метрик, отправка уведомления (опционально), авто-dismiss через N секунд на UI.
### 2.2 Snapshot isolation
- Все прогоны используют snapshot конфигурации и справочников, взятый на момент старта.
- Изменения конфигурации во время выполнения прогона НЕ влияют на текущий прогон.
### 2.3 Retry
- Возможность повторно запустить только failed batch-и (не трогая успешные).
- При перезапуске можно сменить LLM-провайдера.
### 2.4 Data retention
- 90 дней — полная детализация (source-строки, переводы, SQL).
- После 90 дней — агрегация: только метаданные прогона и агрегированные метрики.
- Перед прунингом — сохранение cumulative snapshot метрик.
---
## 3. Перевод (LLM)
### 3.1 Multi-language
- Задача поддерживает N целевых языков (массив, а не один язык).
- LLM получает исходный текст один раз на batch и возвращает переводы для ВСЕХ целевых языков в одном JSON-ответе.
- Не нужно N отдельных LLM-вызовов.
### 3.2 Автоопределение языка оригинала
- LLM определяет язык каждой строки автоматически.
- Возвращает BCP-47 tag (например, "fr", "de", "und" для неопределённого).
- Пользователь НЕ указывает язык оригинала вручную.
### 3.3 Reference copy
- Если язык оригинала включён в список целевых языков — «переводом» для него будет исходный текст (verification copy).
### 3.4 Dictionary injection
- Перед каждым LLM-запросом выполняется per-batch фильтрация справочника:
- Отбираются только те записи, чей source_term встречается (case-insensitive substring match) хотя бы в одной строке batch-а.
- Учитывается языковая пара (source_language записи === detected_language строки, target_language записи === языка промпта).
- Отфильтрованные записи вставляются в промпт как authoritative glossary.
- Записи с совпадающим контекстом (context_data) помечаются priority.
### 3.4 Превью
- Quality gate, а не построчное утверждение.
- Принятие превью = одобрение настроек (промпт, языки, справочники), после чего полный прогон обрабатывает ВСЕ строки.
- Редактуры на уровне превью переносятся в полный прогон для тех же строк (carry-forward).
- Rejected строки превью исключаются из полного прогона (только если были в sample).
---
## 4. Справочники (Dictionaries)
### 4.1 Структура
- Справочник содержит пары «термин оригинала → перевод».
- Каждая запись имеет:
- source_term — термин на языке оригинала.
- target_translation — корректный перевод.
- source_language (BCP-47) — язык термина.
- target_language (BCP-47) — язык перевода.
- context_data (JSON, опционально) — значения контекстных колонок из строки, где был найден термин.
- usage_notes (текст, опционально) — заметки по использованию.
- has_context (boolean) — есть ли контекстные данные.
### 4.2 Привязка к задаче
- К задаче можно привязать несколько справочников.
- Порядок приоритета: чем меньше номер, тем выше приоритет.
- При конфликте (один source_term в нескольких справочниках) побеждает высший приоритет.
### 4.3 Per-batch фильтрация
- В каждый LLM-запрос включаются ТОЛЬКО те записи справочника, чей source_term:
- Встречается хотя бы в одной строке batch-а (substring match).
- source_language совпадает с detected_language строки.
- target_language совпадает с языком текущего промпта.
- Размер справочника не ограничен (фильтрация не даёт промпту расти бесконечно).
### 4.4 Контекстная приоритизация
- Если context_data записи совпадает с контекстом строки batch-а (Jaccard similarity > 50%) — запись помечается как priority_context.
- Priority-записи перечисляются первыми с пометкой # PRIORITY.
- Это soft signal для LLM, не хард-фильтр.
### 4.5 Коррекция через результаты прогонов
- Из любого завершённого прогона можно отправить исправление в справочник.
- context_data заполняется автоматически из строки, где был найден термин.
- Пользователь может отредактировать context_data, добавить usage_notes, убрать контекст.
- Если context_data превышает 500 токенов — обрезается с пометкой.
---
## 5. Обработка ошибок (Edge Cases)
- NULL в колонке перевода → пропуск строки с логированием.
- NULL в ключевой колонке → reject строки (не может быть вставлена).
- LLM вернул неожиданный формат → запрос структурированного JSON, валидация, failed batch.
- Все строки batch упали → run.error_message с деталями.
- Редактирование задачи во время выполнения прогона → не влияет на текущий прогон (snapshot isolation).
- Удаление справочника, привязанного к активной задаче → запрет, предупреждение.
- Scheduled прогон при недоступном датасорсе → запись ошибки, попытка следующего триггера.
- Неподдерживаемый диалект БД → блокировка выполнения с сообщением.
- Вставка через Superset SQL Lab вернула ошибку → insert_status = failed, error_message заполнен.