feat: remove selection plan ref from presentation when a category is removed from a category group#522
feat: remove selection plan ref from presentation when a category is removed from a category group#522
Conversation
📝 WalkthroughWalkthroughAdds a bidirectional ManyToMany between SelectionPlan and PresentationCategoryGroup, a PresentationCategory helper to fetch presentations by selection-plan IDs, service logic to conditionally clear presentations' selection plans when disassociating tracks, and tests covering both clearing and preservation cases. Changes
Sequence DiagramsequenceDiagram
participant Client
participant Service as PresentationCategoryGroupService
participant Category as PresentationCategory
participant Repo as DoctrineRepo
participant Presentation
Client->>Service: disassociateTrack2TrackGroup(groupId, trackId)
Service->>Category: getPresentationsBySelectionPlanIds(selectionPlanIds)
Category->>Repo: execute DQL (filter by category and selection_plan IN ids)
Repo-->>Category: presentations[]
Category-->>Service: presentations[]
loop for each presentation
Service->>Presentation: inspect presentation.selectionPlan
Service->>Service: check other groups for same track within that selection plan
alt no other group covers track
Service->>Presentation: clearSelectionPlan()
Presentation-->>Service: selection plan cleared
else other group covers track
Presentation-->>Service: left intact
end
end
Service->>Service: removeCategory(track) from group
Service-->>Client: disassociation complete
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
📘 OpenAPI / Swagger preview ➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-522/ This page is automatically updated on each push to this PR. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/Services/Model/Imp/PresentationCategoryGroupService.php`:
- Around line 255-261: Check whether the track is actually in the group first
using $track_group->hasCategory($track); only proceed to removeCategory($track)
when true, then fetch presentations by the selection plan ids and for each
presentation verify its current selection plan still contains the track (e.g.,
$presentation->getSelectionPlan()->hasTrack($track)); call
$presentation->clearSelectionPlan() only for presentations whose current plan no
longer has the track, and finally call $track_group->removeCategory($track) (or
call removeCategory before checking presentations if you prefer but still gate
the clearing by hasTrack on each presentation's current plan).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9331089e-20a7-4123-9994-f1a4a80493de
📒 Files selected for processing (5)
app/Models/Foundation/Summit/Events/Presentations/PresentationCategory.phpapp/Models/Foundation/Summit/Events/Presentations/PresentationCategoryGroup.phpapp/Models/Foundation/Summit/SelectionPlan.phpapp/Services/Model/Imp/PresentationCategoryGroupService.phptests/oauth2/OAuth2TrackGroupsApiTest.php
…removed from a category group Signed-off-by: romanetar <roman_ag@hotmail.com>
f0235fc to
d2bd7d4
Compare
|
📘 OpenAPI / Swagger preview ➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-522/ This page is automatically updated on each push to this PR. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/Services/Model/Imp/PresentationCategoryGroupService.php (1)
265-270: Prefix unused parameter with underscore to suppress warning.The
$keyparameter is required by Doctrine'sexists()callback signature but is unused. Use$_or$_keyto signal intent.♻️ Suggested fix
- $track_reachable_via_another_group = $selection_plan->getCategoryGroups()->exists( - function ($key, $group) use ($track, $track_group) { + $track_reachable_via_another_group = $selection_plan->getCategoryGroups()->exists( + function ($_, $group) use ($track, $track_group) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/Services/Model/Imp/PresentationCategoryGroupService.php` around lines 265 - 270, The callback passed to selection_plan->getCategoryGroups()->exists is using an unused $key parameter which triggers a warning; rename it to $_ or $_key (e.g., change function ($key, $group) to function ($_key, $group) or function ($_ , $group)) to indicate it's intentionally unused and suppress the warning while keeping the existing logic that checks $group->getId() !== $track_group->getId() && $group->hasCategory($track->getId()).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/Services/Model/Imp/PresentationCategoryGroupService.php`:
- Around line 265-270: The callback passed to
selection_plan->getCategoryGroups()->exists is using an unused $key parameter
which triggers a warning; rename it to $_ or $_key (e.g., change function ($key,
$group) to function ($_key, $group) or function ($_ , $group)) to indicate it's
intentionally unused and suppress the warning while keeping the existing logic
that checks $group->getId() !== $track_group->getId() &&
$group->hasCategory($track->getId()).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6aee6a81-9a01-4434-80fd-a70a7722c5f4
📒 Files selected for processing (5)
app/Models/Foundation/Summit/Events/Presentations/PresentationCategory.phpapp/Models/Foundation/Summit/Events/Presentations/PresentationCategoryGroup.phpapp/Models/Foundation/Summit/SelectionPlan.phpapp/Services/Model/Imp/PresentationCategoryGroupService.phptests/oauth2/OAuth2TrackGroupsApiTest.php
🚧 Files skipped from review as they are similar to previous changes (4)
- tests/oauth2/OAuth2TrackGroupsApiTest.php
- app/Models/Foundation/Summit/Events/Presentations/PresentationCategory.php
- app/Models/Foundation/Summit/SelectionPlan.php
- app/Models/Foundation/Summit/Events/Presentations/PresentationCategoryGroup.php
smarcet
left a comment
There was a problem hiding this comment.
@romanetar please review
Signed-off-by: romanetar <roman_ag@hotmail.com>
|
📘 OpenAPI / Swagger preview ➡️ https://OpenStackweb.github.io/summit-api/openapi/pr-522/ This page is automatically updated on each push to this PR. |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
app/Services/Model/Imp/PresentationCategoryGroupService.php (1)
255-277:⚠️ Potential issue | 🟠 MajorGuard disassociation side effects when the track is not in the target group.
This block clears presentation selection plans before confirming the track is actually part of
$track_group. If the track was never in that group, this can still clear plans incorrectly.Proposed fix
- $presentations = $track->getPresentationsBySelectionPlanIds($track_group->getSelectionPlanIds()); - - // Only clear the selection plan if no other category group in that plan - // still contains $track. A selection plan can span multiple groups, so - // removing $track from $track_group does not necessarily invalidate the - // plan for presentations under $track — another group may still cover it. - // We exclude $track_group from the check because removeCategory has not - // been called yet at this point. - foreach ($presentations as $presentation) { - $selection_plan = $presentation->getSelectionPlan(); - if (is_null($selection_plan)) continue; - $track_reachable_via_another_group = $selection_plan->getCategoryGroups()->exists( - function ($key, $group) use ($track, $track_group) { - return $group->getId() !== $track_group->getId() - && $group->hasCategory($track->getId()); - } - ); - if (!$track_reachable_via_another_group) { - $presentation->clearSelectionPlan(); - } - } - - $track_group->removeCategory($track); + if ($track_group->hasCategory($track->getId())) { + $presentations = $track->getPresentationsBySelectionPlanIds($track_group->getSelectionPlanIds()); + + // Only clear the selection plan if no other category group in that plan + // still contains $track. A selection plan can span multiple groups, so + // removing $track from $track_group does not necessarily invalidate the + // plan for presentations under $track — another group may still cover it. + // We exclude $track_group from the check because removeCategory has not + // been called yet at this point. + foreach ($presentations as $presentation) { + $selection_plan = $presentation->getSelectionPlan(); + if (is_null($selection_plan)) continue; + $track_reachable_via_another_group = $selection_plan->getCategoryGroups()->exists( + function ($key, $group) use ($track, $track_group) { + return $group->getId() !== $track_group->getId() + && $group->hasCategory($track->getId()); + } + ); + if (!$track_reachable_via_another_group) { + $presentation->clearSelectionPlan(); + } + } + + $track_group->removeCategory($track); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/Services/Model/Imp/PresentationCategoryGroupService.php` around lines 255 - 277, Before iterating presentations, verify the track is actually part of the target group to avoid clearing selection plans when it never belonged there: add a guard that checks $track_group->hasCategory($track->getId()) (or equivalent) and return/skip the disassociation logic if false; keep the existing logic using $track->getPresentationsBySelectionPlanIds(...), the loop that checks $selection_plan->getCategoryGroups()->exists(...), and the final $track_group->removeCategory($track) unchanged but only executed after the membership guard passes.
🧹 Nitpick comments (1)
tests/oauth2/OAuth2TrackGroupsApiTest.php (1)
419-429: Drop unused$responseassignment in preserve-path test.
$responseis assigned but never used; removing it keeps the test cleaner without changing behavior.Proposed cleanup
- $response = $this->action( + $this->action( "DELETE", "OAuth2PresentationCategoryGroupController@disassociateTrack2TrackGroup", $params, [], [], [], $headers );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/oauth2/OAuth2TrackGroupsApiTest.php` around lines 419 - 429, The test assigns $response from the call to action(...) in OAuth2TrackGroupsApiTest::preserve-path test but never uses it; remove the unused $response variable and invoke action(...) directly (or just keep the call without assignment) for the DELETE to OAuth2PresentationCategoryGroupController@disassociateTrack2TrackGroup, leaving the subsequent $this->assertResponseStatus(204) intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@app/Services/Model/Imp/PresentationCategoryGroupService.php`:
- Around line 255-277: Before iterating presentations, verify the track is
actually part of the target group to avoid clearing selection plans when it
never belonged there: add a guard that checks
$track_group->hasCategory($track->getId()) (or equivalent) and return/skip the
disassociation logic if false; keep the existing logic using
$track->getPresentationsBySelectionPlanIds(...), the loop that checks
$selection_plan->getCategoryGroups()->exists(...), and the final
$track_group->removeCategory($track) unchanged but only executed after the
membership guard passes.
---
Nitpick comments:
In `@tests/oauth2/OAuth2TrackGroupsApiTest.php`:
- Around line 419-429: The test assigns $response from the call to action(...)
in OAuth2TrackGroupsApiTest::preserve-path test but never uses it; remove the
unused $response variable and invoke action(...) directly (or just keep the call
without assignment) for the DELETE to
OAuth2PresentationCategoryGroupController@disassociateTrack2TrackGroup, leaving
the subsequent $this->assertResponseStatus(204) intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 411e0f77-a95e-4e69-8a09-eae205d2f8cc
📒 Files selected for processing (2)
app/Services/Model/Imp/PresentationCategoryGroupService.phptests/oauth2/OAuth2TrackGroupsApiTest.php
ref https://app.clickup.com/t/86b8rp3vh
Summary by CodeRabbit
Bug Fixes
Refactor
Tests