feat(web): перевод поста на русский локальной моделью (openspec post-translate)

Кнопка «🌐 Перевести» в карточках кандидатов и отобранных переводит пост
локальной моделью (qwen3:8b-nothink), результат в posts.translated_text
(идемпотентный ALTER при старте). Метка «Оригинальный пост» стала закладкой,
при готовом переводе рядом появляется закладка «Перевод» (активна по умолчанию),
переключение на vanilla JS. Повторный клик не тратит токены: перевод в БД.
call_ollama из classifier не подошла (парсит ответ как JSON) — прямой запрос
к Ollama /v1/chat/completions. POST /posts/{id}/translate, лимит 6000 символов.
This commit is contained in:
kpa39l
2026-09-18 05:40:59 +00:00
parent 745680a3a0
commit 4a166fa9d6
9 changed files with 530 additions and 29 deletions
+10 -1
View File
@@ -1,8 +1,16 @@
# VESTI — Статус
Обновлено: 2026-09-17 (keep-bulk-checkboxes заархивирован, запушен c8fe5f7; активны: extract-post-sources)
Обновлено: 2026-09-18 (активны: extract-post-sources, manual-direction, post-translate)
<!--
История обновлений:
2026-09-18 — post-translate: кнопка «🌐 Перевести» в карточках кандидатов и отобранных.
Перевод на русский локальной моделью (qwen3:8b-nothink), результат в
posts.translated_text (колонка добавляется идемпотентно при старте).
«Оригинальный пост» стал закладкой; при готовом переводе рядом появляется
закладка «Перевод» (активна по умолчанию), переключение без перезагрузки
(vanilla JS в scripts-блоке). Повторный клик «Перевести» токены не тратит.
call_ollama из classifier не подошла (жёстко парсит ответ как JSON) —
перевод идёт прямым запросом к Ollama /v1/chat/completions.
2026-09-17 — keep-bulk-checkboxes: фикс чекбоксов bulk-выбора. Отметки постов сохраняются
в sessionStorage (vesti_bulk_candidates / vesti_bulk_selected) и восстанавливаются
при открытии поста (?selected=N); badge sel-count пересчитывается; при submit
@@ -32,6 +40,7 @@
-->
## Текущее состояние
- **post-translate — В РАЗРАБОТКЕ** (2026-09-18): в карточках кандидатов и отобранных появилась кнопка **«🌐 Перевести»** — переводит пост на русский локальной моделью (qwen3:8b-nothink, Ollama). Результат сохраняется в `posts.translated_text` (новые посты — колонка добавляется при старте веба), кнопка после перевода скрывается, вместо неё — закладка «Перевод» рядом с «Оригинал» (активна по умолчанию, переключение без перезагрузки на vanilla JS). Повторный клик токены не тратит. Ошибки модели — редирект с `?error=translate:...`. Тест e2e на реальной модели пройден (пост 123: «Kali Purple Essential Training»).
- **keep-bulk-checkboxes — ЗААРХИВИРОВАН И ЗАПУШЕН** (2026-09-17, коммит c8fe5f7): проверки массового выбора постов сохраняются между перезагрузками страницы при навигации по постам. Отметки хранятся в sessionStorage браузера (`vesti_bulk_candidates` / `vesti_bulk_selected`); при открытии поста (?selected=N) восстановленные чекбоксы остаются отмеченными, badge sel-count пересчитывается; при submit bulk-формы (Отобрать/Отклонить/Обработать/Опубликовать) отметки очищаются. Изоляция /candidates и /selected независимыми ключами. Попутно исправлен скрытый баг: чекбоксы лежат вне `<form>` (атрибут form="bulk-form") → селектор `#bulk-form input[name="ids"]` не находил их; заменён на глобальный `input[name="ids"]`. Изменены только web/templates/candidates.html и selected.html (frontend, рестарт не нужен).
- **address-field-enhancement — ЗААРХИВИРОВАН** (2026-09-16). Сделано и в проде: форма добавления источника — одно поле Address. Для telegram: `https://t.me/mknewsru` → slug=`mknewsru`, название «Мой Компьютер» (Telethon get_entity); для rss: `https://lwn.net/headlines/rss` → slug=`lwn`, название «LWN.net» (feedparser). Кнопка «🔎 Найти» в форме. direction — datalist из реальных значений (DIRECTIONS + БД), свободный ввод остаётся. БД не менялась (address — только UI-концепция, в yaml по-прежнему url/channel/feed_url).
- **fix-sources-add-channel** (2026-09-16): добавление telegram-источника через веб снова работает. Поле `channel` добавлено в форму (required для telegram через JS) и показывается в таблице. Причина: UI-форма не имела поля channel. `web/templates/sources.html` ранее отсутствовал в git — добавлен.