Files
vesti/openspec/changes/archive/2026-09-16-fix-date-group-status/design.md
T

3.2 KiB

Design

Файл: /opt/vesti/web/app.py, функция _fetch_candidates.

Текущий код (строки ~219-227):

    grouped = []
    for k, it in itertools.groupby(sorted(flat, key=keyf), key=keyf):
        items = list(it)
        grouped.append({
            "key": k,
            "label": _group_label(group_by, k),
            "status": items[0]["status"],          # ← БАГ: статус первого поста
            "posts": items,
        })

Проблема: items[0]["status"] берёт статус первого поста в группе. При group_by=date сортировка идёт по дате (свежие сверху), и первый пост группы — свежайший, который может быть published/rejected, хотя вся остальная группа состоит из new. Шаблон рисует бейдж группы только для new/rejected, поэтому группа с первым published-постом остаётся без бейджа и выглядит как «опубликованная».

Правка — считать статус группы как доминирующий среди всех постов группы:

    def _group_status(items):
        """Статус группы: приоритет new > rejected > published > первый."""
        st = [p["status"] for p in items]
        for s in ("new", "rejected", "published"):
            if s in st:
                return s
        return items[0]["status"]

    grouped = []
    for k, it in itertools.groupby(sorted(flat, key=keyf), key=keyf):
        items = list(it)
        grouped.append({
            "key": k,
            "label": _group_label(group_by, k),
            "status": _group_status(items),
            "posts": items,
        })

Логика приоритета: если в группе есть хотя бы один new — группа «новые» (это важно для группировки по дате, где почти всегда есть новые кандидаты наряду с опубликованными/отклонёнными). Если новых нет, но есть отклонённые — «откл.». Иначе «опубл.» (для фильтра status=published).

Верификация

  • openspec validate fix-date-group-status — чисто.
  • Юнит-проверка (без перезапуска сервиса): python -c "import sys; sys.path.insert(0,'/opt/vesti'); import web.app as A; c=A._db(); g,_,_=A._fetch_candidates(c,'','','','','date',limit=200); [print(x['key'],x['status']) for x in g]; c.close()" → группа week должна иметь status='new' (не published).
  • Перезапуск: sudo systemctl restart vesti-web.
  • Ручная проверка в браузере: GET /candidates?group_by=date → группа «Ранее на этой неделе» показывает бейдж «новые»; правая панель выбранного поста корректно показывает кнопку «Опубликовать», если пост ещё не опубликован.