Skip to content

fix: make legacy invite transitions atomic and race-safe - #764

Merged
TThanos3000 merged 1 commit into
fix/dev-team-security-errorsfrom
fix/dev-invite-integrity
Sep 29, 2026
Merged

TThanos3000 merged 1 commit into
fix/dev-team-security-errorsfrom
fix/dev-invite-integrity

Conversation

@TThanos3000

@TThanos3000 TThanos3000 commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Что изменено

Accept Invite теперь атомарно создаёт Collaborator и завершает Invite. Create/edit/accept/decline/revoke используют общий service и lock protocol; stale PATCH не возвращает обработанное приглашение в pending. Partial unique constraint защищает pending (project,user), проигранный INSERT получает controlled 409.

Зачем

PR B hardening legacy-команд. Спецификация, AC B1–B9 и read-only data preflight: docs/invite-integrity-api.md.

Реализация

  • Base SHA: c44bcf089c41c6e8c657a70390e98c46bc2510e7 (PR A).
  • Head SHA: 3a513846c81dd36e5f3393957ec3450c9fcfb2f7.
  • Changed files: projects/team_service.py; invites/models.py, serializers.py, views.py; migration 0003_legacy_pending_invite_constraint; tests test_invite_api.py, test_invite_integrity.py, test_pending_invite_migration.py; docs/invite-integrity-api.md.
  • Выборочно перенесены atomic/locks/savepoint/current-membership механизмы PROD source. Unrelated lifecycle fields, notifications и nextgen не перенесены.

API

Успешные ответы прежние: create 201, accept/decline 200, edit 200, revoke pending 204. State conflicts теперь {code, detail} с 409: duplicate_pending_invite, invite_already_processed, not_program_member, already_project_member, already_project_leader, invalid_team_member. Permission — 403. Concurrent revoke-first/accept-second может дать 404: Invite удалён, Collaborator не создан. Malformed input остаётся 400.

UI

Не менялся; Angular mapping — отдельный PR D. React untouched.

Permissions

Сохранены legacy роли: управляет лидер, принимает/отклоняет получатель; внутри service проверяются повторно после lock.

Проверки

  • PostgreSQL 18.1, Python 3.11, CI settings с отдельной локальной test DB: 72 targeted tests OK, 957 full-suite tests OK.
  • Реальные параллельные HTTP-клиенты: duplicate create, double accept, accept+decline, accept+revoke, PATCH+accept.
  • Fault injection после Collaborator INSERT: полный rollback.
  • Реальный constraint INSERT failure → HTTP 409; membership deleted → 409.
  • Forward/backward migration сохраняет Invite; duplicate preflight отказывает без удаления/выбора победителя.
  • makemigrations --check --dry-run, Black / Flake8 invites и service, git diff --check.
  • Checked by source / review: AC B1–B9; разрешённые update_fields, общие locks, no stale model save.
  • GitHub PostgreSQL 15 CI PASS на этом head; PR Lint / Tests также PASS.

Acceptance criteria

  • B1–B9 — atomicity, DB uniqueness + mapping, race consistency, stale PATCH, membership, migration preservation; конкретные test names приведены в spec.

Не проверено

Production DB не читалась для поиска конфликтов; live mutations не выполнялись. Browser не применим. Merge/deploy не выполнялись.

Риски / migration

Одна минимальная migration: partial unique uniq_legacy_pending_invite с predicate is_accepted IS NULL. Если существующие данные содержат дубли, migration останавливается без изменения данных; нужны отдельное решение владельца и cleanup перед повторным запуском. PROD migration graph/predicate с is_revoked отличаются: будущий production port требует адаптации, не прямого копирования. Program context и freeze пока относятся к PR C.

Этот Draft PR по согласованию временно направлен в ветку PR A для отдельного reviewable diff. После merge A его base нужно сменить на dev. До этого самостоятельно не мержить.

@TThanos3000
TThanos3000 marked this pull request as ready for review September 29, 2026 17:23
@TThanos3000
TThanos3000 merged commit b7c220d into fix/dev-team-security-errors Sep 29, 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