Story 2443: User Profile Integration – User Roles #2527
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughIntroduces library-scoped and internal profile roles, dynamic profile-role selection, admin validation, periodic recomputation, and updated v3 author rendering with eager-loaded role relationships. ChangesDisplayed profile role system
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
actor User
participant CurrentUserProfileView
participant V3UserProfileForm
participant UserModel
User->>CurrentUserProfileView: submit selected role
CurrentUserProfileView->>V3UserProfileForm: load role options
CurrentUserProfileView->>UserModel: decode and validate role selection
UserModel-->>CurrentUserProfileView: persist displayed role and library
CurrentUserProfileView-->>User: return updated profile context
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@users/tasks.py`:
- Around line 176-197: Update the stale-selection cleanup around stale_ids so it
cannot overwrite a concurrent legitimate selection: retain each stale user’s
exact displayed_profile_role and displayed_profile_role_library values, then
perform the clearing update inside the transaction only when both fields still
match those snapshot values. Keep the existing role-resolution updates unchanged
and ensure concurrent changes cause the conditional clear to affect no rows.
In `@users/tests/test_profile_role.py`:
- Around line 313-324: Strengthen the unauthorized-role rejection tests,
including test_post_rejects_role_for_unheld_library and the corresponding test
around the second reported range, by first assigning the user an eligible
displayed profile role for library before submitting the tampered role. After
the POST, assert the original role and library ID remain unchanged, proving the
request is rejected rather than ignored.
🪄 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 Plus
Run ID: ff96fd6c-a85d-4211-8cda-0b492fe0003b
📒 Files selected for processing (17)
ak/homepage.pyconfig/celery.pycore/views.pylibraries/tasks.pynews/models.pynews/views.pystatic/css/v3/user-profile-page.csstemplates/v3/posts_list.htmltemplates/v3/user_profile_edit.htmlusers/admin.pyusers/forms.pyusers/migrations/0022_user_displayed_profile_role_and_more.pyusers/models.pyusers/profile_cards.pyusers/tasks.pyusers/tests/test_profile_role.pyusers/views.py
💤 Files with no reviewable changes (1)
- users/profile_cards.py
e212783 to
1871c93
Compare
Issue: #2443
Summary & Context
Adds a real, user-controlled displayed profile role to the User model. A user features a library role they actually hold (Author / Maintainer / Contributor, optionally scoped to a library like "Boost.Beast Author"); staff assign internal C++ Alliance titles (e.g. "Board Member") in the admin. The role is resolved on read with no per-author N+1.
Changes
Profile role model & source of truth
ProfileRoleenum with two groups: library roles (Author / Maintainer / Contributor, user-selectable) and internal C++ Alliance titles (admin-only).User:displayed_profile_role+displayed_profile_role_library(FK) – the library role the user chose to feature, optionally scoped to one library.internal_role– the staff-assigned C++ Alliance title.resolved_profile_role– the auto-derived default (maintained by the recompute task, see below).User.rolethe single source of truth, resolved by precedence: chosen role → internal title → auto-derived role.UniqueConstraint.Role selection (edit page)
_field_combo.html) with a native<select>no-JS fallback.<form>saved by the existing Save Changes button. The new save handler re-validates the choice against the user's own options, so they can never feature a role they don't hold.Admin: assign C++ Alliance titles
EmailUserAdminForm: labelsinternal_roleas "C++ Alliance title" and, when a singular title is already taken, blocks the save with an error naming the current holder (the DB constraint is the hard backstop).Role resolution & performance
.rolereads the storedresolved_profile_rolecolumn directly, so a feed of N posts resolves every author's role with no per-author query.recompute_displayed_profile_roles) refreshes that column after each library/commit import, plus a daily backstop.select_related(...)for the scoped-role FK on the feed, homepage, and post-detail querysets.resolved_profile_rolecolumn, so nothing latency-sensitive needs the matview.Cleanup
users/profile_cards.py(user_profile_card); news cards useEntry.author.to_v3_profile_dict(), andto_v3_post_card_dict()drops its now-unusedauthor_roleargument.Peer-Testing Guidelines
Setup
docker compose exec web python manage.py migrate, thendocker compose restart celery-worker celery-beat.docker compose exec web python manage.py shell -c "from users.tasks import recompute_displayed_profile_roles as t; t()".Find accounts that hold a role
3. Most accounts have no library contributions, so first find ones that do — run this SQL to list users with at least one eligible role:
Exercise the role dropdown
5. Open http://localhost:8000/users/me/?edit=true. If your account has no library contributions, "Your Role" is disabled with the "Contribute to a library to unlock a role" hint. To see it populated (and pick/save a role), impersonate one of the eligible users from step 3 — ⭐️ there's a method to do this locally, reach out to me for details. ⭐️
Admin: C++ Alliance titles
6. In the Users admin, open your account and set a C++ Alliance title — the "Derived library roles" panel shows the eligible roles read-only. Then assign a singular title (e.g. CEO) to a second user — the save is blocked, naming the current holder.
Screenshots
Example of more roles filled out
Self-review Checklist
Frontend
Summary by CodeRabbit