openspec: архив 14 завершённых change-ов (веб-фиксы, crawler-queue, own-content-hub, publisher-service); спеки влиты в openspec/specs

This commit is contained in:
kpa39l
2026-09-16 17:01:00 +00:00
parent 584582a48c
commit 771f6a8276
88 changed files with 1632 additions and 3 deletions
@@ -0,0 +1,3 @@
schema: spec-driven
skip_specs: true
created: 2026-09-15
@@ -0,0 +1,106 @@
## Design
Файл: `/opt/vesti/web/templates/candidates.html`, правая панель
(`{% if selected %}`), блок действий (строки ~150–184).
### Текущая разметка
```html
<div class="mb-3 d-flex flex-wrap gap-2">
{% set hid %}...{% endset %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/approve" id="approve-form">
{{ hid }}
<label class="form-label small text-muted mb-0">💬 Мой комментарий...</label>
<textarea class="form-control form-control-sm mt-1" name="comment" rows="2"
placeholder="Комментарий/анонс…">{{ selected.comment or '' }}</textarea>
<div class="mt-2 d-flex gap-2">
<button class="btn btn-success" type="submit" title="...">✅ Опубликовать</button>
<button class="btn btn-sm btn-outline-secondary" type="submit"
formaction="/posts/{{ selected.id }}/comment" title="...">💾 Сохранить комментарий</button>
</div>
</form>
{% endif %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reclassify">
{{ hid }}
<button class="btn btn-info" type="submit" title="...">🤖 Обработать моделью</button>
</form>
{% endif %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/rewrite">
{{ hid }}
<button class="btn btn-outline-primary" type="submit" title="...">✍️ Переписать</button>
</form>
{% endif %}
{% if selected.status != 'rejected' and selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reject">
{{ hid }}
<button class="btn btn-outline-danger" type="submit">🚫 Отклонить</button>
</form>
{% endif %}
</div>
```
### Новая разметка
Кнопки действий выносятся в ОДИН flex-ряд НАД полем комментария; approve-форма
остаётся обёрткой только для «Опубликовать» + «Сохранить комментарий» + textarea
(поля `hid` нужны каждой форме; внутри approve-формы они уже есть).
```html
<div class="mb-3 d-flex flex-wrap gap-2">
{% set hid %}...{% endset %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reclassify">
{{ hid }}
<button class="btn btn-info" type="submit" title="...">🤖 Обработать моделью</button>
</form>
{% endif %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/rewrite">
{{ hid }}
<button class="btn btn-outline-primary" type="submit" title="...">✍️ Переписать</button>
</form>
{% endif %}
{% if selected.status != 'rejected' and selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/reject">
{{ hid }}
<button class="btn btn-outline-danger" type="submit">🚫 Отклонить</button>
</form>
{% endif %}
{% if selected.status != 'published' %}
<form method="post" action="/posts/{{ selected.id }}/approve" id="approve-form">
{{ hid }}
<div class="mt-0 d-flex gap-2">
<button class="btn btn-success" type="submit" title="...">✅ Опубликовать</button>
</div>
<label class="form-label small text-muted mb-0 mt-2">💬 Мой комментарий...</label>
<textarea class="form-control form-control-sm mt-1" name="comment" rows="2"
placeholder="Комментарий/анонс…">{{ selected.comment or '' }}</textarea>
<div class="mt-2">
<button class="btn btn-sm btn-outline-secondary" type="submit"
formaction="/posts/{{ selected.id }}/comment" title="...">💾 Сохранить комментарий</button>
</div>
</form>
{% endif %}
</div>
```
Порядок в ряду: «🤖 Обработать моделью» → «✍️ Переписать» → «🚫 Отклонить» →
«✅ Опубликовать» (кнопка публикации — правая, главная). Затем — поле
комментария и «💾 Сохранить комментарий».
Все кнопки остаются `type="submit"` в своих формах; `formaction` у
«Сохранить комментарий» сохраняется; логика видимости не меняется.
## Верификация
- `openspec validate candidates-buttons-order` — чисто.
- Рендер шаблона проверяется только ч/з сам сервис (TestClient/живой GET),
т.к. прямой рендер `tpl.get_template(...)` блокируется политикой.
- Перезапуск: `sudo systemctl restart vesti-web` (Jinja2-кеш!).
- Ручная проверка: `GET /candidates` → выбран неопубликованный пост → в
правой панели НАД полем комментария в одном ряду кнопки
Обработать/Переписать/Отклонить/Опубликовать, под textarea — «Сохранить
комментарий».
@@ -0,0 +1,46 @@
## Why
В прошлой сессии кнопку «Опубликовать» перенесли в approve-форму (вместе с
полем комментария). В результате в правой панели деталей кандидата кнопки
«Обработать моделью», «Переписать», «Отклонить» оказались ПОСЛЕ блока
комментария отдельным flex-рядом — визуально «съехали» и разорвали основной
ряд действий.
Пользователь: действия модератора должны быть над полем комментария, в одном
ряду с «Опубликовать».
## What Changes
- В `web/templates/candidates.html`, правая панель выбранного поста:
- Перенести кнопки «🤖 Обработать моделью», «✍️ Переписать», «🚫 Отклонить»
из отдельного flex-ряда ПОСЛЕ approve-формы в ОДИН ряд с кнопкой
«✅ Опубликовать» — НАД полем комментария.
- Итоговая структура блока действий (когда пост не опубликован/не отклонён):
```
[✅ Опубликовать] [🤖 Обработать моделью] [✍️ Переписать] [🚫 Отклонить]
💬 Мой комментарий (будет первым в канале):
[textarea комментария]
[💾 Сохранить комментарий]
```
- Логика видимости кнопок не меняется:
- «Опубликовать» — статус != published;
- «Обработать моделью», «Переписать» — статус != published;
- «Отклонить» — статус != rejected и != published.
## Why Not
- Не объединять все кнопки в одну approve-форму: «Сохранить комментарий»
использует отдельный эндпоинт (`/posts/{id}/comment`), а «Обработать
моделью»/«Переписать»/«Отклонить» — свои POST-эндпоинты; в одну форму их
не собрать без JS (а htmx/JS-сложная логика в проекте запрещены).
- Оставлять текущий порядок нельзя — кнопки визуально разорваны.
## Impact
- Файл: `web/templates/candidates.html` (правка только разметки, без JS и
эндпоинтов).
- Данные: без изменений.
- Сервис: `vesti-web` (:8400) — нужен перезапуск (Jinja2-кеш без --reload).
- Rollback: вернуть разметку и перезапустить сервис.
@@ -0,0 +1,10 @@
# candidates-buttons-order
- [x] Создан OpenSpec change (proposal/design) — `skip_specs: true`, без delta-спеки (правка только разметки, поведение кнопок не меняется)
- [x] `openspec validate candidates-buttons-order` — чисто
- [x] candidates.html: кнопки Обработать/Переписать/Отклонить перенесены над полем комментария, в одном ряду с Опубликовать
- [x] Проверка: рендер правой панели (живой GET :8400 после рестарта) — ряд кнопок над textarea комментария
- [x] Перезапуск `sudo systemctl restart vesti-web`
- [x] Ручная проверка в браузере: порядок кнопок над комментарием
- [x] Обновить STATUS.md / TODO.md
- [x] Бэкап (крон 2:45 делает сам, вручную НЕ запускать)