YourBOX Admin Panel
Purpose
Section titled “Purpose”The 2020 admin surface lives under YourBOX/src/accounts/admin/post/ with three PHP
scripts (index.php, edit.php, delete.php) that render a Bootstrap table and
allow editing or deleting videos. There is no user management, no comment
moderation, no report queue and no audit trail.
The new admin panel is built with EasyAdmin and lives under /admin. It is gated by
the ROLE_ADMIN role from the authentication model and exposes four sections:
catalog, users, moderation and audit.
Layout
Section titled “Layout”flowchart TB Dashboard[Admin dashboard] Dashboard --> Catalog[Catalog: Videos, Tags, Categories] Dashboard --> Users[Users: Accounts, Roles, Sessions] Dashboard --> Moderation[Moderation: Reports, Comments, Actions] Dashboard --> Audit[Audit: Read only log of privileged actions] Catalog --> VideoCrud[Video CRUD: title, tags, status, transcoding state] Users --> UserCrud[User CRUD: search, suspend, role change] Moderation --> ReportCrud[Report queue: pending, acknowledged, resolved] Moderation --> CommentMod[Comment moderation: soft delete, restore] Audit --> AuditList[Audit list: filter by actor, target, action]Each EasyAdmin CRUD class lives under the matching bounded context:
App\Catalog\UserInterface\Admin\VideoCrudControllerApp\Catalog\UserInterface\Admin\CategoryCrudControllerApp\Identity\UserInterface\Admin\UserCrudControllerApp\Moderation\UserInterface\Admin\ReportCrudControllerApp\Moderation\UserInterface\Admin\CommentModerationCrudControllerApp\Moderation\UserInterface\Admin\AuditLogCrudController
Catalog Dashboard
Section titled “Catalog Dashboard”The video CRUD lists every video with filterable columns for status (pending,
published, flagged, removed), uploader username, upload date, view count, like
count and tag set. The edit form exposes the title, description, tag list, main
category and a manual override for the status. The form never touches the storage
keys directly; key management happens server side through the Catalog context.
The list view links each row to the public playback page and to a dry run preview that uses the same Twig template but rendered with the moderator context, so the moderator sees the same playback experience the public sees.
A button on the row triggers a RetryTranscoding command for videos in the failed
status. The handler dispatches a new TranscodeVideo message and updates the status.
Users Dashboard
Section titled “Users Dashboard”The user CRUD lists every user with columns for username, email, role list,
oidc_sub presence, last seen timestamp and account age. Filters include the role,
the oidc_sub presence (to separate OIDC users from local fallback accounts), and
the suspension state.
The role change form is gated by an extra confirmation step that captures a free text reason. The reason is written to the audit log alongside the privilege change.
A “view sessions” action lists active session ids for the user and exposes a
“revoke all sessions” button. The Symfony session storage is Redis, so invalidating
a session is a single Redis DEL for the corresponding key prefix.
Moderation Dashboard
Section titled “Moderation Dashboard”The report queue lists every open Report aggregate with the target (video,
comment, user), the reporter username, the reason category and the elapsed time
since the report was filed. Sorting defaults to oldest first to keep the queue moving.
Opening a report shows the targeted content next to the report payload. The
moderator selects one of three actions: dismiss, acknowledge with a soft delete, or
escalate to admin. Each action dispatches a command in the Moderation context and
records an audit log entry.
The comment moderation view exposes a flat list of comments with a search by username and a date range filter. Soft deletion replaces the rendered content with a tombstone while preserving the thread shape and the foreign keys.
Audit Dashboard
Section titled “Audit Dashboard”The audit log is read only. The CRUD class disables every action except index and
detail. The list view filters by actor (subject or username), action type, target
type and date range. The payload column shows the JSONB body, prettified.
The audit log retention policy is documented on the Observability page: 90 days hot in PostgreSQL, then archived to OpenSearch via Logstash for long term cold storage.
Access Control
Section titled “Access Control”EasyAdmin is mounted under /admin and the route is gated by the access control
rule in security.yaml:
access_control: - { path: ^/admin, roles: ROLE_ADMIN }A non admin user reaching /admin is redirected to /oidc/login if not
authenticated, or returns a 403 if authenticated. The 403 page documents the
contact path to request admin access.
Inside the admin panel, finer permissions are enforced by Symfony voters:
ROLE_MODERATORcan use the moderation dashboard but cannot promote users or delete videos.ROLE_ADMINhas full access.- The audit log is visible to both roles but only
ROLE_ADMINcan export it.
CSRF And Form Defenses
Section titled “CSRF And Form Defenses”Every state changing action in the admin panel passes through Symfony Forms with CSRF protection enabled. EasyAdmin generates the tokens automatically. Bulk actions (soft delete N comments, suspend N users) are batched through Symfony Messenger so that a long running operation does not hold an HTTP request.
Visual Identity
Section titled “Visual Identity”The admin panel uses the Tailwind tokens from the Frontend page applied to
EasyAdmin’s Twig override slots. The look matches the public site: same primary
color, same typography, same spacing scale. EasyAdmin’s default Bootstrap theme is
replaced by Tailwind component classes from app/assets/styles/admin.css.