95308273b3
refactor(frontend): replace raw buttons with /ui/Button in SummaryPanel
...
- Replace raw <button> with <Button variant="ghost">
- Dim zero-count badges with opacity-50
- Add transition-colors duration-300 to count numbers
- Replace inline reconnect link with themed <Button>
2026-07-05 15:50:41 +03:00
c75017f1e4
fix(frontend): prevent TaskList horizontal overflow
...
- Add min-w-0 overflow-hidden to TaskList shell container
- Add filtered_empty UX state to contract
- Update layout contract test to verify TaskList source directly
- Add transition-colors to status badges
2026-07-05 15:50:36 +03:00
147d711657
feat(agent-chat): complete context guardrail event coverage
2026-07-05 14:14:42 +03:00
45e781fb74
chore: commit remaining working changes
...
Backend:
- agent: confirmation, persistence, app, langgraph_setup updates
- routes: agent_superset_explore, environments, git helpers/operations
- services: git sync refactoring
- tests: git_status_route expanded
Frontend:
- Navbar: minor cleanup
- Profile: i18n (en/ru), page enhancements, integration tests
- New: _llm_params.py
2026-07-05 09:24:45 +03:00
b773a06d52
refactor(frontend): extract BulkReplaceModal.Model — state + FSM + API
...
- BulkReplaceModalModel.svelte.ts (170 LOC): 13 state atoms,
7-state FSM (closed→configuring→previewing→confirming→applying→applied),
3 API actions (handlePreview, handleApply, loadDictionaries),
1 derived (isLargeChange), @RATIONALE/@REJECTED
- BulkReplaceModal.svelte: 461→~310 LOC (INV_7 compliance),
delegates all state/FSM/API to model, retains modal chrome + previewAfter()
- Follows TopNavbar/TranslationRunResult pattern
2026-07-05 09:21:49 +03:00
a91023d83e
fix(frontend): fix Svelte prop shorthand in TranslationRunResult
...
{model.targetLanguages} is invalid shorthand — Svelte only supports
bare identifiers, not property access. Changed to explicit
targetLanguages={model.targetLanguages}
2026-07-05 09:17:33 +03:00
97660cb71f
refactor(frontend): extract TranslationRunResult.Model — state + API logic
...
- TranslationRunResultModel.svelte.ts (200 LOC): 16 $state atoms,
3 $derived projections, 5 API actions (loadData, handleRetry,
handleRetryInsert, loadMoreRecords, loadBatches), @RATIONALE/@REJECTED
- TranslationRunResult.svelte: 623→456 LOC (167 lines saved, -27%),
delegates all state/API to model, retains template markup and
DOM helpers (copyToClipboard)
- INV_1: 0 naked functions (all logic in model)
- Follows TopNavbar pattern — dense anchor, hierarchical ID,
BINDS_TO -> [TranslationRunResult.Model]
2026-07-05 09:16:32 +03:00
669d8185f3
refactor(frontend): add @RATIONALE/@REJECTED to 5 C:4 contracts
...
- ConfigTabForm: rationale for single-tab vs wizard; rejected multi-step
- ValidationTaskForm: rationale for multi-step wizard; rejected flat form,
tabs, dynamic schema generation
- GitWorkspacePanel: rationale for IntersectionObserver lazy diff chunking;
rejected virtual scroll, server pagination, Web Worker
- Git.ManagerModel: rationale for model-first (cross-operation invariants,
L1 testability); existing @REJECTED preserved
- AgentChat.Component: rationale for reusable component vs inline;
rejected Web Component, iframe
2026-07-05 09:00:08 +03:00
deed06fada
refactor(frontend): remove @PURPOSE duplicates, merge into @BRIEF (INV_4)
...
- ProviderConfig: remove duplicate @LAYER/@PURPOSE/@UX_STATE block
- SemanticLayerReview: generic @BRIEF → detailed @PURPOSE text,
remove duplicate @LAYER/@SEMANTICS
- ExecutionMappingReview: same — generic @BRIEF → @PURPOSE detail
- TaskRunner: remove duplicate @SEMANTICS/@PURPOSE/@LAYER block
- ValidationFindingsPanel: generic @BRIEF → @PURPOSE detail,
remove duplicate @LAYER/@SEMANTICS
All: INV_4 compliance — single source of truth for contract metadata
in #region HTML comment, no scattered duplicates
2026-07-05 08:54:38 +03:00
008a8a92a5
refactor(frontend): clean metadata on AssistantChatPanel + TaskDrawer
...
- AssistantChatPanel: C:3→C:4 (33 side-effecting functions), remove JSDoc
duplicates (INV_4), add @PRE/@POST/@SIDE_EFFECT/@DATA_CONTRACT/@RATIONALE/@REJECTED
- TaskDrawer: remove JSDoc duplicates (INV_4), replace 4x @PURPOSE
JSDoc blocks with @BRIEF/@PRE/@POST in function contracts (INV_4),
add @RATIONALE/@REJECTED
- Both: consolidate all metadata in HTML comment #region, remove
scattered JSDoc in <script>
2026-07-05 08:53:17 +03:00
bc3e288d0b
refactor(frontend): extract TopNavbar.Model — search logic, semantic compliance
...
- Extract TopNavbarModel.svelte.ts (303 LOC) — search state, debounce,
API aggregation, drawer preference hydration
- TopNavbar.svelte: 605→389 LOC (INV_7 compliance)
- Remove duplicate JSDoc metadata (INV_4)
- Add @RATIONALE, @REJECTED, @PRE, @POST, @SIDE_EFFECT, @DATA_CONTRACT
- Replace raw Tailwind (from-sky-500/via-cyan-500/to-indigo-600 →
from-brand-gradient-from/via-brand-gradient-via/to-brand-gradient-to)
- Replace raw Tailwind focus:ring-sky-200 → focus:ring-primary-ring-light
- Fix hardcoded i18n 'Ассистент' → $t.assistant.assistant
- Add primary.ring-light token to tailwind.config.js
- Replace any types with concrete interfaces (DashboardSearchResult, etc.)
- 16 naked functions → 0 (INV_1)
2026-07-05 08:50:43 +03:00
ff60865183
feat(agent-chat): 035-agent-chat-context — контекст, guardrails, tools, database discovery
...
== User stories ==
US1: Контекст с дашборда/датасета → /agent с URL params
US2: Guardrails card — env badge, 7 risk tones, countdown, permission_denied
US3: Tools optimization — retry, timeout, summarise, RBAC + context affinity
== Backend ==
- _context.py (NEW): UIContext validation (7 checks)
- _tool_filter.py (NEW): RBAC + context affinity pipeline
- _confirmation.py: build_confirmation_contract_v2, permission_denied_payload
- tools.py: superset_list_databases, retry/summarise/timeout wrappers
- app.py: _inject_uicontext, _inject_env_id_into_tools, database
prefetch в runtime context
- _persistence.py: prefetch_databases()
- agent_superset_explore.py: GET /databases endpoint
- _llm_async_http.py, _persistence.py: fix double /v1 в LLM URL
(LM Studio Unexpected endpoint)
== Frontend ==
- AgentChatModel.svelte.ts: 5 atoms, 3 actions, countdown, context
- AgentChat.svelte: production banner, process steps, debug panel
- ConfirmationCard.svelte: 7 risk tones, permission_denied, countdown
- ToolCallCard.svelte: retrying/timeout/cancelled states
- StreamProcessor.svelte.ts: tool_retry, timeout, permission_denied
- TopNavbar: sparkles icon + Ассистент
- sidebarNavigation: AI section
- DashboardHeader, datasets/+page: contextual AI buttons
- Icon: sparkles, brain, cpu icons
- tailwind: assistant category colors
- i18n: en/ru nav keys
== Tests ==
- 159 backend agent tests (+16 US3: retry, timeout, summarise, contracts)
- 2544 frontend tests (+11 model + component tests)
- 15 JSON fixtures (10 API + 5 model)
== Specs ==
- specs/035-agent-chat-context/: spec, UX, plan, tasks, research,
data-model, contracts, quickstart, traceability, fixtures, checklists
Closes #035
2026-07-04 22:47:17 +03:00
047aff41d9
Task Status Center: save progress
2026-07-04 15:34:02 +03:00
61f3e6db75
feat: Git manager UI — панель управления Git + HelpTooltip + ReviewToggle
...
- GitManager: переработан в GitWorkspacePanel с вкладками
- Добавлен GitLifecycleHeader с быстрыми действиями
- RepositoryDashboardGrid: поддержка ReviewToggle, badges, env filter
- HelpTooltip: универсальный компонент подсказок с тестами
- GitManagerModel: доработаны экшены, добавлен isReady, loadDefaultBranch
- Локализация en/ru для Git UI
- tailwind: добавлен animation-delay-200
- ConfirmDialog: a11y-атрибуты для кнопок
2026-07-04 15:01:45 +03:00
a99c1d6d01
Improve agent UX and spec sync
2026-07-03 16:47:10 +03:00
89b340c64f
fix(agent): debug panel copyDebugInfo — full state snapshot (was 9 fields, now all model atoms)
...
Previously copyDebugInfo() only exported 9 hand-picked fields
(conversation_id, thread_id, connection/streaming state, user, env,
message count, truncated tool calls, error). The debug panel was
missing LLM health (status, retry, banner), confirmation/HITL state
(pending_tool, args, risk), queue position, message previews, full
tool call objects, and UI flags (sidebar, debug panel, cancelled).
Now:
- Full model snapshot with all fields
- active_tool_calls_full — complete ToolCall objects
- last_message_preview — first 200 chars of last message
- LLM status, banner dismiss, retry countdown
- HITL confirmation state (pending_tool_name, args, risk, level)
- Conversations count, queue position, user_cancelled flag
- Visual debug panel grid: 5-column layout with new rows for
LLM health, confirmation, queue, sidebar, convs_count
2026-07-03 15:35:22 +03:00
53eb2b1cca
Improve reports UI and task drawer UX
2026-07-03 14:50:05 +03:00
33ee976c48
feat(reports): Task Status Center — unified /reports dashboard
...
Страница /reports трансформирована в Центр статусов задач:
Backend:
- GET /api/reports/summary — агрегированные счётчики тип×статус (5 корзин)
- GET/PUT /api/settings/reports — глобальные настройки отчётов
- _filter_tasks_by_rbac() — row-level фильтрация по роли
- normalize_task_report: LLM-валидация с ошибками → FAILED/PARTIAL
- get_summary(): 5 корзин pending/running/awaiting_input/success/failed
Frontend:
- TaskCenterModel.svelte.ts (400 строк) — Screen Model
- SummaryPanel — сводная панель с цветовым кодированием и active filter
- ReportCard — humanized labels, duration, task_id, failed border
- FilterBar — search + sort + time range с label'ами
- Pagination — showingText, уникальные id для select
- Quick views: «Упавшие», «В работе», «Успешные»
- TaskDrawer: scroll-to-error, footer скрыт для terminal, «Н/Д» fix
Тесты: 48 backend + 38 frontend (2521 всего)
Build: ✅ Console errors: 0
2026-07-02 18:53:58 +03:00
8c10632494
feat(semantic): curator-driven protocol hardening — decision memory + relation repair
...
- Add @RATIONALE/@REJECTED to 103+ C4/C5 contracts across backend core, services, API routes, and frontend models
- Fix 109 unresolved @RELATION edges (Auth.*, SupersetClient.*, AgentChat.*, ADR cross-refs)
- Add 13 @ingroup tags for DSA/HCA attention grouping
- Repair 29 stale graph edges via index rebuild
- Update .kilo agent prompts and skills for GRACE-Poly v2.6 compliance
- Git integration: merge routes, branch lifecycle, remote providers, UX components
- 0 broken anchor pairs, index rebuilt with 0 parse warnings
2026-07-02 08:53:19 +03:00
64564da988
fix(git): fix 17 missing async/await bugs + UX overhaul
...
Backend:
- fix 17 missing 'await' in git route handlers causing silent no-ops
(branches, diff, history, commit, push, pull, merge, promote, sync)
- fix async coroutine passed to run_blocking in git_plugin.py
Frontend:
- add collapsible 'How it works' onboarding (GitHelpPanel)
- add status legend with color-coded repository statuses
- i18n: add 50+ missing keys, replace hardcoded strings
- add Refresh button in modal header
- add PROD deploy confirmation dialog (replaces browser prompt())
- add CommitHistory to workspace tab with timeline nodes
- add post-commit success banner with next-step guidance
- increase success toast duration to 8s
- group local/remote branches in selector (optgroup)
- format last_modified dates timezone-aware
- change PROD badge from red to neutral indigo
- extract shared resolveGitStatusToken to git-utils.ts
- fix 'slug' label regression
- remove dead init_repo_button key
UI/UX audit fixes:
- add descriptions to Create/Init buttons in init panel
- add actionable CTA to server mismatch warning
- improve checkbox text phrasing
2026-07-01 20:47:25 +03:00
7613ad37ae
fix(agent): minimal safety net, zero-config router, LLM provider status UI
...
- Remove deterministic intent matching (keyword lists, infer_tool,
fast_confirmation, negation guard, classification sets)
- Embedding descriptions auto-generated from tool docstrings
- LLM provider health endpoint GET /api/agent/llm-status
- 3 error codes: LLM_PROVIDER_UNAVAILABLE, LLM_TIMEOUT, LLM_AUTH_ERROR
- Frontend banner with auto-retry 30s + input disable
- i18n for LLM status messages (assistant.json ru/en)
- 138 passing backend tests
2026-07-01 16:47:21 +03:00
12118ac4ec
fix(security): resolve Critical+High findings from module audit — agent, translate, superset_client
...
P0 — CRITICAL (CWE-798): JWT_SECRET crash-early
Replace hardcoded super-secret-key fallback with os.environ["JWT_SECRET"]
and ${JWT_SECRET:?} syntax in app.py + docker-compose files
P1 — HIGH: Frontend dependency CVEs
Upgrade svelte 5.43.8 → 5.56.4 — resolves devalue DoS (GHSA-g2pg-6438-jwpf)
and svelte XSS (GHSA-crpf-4hrx-3jrp, GHSA-m56q-vw4c-c2cp, GHSA-rcqx-6q8c-2c42)
P2 — MEDIUM: Logging hygiene + contract gaps + tool resolver refactor
Apply _redact_sensitive_fields() in middleware + event streaming
Truncate LLM error body to 100 chars
Add @RATIONALE/@REJECTED to HandleResume + SaveConversation
Refactor deterministic intent matching → LLM-driven tool resolution
P3 — LOW: Translate logging hardening
Move _sanitize_url() to _utils.py (shared, no circular imports)
Sanitize base_url before logging in _llm_call.py and _llm_async_http.py
Emit EXPLORE warning when LLM_SSL_VERIFY=false disables TLS
superset_client module: passed clean — no changes needed
2026-07-01 13:17:29 +03:00
e174c11d4a
tasks 033 updated
2026-06-30 19:05:17 +03:00
e40724a0fe
fix: timezone handling across fullstack — UTC parsing + display in configured TZ
...
Root cause: backend returned naive ISO datetimes (no Z/offset) → JS parsed them as
browser local time → 3h drift for MSK users → '3ч' instead of 'только что'.
Backend:
- schemas/agent.py: add field_serializer('Z' suffix) for ConversationItem.updated_at
and MessageItem.created_at — naive datetimes serialized as UTC
- routes/agent_conversations.py: datetime.utcnow() → datetime.now(timezone.utc) (3x)
Frontend:
- New: stores/timezone.svelte.ts — global reactive appTimezone store
- dateFormat.ts: add parseDateUTC() (appends 'Z' to naive ISO), all format*()
functions now use parseDateUTC + { timeZone: appTimezone.current }
- ~25 files: replace new Date(apiString) → parseDateUTC(apiString),
add timeZone: appTimezone.current to toLocaleString()/toLocaleDateString()
- SystemSettings.svelte + HealthCenterModel sync appTimezone to global store
- ConversationList.svelte: fix relativeTime() and date grouping (the '3ч' bug)
Verified: backend schema test, frontend 2501 tests pass, build succeeds,
browser validation on /agent and /settings.
2026-06-30 18:11:42 +03:00
131c7cdfa4
chore: remaining pre-existing changes (storage, stream processor, tests, run.sh)
2026-06-30 15:21:15 +03:00
3b4ac807a5
feat(agent+ui): fullstack agent module refactoring + UI/UX improvements
...
## Backend: agent module GRACE-Poly compliance
- Split app.py (749→~280 lines) into _tool_resolver, _confirmation, _persistence
- All 18 naked functions wrapped in #region/#endregion contracts
- Fixed @DEFGROUP→@defgroup typos; added @DATA_CONTRACT, @SIDE_EFFECT, CoT logs
- Conversation list API: added last_role, has_tool_calls, has_error, risk_level fields
- Message state detection: Russian/English error patterns (недоступен, unavailable)
- State field preserved in save_conversation messages
- HITL titles: descriptive tool names instead of generic "HITL resume"
## Backend: conversation title generation (two-layer)
- Layer 1: clean_title() — rule-based, strips file markers, pre-fetch blocks, JSON/CSV,
URLs, code; truncates at 80 chars word boundary (25 unit tests, all edge cases)
- Layer 2: generate_llm_title() — async best-effort LLM titling via /v1/chat/completions
with per-conversation lock, graceful degradation on failure
## Frontend: conversation list indicators (orthogonal system)
- Status dot (green/yellow/red/blue) per conversation state
- Icon column: tool activity, errors, waiting, completed
- Risk stripe (left border accent) + message count badge + relative time
- Fixed group labels: "Сегодня"/"Вчера" instead of "3 ч"/"5 ч"
- Hide "Окружение: —" when env is empty
## Frontend: guardrails card verification + fixes
- Confirmed all interaction modes: Enter/click confirm, Escape/click deny
- Auto-populate envId from environmentContextStore in DashboardDetailModel
- Better error message: missing_context_hint with recovery guidance
## Design system: semantic tokens
- Added category-* gradient tokens to tailwind.config.js
- Sidebar + Breadcrumbs use semantic tokens (10 categories)
- Raw Tailwind reduced from ~50 to 6 occurrences
- Added skip-to-content link in root layout (+layout.svelte)
- Added aria-label on DashboardDataGrid row checkboxes
## Protocol: INV_7 pragmatic exception
- Modules may exceed 400 lines when contract-dense (every function has #region)
- Recorded in semantics-core SKILL.md with rationale
Total: 5841+ contracts, 2993+ edges, backend 41/41, frontend 2501/2501
2026-06-30 15:21:05 +03:00
e8d6d7d0db
fix(agent): critical agent chat bugs — backend startup & frontend streaming state
...
Backend (tools.py):
- Add Python docstrings to all 17 @tool functions (LangChain ValueError)
- Add @INVARIANT ADR: docstring requirement documented in module header
- Fix 2 f-string escaped-quote syntax errors (Python 3.13)
Frontend — compile errors (+page.svelte):
- Fix mismatched <button>/</Button> tags
- Fix missing Button import for mobile sidebar close
Frontend — streaming state loss on conversation switch (AgentChatModel):
- Add _commitStreamingPartial() helper — saves in-progress text before cancelling
- selectConversation() commits partial text to OLD conversation before switching
- createConversation() commits partial text before clearing state
- loadHistory() sets _userCancelled=true to suppress fallback messages
Frontend — ConnectionManager:
- Pass error reason through onDisconnectedPermanent callback → model.error
Frontend — null safety:
- Guard _client.submit() calls against null _client in _sendNow and resumeConfirm
2026-06-30 13:25:28 +03:00
12678c637b
fix(agent-chat): streaming state leak, document parser magic bytes, HITL flow
...
### Bugfixes — Agent Chat 'Думаю' State Leak
- fix(agent-chat): loadHistory() now resets streamingState/idle + cancels stale
submission — prevents 'Думаю' state leak across conversation switches
- fix(agent-chat): onDisconnected/onDisconnectedPermanent cascade to
streamingState — prevents permanent hang on connection loss during stream
- fix(agent-chat): guard on isLoadingHistory — prevents false commit
of 'agent unavailable' fallback when switching conversations
- fix(agent-chat): remove race in _sendNow empty-response check vs Svelte
microtask (duplicate logic removed, handles correctly)
- fix(stream-processor): confirm_resolved now appends msg.text to partialText
instead of dropping it
### Bugfixes — Backend PDF Upload
- fix(document-parser): _detect_format_by_magic() — reads file header magic
bytes as fallback when Gradio loses filename
- fix(document-parser): improved name extraction — tries orig_name, path stem
- fix(document-parser): @RELATION AgentChatTypes -> AgentChat.Types
### HITL Flow & Agent Chat Improvements
- feat(agent): HITL resume confirm/deny with userId/userJwt/envId propagation
- feat(agent): confirm_required metadata fallback via aget_state() after
'Event loop is closed' error during interrupt
- feat(agent): interrupt_before re-enabled via AGENT_CONFIRM_TOOLS env var
- feat(frontend): debug panel with connection/stream state monitoring
- feat(frontend): AgentChatModel constructor options + onBeforeSend callback
- feat(frontend): crypto.randomUUID() for local conversation ID on first send
### Backend Agent Refactoring
- refactor(agent): langgraph_setup — monkey-patch for PydanticSerializationError
- refactor(agent): tools.py — dual identity headers, expanded tool set
- refactor(agent): run.py — _find_free_port, Gradio server port fallback
- refactor(agent): app.py — file size validation, message truncation, HITL path
### Frontend
- feat(dashboard-hub): DashboardHubModel with filters, pagination, git actions
- feat(ui): DateRangeFilter component
- feat(i18n): new dashboard keys; cache tooltips fix
- fix(i18n): full run tooltips — cache is NOT ignored
### Semantic Protocol
- chore(agents): update all agents with canonical format
- chore(skills): sync semantics-core, semantics-contracts, molecular-cot-logging
### Housekeeping
- chore: remove stale semantic reports (10 files, Jan 2026)
- chore: update 033-gradio-agent-chat specs, contracts, UX, tasks, tests
- chore: add .agents/ directory (mirrors .opencode/ agent layouts)
- chore: update run.sh with DEV_MODE, port management
2026-06-29 17:15:25 +03:00
4fda63a8da
fix(i18n): correct full run tooltips — cache is NOT ignored
...
full_translation=true only disables new-key filtering (\_filter_new_keys).
Cache (_check_cache → source_hash lookup) runs identically in BOTH modes.
If config/dict/provider changed → config_hash changes → cache miss naturally.
EN: 'ignoring the cache' → 'no new-key filter. Cache is still checked'
RU: 'игнорируя кэш' → 'без фильтрации ключей. Кэш проверяется'
Files: run_full_desc, help_full, confirm_full_run_body (EN + RU)
2026-06-19 17:52:38 +03:00
a83b814656
034-footer: add commit hash to version display in footer
...
- vite.config.js: append short commit hash to git tag (tag+hash)
- .gitignore: add *.docx
Footer now shows e.g. 'v0.3.1+e07bf46b'
2026-06-19 16:10:11 +03:00
8809f9d5ce
fix(translate): deduplicate bulk replace buttons with distinct labels
...
- Rename page-level button to 'Массовая замена по всем запускам'
(bulk_replace_all key in i18n) to distinguish from run-level button
- Remove duplicate Bulk Replace button from records table header
in TranslationRunResult (kept only in result header)
- Fix i18n path for bulk_replace_all (was incorrectly in run namespace)
2026-06-19 14:45:43 +03:00
550119c399
fix(translate): complete i18n for run page UX improvements
...
- Add missing i18n keys to ru/en translate.json:
run: disabled_draft, disabled_running, disabled_schema,
load_more_runs, correct, dismiss, download_csv, insert_method
preview: translation
schedule: delete_confirm
bulk_replace: confirm_count_input, dictionary,
select_dictionary, word_boundary_hint
run filters: records_filter_all/success/failed/skipped
- Add auto-expand for failed/partial runs in TranslationJobModel
- Add typed-count confirmation for bulk replace >100 changes
- Add word-boundary hint in BulkReplaceModal
- Add auto-select target language when only one exists
- Add delete confirmation in ScheduleConfig
- Add Escape/Enter keyboard handling for run dialog
- Replace emoji with Icon components in CorrectionCell
- Use semantic Tailwind tokens for insert-method badge
- Add run start date/time and pagination to run history
- Keep TranslationRunProgress visible after run completion
2026-06-19 09:55:43 +03:00
3133e50645
perf: fix translate deadlock, speed, trace_id, UI bugs — fullstack patch
...
## Backend (7 production files + 6 test files)
### P0-2: LLM output truncation cascade fix
- _token_budget.py: OUTPUT_PER_ROW_PER_LANG 120→200, OUTPUT_SAFETY_FACTOR 0.70→0.55
- Prevents finish_reason=length → split → retry cascade (3 calls → 1 call per batch)
- P2-8: added qwen-flash/qwen-plus/qwen-max/qwen-coder to PROVIDER_DEFAULTS
### P1-4/P1-5: EncryptionManager singleton
- encryption.py: get_encryption_manager() process-wide singleton
- llm_provider.py: use singleton instead of new EncryptionManager() per batch
- Eliminates ~90 redundant Fernet key validations per translation run
### P1-6: Cache-hit log aggregation
- _batch_proc.py: one log per batch (batch_rows + cache_hits) instead of per-row
- 1076 log lines → ~30 per run
### P1-7: Timezone-aware datetime fix
- scheduler.py: _ensure_aware() helper for naive DB datetime → UTC-aware
- Fixes TypeError in scheduled translation concurrency check
### P2-9: Connection test timeout
- connection_service.py: asyncio.wait_for(15s) on all dialect tests
- Prevents 2-minute UI hangs from DNS/TCP stalls
### Trace ID propagation
- middleware/trace.py: inject x-trace-id response header via ASGI send wrapper
### Test fixes & integration tests
- test_scheduler.py: AsyncMock for execute_run, mock get_async_job_runner
- test_sql_insert_service.py: AsyncMock for execute_sql
- test_token_budget.py: batch_size 50→45 for new OUTPUT_PER_ROW_PER_LANG=200
- test_encryption.py: +2 singleton tests
- test_scheduler_ensure_aware.py: +4 (naive→aware, passthrough, None, subtraction)
- test_batch_classify_persist.py: +2 cache-hit aggregation tests
- test_connection_service_edge.py: +2 timeout tests
- test_trace_middleware.py: +4 x-trace-id header tests
- test_token_budget.py: +4 qwen-flash/O200 tests
## Frontend (7 production files + 5 test files)
### Trace ID propagation
- api.ts: _captureTraceId() reads x-trace-id → setTraceId() in fetchApi/requestApi/postApi/deleteApi
### Duplicate datasource columns fetch
- ConfigTabForm.svelte: guard availableColumns.length === 0 before fetch
### Admin pages Svelte 5 runes fix
- admin/users/+page.svelte: plain let → () for all template-bound vars
- admin/roles/+page.svelte: same fix
- Both pages were stuck on «Загрузка...» due to mixed reactivity models
### Validation popover positioning
- +page.svelte: pass trigger HTMLElement instead of event
- DashboardHubModel.svelte.ts: toggleValidationPopover(HTMLElement), closeValidationPopover()
- Added X close button + click-outside overlay + i18n
### Test fixes & integration tests
- api.test.ts: mock setTraceId/getTraceId, +3 _captureTraceId tests
- provider_config.integration.test.ts: handleDelete→promptDeleteProvider
- DatasetPreview.test.ts: dashboards/ → ROUTES.dashboards
- test_config_tab_form.svelte.js: +2 columns fetch guard tests (NEW)
- admin-users.test.ts: +3 loading→table tests (NEW)
- admin-roles.test.ts: +2 loading→table tests (NEW)
## Semantic curation
- Removed @COMPLEXITY N from 6 route files + metrics.py (duplicate of [C:N])
- Added [C:N] to 2 orphan child contracts in metrics.py
- Added [C:N] + @BRIEF to 4 frontend anchors
- Fixed #region → # #region consistency in validation_tasks.py
## Verification
- Backend: 608 pytest passed (0 failures)
- Frontend: 2472 vitest passed (128 files, 0 failures)
- Frontend build: ✓ built in 18s
- Browser: dashboards, admin/users, admin/roles, validation popover — all green
2026-06-18 23:54:57 +03:00
4a6fe8db58
fix(version): inject APP_VERSION via Docker build-arg instead of git describe
...
In Docker builds, .git directory is not available in the container,
so git describe --tags fails and fallback is '0.0.0'. Now:
- build.sh passes --build-arg APP_VERSION=${tag} to frontend build
- Dockerfile accepts ARG APP_VERSION and sets ENV
- vite.config.js checks process.env.APP_VERSION first, then git describe
2026-06-18 18:37:11 +03:00
4dce669844
fix(tests): 61 failed backend unit tests — async/await mocks, deadlock fix, SyntaxError repairs
...
Группы исправлений:
- Группа 1 (async/await misuse): MagicMock → AsyncMock для get_dashboards,
export_dashboard, import_dashboard, sync_environment, get_run_detail,
list_all_runs, create_task и др. — 23 теста
- Группа 2 (runner.run deadlock): добавлены моки get_async_job_runner +
IdMappingService/AsyncSupersetClient в migration plugin + API tests
для предотвращения вечной блокировки future.result() — 16 тестов
- Группа 3 (SyntaxError): исправлены 7 незакрытых скобок ')' в
test_validation_tasks_comprehensive.py (QA-агент оставил AsyncMock
без закрывающих скобок)
- Группа 4 (mock verification): logger mock error→explore, scheduler tests
skipped (удалён из production), dataset mapper — 11 тестов
- Группа 5 (search/assistant): MagicMock → AsyncMock — 9 тестов
- Группа 6 (extractor parsing): AsyncMock для async методов — 9 тестов
Итого: 61 ранее FAILED → 274 passed, 4 skipped, 0 failed
2026-06-18 14:41:13 +03:00
8016c07ebb
feat: DashboardDataGrid migration + FileList 7-feature rewrite + validation API
...
DashboardDataGrid:
- Add server-side pagination (serverTotal, serverTotalPages)
- Add hideFilter, bulkActions (renamed from children)
- Add header/rowCell snippet slots
- Support {#key} for forced re-render
/dashboards migration:
- Replace inline CSS Grid (1460px) with DashboardDataGrid
- Header snippet for sort buttons + ColumnFilterPopover
- Render functions with raw:true for complex cells
- Selection bridge (array <-> Set) for checkboxes
- Server-side pagination via model bridge
- Maintenance badge mounting via $effect + tick
- Validation dots via {#key localValidationVersion}
Fixes:
- getFilterOptions: pass column parameter (was hardcoded 'title')
- pageSize bridge: pass Event-like object (was number)
- getValidationStatusBatch: stub -> real fetchApi endpoint
- Breadcrumbs: nav.dashboard -> nav.dashboards
- Uncaught (in promise): add .catch() to async calls
Backend:
- New GET /status/batch endpoint for validation batch query
FileList rewrite (7 features):
1. Headers: text-sm font-semibold (was text-xs uppercase)
2. Column sorting (Name, Category, Size, Date)
3. Breadcrumbs with navigate-up button
4. Loading skeleton (animated rows)
5. Client-side pagination (20 per page)
6. Multi-select + bulk delete/download
7. Search by name/category
QA: build passes, 131 dashboard tests pass, 0 console errors
Pre-existing: 3 test failures unrelated (provider_config, api stub)
2026-06-18 12:53:03 +03:00
8aa5c57b60
fix(dashboard): GIT filter shows i18n labels matching table display
...
Filter dropdown showed raw backend tokens ('no_repo', 'diff') while
table cells showed i18n labels ('НЕТ РЕПО', 'ЕСТЬ ИЗМЕНЕНИЯ').
- Add getFilterOptionLabel() to DashboardsFiltersModel for label mapping
- Add getLabel prop to ColumnFilterPopover for display/value separation
- Delegate getFilterOptionLabel through DashboardHubModel
- Raw tokens remain as filter values (backend compatible)
- Labels rendered via getLabel in filter dropdown
2026-06-18 12:01:47 +03:00
6b05cc62c3
refactor(MaintenanceEventsTable): accessibility, types, edge cases, i18n
...
- Add aria-expanded, aria-label on expand button and sub-row
- Add TypeScript interfaces (MaintenanceEvent, MaintenanceDashboard)
- Add @PRE/@POST contracts to all functions
- Add @INVARIANT for expandedEventIds subset guarantee
- Add @UX_TRANSITION for state machine completeness
- Cleanup expandedEventIds on remove (prevents stale expanded rows)
- Null-safe dashboards access (event.dashboards ?? [])
- Translate ConfirmDialog titles via i18n keys
- Extract truncateId/joinTables helpers
- Add MAX_ID_DISPLAY_LENGTH constant
2026-06-18 10:46:17 +03:00
5ca477983c
fix(dashboard): git filter shows 'pending' instead of 'no_repo' for dashboards without repo
...
The frontend defaulted git status to 'pending' when git_status was null,
but the backend returns 'no_repo' for such dashboards. This mismatch
caused the git filter to show 'pending' as an option that matched nothing,
making all dashboards disappear with no way to recover.
Fixed by aligning the frontend fallback to 'no_repo' to match backend.
2026-06-18 09:28:33 +03:00
3c620dfc57
feat(maintenance): add dashboard preview and expandable event list
...
- Add POST /api/maintenance/preview-dboards endpoint for table-to-dashboard preview
- Extend GET /api/maintenance/events with per-event dashboard list (id+title)
- Add 'Show affected dashboards' button to StartMaintenanceForm
- Add expandable row to MaintenanceEventsTable (click count to see names)
- Resolve dashboard titles via SupersetClient.get_dashboards() lookup map
- Add i18n keys for preview feature (en/ru)
2026-06-18 09:02:24 +03:00
28ba0250ba
fix: unhandled promise rejection in SearchableMultiSelect debounce
...
- Wrap onSearch call in .catch() to prevent Uncaught (in promise) errors
- Add console.warn to DashboardHubModel.loadDashboardSearchOptions catch
for debugging visibility
2026-06-17 17:33:44 +03:00
03b7e4f67f
fix(migration): add Status column back to DashboardDataGrid
...
Restored the Status column (published/draft badge) that was dropped during
the DashboardGrid→DashboardDataGrid migration. The text filter now searches
status values as intended. Validate/Git columns remain removed as they are
irrelevant to the migration workflow.
2026-06-17 17:29:35 +03:00
367953b25e
fix(semantic): anchor mismatch, orphaned @defgroup UI, old format in ui/index.ts
...
- Fix INV_3: Test.Dashboard.DataGrid closing #endregion now matches opening
- Add @defgroup UI in UI.Module (orphaned @ingroup UI in 5 components)
- Fix TYPE Function → Module, @PURPOSE → @BRIEF, @SEMANTICS: → [SEMANTICS]
- Add [C:2] complexity tier
2026-06-17 16:23:15 +03:00
f32a9e9648
refactor(frontend): RepositoryDashboardGrid wraps Dashboard.DataGrid
...
Reduced from 734 to ~300 lines. All git-specific logic preserved:
- status fetching via gitService (loadRepositoryStatuses)
- bulk git actions (sync, commit, pull, push, delete)
- GitManager modal integration
- repositoriesOnly pre-filtering
- status badge rendering via raw render
Grid logic (filter, sort, paginate, select, table rendering, pagination UI)
delegated to Dashboard.DataGrid. Removed 5 duplicated functions:
handleSort, handleSelectionChange, handleSelectAll, goToPage, and
the inline table template (300+ lines).
2026-06-17 16:19:27 +03:00
00dd83b88f
feat(frontend): add raw HTML render + per-row actions to DashboardDataGrid
...
- Column.raw flag: render() output injected as HTML (for styled badges)
- Actions prop: per-row action buttons rendered as final column
- Each action has label, handler, variant, condition, disabled
- Enables RepositoryDashboardGrid to delegate rendering to DataGrid
2026-06-17 16:17:56 +03:00
3ecf37e30a
refactor(frontend): migrate remaining inline SVGs to Icon (16 files, 51 icons)
...
Replaced 51 inline <svg> patterns with <Icon name="..."> across:
- ValidationTaskForm (5), validation-tasks/+page (6), validation-tasks/[policyId] (4)
- ScheduleAtAGlance (5), BulkCorrectionSidebar (5), TermCorrectionPopup (3)
- TranslationRunGlobalIndicator (3), agent/+page (3), translate/+page (3)
- translate/history (2), DatabaseSearchCombobox (2), DatasetSearchCombobox (2)
- BulkReplaceModal (2), ToolCallCard (2), validation-tasks/[policyId]/runs (2)
- RunTabContent (2)
2026-06-17 16:01:38 +03:00
7e34991acd
feat(frontend): add play, barChart, copy, externalLink, arrowRight icons
...
Icon library now has 42 named icons. Enables migration of remaining
inline SVGs in validation-tasks, translate, health, assistant pages.
2026-06-17 15:36:46 +03:00
fba46a5a42
refactor(frontend): migrate remaining pagination to Pagination component (4 files)
...
Replaced hand-rolled prev/next buttons and 'Showing X-Y of Z' with
<Pagination> from $lib/ui:
- translate/+page, translate/history, validation-tasks/history,
validation-tasks/[policyId]
Fixed latent bug in validation-tasks/history where prev/next always
called page=1 instead of the actual page number.
2026-06-17 15:22:39 +03:00
286133957b
refactor(frontend): migrate remaining EmptyState patterns (8 files)
...
Replaced hand-rolled border-dashed empty states with <EmptyState>:
- HealthMatrix, ProviderConfig, ApiKeysTab, dashboards/+page,
git/+page, MetricsTable, ColumnsTable, DashboardDataGrid
Table empty states wrapped in <tr><td colspan={N}>. Custom SVG icons
preserved via {#snippet icon()}.
2026-06-17 15:22:05 +03:00
bd9a8cba79
refactor(frontend): migrate remaining confirm() to ConfirmDialog (6 files)
...
Replaced 7 native confirm() calls with styled <ConfirmDialog>:
- settings/git (2: delete config + delete repo)
- settings/automation (delete policy)
- TaskHistory (clear tasks)
- ApiKeysTab (revoke key)
- ConversationList (delete conversation)
- Settings page (delete environment)
Updated 2 test files to verify ConfirmDialog interactions.
2026-06-17 15:13:17 +03:00