Skip to content

feat: add ghosting functionality to hide members from public lists and unapprove list without deletion#73

Merged
callofcode07 merged 5 commits into
mainfrom
feature/ghost-request
Jun 18, 2026
Merged

feat: add ghosting functionality to hide members from public lists and unapprove list without deletion#73
callofcode07 merged 5 commits into
mainfrom
feature/ghost-request

Conversation

@Harish-Naruto

@Harish-Naruto Harish-Naruto commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Added “Dead Zone” member moderation to ghost/unghost members.
    • New endpoint to list members currently in the Dead Zone.
    • Ghosting is tracked with an audit-style attribution to the moderator.
    • Standard approved/unapproved member listings now exclude ghosted members.
  • Tests
    • Added coverage for ghost/unghost behavior, validation, and Dead Zone listing.
  • Chores
    • Removed an unused client import from app setup.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Harish-Naruto, we couldn't start this review because you've reached your PR review rate limit.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 673bf611-6a21-4245-a648-5152bcce9f61

📥 Commits

Reviewing files that changed from the base of the PR and between f35d8e9 and 7c2ac0b.

📒 Files selected for processing (2)
  • src/controllers/member.controller.ts
  • tests/Member.test.ts
📝 Walkthrough

Walkthrough

Adds a "Dead Zone" moderation feature: the Member table gains isGhosted and ghostedById fields (schema + migration), the service adds role-authorized ghost/unghost logic and excludes ghosted members from approved/unapproved queries, two new Express endpoints expose the feature, and controller tests cover the full feature surface.

Changes

Dead Zone Ghost Feature

Layer / File(s) Summary
Member schema and migration
prisma/schema.prisma, prisma/migrations/20260616190854_add_is_ghosted/migration.sql
Adds isGhosted boolean (default false), ghostedById nullable text, and the MemberGhosts self-referential relationship to the Member model, backed by the SQL migration with ON DELETE SET NULL / ON UPDATE CASCADE.
Ghost service logic and query filters
src/services/member.service.ts
Defines GHOST_ALLOWED_ROLES, filters approvedMembers and unapprovedMembers to exclude ghosted users, adds ghostMember with admin role check and self-ghost prevention, and adds deadZoneMembers returning ghosted members with ghostedBy details.
Controller handlers and Express routes
src/controllers/member.controller.ts, src/routes/members.ts, src/app.ts
Adds ghostMember and getDeadZoneMembers controller handlers with request-body validation; registers GET /dead-zone and PATCH /ghost/:memberId routes with API docs; removes unused supabase import from app.ts.
Controller tests for ghost and dead zone
tests/Member.test.ts
Introduces makeBaseMember helper, extends updateAMember expectations with ghost fields, and adds full suites for ghostMember (ghost, unghost, validation errors, 403 propagation) and getDeadZoneMembers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • call-0f-code/COC-API#72: The new ghostMember authorization logic depends on Role enum and role-based checks standardized in that PR.
  • call-0f-code/COC-API#15: Modifies the same member.controller.ts, routes/members.ts, and services/member.service.ts files to introduce Dead Zone controller handlers and route endpoints.

Suggested reviewers

  • i-am-that-guy

Poem

🐰 Hop hop, into the Dead Zone they go,
A ghost flag flips with one boolean's glow.
Admins decide who fades from the list,
Self-ghosting blocked — no tricks to be missed.
The dead zone awaits with a isGhosted: true,
While bunnies write tests to keep the code through! 🕳️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: adding ghosting functionality to hide members from public lists without deletion.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/ghost-request

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 240cf37 and 06e9c2a.

📒 Files selected for processing (7)
  • prisma/migrations/20260616190854_add_is_ghosted/migration.sql
  • prisma/schema.prisma
  • src/app.ts
  • src/controllers/member.controller.ts
  • src/routes/members.ts
  • src/services/member.service.ts
  • tests/Member.test.ts
💤 Files with no reviewable changes (1)
  • src/app.ts

Comment thread src/controllers/member.controller.ts
Comment thread src/controllers/member.controller.ts
Comment thread src/services/member.service.ts
Comment thread src/services/member.service.ts
Comment thread tests/Member.test.ts
Harish-Naruto and others added 3 commits June 18, 2026 21:41
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@callofcode07 callofcode07 merged commit f2fdf51 into main Jun 18, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants