Two new moderator role types landed today: File Moderator and Game Moderator, both scoped per-platform. This is the first phase — schema, apply flow, admin appointment, and profile surfacing — with the actual mod-facing action queues coming in a later pass.
How to apply. Head to any /files/{platform} page (e.g. /files/atari-st) or any /games/{shelf} page whose platform has a row in the platforms table (C64, C128, VIC-20, Atari XL/XE today). If the platform has no moderators yet you'll see an Apply to be a File Moderator or Apply to be a Game Moderator button. Click, and the application lands in the super-admin's queue.
How appointment works. Super-admins manage all of it from one page: /admin/platform-mods. Three blocks:
- Pending applications — approve or deny with one click. Approving creates a plain
moderatorrow; the "owner" role is super-admin-appointed directly via the grant form. - Grant form — pick a platform, a username, scope (files or games), and role (moderator or owner). One row = one click.
- Per-platform mod cards — each platform that has at least one mod shows a card listing its file mods and game mods, with Revoke buttons per row.
Every appointment, revocation, approval, and denial audit-logs as platform.file_mod_appointed, platform.file_mod_revoked, platform.game_mod_appointed, platform.game_mod_revoked, platform.mod_app_approved, or platform.mod_app_denied — all visible in the existing admin audit view alongside forum mod actions.
Profile surfacing. On /profile/{username} there's now a "Moderator of:" line under the existing role pill, listing every scope a user moderates — forum, category, file platform, game platform — each as a clickable link back to the scope. Hidden for users with no memberships. Public: anonymous visitors see the same badges as logged-in ones, matching the existing forum-mod transparency.
Combinations are expected. A user can be a C64 file mod AND a C64 game mod AND a moderator of the Commodore 64 forum — all different rows in different tables, all visible together on the profile. The permission surfaces don't overlap; a file mod has no game mod authority, and vice versa.
What's still to build (later phases). The actual moderator action tooling — triaging file_reports, marking games as needing-review, rollback/soft-delete with restore, appeal paths, escalation-to-SysOps, a mod-facing metrics dashboard. Each will ship with its own plan-first review rather than a lump of surprise behavior. This phase's job was to stand up the membership substrate; the workflow surfaces sit on top of it.
Implementation details for anyone poking around:
- New tables:
file_moderatorsandgame_moderators, both mirroringforum_moderatorskeyed on(platform_id, user_id, role). Migration atdatabase/migrations/2026-04-21-platform-moderators.sql. - New models:
App\Models\FileModerator,App\Models\GameModerator. - New helper:
App\Helpers\ModeratorBadges::forUser($userId)— aggregates memberships across every scope for the profile renderer. AlsoscopeLabel($scope)for human-readable labels. - New admin controller:
App\Controllers\AdminPlatformModController— super-admin-only viarequireRole(5), CSRF-validated on all POSTs. mod_applications.target_typeenum widened from('forum','category')to('forum','category','file_platform','game_platform'). Existing forum and category applications are unaffected.- Plan doc at
docs/plans/platform-moderators-phase-1.mdcaptures the full shape + open-question answers so future work knows why it's structured this way.
Four commits shipped: phase 1a (schema + models + helper), 1b (apply buttons + flow), 1c (admin UI), 1d (profile surfacing). Latest on main is ad57747.