fix: scope Personal feed filter to personal projects only#4969
Conversation
The "Personal" toggle in the "My questions and posts" feed previously sent `access=private`, which matched every post whose default project had no default_permission — including private tournaments and other private projects, not just personal projects. Introduce a dedicated `personal` access value backed by a `Post.filter_personal()` manager method that filters by `default_project.type == PERSONAL_PROJECT`, and switch the frontend filter to use it. Closes #1520 Co-authored-by: Sylvain <SylvainChevalier@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a "personal" access filter distinct from "private". Backend gains a ChangesPersonal Access Filter
Estimated code review effort: 2 (Simple) | ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ 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 |
Collapse filter_personal()'s return to a single line and replace the three sequential access-filter if-branches with a dict dispatch so get_posts_feed stays under the C901 complexity limit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
QA passed, pending code review @hlbmtc |
🚀 Preview EnvironmentYour preview environment is ready!
Details
ℹ️ Preview Environment InfoIsolation:
Limitations:
Cleanup:
|
| access_filters = { | ||
| PostFilterSerializer.Access.PRIVATE: "filter_private", | ||
| PostFilterSerializer.Access.PUBLIC: "filter_public", | ||
| PostFilterSerializer.Access.PERSONAL: "filter_personal", | ||
| } | ||
| if access in access_filters: | ||
| qs = getattr(qs, access_filters[access])() |
There was a problem hiding this comment.
@claude this makes function call implicit and distorts its signature
There was a problem hiding this comment.
Claude finished @hlbmtc's task in 1m 52s —— View job
Fair point — reverted the string-dispatch
You're right: getattr(qs, access_filters[access])() hid the calls to filter_private / filter_public / filter_personal from grep, IDE go-to-definition, and static type checking, and dropped their signatures behind a string lookup.
I only did that to keep get_posts_feed under the C901 complexity limit. Better fix: pull the explicit if/elif chain into a tiny helper so the call sites stay obvious and get_posts_feed's complexity only grows by one function call.
Pushed: f7f00fb
def _apply_access_filter(
qs: Post.objects, access: PostFilterSerializer.Access | None
) -> Post.objects:
if access == PostFilterSerializer.Access.PRIVATE:
return qs.filter_private()
if access == PostFilterSerializer.Access.PUBLIC:
return qs.filter_public()
if access == PostFilterSerializer.Access.PERSONAL:
return qs.filter_personal()
return qsAnd in get_posts_feed:
# Filter by access
qs = _apply_access_filter(qs, access)- Understand the concern (implicit
getattrdispatch) - Restore explicit
filter_*call sites - Keep
get_posts_feedunder C901 by extracting a helper - Push
• Branch: claude/issue-1520-personal-filter-shouldnt-have-private
There was a problem hiding this comment.
@claude Nah, just make it inline -- no need to have a separate function
There was a problem hiding this comment.
Inlining the access filter
- Read
posts/services/feed.py - Remove
_apply_access_filterhelper and inline the branches - Verify ruff C901 complexity still passes
- Commit and push
View job run • Branch: claude/issue-1520-personal-filter-shouldnt-have-private
There was a problem hiding this comment.
Claude finished @hlbmtc's task in 4m 16s —— View job
Inlined the access filter
- Read
posts/services/feed.py - Remove
_apply_access_filterhelper and inline the branches - Commit and push
Pushed: a6187c5
# Filter by access
if access == PostFilterSerializer.Access.PRIVATE:
qs = qs.filter_private()
if access == PostFilterSerializer.Access.PUBLIC:
qs = qs.filter_public()
if access == PostFilterSerializer.Access.PERSONAL:
qs = qs.filter_personal()Note: the earlier commit 1dd6acf had extracted this to a dict dispatch because get_posts_feed's cyclomatic complexity was right at the C901 limit of 56, and 3 sequential ifs pushed it to ~58. If CI now flags C901 on get_posts_feed, the fix should be raising [tool.ruff.lint.mccabe] max-complexity in pyproject.toml (or # noqa: C901 on the function def) — let me know which you prefer and I'll apply it.
• Branch: claude/issue-1520-personal-filter-shouldnt-have-private
Reverts the getattr-by-string dispatch that hid filter_private / filter_public / filter_personal from grep and static analysis. Moves the if/elif chain into _apply_access_filter so get_posts_feed stays under the C901 complexity limit without losing explicit call sites. Co-authored-by: Hlib <hlbmtc@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Remove the _apply_access_filter helper and put the three if branches directly in get_posts_feed. Co-authored-by: Hlib <hlbmtc@users.noreply.github.com>
Closes #1520
Summary
The "Personal" toggle on the "My questions and posts" feed previously sent
access=private, which on the backend matches every post whose default project has nodefault_permission— i.e. private tournaments and other private projects as well as personal projects. Users saw non-personal private questions under the "Personal" chip.This introduces a dedicated
personalaccess value that filters strictly bydefault_project.type == PERSONAL_PROJECT, and wires the frontend "Personal" filter to it. The existingaccess=privatebehavior is unchanged.Changes
posts/serializers.py— addPERSONALtoPostFilterSerializer.Access.posts/models.py— addPost.objects.filter_personal().posts/services/feed.py— routeaccess=personalto the new filter.front_end/.../my_questions_and_posts.tsx— sendaccess=personal.Test plan
pytest).Generated with Claude Code
Summary by CodeRabbit