Portal
›
Admin
›
Organization Analytics
Executive Summary
Organization Analytics APIs provide detailed insights into AI usage patterns, productivity metrics, and user activity across the entire organization. All queries are automatically scoped to the Admin's organization via JWT claims.
✅ Comprehensive Users, sessions, AI tools, trends
✅ Plan-Gated Advanced analytics require Pro+ plans
⚠️ No Caching Queries hit database every request
🎯 Pagination Large datasets use cursor pagination
📊 API Inventory
Controller Route Endpoints Authorization Plan Feature
AnalyticsController
/api/analytics
10
[Authorize]+Plan
Analytics
AdminAnalyticsController
/api/adminanalytics
4
SuperAdmin+Admin
Analytics
TimeAggregationController
/api/timeaggregation
4
[Authorize]
Analytics
🔌 Key Endpoints
Organization Overview
GET
/api/analytics/organization/{id}
Comprehensive organization analytics including user activity, AI usage, and productivity metrics.
Admin+HasPermission Existing
Response: {
"organizationId": "org-123",
"totalUsers": 50,
"activeUsers": 42,
"totalSessions": 1250,
"totalWorkTime": "420:30:00",
"aiUsageTime": "156:45:00",
"aiUsagePercent": 37.2,
"avgProductivityScore": 82,
"topUsers": [...],
"trends": { ... }
}
GET
/api/adminanalytics/overview
Dashboard KPI summary optimized for quick loading.
SuperAdmin+Admin Existing
User Analytics
GET
/api/analytics/top-users
Top users by various metrics: AI usage, session count, productivity.
Admin+HasPermission Existing
GET
/api/analytics/user/{id}
Detailed analytics for a specific user in the organization.
Admin+HasPermission Existing
Trends & Time-Series
GET
/api/analytics/trends
Time-series trends for organization AI usage, productivity, sessions.
Admin+HasPermission Existing
GET
/api/timeaggregation/daily
Daily aggregated metrics with optional filters.
[Authorize] Existing
🅰️ Frontend Integration
Analytics Frontend Data Flow
═══════════════════════════════════════════════════════════════════════════════
Angular Dashboard (home.component.ts)
───────────────────────────────────────────────────────────────────────────────
ngOnInit() {
// 1. Load dashboard KPIs
this.analyticsService.getOrganizationOverview()
.subscribe(data => this.overview = data);
// 2. Load trends for charts
this.analyticsService.getTrends({
fromDate: this.startDate,
toDate: this.endDate
}).subscribe(data => this.chartData = data);
// 3. Load top users list
this.analyticsService.getTopUsers({ limit: 10 })
.subscribe(data => this.topUsers = data);
}
Service Layer (analytics.service.ts)
───────────────────────────────────────────────────────────────────────────────
@Injectable()
export class AnalyticsService {
private apiUrl = '/api/analytics';
getOrganizationOverview(): Observable {
const orgId = this.authService.getCurrentOrgId();
return this.http.get(`${this.apiUrl}/organization/${orgId}`);
}
getTrends(params: DateRange): Observable {
return this.http.get(`${this.apiUrl}/trends`, { params });
}
getTopUsers(options: { limit: number }): Observable {
return this.http.get(`${this.apiUrl}/top-users`, {
params: { limit: options.limit.toString() }
});
}
}
Caching Strategy:
• Component-level: 5-minute cache for KPIs
• HTTP-level: No browser caching (Cache-Control not set)
• Opportunity: Add Redis caching for API responses
🗄️ Database Query Patterns
Endpoint Primary Tables Key Joins Filters
/api/analytics/organization/{id}
Sessions, Users
Users → Sessions (1:N)
OrganizationId = @orgId
/api/analytics/top-users
Sessions, Users
Users → Sessions (aggregate)
OrganizationId, date range
/api/analytics/trends
Sessions
Self (group by date)
OrganizationId, date range
/api/timeaggregation/daily
SessionDailySummary
None (pre-aggregated)
OrganizationId, date range
⚠️ Performance Concerns
✗
N+1 Query Pattern
Top users endpoint queries users then iterates to get session counts. Needs JOIN optimization.
⚠
No Response Caching
Analytics queries executed on every dashboard load. Redis caching recommended with 5-minute TTL.
⚠
Missing Composite Indexes
Need IX_Sessions_OrgId_StartTime for date range queries.
✓
Pre-aggregated Table
SessionDailySummary exists for fast time-series queries but underutilized.