Platform admin, moderation, analytics
Platform admin (/admin)
Only users with is_platform_admin = 1 can open /admin. Grant it with:
php bin/make-admin [email protected] # grant
php bin/make-admin [email protected] --revoke
Emails listed in PLATFORM_ADMIN_EMAILS are promoted automatically by the scheduler task admin.sync_platform_admins (every 5 minutes, needs php bin/worker running or cron php bin/worker --once).
| Page | What it does |
|---|---|
/admin | Tenants, users, MRR estimate (active subscriptions × monthly price), orders today, failed jobs, webhook errors, open reports, live streams / players |
/admin/tenants | Search, change plan (rewrites plan limits), suspend / reactivate, *Open dashboard* (impersonate: sets your session's active tenant) |
/admin/users | Search, platform-wide ban / unban (kills sessions, writes a bans row with tenant_id 0), grant / revoke platform admin |
/admin/refunds | Orders in refunded / disputed state across all tenants |
/admin/audit | Global audit log with action / tenant / user filters |
/admin/flags | Feature flags (feature_flags table). Convention: social.<provider> gates providers that need app review or paid tiers; ai.copilot gates AI features |
/admin/jobs | Queue overview, failed jobs with *Retry*, registered handlers and scheduler tasks |
/admin/webhooks | Inbound webhook events (Stripe, verification…) with errors; *Reprocess* re-queues <provider>.process_event |
Every admin mutation is written to audit_logs with tenant_id = 0.
Moderation (/dashboard/moderation, role ≥ moderator)
- Anyone signed in can report a profile, community, post, user or server (
POST /report). Pages can embed the button with$__view->partial('moderation::report-button', ['type' => 'profile', 'id' => $id]). - Reports are routed to the tenant that owns the target; owners/admins get a notification.
- Moderators resolve / dismiss reports and ban users from one community or the whole workspace (with optional expiry). Banning removes community memberships; banned users get
403when joining. Bans can be lifted. - Moderators cannot ban owners/admins.
Analytics (/dashboard/analytics, role ≥ staff)
KPI tiles (revenue with period-over-period delta, orders + AOV, subscribers with new/churned, members), inline SVG charts (revenue and orders by day, subscribers vs churn per week, server population), top products, per-product order counts, audience (follower counts per connected account) and post performance (from post_targets.metrics). Range 7 / 30 / 90 days, CSV export at /dashboard/analytics/export.csv?range=30.
Conversion is currently *orders per product*: product-view tracking is not wired into the store yet, so view→order conversion cannot be computed.
The scheduler task analytics.rollup (hourly) writes per-tenant daily metrics into analytics_daily (revenue_cents, orders, new_members, players_peak, posts_published, active_subs), which the public API exposes at GET /api/v1/analytics/summary.
Notifications
$app->make('notify')->send($userId, $type, $title, $body, $link, $tenantId) stores an in-app notification and emails the user when they have a verified email and email notifications on. Per-type preferences (orders, security, social, servers, automations, system) live in users.privacy.notify and are managed at /dashboard/notification-settings; security alerts cannot be muted. owners($tenantId, …) notifies every owner/admin of a tenant.