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,57 @@
## Design
Файл: `/opt/vesti/web/app.py`.
### 1. `reject()` — строка 582
Сейчас:
```python
return RedirectResponse(url=_cand_back(group_by, direction, own, q, status="rejected"), status_code=302)
```
Стало:
```python
return RedirectResponse(url=_cand_back(group_by, direction, own, q), status_code=302)
```
`_cand_back` без `status` строит `/candidates` с сохранением
`group_by/direction/own/q` — очереди кандидатов (`status=new` по умолчанию).
### 2. `candidates_bulk()` — строки 345, 358
Сейчас:
```python
if action == "reject":
...
return RedirectResponse(url=back + "&status=rejected", status_code=302)
...
if action == "reject-old":
...
return RedirectResponse(url=back + "&status=rejected", status_code=302)
```
Стало: редирект на `back` (уже содержит `group_by` + фильтры), без
`&status=rejected`.
```python
if action == "reject":
...
return RedirectResponse(url=back, status_code=302)
...
if action == "reject-old":
...
return RedirectResponse(url=back, status_code=302)
```
## Верификация
- `openspec validate reject-stay-candidates` — чисто.
- Юнит (TestClient): login → POST `/posts/{id}/reject` с `group_by=date`
→ ожидаем `Location: /candidates?group_by=date` (БЕЗ `status=rejected`).
- Перезапуск: `sudo systemctl restart vesti-web`.
- Ручная проверка: отклонить пост из правой панели → остаёмся на
«Кандидатах» в той же группировке, пост пропал из списка; список
отклонённых доступен через фильтр «🗑 Отклонённые».
@@ -0,0 +1,37 @@
## Why
После нажатия «🚫 Отклонить» в правой панели кандидата пользователь
попадает на страницу `/candidates?status=rejected` (отдельный список
отклонённых), а не остаётся в текущем списке кандидатов. Это разрывает
поток отбора: после отклонения одного поста нужно вернуться в очередь
кандидатов и продолжить.
Same для массового отклонения через bulk-форму (левая панель,
«🚫 Отклонить» / «🗑 Старьё»): редирект уводит на `status=rejected`.
## What Changes
- `web/app.py`, `reject()` (`POST /posts/{id}/reject`): редирект после
отклонения — на `/candidates` с сохранением текущей группировки и
фильтров, БЕЗ `status=rejected` (чтобы остаться в очереди кандидатов).
Т.е. `_cand_back(group_by, direction, own, q)` без `status`.
- `web/app.py`, `candidates_bulk()`: для `action == "reject"` и
`action == "reject-old"` — редирект на `back` (текущая группировка +
фильтры) БЕЗ `&status=rejected`.
Текущее поведение (reject → список отклонённых) доступно вручную через
фильтр статуса «🗑 Отклонённые» или `?status=rejected`.
## Why Not
- Не менять approve: после публикации переход на опубликованные —
осознанное поведение (посмотреть результат), менять не просили.
- Не добавлять параметр «куда вернуться»: редирект на текущую группировку
достаточен и предсказуем.
## Impact
- Файл: `web/app.py` (две точки редиректа).
- Данные: без изменений.
- Сервис: `vesti-web` (:8400) — перезапуск.
- Rollback: вернуть `status="rejected"` в редиректах и перезапустить.
@@ -0,0 +1,11 @@
# reject-stay-candidates
- [x] Создан OpenSpec change (proposal/design) — `skip_specs: true`
- [x] `openspec validate reject-stay-candidates` — чисто
- [x] web/app.py `reject()`: редирект на `/candidates` без `status=rejected`
- [x] web/app.py `candidates_bulk()`: reject/reject-old → `back` без `status=rejected`
- [x] Тест (TestClient): Location после reject содержит group_by, не содержит `status=rejected`
- [x] Перезапуск `sudo systemctl restart vesti-web`
- [x] Ручная проверка: после отклонения остаёмся на кандидатах (живой URL `/candidates?group_by=date`)
- [x] Обновить STATUS.md / TODO.md
- [x] Бэкап (крон 2:45 делает сам, вручную НЕ запускать)