Media Analytics Dashboard โ Developer Guide
Overview
The Media Analytics Dashboard provides platform administrators with real-time insights into media upload activity, storage consumption, file type distribution, and processing pipeline health across the Mallnline platform. It renders as one of five sub-tabs within the Admin Dashboard's Analytics section (Revenue | Blog | Media | Search | Alerts).
| Component | Purpose | Location |
|---|---|---|
| MediaAnalytics.svelte | Full analytics dashboard UI | src/lib/components/admin/MediaAnalytics.svelte |
| GraphQL Queries | 4 media subgraph queries | src/lib/queries/adminAnalytics.ts |
| Admin Integration | Sub-tab in Analytics panel | src/routes/admin/+page.svelte |
| Unit Tests | Utility function coverage | tests/mediaAnalytics.test.ts |
Architecture
graph TD
A["Admin +page.svelte"] --> B["Analytics Sub-Tab Switcher"]
B --> C["RevenueAnalytics"]
B --> D["BlogAnalytics"]
B --> E["MediaAnalytics"]
B --> F2["SearchAnalytics"]
B --> G2["AlertsAnalytics"]
E --> F["GET_MEDIA_UPLOADS_BY_DAY"]
E --> G["GET_MEDIA_TYPE_DISTRIBUTION"]
E --> H["GET_MEDIA_STORAGE_BY_MALET"]
E --> I["GET_MEDIA_STATUS_BREAKDOWN"]
F --> J["media subgraph"]
G --> J
H --> J
I --> J
E --> K["AdminChart (bar)"]
E --> L["AdminChart (line)"]
E --> M["SVG Donut (MIME)"]
E --> N["SVG Donut (Status)"]
style E fill:#06b6d4,color:#fff
style J fill:#dc2626,color:#fff
Data Flow
- User selects the Media sub-tab in the Analytics panel
MediaAnalytics.sveltefires 4 parallelPromise.allSettledGraphQL requests- Each response is independently handled (resilient to partial failures)
- Data is transformed into chart-ready formats and rendered
Component Props
MediaAnalytics
| Prop | Type | Default | Description |
|---|---|---|---|
malets |
{ maletID: string; name: string }[] |
[] |
Available Malets for filter dropdown |
GraphQL Queries
GET_MEDIA_UPLOADS_BY_DAY
Daily upload volume with cumulative storage. Used for the bar chart (upload count) and line chart (storage growth).
query GetMediaUploadsByDay($filter: MediaAnalyticsFilter) {
mediaUploadsByDay(filter: $filter) {
days { date, count, totalSizeBytes }
totalUploads
totalStorageBytes
periodStart
periodEnd
}
}
GET_MEDIA_TYPE_DISTRIBUTION
Files grouped by MIME type โ rendered as a donut chart with per-type legend showing count and storage.
query GetMediaTypeDistribution($filter: MediaAnalyticsFilter) {
mediaTypeDistribution(filter: $filter) {
mimetype
count
totalSizeBytes
}
}
GET_MEDIA_STORAGE_BY_MALET
Storage leaderboard ranked by total bytes โ rendered as a table with medal rankings.
query GetMediaStorageByMalet($limit: Int, $filter: MediaAnalyticsFilter) {
mediaStorageByMalet(limit: $limit, filter: $filter) {
maletId
fileCount
totalSizeBytes
averageFileSize
}
}
GET_MEDIA_STATUS_BREAKDOWN
Processing pipeline health โ donut chart showing PENDING / COMPLETE / FAILED distribution.
query GetMediaStatusBreakdown {
mediaStatusBreakdown {
status
count
}
}
Filter Input
All queries accept MediaAnalyticsFilter:
| Field | Type | Default | Description |
|---|---|---|---|
dateRange |
MediaAnalyticsDateRange |
LAST_30_DAYS |
Preset: LAST_7_DAYS, LAST_30_DAYS, LAST_90_DAYS, LAST_365_DAYS |
maletId |
ID |
โ | Optional Malet scope |
UI Sections
KPI Cards
| Card | Source Field | Formatting | Accent Gradient |
|---|---|---|---|
| Total Uploads | totalUploads |
formatCompact() |
Cyan #06b6d4 โ #22d3ee |
| Total Storage | totalStorageBytes |
formatBytes() |
Teal #14b8a6 โ #2dd4bf |
| Avg File Size | computed | formatBytes() |
Purple #8b5cf6 โ #a78bfa |
| MIME Types | typeDistribution.length |
raw number | Amber #f59e0b โ #fbbf24 |
Charts
- Upload Volume: Bar chart via
AdminChartcomponent, color#06b6d4(cyan) - Storage Growth: Line chart via
AdminChart, color#14b8a6(teal), Y-axis in KB
Donut Charts
- File Type Distribution: SVG donut with
MIME_COLORSmapping, legend shows MIME subtype + count + storage - Processing Health: SVG donut with
STATUS_COLORS(green/amber/red), legend shows status + count
Storage Leaderboard
Table with columns: Rank (emoji medals), Malet ID (truncated mono), Files, Total Storage (formatBytes), Avg File Size (formatBytes).
Utility Functions
`formatBytes(bytes: number): string`
Converts raw bytes to human-readable format with appropriate unit:
formatBytes(0) // "0 B"
formatBytes(1536) // "1.5 KB"
formatBytes(5242880) // "5.0 MB"
formatBytes(1073741824) // "1.0 GB"
MIME Color Map
9 pre-defined colors for common MIME types, with #6b7280 (gray) fallback for unknown types.
Access Control
Media analytics queries require:
@RequirePermission(Permission.MANAGE_ANALYTICS)guard- Runtime
assertPlatformAdmin(actor)verification
The admin page is already guarded by the is_privileged / PLATFORM_ADMIN role check.
File Reference
| File | Purpose |
|---|---|
src/lib/components/admin/MediaAnalytics.svelte |
Dashboard component |
src/lib/queries/adminAnalytics.ts |
GraphQL queries + types (media section) |
src/routes/admin/+page.svelte |
Sub-tab integration |
src/lib/docs/media-analytics-api.md |
Backend API documentation |
src/lib/docs/media-analytics-dashboard.md |
This document |
tests/mediaAnalytics.test.ts |
Unit tests |
Related
- Media Analytics API โ Backend aggregation pipelines
- Admin Analytics Dashboards โ Revenue & Blog analytics
- Workspaces & The Tower โ Tower architecture and all 5 analytics sub-tabs
- Alerts & Resilience โ Alerts sub-tab data source
- Search Engine Administration โ Search sub-tab data source
- Media Infrastructure โ Upload flow, thumbnails, LQIP
- Image Editing Pipeline โ Crop, rotate, resize tools