## Why Страница «Кандидаты» (`/candidates`) показывает посты, которые пользователь должен рассмотреть и решить: публиковать или отклонить. Сейчас в списке кандидатов отображаются посты, которым там не место: 1. **Опубликованные (`status='published'`)** — уже решённые посты. При `status=''` (фильтр «Все», значение по умолчанию) запрос `_fetch_candidates` НЕ фильтрует по статусу, поэтому published (6) и rejected (3) попадают в список кандидатов. Пользователь: «в списке кандидатов не должно быть одобренных к публикации постов». 2. **Свои посты канала @dedinit (`is_own=1`)** — 846 постов backfill'а своего канала «Дед в АйТи» лежат в БД как `new`, но это контент из собственного канала пользователя, а не кандидаты на публикацию. Пользователь их не одобрял и не считает кандидатами: «при группировке по дате все посты отображаются как „свои“, но они не мои, в канале их нет, я их не одобрял». Отклонённые (rejected) — тоже уже решённые. Итог: в списке кандидатов должны быть ТОЛЬКО внешние (is_own=0) посты в статусе `new`. ## What Changes В `web/app.py`, функция `_fetch_candidates`: - При пустом `status` (фильтр «Все», используется по умолчанию и для группировок source/date) — жёстко добавлять `p.status='new'` в WHERE. Это исключает published и rejected из списка кандидатов. - ВСЕГДА добавлять `p.is_own=0` в WHERE (независимо от фильтра own). Свои посты (is_own=1) не являются кандидатами — это контент собственного канала, управляется отдельно (fan-out). Исключаем их из списка кандидатов. Фильтры `own`, `status` в форме остаются (они по-прежнему работают в рамках внешних new-постов; `own='1'` теперь вернёт 0 постов — это ок, т.к. свои посты не кандидаты). ## Why Not - Не показывать published/rejected в отдельном разделе списка кандидатов: для них есть страница «Опубликованные» (/published) и фильтры. Кандидаты — это очередь на решение, не архив. - Не удалять is_own посты из БД: они нужны для fan-out и «Своих»; меняется только фильтрация на веб-странице кандидатов. - Не трогать краулер/backfill: семантика is_own корректна (свой канал), проблема только в отображении кандидатов. ## Impact - Файл: `web/app.py`, `_fetch_candidates` (WHERE-условия). - Данные: без миграций БД. - Сервис: `vesti-web` (:8400) — перезапуск. - Rollback: откатить WHERE-правку, перезапустить.