Files
vesti/openspec/changes/candidates-only-external-new/proposal.md
T
kpa39l acb49cc702 fix(candidates): только внешние new-посты в списке кандидатов
- _fetch_candidates: в WHERE всегда is_own=0 AND status='new' → свои посты
  канала @dedinit (is_own=1, backfill) и published/rejected больше не
  показываются как кандидаты
- counts табов: считаются по внешним постам (не по жёсткому where), чтобы
  табы статусов показывали реальные счётчики
- change: candidates-only-external-new (skip_specs)
2026-09-14 05:11:54 +00:00

54 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 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-правку, перезапустить.