[404]Add "Invalidate reports from a reporter" action for MRT#644
[404]Add "Invalidate reports from a reporter" action for MRT#644juanmrad wants to merge 4 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughAdds end-to-end reporter-scoped invalidation: UI trigger/modal, GraphQL mutation, service sweep and payload-scrub logic, safe queue operations for removal, DB migration, tests, and docs. ChangesReport Invalidation Feature
Sequence Diagram(s)sequenceDiagram
participant Moderator as Moderator(UI)
participant InvalidateButton as InvalidateReportsButton
participant GraphQL as GraphQL:invalidateReportsFromReporter
participant Service as ManualReviewToolService
participant QueueOps as ReporterInvalidation/QueueOperations
participant Callback as onInvalidated
Moderator->>InvalidateButton: open modal / confirm
InvalidateButton->>GraphQL: mutate(input: reporter, reason?, jobId?)
GraphQL->>Service: invalidateReportsFromReporter(invokedBy, input)
Service->>QueueOps: sweep queues / scrub or delete/update jobs
QueueOps-->>Service: aggregated counters (reportsRemoved, jobsDeleted, truncated)
Service-->>GraphQL: return result
GraphQL-->>InvalidateButton: mutation resolved
InvalidateButton->>Callback: await onInvalidated()
Callback-->>InvalidateButton: resolves
InvalidateButton-->>Moderator: display success/warning, close modal
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ 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 |
There was a problem hiding this comment.
Pull request overview
Adds an MRT action to invalidate reports from a selected reporter, scoped either to the current job or to all pending jobs in the org.
Changes:
- Adds server-side reporter invalidation logic, queue helpers, GraphQL mutation, and tests.
- Adds client UI controls and post-invalidation navigation/refetch behavior.
- Updates docs, generated GraphQL types, and MRT job-id DB column sizing.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
server/services/manualReviewToolService/modules/ReporterInvalidation.ts |
Implements report scrubbing/deletion flow. |
server/services/manualReviewToolService/modules/ReporterInvalidation.test.ts |
Adds unit/integration coverage for invalidation behavior. |
server/services/manualReviewToolService/modules/QueueOperations.ts |
Adds pending-job iteration, job lookup, and removal helpers. |
server/services/manualReviewToolService/manualReviewToolService.ts |
Wires reporter invalidation into MRT service and adjusts job creation logging conflicts. |
server/graphql/modules/manualReviewTool.ts |
Adds GraphQL mutation schema and resolver. |
server/graphql/generated.ts |
Updates generated server GraphQL types. |
client/src/webpages/dashboard/mrt/manual_review_job/InvalidateReportsButton.tsx |
Adds confirmation modal and mutation trigger. |
client/src/webpages/dashboard/mrt/manual_review_job/InvalidateReportsButton.test.tsx |
Tests invalidation button behavior. |
client/src/webpages/dashboard/mrt/manual_review_job/ReportInfoComponent.tsx |
Adds primary reporter invalidation action. |
client/src/webpages/dashboard/mrt/manual_review_job/MergedReportsComponent.tsx |
Adds invalidation actions to merged report rows. |
client/src/webpages/dashboard/mrt/manual_review_job/MergedReportsComponent.test.tsx |
Tests merged report invalidation buttons. |
client/src/webpages/dashboard/mrt/manual_review_job/ManualReviewJobReview.tsx |
Handles permissions, refetching, and advancing after invalidation. |
client/src/graphql/generated.ts |
Updates generated client GraphQL types/hooks. |
docs/user/reports.md |
Documents the new invalidation workflow. |
db/src/scripts/api-server-pg/2026.05.27T21.33.27.widen_mrt_job_id_columns.sql |
Widens MRT job/item id columns and recreates the flattened view. |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
docs/user/reports.md (1)
26-26: ⚡ Quick winConsider breaking this sentence to improve readability.
The sentence contains nested parentheticals and multiple conditions, making it harder to parse. Additionally, the phrase "enqueued purely from a user report" could be clarified—readers might wonder if this distinguishes user reports from automated detection, when it actually means the job had no other reporters or report sources.
✍️ Suggested rewrite for clarity
-By default the action is scoped to the report you're viewing: it strips this reporter's entries from the current job's report history (and removes the job if no other reporters were left and the job was enqueued purely from a user report). Tick "Apply across the whole organization" in the confirmation modal to instead sweep every pending job in the org. Decided/closed jobs are not modified. +By default the action is scoped to the current job: it strips this reporter's entries from the job's report history. If this reporter was the only source for the job, the job is removed from the queue entirely. To instead sweep every pending job in your organization, enable the checkbox in the confirmation modal. Decided or closed jobs are never modified.🤖 Prompt for 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. In `@docs/user/reports.md` at line 26, The long sentence is hard to parse; split it into shorter sentences and remove nested parentheticals: explain first that the default action only affects the current report by removing this reporter's entries from the job's report history (and, if that leaves the job with no other reporters or report sources, remove the job), then state separately that ticking "Apply across the whole organization" in the confirmation modal instead sweeps every pending job in the org; also replace "enqueued purely from a user report" with an explicit phrase such as "the job has no other reporters or other report sources (for example, automated detectors)" and make "Decided/closed jobs are not modified" its own sentence for clarity.
🤖 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 `@server/services/manualReviewToolService/manualReviewToolService.ts`:
- Around line 1183-1195: The invalidateReportsFromReporter method currently only
checks UserPermission.EDIT_MRT_QUEUES and trusts input.orgId, allowing cross-org
mutation; before calling reporterInvalidation.invalidateReportsFromReporter,
override/bind input.orgId to input.invokedBy.orgId (i.e., set input.orgId =
input.invokedBy.orgId) so the service enforces the invokedBy caller's org at the
service boundary and prevents in-process callers from operating on a different
org.
In `@server/services/manualReviewToolService/modules/ReporterInvalidation.ts`:
- Around line 76-90: The span created in tracer.addActiveSpan for operation
'invalidateReportsFromReporter' is missing the audit reason; include the
incoming input.reason (or a sanitized/encoded form) in the span attributes and
any audit sink used by this service so the "reason (optional, logged for audit)"
contract is satisfied. Specifically, update the attributes object in the call to
tracer.addActiveSpan (inside invalidateReportsFromReporter) to add a key like
'reporterInvalidation.reason' whose value is either the raw input.reason or a
jsonStringify/sanitized version, and ensure the same reason is propagated to any
audit logging function used by this module so the reason is recorded for audits.
- Around line 305-330: The DEFAULT payload branch updates reportHistory and
reportedForReasons but leaves legacy singular fields (reportedForReason,
reporterIdentifier) stale; when computing reportedForReasons and reportHistory
(using payload, filteredHistory, filteredReasons), also update or clear
payload.reportedForReason and payload.reporterIdentifier to reflect
filteredHistory[0] (or undefined/null when filteredHistory is empty) so legacy
fields are consistent with the scrubbed state.
---
Nitpick comments:
In `@docs/user/reports.md`:
- Line 26: The long sentence is hard to parse; split it into shorter sentences
and remove nested parentheticals: explain first that the default action only
affects the current report by removing this reporter's entries from the job's
report history (and, if that leaves the job with no other reporters or report
sources, remove the job), then state separately that ticking "Apply across the
whole organization" in the confirmation modal instead sweeps every pending job
in the org; also replace "enqueued purely from a user report" with an explicit
phrase such as "the job has no other reporters or other report sources (for
example, automated detectors)" and make "Decided/closed jobs are not modified"
its own sentence for clarity.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 596199c8-936d-434d-9a20-c0b3a86e3504
⛔ Files ignored due to path filters (2)
client/src/graphql/generated.tsis excluded by!**/generated.tsserver/graphql/generated.tsis excluded by!**/generated.ts
📒 Files selected for processing (13)
client/src/webpages/dashboard/mrt/manual_review_job/InvalidateReportsButton.test.tsxclient/src/webpages/dashboard/mrt/manual_review_job/InvalidateReportsButton.tsxclient/src/webpages/dashboard/mrt/manual_review_job/ManualReviewJobReview.tsxclient/src/webpages/dashboard/mrt/manual_review_job/MergedReportsComponent.test.tsxclient/src/webpages/dashboard/mrt/manual_review_job/MergedReportsComponent.tsxclient/src/webpages/dashboard/mrt/manual_review_job/ReportInfoComponent.tsxdb/src/scripts/api-server-pg/2026.05.27T21.33.27.widen_mrt_job_id_columns.sqldocs/user/reports.mdserver/graphql/modules/manualReviewTool.tsserver/services/manualReviewToolService/manualReviewToolService.tsserver/services/manualReviewToolService/modules/QueueOperations.tsserver/services/manualReviewToolService/modules/ReporterInvalidation.test.tsserver/services/manualReviewToolService/modules/ReporterInvalidation.ts
# Conflicts: # client/src/webpages/dashboard/mrt/manual_review_job/ReportInfoComponent.tsx
|
Checklist:
|
Fixes #404
Context & Requests for Reviewers
Lets moderators with
EDIT_MRT_QUEUES( May need follow up to create a specific permission for this ) invalidate reports from a bad-faith reporter (#404), scoped to the current job or org-wide. Removing a reporter's entries strips them from the job's report history. If that empties a job that was enqueued purely from a user report, the job is removed and the moderator advances to the next item.Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests