/
systemsstrategyy
/
Treker
Обзор
Документация
Войти
/
systemsstrategyy
/
Treker
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
api/modules/checklists/api.py
70 строк
3 KB
SystemsStrategy
Initial import
02 июл 2026, 15:15
02 июл 2026, 15:15
9624ed1
Код
Авторство
О чём код?
# ruff: noqa: I001 — см. tests/modules/checklists/test_api.py """Публичный интерфейс модуля checklists для остальных доменов. Другие модули (Kanban — для card modal, Comms — для notifications) импортируют ТОЛЬКО отсюда. Прямые импорты из `api.modules.checklists.models` или `service` запрещены — это нарушение границ модулей (см. конвенций разработки правило #4). Здесь нет HTTP-эндпоинтов — это in-process API между модулями. """ from __future__ import annotations from uuid import UUID from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload from api.modules.cards.api import CardDirectory from api.modules.checklists.domain import RunItemStatus, compute_completion_summary from api.modules.checklists.models import ChecklistRun from api.modules.checklists.schemas import ChecklistRunSummary class ChecklistDirectory: """Чтение публичных данных run'ов для других модулей. Используется Kanban для отображения list'а чек-листов в card modal.""" @staticmethod async def get_runs_for_card(*, db: AsyncSession, card_uid: UUID) -> list[ChecklistRunSummary]: """Все чек-листы привязанные к карточке (card.uid). Сортировка: - in-progress (`completed_at IS NULL`) первыми; - дальше по `completed_at DESC` (самые свежие наверху). Возвращает пустой список если у карточки нет чек-листов или карточка не существует — без NotFoundError (это публичный view, не CRUD). Резолв `card_uid → card.id` через `CardDirectory.get_internal_id` (cross-module API, опубликован Kanban в рамках issue #22).""" card_id = await CardDirectory.get_internal_id(db, uid=card_uid) if card_id is None: return [] stmt = ( select(ChecklistRun) .options(selectinload(ChecklistRun.items), selectinload(ChecklistRun.template)) .where(ChecklistRun.card_id == card_id) .order_by( ChecklistRun.completed_at.is_(None).desc(), # NULL первыми ChecklistRun.completed_at.desc(), ) ) runs = (await db.scalars(stmt)).all() return [ ChecklistRunSummary( uid=run.uid, template_name=run.template.name, completed_at=run.completed_at, percent_done=compute_completion_summary( [RunItemStatus(item.status) for item in run.items] ).percent_done, ) for run in runs ]