Executive Summary

Platform Analytics APIs provide SuperAdmins with cross-tenant visibility into AI usage patterns, organization adoption rates, and platform health metrics. These endpoints bypass tenant isolation to deliver aggregated insights across all organizations.

✅ Cross-Tenant Visibility
Aggregated metrics across all organizations
✅ Usage Trends
Daily, weekly, monthly aggregations
⚠️ Performance Risk
Unbounded queries over entire dataset
🎯 Cache Needed
Redis caching recommended

📊 API Inventory

ControllerRouteEndpointsAuthorizationScoping
AdminAnalyticsController /api/adminanalytics 4 SuperAdmin+Admin SuperAdmin=All, Admin=Own
AnalyticsController /api/analytics 10 [Authorize]+Plan Organization-scoped
TimeAggregationController /api/timeaggregation 4 [Authorize] Time-series data

🔌 Platform Analytics Endpoints

Overview & KPIs

GET /api/adminanalytics/overview

Platform-wide KPI summary: total organizations, active users, sessions, AI usage hours.

SuperAdmin only Existing

Response: { totalOrgs, activeUsers, totalSessions, aiUsageHours, trend }

GET /api/analytics/comprehensive

Comprehensive analytics including top users, domains, organizations, and trends.

SuperAdmin+Admin Existing

Usage Trends

GET /api/adminanalytics/usage-trends

Time-series usage trends with date range filtering. Returns daily/weekly aggregated metrics.

SuperAdmin+Admin Existing

Query params: fromDate, toDate, granularity (day|week|month)

GET /api/timeaggregation/daily

Daily aggregated AI usage data with optional organization and user filters.

[Authorize] Existing

Top Organizations & AI Tools

GET /api/adminanalytics/top-tools

Most used AI tools across the platform. Aggregated from all organization usage data.

SuperAdmin only Existing

GET /api/analytics/top-organizations

Top organizations by AI usage, session count, or productivity metrics.

SuperAdmin+Admin Existing

🏢 Cross-Tenant Data Flow

Platform Analytics Data Flow (SuperAdmin Context) ═══════════════════════════════════════════════════════════════════════════════ ┌─────────────────────────────────────────────────────────────────────────────┐ │ SUPERADMIN QUERY │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ User: SuperAdmin │ │ Request: GET /api/adminanalytics/overview │ │ JWT Claims: { role: "SuperAdmin", orgId: null } │ │ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ MultiTenantIsolationMiddleware │ │ │ │ │ │ │ │ if (user.IsSuperAdmin) │ │ │ │ → BYPASS tenant validation (explicit check) │ │ │ │ │ │ │ │ Result: No OrganizationId filter applied │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ AdminAnalyticsController │ │ │ │ │ │ │ │ if (IsSuperAdmin) { │ │ │ │ // Query across ALL organizations │ │ │ │ data = await _analyticsService.GetPlatformOverviewAsync(); │ │ │ │ } │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ IAnalyticsService │ │ │ │ │ │ │ │ // Unbounded query - no WHERE OrganizationId = clause │ │ │ │ var allOrgs = await _orgRepository.GetAllAsync(); │ │ │ │ foreach (var org in allOrgs) { │ │ │ │ metrics.Add(await GetOrgMetricsAsync(org.Id)); │ │ │ │ } │ │ │ │ │ │ │ │ ⚠ N+1 Query Pattern - calls repo per organization! │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Database Query │ │ │ │ │ │ │ │ SELECT o.*, COUNT(s.Id) as SessionCount, │ │ │ │ SUM(s.AIUsageTime) as TotalAIUsage │ │ │ │ FROM Organizations o │ │ │ │ LEFT JOIN Sessions s ON s.OrganizationId = o.Id │ │ │ │ WHERE s.StartTime >= @fromDate AND s.StartTime <= @toDate │ │ │ │ GROUP BY o.Id, o.Name │ │ │ │ │ │ │ │ ⚠ Missing composite index: IX_Sessions_OrgId_StartTime │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ Response: Aggregated metrics across all tenants │ │ │ └─────────────────────────────────────────────────────────────────────────────┘

📈 Scalability & Performance Concerns

N+1 Query Pattern
SuperAdmin endpoints iterate organizations and query each separately. At 1000 orgs = 1000 queries.
Missing Composite Index
Sessions table lacks IX_Sessions_OrgId_StartTime. Date range queries scan full table.
No Caching
Platform-wide metrics re-queried on every request. Should cache for 5-15 minutes.
Memory Pressure
Large result sets loaded into memory for aggregation. Risk of OOM at scale.

✅ Recommended Improvements

1. Pre-Aggregated Tables

Create SessionDailySummary, OrganizationDailyStats tables with hourly aggregation jobs.

Recommended High Priority

2. Redis Cache Layer

Cache platform-wide KPIs with 5-minute TTL. Cache key: platform:kpi:overview

Recommended High Priority

3. Materialized Views

Use SQL Server indexed views for top organizations, top tools aggregations.

Recommended Medium Priority

4. Pagination

Add pagination to organization lists. Currently loads all orgs into memory.

Recommended Medium Priority

🗄️ Database Dependencies

TableRelationshipUsageIndex Status
OrganizationsPrimaryList all orgs, filter by status✓ PK on Id
SessionsChildAggregate usage time, session counts⚠ Missing composite index
UsersChildCount active users per org✓ FK on OrganizationId
DevicesChildCount registered devices✓ FK on OrganizationId
SessionDailySummaryChildUnderutilizedExists but not used