Skip to content

Report Remotes messages and people to moderators - #1518

Open
shanerbaner82 wants to merge 1 commit into
dev-null-sh:productionfrom
shanerbaner82:feat/report-messages-and-users
Open

shanerbaner82 wants to merge 1 commit into
dev-null-sh:productionfrom
shanerbaner82:feat/report-messages-and-users

Conversation

@shanerbaner82

Copy link
Copy Markdown
Contributor

Summary

Apple rejected the /dev/null iOS app under App Store Review Guideline 1.2, which requires apps with user-generated content to let people report objectionable content and abusive users. Commits could already be reported. Remotes messages and people could not. This PR adds API endpoints for reporting both, plus a moderation tab where admins review and dismiss those reports. The mobile app PR NativePHP/dev-null-app uses these endpoints (linked below).

cc @nunomaduro @simonhamp

Changes

  • POST api/v1/remotes/messages/{message}/reports (api-message-report.store) and POST api/v1/users/{user:handle}/reports (api-user-report.store).
    • Body: {reason, details?}, using the same reasons as commit reports. Response: 204.
    • Reporting the same thing again keeps the first report.
    • A message the reporter can't see, an org event, or a missing id all get the same 404.
    • Reporting your own message returns 403 own_message, and reporting yourself returns 403 own_profile.
    • Both endpoints share a new reports rate limit of 5 per minute per user.
  • New message_reports and user_reports tables, models and factories, mirroring commit_reports.
    • Foreign keys cascade on delete.
    • reporter_id is never serialized.
  • Actions: CreateMessageReport, CreateUserReport, UpdateMessageReportDismissedAt and UpdateUserReportDismissedAt. They notify admins with UsersUpdated(..., Moderation), which carries ids only.
  • Moderation: a new admin-only Messages & people tab (moderation/people-reports). It lists open reports with the reported message's text or the reported person, each linked to the profile where timeout and ban already live, with a Dismiss button.
  • Account deletion cascades remove these reports. CreateExport includes the reports a user filed, and schema_version goes from 8 to 9.
  • KNOWLEDGE_BASE.md has a new user-facing section, "Reporting messages and people".

Not included: AI moderation of messages before they are sent. Commits already go through ModerationProvider. Doing the same for Remotes would send private, encrypted-at-rest DMs to OpenAI, which the data guidelines push against, so I left it out on purpose. For direct messages, reporting plus the existing blocking covers 1.2. This is open for discussion if you want it.

Validation

All of these were run locally on PHP 8.5 with Postgres 17. CI has not run yet.

  • pest --parallel --ci --coverage --exactly=100.0: 5887/5887 passed, 100.0% coverage. This used Herd's xdebug, and the web tests ran with a temporary public/hot, because the local Vite build was missing.
  • PHPStan: 0 errors.
  • Type coverage: 100%.
  • Pint and Rector: passed.
  • bun run test:lint: passed, with warnings only.
  • bun run test:types: passed.
  • bun run test:unit: 308 passed.

Independent review

A separate reviewer agent did a read-only review of the staged diff on base af8dc37a. It checked the change against .ai/guidelines and the existing commit-report implementation. Verdict: correctness, regressions, architecture and tests all PASS. It found no authorization holes and no leaks to non-admins. Its non-blocking notes are listed under Limitations.

Limitations

  • Evidence can disappear. The moderation page shows the message's current text. Deleting the message removes its reports, and an author could edit or delete a message before a moderator reviews it. Commit reports work the same way. Storing a copy of the text on the report would fix this, but it means storing more data.
  • Naming. ReportedUserController, ReportedUsersQuery and reported-user.index serve both message and user reports. They could be split into separate message and user versions.
  • Duplicate notifications. Repeat reports and repeat dismissals send the admin moderation event again. The only effect is a little extra realtime noise.
  • Moderation tab is basic. It has no realtime updates and no infinite scroll, and it shows up to 100 open reports per list.
  • No screenshots. The only UI change is the admin-only moderation tab, so this PR has no media.

Adds POST remotes/messages/{message}/reports and POST users/{user}/reports
for the mobile app, alongside commit reports, and a Messages & people
moderation tab where admins see open reports and dismiss them.
@shanerbaner82

Copy link
Copy Markdown
Contributor Author

The mobile app side is NativePHP/dev-null-app#173.

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.

1 participant