Skip to content

DEV: add not-submitted projects attention drilldown - #726

Draft
TThanos3000 wants to merge 1 commit into
devfrom
feature/dev-program-not-submitted-attention-api
Draft

DEV: add not-submitted projects attention drilldown#726
TThanos3000 wants to merge 1 commit into
devfrom
feature/dev-program-not-submitted-attention-api

Conversation

@TThanos3000

Copy link
Copy Markdown
Collaborator

Изменения

Добавлена read-only детализация «Проекты не сдали решение». Только backend DEV; merge и deploy не выполнялись.

Аудит «2 vs 6»

participant_funnel.submitted_project_creators считает уникальных зарегистрированных user_id, руководящих хотя бы одним сданным проектом программы. solution_funnel.submitted считает сданные связи PartnerProgramProject. Два зарегистрированных руководителя с тремя сданными проектами у каждого дают 2 человека и 6 связей. Это разные единицы измерения. API-поля, их имена и расчёт сохранены; regression-тест фиксирует именно 2 vs 6. Изменение строки в Angular-воронке не входит в этот PR.

Контракт

В overview добавлено:

"attention": {
  "projects_not_submitted": {"applicable": true, "total": 4}
}

Остальные поля attention сохраняются. Новый endpoint:

GET /programs/<program_id>/manager-overview/projects-not-submitted/

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [{
    "program_project_id": 70,
    "project": {"id": 55, "name": "Проект А"},
    "leader": {"user_id": 123, "full_name": "Анна Петрова", "avatar": null},
    "linked_at": "2026-09-01T10:00:00+03:00"
  }],
  "applicable": true,
  "submission_deadline": "2026-09-10T23:59:00+03:00",
  "submission_open": true
}

Применимость и согласованность

  • Только is_competitive=true: связь текущей программы с submitted=false включается независимо от draft/publicity проекта, команды и назначений.
  • Одна связь = одна строка. Связь этого же Project в другой программе не влияет на результат.
  • Общий _not_submitted_filter() используется в воронке и списке; attention повторно использует агрегат воронки без нового SQL.
  • При одном состоянии БД без поиска: attention.projects_not_submitted.total == solution_funnel.not_submitted == count.
  • Для несоревновательной программы: applicable=false, count=0, results=[], next/previous=null, submission_deadline=null, submission_open=false, attention total=0. Старый solution_funnel.not_submitted не пересчитывается и может быть ненулевым.

Сроки и доступ

  • submission_deadline: существующий get_project_submission_deadline() — отдельный срок сдачи, иначе datetime_registration_ends.
  • submission_open: существующий is_project_submission_open(). Срок отсутствует или ещё не прошёл, включая равенство текущему времени; новый SLA не вычисляется.
  • Доступ через существующий can_manage_program: manager текущей программы / staff / superuser.
  • Anonymous — 401; участник / эксперт без роли manager / manager другой программы / посторонний — 403; неизвестная программа — 404; write-методы для manager — 405.
  • Поля строки заданы явным безопасным набором; нет email, телефона, анкет, auth-полей или полного User serializer. Пустое имя: Участник №ID; пустой avatar: null; nullable leader поддержан защитно без изменения схемы. linked_at — дата создания связи, не Project.

Поиск, пагинация и SQL

  • Существующая пагинация DEV: детализация блока «Требует внимания» — API #725: limit по умолчанию 25, диапазон 1–100; offset по умолчанию 0, неотрицательный. Невалидные параметры — 400.
  • Search обрезает внешние пробелы и ищет только по названию проекта (icontains) до count/page. Не ищет по руководителю, email и приватным полям.
  • Стабильный порядок: дата создания связи, затем её pk. Next/previous сохраняют поиск. Offset за пределами — 200 с пустым results и актуальным count.
  • JOIN/select_related и явный набор полей; сериализация выбранных строк — 0 SQL.
  • Regression 1 → 31 строка с разными руководителями: фактически 4 → 4 SQL для аутентифицированного manager. Overview сохраняет бюджет ≤10 SQL.

Проверки

  • Новые regression-тесты: 25/25, включены в каждый полный suite ниже.
  • Targeted analytics (новый список, два списка DEV: детализация блока «Требует внимания» — API #725, overview, assignments/scores/delayed experts): 136 тестов, успешно, 1 существующий PostgreSQL-only skip на SQLite.
  • Локальный полный backend suite: 700 тестов, успешно, 2 существующих PostgreSQL-only skip на SQLite.
  • Backend PostgreSQL CI: успешно на этом head SHA. PostgreSQL 15, vendor postgresql, has_select_for_update=True; migrations применены на пустую БД; 39/39 locking/lifecycle тестов и 700/700 полного backend suite, без skip. Новые analytics tests выполнялись на PostgreSQL в полном suite.
  • Black и Flake8 всех 6 изменённых Python-файлов: успешно.
  • manage.py check, check --tag models, makemigrations --check --dry-run: успешно локально и на PostgreSQL CI; No changes detected.
  • git diff origin/dev...HEAD --check: успешно.
  • Штатный CI: оба job успешно — полный Flake8 и полный backend suite (700 тестов, 2 существующих PostgreSQL-only skip на SQLite).

Особенности локального окружения: Python 3.12 / Windows / SQLite; для импорта WeasyPrint использована уже существующая внешняя тестовая заглушка из-за отсутствия Pango. Поэтому полноценный Linux/PostgreSQL CI с реальными зависимостями указан отдельно. Старый локальный Flake8 5.0.4 под Python 3.12 выдал 29 диагностик в неизменённых файлах; unrelated файлы не исправлялись. Изменённые файлы прошли локальный lint, весь репозиторий — штатный CI lint на Python 3.11.

Изменённые файлы

  • partner_programs/services/analytics.py
  • partner_programs/serializers/analytics.py
  • partner_programs/serializers/attention.py
  • partner_programs/views.py
  • partner_programs/urls.py
  • partner_programs/tests/test_not_submitted_analytics_api.py
  • docs/program-manager-analytics-api.md

Границы

Angular и React не менялись. Models/migrations не менялись. Scoring/submission lifecycle не менялся. Dependencies, workflows, Docker и deploy не менялись. Существующие overview-поля, assignments, scores, delayed experts и два списка внимания сохранены. Метаданные нового списка добавлены через локальный hook общей read-only пагинации без изменения ответов прежних endpoints.

Кейсы, напоминания, сообщения, назначение экспертов и новые frontend-функции не входят в PR. После открытия Draft PR работа останавливается; merge/deploy запрещены.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant