Gamend.Chat.Reports (gamend_core v1.0.1192)

Copy Markdown View Source

The chat report queue.

Players report a message through report_message/3; the word filter files its own reports (with reporter_id nil) when a flag word matches. Moderators work the queue from the admin console via list_reports/2 and resolve_report/3.

Reports keep a denormalized reported_user_id and content_snapshot, so the queue still makes sense after the message itself is deleted.

Summary

Functions

Count reports grouped by status, as %{status => count}.

Count reports still awaiting a moderator.

Count reports filed by reporter_id in the last 24 hours.

Count reports matching filters.

Delete a report outright (admin).

Fetch one report with its associations loaded.

List reports, newest first. Filters: :status, :reported_user_id, :reporter_id.

File a report on the word filter's behalf (reporter_id stays nil).

File a report about message_id on behalf of reporter_id.

Resolve a report: set its status, note who resolved it and when.

Claim a report for review ("open""reviewing").

Functions

count_by_status()

@spec count_by_status() :: map()

Count reports grouped by status, as %{status => count}.

count_open_reports()

@spec count_open_reports() :: non_neg_integer()

Count reports still awaiting a moderator.

count_recent_by_reporter(reporter_id)

@spec count_recent_by_reporter(Ecto.UUID.t()) :: non_neg_integer()

Count reports filed by reporter_id in the last 24 hours.

Backs the per-player daily cap; unlike the rate limiter this is durable, so it holds across restarts and every instance.

count_reports(filters \\ %{})

@spec count_reports(map()) :: non_neg_integer()

Count reports matching filters.

delete_report(report)

@spec delete_report(Gamend.Chat.Report.t()) ::
  {:ok, Gamend.Chat.Report.t()} | {:error, Ecto.Changeset.t()}

Delete a report outright (admin).

get_report(id)

@spec get_report(Ecto.UUID.t()) :: Gamend.Chat.Report.t() | nil

Fetch one report with its associations loaded.

list_reports(filters \\ %{}, opts \\ [])

@spec list_reports(
  map(),
  keyword()
) :: [Gamend.Chat.Report.t()]

List reports, newest first. Filters: :status, :reported_user_id, :reporter_id.

report_flagged_message(message, flagged_words)

@spec report_flagged_message(Gamend.Chat.Message.t(), [String.t()]) ::
  {:ok, Gamend.Chat.Report.t()} | {:error, term()}

File a report on the word filter's behalf (reporter_id stays nil).

Called after the flagged message is committed — at filter time it has no id yet.

report_message(reporter_id, message_id, reason \\ nil)

@spec report_message(Ecto.UUID.t(), Ecto.UUID.t(), String.t() | nil) ::
  {:ok, Gamend.Chat.Report.t()} | {:error, term()}

File a report about message_id on behalf of reporter_id.

Returns {:error, :not_found} for an unknown message, {:error, :own_message} when a player reports themselves, and {:error, :already_reported} when they have already reported that message.

resolve_report(report, status, attrs \\ %{})

@spec resolve_report(Gamend.Chat.Report.t() | Ecto.UUID.t(), String.t(), map()) ::
  {:ok, Gamend.Chat.Report.t()} | {:error, term()}

Resolve a report: set its status, note who resolved it and when.

status is one of Gamend.Chat.Report.statuses/0 other than "open".

review_report(report)

@spec review_report(Gamend.Chat.Report.t() | Ecto.UUID.t()) ::
  {:ok, Gamend.Chat.Report.t()} | {:error, term()}

Claim a report for review ("open""reviewing").

Purely a signal to other moderators that someone has picked this one up; it sets no resolution, so the report stays in the queue until it is dismissed or actioned.