analytics — CONTEXT.md
Internal Angular 20 dashboard for syncc engineering/ops use only. Aggregates telemetry from all three client apps (web-admin, mobile-driver, passengers-app) across both city silos (Cochabamba and La Paz) into a single unified view. For global conventions (branding, Angular patterns), see
/CLAUDE.md.
1. Purpose
The analytics app consumes the POST /analytics/events endpoint on each silo's API server.
It does not replace the web-admin — it is a separate internal tool for monitoring
product usage, HTTP errors, session durations, and device/platform breakdowns.
2. Routes
| Path | Component | Guard |
|---|---|---|
/login |
LoginComponent (lazy) |
Public |
/dashboard |
DashboardComponent (lazy) |
authGuard |
/ |
Redirects to /dashboard |
— |
** |
Redirects to /dashboard |
— |
3. Dual-Silo Auth
The app authenticates in parallel to both city API servers on login.
Tokens are stored per silo in localStorage:
| Key | Value |
|---|---|
analytics.token.cochabamba |
JWT for api.cbba.dev.syncc.me |
analytics.token.lapaz |
JWT for api.lpz.dev.syncc.me |
- Login succeeds if at least one silo responds with a valid token.
AuthService.isLoggedInis asignal(boolean)derived from whether any token exists.authGuardredirects to/loginwhenisLoggedIn()is false.- Tokens are cleared from
localStorageonlogout().
Credentials must be a SUPER_ADMIN account that exists in the target silo.
4. Services
| Service | Path | Purpose |
|---|---|---|
AuthService |
core/auth.service.ts |
Parallel silo login, token storage, isLoggedIn signal |
AnalyticsService |
core/analytics.service.ts |
Fetches EventsReport from both silos and merges results |
AnalyticsService.getReport(filters)
Queries GET /analytics/events/report on both silos in parallel via Promise.allSettled.
If a city filter is set, only the matching silo is queried.
Results are merged client-side via mergeReports() — sums for numeric fields, union+sort for arrays.
The EventsReport interface shape:
interface EventsReport {
summary: { totalPageViews; totalErrors; totalSessions; avgSessionDurationMs };
breakdown: {
byDevice: { device: string | null; count: number }[];
byPlatform: { platform: string | null; count: number }[];
byCity: { city: string | null; count: number }[];
byApp: { app: string; count: number }[];
};
charts: {
hourlyActivity: { hour: string; count: number }[];
topPaths: { path: string | null; app: string; views: number }[];
topErrors: { path: string | null; code: number | null; app: string; count: number }[];
};
}
5. Dashboard Component
pages/dashboard/dashboard.component.ts — all state via Angular signals.
| Signal / Computed | Purpose |
|---|---|
filterApp, filterCity, startDate, endDate |
Bound to filter inputs (not applied until "Aplicar" click) |
appliedFilters |
Private signal — only updated on applyFilters() |
report |
resource<EventsReport, ...> — reloads when appliedFilters changes |
avgSessionMin |
Derived from report.value()?.summary.avgSessionDurationMs |
totalByApp |
report.value()?.breakdown.byApp |
maxPathViews |
Max views across topPaths (used for bar chart scaling) |
maxAppCount |
Max count across byApp (used for bar chart scaling) |
hourlyBars |
Derived from hourlyActivity — includes heightPct for CSS bar height |
deviceTotal |
Sum of byDevice[*].count (denominator for percentages) |
platformTotal |
Sum of byPlatform[*].count |
The resource() params option drives lazy loading — data only fetches when filters are explicitly applied, not on every keystroke.
6. Environment Config
| File | Used when |
|---|---|
src/environments/environment.ts |
Dev build (ng serve) |
src/environments/environment.prod.ts |
Production build (ng build --configuration=production) |
// environment.ts (dev)
export const environment = {
production: false,
silos: {
cochabamba: 'https://api.cbba.dev.syncc.me',
lapaz: 'https://api.lpz.dev.syncc.me',
},
analyticsKey: 'syncc-analytics',
};
7. Dev Workflow
cd apps/analytics
npm install
npm start # Dev server at http://localhost:4200
npm run build:prod # Production build → dist/analytics/
No set-env.cjs script — environment files are edited directly.
8. Key File Paths
| What | Path |
|---|---|
| Routes | src/app/app.routes.ts |
| App config | src/app/app.config.ts |
| Auth service | src/app/core/auth.service.ts |
| Auth guard | src/app/core/auth.guard.ts |
Analytics service + EventsReport interface |
src/app/core/analytics.service.ts |
| Dashboard page | src/app/pages/dashboard/ |
| Login page | src/app/pages/login/ |
| Environments | src/environments/ |
| Tailwind config | tailwind.config.js |
| Global styles | src/styles.css |
Last updated: 2026-07-05.