## Design Файл: `/opt/vesti/web/templates/candidates.html`, правая панель (`{% if selected %}`), блок действий (строки ~150–184). ### Текущая разметка ```html
{% set hid %}...{% endset %} {% if selected.status != 'published' %}
{{ hid }}
{% endif %} {% if selected.status != 'published' %}
{{ hid }}
{% endif %} {% if selected.status != 'published' %}
{{ hid }}
{% endif %} {% if selected.status != 'rejected' and selected.status != 'published' %}
{{ hid }}
{% endif %}
``` ### Новая разметка Кнопки действий выносятся в ОДИН flex-ряд НАД полем комментария; approve-форма остаётся обёрткой только для «Опубликовать» + «Сохранить комментарий» + textarea (поля `hid` нужны каждой форме; внутри approve-формы они уже есть). ```html
{% set hid %}...{% endset %} {% if selected.status != 'published' %}
{{ hid }}
{% endif %} {% if selected.status != 'published' %}
{{ hid }}
{% endif %} {% if selected.status != 'rejected' and selected.status != 'published' %}
{{ hid }}
{% endif %} {% if selected.status != 'published' %}
{{ hid }}
{% endif %}
``` Порядок в ряду: «🤖 Обработать моделью» → «✍️ Переписать» → «🚫 Отклонить» → «✅ Опубликовать» (кнопка публикации — правая, главная). Затем — поле комментария и «💾 Сохранить комментарий». Все кнопки остаются `type="submit"` в своих формах; `formaction` у «Сохранить комментарий» сохраняется; логика видимости не меняется. ## Верификация - `openspec validate candidates-buttons-order` — чисто. - Рендер шаблона проверяется только ч/з сам сервис (TestClient/живой GET), т.к. прямой рендер `tpl.get_template(...)` блокируется политикой. - Перезапуск: `sudo systemctl restart vesti-web` (Jinja2-кеш!). - Ручная проверка: `GET /candidates` → выбран неопубликованный пост → в правой панели НАД полем комментария в одном ряду кнопки Обработать/Переписать/Отклонить/Опубликовать, под textarea — «Сохранить комментарий».