feat: add ghosting functionality to hide members from public lists and unapprove list without deletion#73
Conversation
…d unapprove list without deletion
|
Warning Review limit reached
More reviews will be available in 50 minutes and 13 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a "Dead Zone" moderation feature: the ChangesDead Zone Ghost Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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: 5
🤖 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 `@src/controllers/member.controller.ts`:
- Around line 200-205: The response message in the JSON response at the location
where you construct the message for the ghost action is hardcoded to always say
"moved to Dead Zone" regardless of whether ghost is true or false. Modify the
message construction so that when ghost is true, it states the member is moved
to Dead Zone, and when ghost is false, it states the member is moved out of Dead
Zone. You can use the existing ghost variable to make this message conditional,
similar to how the action variable is already conditionally set.
- Around line 188-199: The authorization logic in the ghostMember endpoint is
using adminId from req.body, which allows clients to spoof an admin ID and
bypass authorization checks. Replace the adminId parameter passed to
memberService.ghostMember() with the authenticated admin ID from the request
context (such as req.user.id or req.admin.id, depending on your authentication
middleware), which should be set by your authentication/authorization middleware
from a verified token or session, rather than trusting client-supplied data from
req.body.
In `@src/services/member.service.ts`:
- Around line 202-208: The prisma.member.update call at Line 202 throws an
unhandled error when the memberId does not exist, resulting in a 500 Internal
Server Error instead of a proper 404 response. Wrap the prisma.member.update
call in a try-catch block to catch the Prisma error (specifically when no record
is found, typically indicated by a PrismaClientKnownRequestError), and throw or
return a 404 "Member not found" error in that catch block. Let other errors
propagate normally or handle them appropriately.
- Around line 214-223: The deadZoneMembers function returns sensitive ghosted
member data including emails and ghostedBy metadata without enforcing any role
authorization checks. Add a role authorization check at the start of the
deadZoneMembers function to verify that the requester has admin privileges
before executing the prisma query. This should reject the request with an
appropriate error if the user lacks the required admin role, preventing
unauthorized access to this sensitive member data.
In `@tests/Member.test.ts`:
- Line 385: Remove the `as any` type cast from the jest.spyOn mock setup for the
deadZoneMembers method in the test. The ghostedList variable should already have
the correct type that matches the return type of the deadZoneMembers method, so
the explicit any cast is unnecessary and violates the no-explicit-any linting
rule. Simply remove the `as any` portion from the mockResolvedValue call to
resolve the lint error.
🪄 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: 607f6bd7-d4e0-47ce-96b8-c856cebd2c4e
📒 Files selected for processing (7)
prisma/migrations/20260616190854_add_is_ghosted/migration.sqlprisma/schema.prismasrc/app.tssrc/controllers/member.controller.tssrc/routes/members.tssrc/services/member.service.tstests/Member.test.ts
💤 Files with no reviewable changes (1)
- src/app.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Summary by CodeRabbit