5971: added organizations to invitation model#6008
Conversation
|
👋 Hi @ArthurMousatov, thanks for contributing! For the review process to begin, please verify that the following is satisfied:
Also check that issue requirements are satisfied & you ran Pull requests that don't follow the guidelines will be closed. Reviewer assignment can take up to 2 weeks. |
|
📢✨ Before we assign a reviewer, we'll turn on |
rtibblesbot
left a comment
There was a problem hiding this comment.
Three blocking issues must be resolved before merge: broken method dispatch in accept(), a two-write invalid-state pattern in _accept_organization_invitation, and missing acceptance-criteria tests. One migration safety concern is flagged as a suggestion. CI was pending at review time.
- blocking
accept()calls non-existent method names — every invitation acceptance raisesAttributeError(see inline models.py:3754) - blocking
_accept_organization_invitationwrites an empty-stringroleon firstcreate(), then overwrites it; unknownshare_modesilently persists invalid data; re-acceptance raisesIntegrityError(see inline models.py:3767) - blocking Acceptance criteria require unit tests for the invitation–organization relationship, the mutual-exclusivity constraint violation case, and the
share_mode→ org-role mapping — none are present in this PR - suggestion
AddConstraintin the migration may fail at deployment if any existing rows havechannel=NULL(see inline migration:19) - praise Splitting
accept()into named per-type helpers is a clean refactor — the dispatch logic is now symmetrical and the original comment about the nullable channel field is correctly removed
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran a phased review pipeline over the pull request diff:
- Classified the diff to select review passes (core, frontend, backend) and whether manual QA was required
- Core review pass checked correctness, design, architecture, testing, completeness, and DRY/SRP/Rule-of-Three principles
- Specialized frontend/backend review passes applied framework-specific lenses where those files changed
- For UI changes: manual QA and an accessibility audit against a live dev server, when available
- Checked CI status and linked issue acceptance criteria
- Synthesized one review from those passes and chose the verdict from the findings, CI status, and QA evidence
…exception for invalid share_mode
…thurMousatov/studio into add-organizations-to-invitation-model
rtibblesbot
left a comment
There was a problem hiding this comment.
1 of 4 prior findings resolved; 3 still open (see below).
- blocking
_accept_organization_invitationunchanged from last round — still writes an emptyrole, silently drops unknownshare_mode, raisesIntegrityErroron re-accept. See inline comment. - blocking The mutual-exclusivity
CheckConstraintonInvitationwas deleted with no replacement (noMeta.constraintsremains; not visible in the diff since it was added and removed within this branch's own history). The maintainer thread called forNOT VALID+ separate validate, not removal. - blocking This leaves the XOR invariant ("Organizations XOR channels", #5971) enforced nowhere, so the required "invitations with channel & organization set" unit test has nothing to validate against — and no such test was added anyway.
- nitpick Duplicate imports in the new migration (see inline comment).
Prior-finding status
RESOLVED — models.py:3746 — accept() dispatch to nonexistent method names
UNADDRESSED — models.py:3761 — _accept_organization_invitation two-write invalid-state pattern, silent corruption, IntegrityError on re-acceptance
UNADDRESSED — missing acceptance-criteria unit tests
UNADDRESSED — mutual-exclusivity constraint: previously a deployment-safety suggestion on the AddConstraint, now the constraint has been removed entirely rather than fixed, regressing the acceptance criterion
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:
- Retrieved prior bot reviews via the GitHub API
- Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
- Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence
rtibblesbot
left a comment
There was a problem hiding this comment.
2 of 5 prior findings resolved; 3 still open (see below). CI passing.
- [blocking] Mutual-exclusivity constraint between
channelandorganizationstill not restored — see inline comment. - [blocking] No unit tests added for the invitation–organization relationship, mutual-exclusivity violation, or
share_mode→role mapping, despite these being acceptance criteria for #5971. - [nitpick] Duplicate imports in
migrations/0168_invitation_organization.py(lines 3, 5, 6) — still unresolved from the open thread on this PR. - New [suggestion] — see inline comment on the bare
ValueErrorin_accept_organization_invitation.
Prior-finding status
RESOLVED — models.py:3746 — accept() dispatch to nonexistent method names
RESOLVED — models.py:3761 — _accept_organization_invitation two-write invalid-state pattern, silent corruption, IntegrityError on re-acceptance
UNADDRESSED — missing acceptance-criteria unit tests
UNADDRESSED — models.py:3742 — mutual-exclusivity constraint removed entirely, XOR invariant enforced nowhere
UNADDRESSED — migrations/0168_invitation_organization.py:3-6 — duplicate imports
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:
- Retrieved prior bot reviews via the GitHub API
- Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
- Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence
rtibblesbot
left a comment
There was a problem hiding this comment.
2 of 6 prior findings resolved.
4 still open, listed below.
- [blocking] Mutual-exclusivity constraint between
channelandorganizationstill missing. - [blocking] Missing acceptance-criteria unit tests.
- [blocking] Invalid-
share_modepath still raises an exception DRF won't convert to a 400. - [nitpick] Migration still has duplicate imports.
Prior-finding status
RESOLVED — models.py:3746 — accept() dispatch to nonexistent method names
RESOLVED — models.py:3761 — two-write invalid-state pattern / IntegrityError on re-acceptance
UNADDRESSED — models.py:3742 — mutual-exclusivity constraint removed entirely, XOR invariant enforced nowhere
UNADDRESSED — missing acceptance-criteria unit tests
UNADDRESSED — migrations/0168_invitation_organization.py:3-6 — duplicate imports
UNADDRESSED — models.py:3770 — invalid-share_mode error path still won't surface as a clean 400
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:
- Retrieved prior bot reviews via the GitHub API
- Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
- Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence
rtibblesbot
left a comment
There was a problem hiding this comment.
3 of 6 prior findings resolved; 3 still open (see below).
CI passing.
- blocking —
Invitation.Metastill lacks a mutual-exclusivity guard forchannel/organization. See inline comment. - blocking — No test for the invitation–organization relationship (
organizationFK usage inaccept()). - blocking — No test for the mutual-exclusivity violation case (channel + organization both set).
- blocking — No test for the
share_mode→role mapping in_accept_organization_invitation. - blocking — Invalid
share_modestill raises a non-DRFValidationError. See inline comment.
Prior-finding status
RESOLVED — models.py:3746 — accept() dispatch fix
RESOLVED — models.py:3761 — two-write pattern fix
UNADDRESSED — models.py:3742 — mutual-exclusivity constraint missing
UNADDRESSED — missing acceptance-criteria tests
UNADDRESSED — models.py:3770 — non-DRF ValidationError
RESOLVED — migrations/0168_invitation_organization.py:3-6 — duplicate imports
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Ran an automatic code-only delta review triggered by new commits on a previously reviewed PR:
- Retrieved prior bot reviews via the GitHub API
- Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Core review pass only — specialized frontend/backend lenses and manual QA run when a review is explicitly requested
- Synthesized one review from the passes and chose the verdict from the findings, CI status, and QA evidence
Summary
As detailed in Issue #5971, this PR adds organizations to the invitation model. The saving behavior for organizations is slightly different to channels, as there is a separate model for org roles.
I have also omitted tests in this PR, as this is just a model change and does not affect current code (organizations are fully optional in the invitation). I suggest moving testing to the next implementation step (Organization/Invitation viewsets).
References
Direct PR for Issue #5971.
Reviewer guidance
As part of these changes, migrations were run successfully. I tried running
make test, but it ran into 905 failures, mostly related to S3Storage errors. No linting was performed, since no frontend work was done.AI usage
Only basic VS code autocomplete was used.