Skip to content

feat: enforce competitive legacy team policy - #765

Merged
TThanos3000 merged 3 commits into
devfrom
feature/dev-competitive-team-policy
Oct 16, 2026
Merged

TThanos3000 merged 3 commits into
devfrom
feature/dev-competitive-team-policy

Conversation

@TThanos3000

@TThanos3000 TThanos3000 commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Что изменено

Конкурсная legacy-команда использует общую policy для Invite, Collaborator, vacancy, leave/switch, apply/bind/clone, admin/model save и submission. Submitted-состав фиксируется; pending decline/revoke остаются доступны. Exclusivity действует для draft/submitted команд до окончания программы. Min/max задаются в программе, NULL отключает соответствующую границу.

Зачем

Сдача проекта должна фиксировать состав команды, а приглашение, accept и другие writers должны одинаково проверять program membership, exclusivity и capacity. Spec и AC C1–C15: docs/competitive-team-policy.md; read-only диагностика данных: docs/legacy-team-data-audit.sql.

Реализация

  • Target: dev, base ccf920308d38329a6626fceee1fc1ea3d01c8550.
  • Head: c57e62b91d76b58fec38bcc7d5de95f5dd44bd24.
  • Исходный C 88f114b… обновлён актуальным dev без force-push. A fix: enforce project team management authorization #763 и B fix: port legacy invite integrity hardening to dev #767 уже входят в base; diff не дублирует их доставку.
  • 44 файла — исходный scope C и совместимость с текущим dev. Разрешены конфликты в invites/models.py, serializers.py, views.py, tests/test_invite_integrity.py, tests/test_pending_invite_migration.py, projects/team_service.py и projects/models.py.
  • В шести Invite/service/test файлах dev совпадал с original B: сохранены policy/context расширения C, atomic transitions и DB/model error mapping. В Project.save() объединены team locks/leader validation и новая нормализация имени из dev. Актуальные университеты и аналитика сохранены.
  • Lock order: Project → Programs по ID → links → Invite/Vacancy → PUP/Collaborator. Shared Program lock сериализует разные команды одной программы. Все competitive links общего roster участвуют в проверках.

API

Optional program_link_id — ID связи, принадлежащей Project. Ноль links — ordinary project; один — unique context; несколько — explicit ID либо 409 program_context_required. Новый Invite хранит context. Сохранённый context не переназначается. Link-scoped submission URL сохранён.

Project list/detail и компактные user-projects возвращают team_policy: is_frozen, единственный program_link_id либо NULL, requires_program_context, program_links. Legacy read projection сохранён.

409: team_frozen, already_in_program_team, team_min_size, team_max_size, program_context_required, program_context_in_use, submission_closed; A/B codes сохраняются. Permission — 403, foreign context — 422, malformed input / existing case validation — 400. Контракт исходного C при актуализации не менялся.

UI

Backend-only diff. Angular согласуется в Draft #392 и внедряется после C. React не затронут. Admin использует controlled validation.

Permissions

Управляет текущий leader, actor перепроверяется под lock. Existing staff override vacancy service сохранён. Freeze любой submitted competitive связи действует на shared roster и не обходится context другой программы.

Проверки

  • PostgreSQL 18.1: 147 targeted tests PASS, 113.389 s. Competitive policy, все Invite tests, migration forward/backward, admin/case locks, security A, collaborators regression, новые default project names, user-project contract.
  • Реальные HTTP races: concurrent accept A/B, max reservation, submit/accept, submit/remove; inherited B duplicate/create/accept/decline/revoke/PATCH races и fault injection.
  • Black 42 изменённых/new Python-файлов; Flake8 по всем tracked Python-файлам; migration consistency (No changes detected); diff checks.
  • Полный локальный PostgreSQL 18.1 suite на свежей БД: 1035 tests PASS, 653.390 s.
  • GitHub PostgreSQL 15 CI: 1035 full-suite tests PASS, 409.053 s, 39 targeted locking/vacancy tests PASS, empty-DB migrations и configuration/model checks PASS.
  • GitHub Lint / Tests: PASS на текущем head.

Первый локальный full run не прошёл: reused targeted DB уже была очищена от data-migration seed, один websocket timeout и Windows error 1450/fsync привёл к recovery старого тестового кластера. Повтор выполнялся на отдельном свежем кластере/БД и прошёл целиком; production code и university tests ради результата не менялись.

Acceptance criteria

  • C1–C2: все roster mutations frozen; pending decline/revoke разрешены.
  • C3–C5: exclusivity независимо от роли; другие/завершённые программы разрешены; concurrent accept имеет одного победителя.
  • C6–C7: solo draft, configured min на submit, max с pending reservation, unique leader count, independent NULL bounds.
  • C8–C10: explicit multi-link context, current PUP/required fields на submit, согласованные submit/accept/remove locks.
  • C11–C15: поддерживаемые writers используют policy; recommendations actionable; export unique size; безопасный backfill; ordinary flows сохранены.
  • Regression A/B и новые contracts актуального dev подтверждены targeted tests.
  • Полный suite и remote CI обновлённого head — PASS; review C1–C15 не выявил actionable findings.

Migrations / DB guarantees

Только две migrations C: partner_programs/0019_legacy_project_team_policy и invites/0004_legacy_project_team_policy. invites/0003 из B не дублируется и не меняется. Новые defaults для границ — NULL; три checks защищают положительные значения и min ≤ max. Invite получает nullable FK RESTRICT; backfill только для ровно одного link, остальные NULL. Forward/backward tests сохраняют Invite/roster.

Pending unique Invite, unique Collaborator pair, unique PUP pair и FK/checks защищены БД. Exclusivity/freeze/capacity между таблицами гарантируются application locks поддерживаемых writers. Raw SQL, QuerySet bulk/update и cascade удаления целых родителей не являются roster-service командами. Отдельная materialized membership table автоматически не добавлялась.

Не проверено

Live DEV/PROD data audit и mutations, browser на новом коде не выполнялись. Доступа к read-only DEV DB из этого окружения нет; отсутствие исторических конфликтов не утверждается. Повторная проверка исходного C от сентября не выдаётся за проверку текущей версии. Merge/deploy не выполняются.

Риски / rollout

До rollout выполнить read-only legacy-team-data-audit.sql. C не удаляет исторические конфликтующие команды и не выбирает программу для ambiguous Invite. Такие записи могут потребовать отдельного решения владельца данных; новые конфликтующие mutations отклоняются. Program locks могут повысить contention. PROD имеет другой migration graph и lifecycle, прямой перенос DEV migrations туда не является release plan.

A/B уже merged в dev; следующий пользовательский merge — этот C в dev. Затем backend schema/API должны быть доступны до внедрения Angular D. PR остаётся Draft.

@TThanos3000
TThanos3000 changed the base branch from fix/dev-invite-integrity to dev October 16, 2026 14:34
@TThanos3000
TThanos3000 marked this pull request as ready for review October 16, 2026 16:14
@TThanos3000
TThanos3000 merged commit 742f6df into dev Oct 16, 2026
3 checks passed
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.

2 participants