Remove abuse report user mentions and drop its table

What does this MR do and why?

Drops the abuse_report_user_mentions table and the abuse-report notes/mentions code that fed it.

This started as a fix to add the organization_id sharding key to the table's unique index (Cells compatibility gap). Investigating the write path showed the table is unreachable dead schema, so removing it closes the gap outright instead of patching an index nothing uses.

Why the table is dead

Notes on abuse reports were attempted twice and abandoned both times:

  1. Shared notes table, behind the abuse_report_notes feature flag, never enabled. Those rows were deleted in 17.2 by !155327 (merged), because notes could not be sharded by namespace_id while they existed. abuse_report_user_mentions.note_id is NOT NULL with an ON DELETE CASCADE FK to notes, so that deletion emptied this table too.
  2. A dedicated abuse_report_notes table, dropped in 18.7 by !209042 (merged) under the breaking-change exception at gitlab-com/Product#14362 (closed) — "never released to any customers or instances, so they represent dead code".

The sibling tables went with it — abuse_report_assignees in 18.5 (!207614 (merged)) and abuse_report_labels in 18.6 (!205292 (merged)) — but abuse_report_user_mentions was missed. The sharding-key work on it (!202365 (merged), 18.4) landed before that cleanup, and #553434 (closed) only asked what the table's sharding key should be, never whether the table should exist.

Nothing can write to it today. An abuse-report note cannot even be created:

  • app/models/note.rb:107 requires a namespace for non-project noteables, and AbuseReport has none.
  • does_not_exceed_notes_limit? calls noteable.notes, which AbuseReport does not define — NoMethodError.

Notes and mentions, and why the dependency was total

On other mentionable types the same table pattern carries a second kind of row: description-level mentions, where note_id IS NULL, capturing references in an issue's or MR's own description rather than in a comment. That's why issue_user_mentions has both UNIQUE (issue_id, note_id) and a partial UNIQUE (issue_id) WHERE note_id IS NULL.

Abuse reports never had that second form. note_id was NOT NULL, there was no partial index, and AbuseReport never called attr_mentionable, so its message field was never scanned for references at all.

So for this table specifically the dependency was total: mentions could only ever be derived from notes on abuse reports. With that feature gone twice over, the table has no independent reason to exist — which is what makes dropping it the right move rather than patching its index.

Commits

  1. Remove abuse report notes and user mentions code — the mention model and its association, the orphaned AntiAbuse::Reports::IndividualNoteDiscussion, the Mentionable and Noteable wiring on AbuseReport, AbuseReport from Noteable's replyable and resolvable type lists, Note#for_abuse_report?, the matching UrlBuilder branch, and AbuseReport#project (which existed only so the createNote mutation could call noteable.project; the one other caller, CacheMarkdownField, guards it with respond_to?).
  2. Drop abuse_report_user_mentions table — three FK-removal migrations, the post-deployment drop, the transfer-support registry entry, and the dictionary move.

Notes for reviewers

  • Migration ordering. Each foreign key is removed in its own regular migration ahead of the drop, so no single migration holds locks on more than one parent table. The notes FK goes first and takes its locks in parent-to-child order (remove_foreign_key_if_exists defaults to reverse_lock_order: true) because notes is high-traffic. The table itself is dropped in a post-deployment migration so it outlives the code that referenced it during the rollout window. Same shape as !207614 (merged).
  • Does this need its own breaking-change exception? The 14362 exception covered the abuse_report_labels and abuse_report_notes flags, not this table. !207614 (merged) dropped abuse_report_assignees without a separate one. Given the table is unwritable and empty, I've assumed none is needed — flagging it for group::anti-abuse to confirm.
  • Scope. This sweeps the Mentionable/Noteable wiring and IndividualNoteDiscussion as well as the table, because leaving include Mentionable without has_many :user_mentions would make Mentionable's helpers raise if ever called.

References

Database

abuse_report_user_mentions was table_size: small and, per the history above, is expected to be empty on GitLab.com.

Confirmation that the table is empty in GitLab.com: https://console.postgres.aiundefined/shared/fe27345a-b03f-480c-93e4-68df406d8ac6

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Eugie Limpin

Merge request reports

Loading
Loading