1. Frontend Executive Summary

πŸ“Š Project Overview
Project Name aiusage-app
Framework Angular 15.2.10
TypeScript 4.9.5
Build Tool Angular CLI 15.2.11
State Management RxJS BehaviorSubjects (No NgRx)
HTTP Client Angular HttpClient with 5 Interceptors
UI Notifications ngx-toastr 15.2.2
Charts Chart.js 4.5.1
βœ… Production
Auth & Routing
βœ… Complete
Role-Based Guards
⚠️ Partial
Admin Portal Pages
βœ… Complete
API Integration
Enterprise Readiness: The frontend has a solid architectural foundation with proper authentication, role-based routing, and API integration. The codebase follows Angular best practices with lazy loading, dependency injection, and proper separation of concerns.

2. Current Angular Folder Structure

πŸ“ src/app Directory Tree

src/app/ β”œβ”€β”€ app.component.ts # Root component (minimal) β”œβ”€β”€ app.module.ts # Root module with interceptors β”œβ”€β”€ app-routing.module.ts # Root routing with lazy loading β”‚ β”œβ”€β”€ core/ # Singleton services, guards, interceptors β”‚ β”œβ”€β”€ config/ β”‚ β”‚ └── app-config.ts # APP_CONFIG injection token β”‚ β”œβ”€β”€ guards/ β”‚ β”‚ β”œβ”€β”€ auth.guard.ts # Authentication check β”‚ β”‚ β”œβ”€β”€ admin.guard.ts # Admin/OrgAdmin role check β”‚ β”‚ β”œβ”€β”€ super-admin.guard.ts # SuperAdmin role check β”‚ β”‚ β”œβ”€β”€ role.guard.ts # Multi-role check β”‚ β”‚ └── permission.guard.ts # Fine-grained permission check β”‚ β”œβ”€β”€ interceptors/ β”‚ β”‚ β”œβ”€β”€ auth.interceptor.ts # JWT token injection β”‚ β”‚ β”œβ”€β”€ org.interceptor.ts # X-Active-Organization-Id header β”‚ β”‚ β”œβ”€β”€ loading.interceptor.ts # Loading state management β”‚ β”‚ β”œβ”€β”€ retry.interceptor.ts # HTTP retry logic β”‚ β”‚ └── error.interceptor.ts # Global error handling β”‚ β”œβ”€β”€ handlers/ β”‚ β”‚ └── global-error-handler.ts # Uncaught error handling β”‚ β”œβ”€β”€ services/ β”‚ β”‚ β”œβ”€β”€ auth.service.ts # Authentication & JWT β”‚ β”‚ β”œβ”€β”€ api.service.ts # Base HTTP wrapper β”‚ β”‚ β”œβ”€β”€ org-context.service.ts # Organization context β”‚ β”‚ β”œβ”€β”€ permission.service.ts # Permission checks β”‚ β”‚ β”œβ”€β”€ loading.service.ts # Loading state β”‚ β”‚ β”œβ”€β”€ notification.service.ts # Toast notifications β”‚ β”‚ β”œβ”€β”€ subscription-state.service.ts # Subscription validation β”‚ β”‚ └── export.service.ts # Export functionality β”‚ β”œβ”€β”€ models/ β”‚ β”‚ └── subscription-state.model.ts β”‚ └── core.module.ts # Core module imports β”‚ β”œβ”€β”€ layout/ # Shell components β”‚ β”œβ”€β”€ layout/ β”‚ β”‚ β”œβ”€β”€ layout.component.ts # Main app shell β”‚ β”‚ β”œβ”€β”€ layout.component.html β”‚ β”‚ └── layout.component.css β”‚ β”œβ”€β”€ sidebar/ β”‚ β”‚ β”œβ”€β”€ sidebar.component.ts # Navigation sidebar β”‚ β”‚ β”œβ”€β”€ sidebar.component.html β”‚ β”‚ β”œβ”€β”€ sidebar.component.css β”‚ β”‚ └── nav-menu.config.ts # Navigation menu definition β”‚ β”œβ”€β”€ header/ β”‚ β”‚ β”œβ”€β”€ header.component.ts # Top navigation bar β”‚ β”‚ β”œβ”€β”€ header.component.html β”‚ β”‚ └── header.component.css β”‚ β”œβ”€β”€ footer/ β”‚ β”‚ └── footer.component.ts # Footer component β”‚ └── layout.module.ts # Layout module β”‚ β”œβ”€β”€ modules/ # Feature modules (lazy loaded) β”‚ β”œβ”€β”€ auth/ # Authentication module β”‚ β”‚ β”œβ”€β”€ components/ β”‚ β”‚ β”‚ β”œβ”€β”€ login/ β”‚ β”‚ β”‚ β”œβ”€β”€ register/ β”‚ β”‚ β”‚ β”œβ”€β”€ forgot-password/ β”‚ β”‚ β”‚ β”œβ”€β”€ reset-password/ β”‚ β”‚ β”‚ └── verify-email/ β”‚ β”‚ β”œβ”€β”€ auth.module.ts β”‚ β”‚ └── auth-routing.module.ts β”‚ β”œβ”€β”€ dashboard/ # Dashboard module β”‚ β”‚ β”œβ”€β”€ dashboard.module.ts β”‚ β”‚ └── dashboard-routing.module.ts β”‚ β”œβ”€β”€ users/ # User management β”‚ β”‚ β”œβ”€β”€ users.module.ts β”‚ β”‚ └── users-routing.module.ts β”‚ β”œβ”€β”€ organizations/ # Organization management β”‚ β”‚ β”œβ”€β”€ organizations.module.ts β”‚ β”‚ └── organizations.service.ts β”‚ β”œβ”€β”€ devices/ # Device management β”‚ β”‚ └── devices.module.ts β”‚ β”œβ”€β”€ agents/ # Agent management β”‚ β”‚ └── agents.module.ts β”‚ β”œβ”€β”€ analytics/ # Analytics & reports β”‚ β”‚ └── analytics.module.ts β”‚ β”œβ”€β”€ billing/ # Billing & plans β”‚ β”‚ β”œβ”€β”€ billing.module.ts β”‚ β”‚ └── plans/ β”‚ β”‚ └── plans.module.ts β”‚ β”œβ”€β”€ settings/ # Settings module β”‚ β”‚ └── settings.module.ts β”‚ β”œβ”€β”€ audit-logs/ # Audit log viewing β”‚ β”‚ └── audit-logs.module.ts β”‚ β”œβ”€β”€ hierarchy/ # Organization hierarchy β”‚ β”‚ └── hierarchy.module.ts β”‚ β”œβ”€β”€ data-retention/ # Data retention policies β”‚ β”‚ └── data-retention.module.ts β”‚ β”œβ”€β”€ onboarding/ # Agent onboarding β”‚ β”‚ └── onboarding.module.ts β”‚ β”œβ”€β”€ fleet/ # Fleet management β”‚ β”‚ └── fleet.module.ts β”‚ └── profile/ # User profile β”‚ └── profile.module.ts β”‚ β”œβ”€β”€ shared/ # Shared components, models, utilities β”‚ β”œβ”€β”€ components/ β”‚ β”‚ β”œβ”€β”€ page-not-found/ β”‚ β”‚ β”œβ”€β”€ loading-spinner/ β”‚ β”‚ β”œβ”€β”€ confirm-dialog/ β”‚ β”‚ └── data-table/ β”‚ β”œβ”€β”€ models/ β”‚ β”‚ β”œβ”€β”€ user.model.ts # User, AuthUser, JwtClaims β”‚ β”‚ β”œβ”€β”€ org-context.model.ts # Organization context β”‚ β”‚ β”œβ”€β”€ device.model.ts β”‚ β”‚ β”œβ”€β”€ session.model.ts β”‚ β”‚ └── api-response.model.ts β”‚ β”œβ”€β”€ directives/ β”‚ β”œβ”€β”€ pipes/ β”‚ └── shared.module.ts β”‚ └── device-setup/ # Public device setup (no auth) β”œβ”€β”€ device-setup.component.ts └── device-setup.module.ts

πŸ“Š Module Statistics

Category Count Description
Feature Modules 16 Lazy-loaded feature modules
Route Guards 5 Auth, Admin, SuperAdmin, Role, Permission
HTTP Interceptors 5 Auth, Org, Loading, Retry, Error
Core Services 10+ Auth, API, OrgContext, Permissions, etc.
Layout Components 4 Layout, Sidebar, Header, Footer

3. Routing Architecture Analysis

πŸ›‘οΈ Route Guard Hierarchy

Route Protection Layers ═══════════════════════════════════════════════════════════════════════════════ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ LAYER 1: AuthGuard (Base Protection) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Applied to: LayoutComponent shell route β”‚ β”‚ Purpose: Blocks unauthenticated access to ALL protected routes β”‚ β”‚ Behavior: β”‚ β”‚ β€’ Authenticated β†’ allow β”‚ β”‚ β€’ Unauthenticated β†’ redirect to /auth/login with returnUrl β”‚ β”‚ β”‚ β”‚ Implementation: β”‚ β”‚ - Uses AuthService.isAuthenticated$ (BehaviorSubject) β”‚ β”‚ - Reacts to real-time session changes β”‚ β”‚ - Preserves attempted URL for post-login redirect β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ LAYER 2: Role-Specific Guards β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ SuperAdminGuard β”‚ β”‚ ─────────────── β”‚ β”‚ Routes: /organizations, /hierarchy, /audit-logs, /data-retention, /plans β”‚ β”‚ Allow: superAdmin only β”‚ β”‚ Redirect: /dashboard (if wrong role) β”‚ β”‚ β”‚ β”‚ AdminGuard β”‚ β”‚ ─────────── β”‚ β”‚ Routes: /users, /agents, /analytics, /billing, /fleet, /onboarding β”‚ β”‚ Allow: admin, orgAdmin (superAdmin passes through) β”‚ β”‚ Redirect: /dashboard (if user/manager) β”‚ β”‚ β”‚ β”‚ RoleGuard (Multi-Role) β”‚ β”‚ ───────────────────── β”‚ β”‚ Routes: /devices (roles: ['orgAdmin', 'admin', 'manager']) β”‚ β”‚ /settings (roles: ['superAdmin', 'orgAdmin', 'admin']) β”‚ β”‚ Allow: Any role in data.roles array β”‚ β”‚ Configuration: Route.data = { roles: ['role1', 'role2'] } β”‚ β”‚ β”‚ β”‚ PermissionGuard (Fine-Grained) β”‚ β”‚ ────────────────────────────── β”‚ β”‚ Purpose: Check specific permissions like 'devices:read' β”‚ β”‚ Status: ⚠️ Infrastructure exists, limited usage β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Complete Route Map

Route Module Guard Roles Status
/auth/* AuthModule None (Public) All Production
/device/setup DeviceSetupModule None (Public) All Production
/dashboard DashboardModule AuthGuard All Authenticated Production
/super-admin/dashboard DashboardModule SuperAdminGuard superAdmin Production
/organizations OrganizationsModule SuperAdminGuard superAdmin Production
/hierarchy HierarchyModule SuperAdminGuard superAdmin Partial
/audit-logs AuditLogsModule SuperAdminGuard superAdmin Partial
/settings SettingsModule RoleGuard superAdmin, orgAdmin, admin Production
/data-retention DataRetentionModule SuperAdminGuard superAdmin Planned
/billing BillingModule AdminGuard admin, orgAdmin Partial
/plans PlansModule SuperAdminGuard superAdmin Partial
/users UsersModule AdminGuard admin, orgAdmin Partial
/agents AgentsModule AdminGuard admin, orgAdmin Planned
/analytics AnalyticsModule AdminGuard admin, orgAdmin Partial
/devices DevicesModule RoleGuard orgAdmin, admin, manager Production
/onboarding OnboardingModule AdminGuard admin, orgAdmin Planned
/fleet FleetModule AdminGuard admin, orgAdmin Planned
/profile ProfileModule AuthGuard All Authenticated Production

πŸ”„ Lazy Loading Configuration

// Example lazy loading pattern from app-routing.module.ts { path: 'users', canActivate: [AdminGuard], loadChildren: () => import('./modules/users/users.module').then((m) => m.UsersModule), }
Lazy Loading Status: All feature modules use lazy loading. This provides good code splitting and faster initial page loads. The root module only imports CoreModule, SharedModule, and LayoutModule.

4. Authentication & Login Flow

πŸ” Authentication Architecture Overview

Authentication Flow ═══════════════════════════════════════════════════════════════════════════════ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ STEP 1: Login Initiation β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ User enters credentials on /auth/login β”‚ β”‚ β”‚ β”‚ LoginComponent ──► AuthService.login(email, password, rememberMe) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ STEP 2: API Authentication β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ POST /api/auth/login β”‚ β”‚ Body: { email, password, deviceId? } β”‚ β”‚ β”‚ β”‚ Response: { β”‚ β”‚ token: "eyJhbGciOiJSUzI1NiIs...", ← JWT access token β”‚ β”‚ refreshToken: "dGhpcyBpcyBhIHJlZnJlc2g...", ← Refresh token β”‚ β”‚ user: { id, email, role, organizationId } β”‚ β”‚ } β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ STEP 3: Token Storage & Processing β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ AuthService.processAuthResponse(response): β”‚ β”‚ β”‚ β”‚ 1. Store JWT in: β”‚ β”‚ β€’ rememberMe=true β†’ localStorage (persistent) β”‚ β”‚ β€’ rememberMe=false β†’ sessionStorage (session only) β”‚ β”‚ β”‚ β”‚ 2. Store refreshToken (always localStorage for recovery) β”‚ β”‚ β”‚ β”‚ 3. Decode JWT and extract claims: β”‚ β”‚ β€’ sub (userId) β”‚ β”‚ β€’ email β”‚ β”‚ β€’ organizationId β”‚ β”‚ β€’ role (normalized from PascalCase to camelCase) β”‚ β”‚ β€’ roleLevel (0-4) β”‚ β”‚ β€’ permissions array β”‚ β”‚ β”‚ β”‚ 4. Create AuthUser object and emit to currentUser$ β”‚ β”‚ β”‚ β”‚ 5. Start silent refresh timer (90% of token lifetime) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ STEP 4: Organization Context Initialization β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ OrgContextService.initialize(user): β”‚ β”‚ β”‚ β”‚ IF SuperAdmin: β”‚ β”‚ β€’ Load all organizations via OrganizationsService.getOrganizations() β”‚ β”‚ β€’ Emit availableOrgs$ β”‚ β”‚ β€’ Restore active org from sessionStorage (if exists) β”‚ β”‚ β€’ Allow org switching via header dropdown β”‚ β”‚ β”‚ β”‚ IF Standard User (Admin, Manager, User): β”‚ β”‚ β€’ Build context from JWT claims β”‚ β”‚ β€’ Single organization context β”‚ β”‚ β€’ No org switching capability β”‚ β”‚ β”‚ β”‚ Result: OrgContext { id, name, primaryColor, initials } β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ STEP 5: Navigation to Default Route β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ AuthService.getDefaultRoute(): β”‚ β”‚ β€’ superAdmin β†’ '/super-admin/dashboard' β”‚ β”‚ β€’ admin β†’ '/dashboard' β”‚ β”‚ β€’ others β†’ '/dashboard' β”‚ β”‚ β”‚ β”‚ Router.navigate([defaultRoute]) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”„ Token Refresh Flow

Silent Token Refresh ═══════════════════════════════════════════════════════════════════════════════ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Automatic Refresh (Silent) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ Timer set to: token.exp - Date.now() * 0.9 β”‚ β”‚ (90% of token lifetime) β”‚ β”‚ β”‚ β”‚ When timer fires: β”‚ β”‚ POST /api/auth/refresh β”‚ β”‚ Body: { refreshToken } β”‚ β”‚ β”‚ β”‚ Success: Update stored tokens, reset timer β”‚ β”‚ Failure: Logout user, redirect to login β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Manual Refresh (On 401 Response) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ API returns 401 Unauthorized β”‚ β”‚ β”‚ β”‚ ErrorInterceptor catches 401: β”‚ β”‚ β€’ Attempt token refresh β”‚ β”‚ β€’ If refresh succeeds: retry original request β”‚ β”‚ β€’ If refresh fails: logout and redirect to login β”‚ β”‚ β”‚ β”‚ ⚠️ Note: ErrorInterceptor not fully implemented (placeholder) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”‘ JWT Claims Structure

// JwtClaims interface (from shared/models/user.model.ts) interface JwtClaims { sub: string; // User ID email: string; // User email organizationId?: string; // Tenant ID (null for SuperAdmin) organizationName?: string; // Org name for display role: UserRole; // 'superAdmin' | 'admin' | 'orgAdmin' | 'manager' | 'user' | 'viewer' roleLevel?: string; // 0=SuperAdmin, 1=Admin, 2=Manager, 3=User, 4=Viewer permissions: string[]; // Fine-grained permissions ['devices:read', 'users:write'] iat: number; // Issued at (Unix seconds) exp: number; // Expiry (Unix seconds) }

πŸ›‘οΈ AuthService Key Methods

Method Purpose Returns
login(email, password, rememberMe) Authenticate user Observable<LoginResponse>
logout() Clear session void
refreshToken() Get new access token Observable<boolean>
getCurrentUser() Get current AuthUser AuthUser | null
decodeToken(token) Decode JWT claims JwtClaims
normalizeRole(role) Convert PascalCase to camelCase UserRole
isTokenExpired(token) Check token expiry boolean
getDefaultRoute() Get post-login route string

πŸ“¦ Token Storage Strategy

Storage Token Persistence Use Case
localStorage JWT + RefreshToken Across sessions Remember Me = true
sessionStorage JWT Single session Remember Me = false
sessionStorage aiusage_active_org Single session SuperAdmin org switcher
Memory AuthUser Page lifecycle currentUser$ BehaviorSubject

5. Current Role Handling

πŸ‘₯ Role Definitions

// UserRole type (from shared/models/user.model.ts) type UserRole = 'superAdmin' | 'admin' | 'orgAdmin' | 'manager' | 'user' | 'viewer'; // Role levels (from JWT claims) const ROLE_LEVELS = { superAdmin: 0, // Cross-tenant access admin: 1, // Organization Admin orgAdmin: 1, // Organization Admin (alias) manager: 2, // Department/Team Manager user: 3, // Standard user viewer: 4 // Read-only access };

πŸ“‹ Role Implementation Matrix

Role Backend Frontend JWT Claims Guard Status
SuperAdmin βœ… Exists βœ… Full role: 'superAdmin', roleLevel: 0 SuperAdminGuard Production
Admin βœ… Exists βœ… Full role: 'admin', roleLevel: 1 AdminGuard Production
OrgAdmin βœ… Exists βœ… Full role: 'orgAdmin', roleLevel: 1 AdminGuard Production
Manager βœ… Exists ⚠️ Partial role: 'manager', roleLevel: 2 RoleGuard Partial
User βœ… Exists ⚠️ Partial role: 'user', roleLevel: 3 AuthGuard only Partial
Viewer ⚠️ Exists? ⚠️ Fallback role: 'viewer', roleLevel: 4 Sidebar fallback Planned

🎭 Role Hierarchy Visualization

Role Hierarchy & Access Levels ═══════════════════════════════════════════════════════════════════════════════ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SuperAdmin β”‚ ← Level 0 β”‚ (Cross-tenant) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Admin β”‚ β”‚ OrgAdmin β”‚ β”‚ (Same β”‚ ← Level 1 β”‚ β”‚ β”‚ β”‚ β”‚ Level) β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Manager β”‚ ← Level 2 β”‚(Team/Dept) β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ User β”‚ β”‚ Viewer β”‚ β”‚ (Custom) β”‚ ← Levels 3-4 β”‚ β”‚ β”‚(Read-onlyβ”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ═══════════════════════════════════════════════════════════════════════════════ Access Inheritance: SuperAdmin > Admin/OrgAdmin > Manager > User > Viewer ═══════════════════════════════════════════════════════════════════════════════

🎯 Sidebar Navigation by Role

// nav-menu.config.ts - Navigation items with role restrictions export const NAV_MENU: NavItem[] = [ // All authenticated users { path: '/dashboard', icon: 'dashboard', label: 'Dashboard', roles: ALL_ROLES }, { path: '/profile', icon: 'user', label: 'Profile', roles: ALL_ROLES }, // SuperAdmin only { path: '/organizations', icon: 'building', label: 'Organizations', roles: ['superAdmin'] }, { path: '/hierarchy', icon: 'sitemap', label: 'Hierarchy', roles: ['superAdmin'] }, { path: '/audit-logs', icon: 'file-alt', label: 'Audit Logs', roles: ['superAdmin'] }, { path: '/data-retention', icon: 'archive', label: 'Data Retention', roles: ['superAdmin'] }, { path: '/plans', icon: 'credit-card', label: 'Plans', roles: ['superAdmin'] }, // Admin/OrgAdmin { path: '/users', icon: 'users', label: 'Users', roles: ['admin', 'orgAdmin'] }, { path: '/agents', icon: 'robot', label: 'Agents', roles: ['admin', 'orgAdmin'] }, { path: '/analytics', icon: 'chart-line', label: 'Analytics', roles: ['admin', 'orgAdmin'] }, { path: '/billing', icon: 'dollar-sign', label: 'Billing', roles: ['admin', 'orgAdmin'] }, { path: '/onboarding', icon: 'download', label: 'Onboarding', roles: ['admin', 'orgAdmin'] }, { path: '/fleet', icon: 'server', label: 'Fleet', roles: ['admin', 'orgAdmin'] }, // Admin + Manager { path: '/devices', icon: 'laptop', label: 'Devices', roles: ['admin', 'orgAdmin', 'manager'] }, // Multi-role { path: '/settings', icon: 'cog', label: 'Settings', roles: ['superAdmin', 'orgAdmin', 'admin'] }, ];
⚠️ Role Implementation Gaps:
  • Manager Role: Sidebar shows devices, but manager-specific views not implemented
  • User Role: Only has access to dashboard and profile, self-service features missing
  • Viewer Role: Used as fallback in sidebar, but no explicit viewer pages exist
  • Fine-grained Permissions: PermissionService exists but limited usage in templates

6. Layout/UI Architecture

πŸ—οΈ Layout Component Structure

Layout Component Hierarchy ═══════════════════════════════════════════════════════════════════════════════ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ LayoutComponent (app-layout) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ HeaderComponent (app-header) β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ β”‚ β”‚ β”‚ β€’ Logo / Brand β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β€’ Organization Switcher (SuperAdmin only) β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β€’ Notification Bell β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β€’ User Profile Dropdown β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β€’ Logout Button β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ SidebarComponent β”‚ β”‚ Router Outlet (Feature Modules) β”‚β”‚ β”‚ β”‚ (app-sidebar) β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Dashboard β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β€’ Users β”‚β”‚ β”‚ β”‚ β”‚ Nav Items β”‚ β”‚ β”‚ β€’ Devices β”‚β”‚ β”‚ β”‚ β”‚ (Filtered by β”‚ β”‚ β”‚ β€’ Analytics β”‚β”‚ β”‚ β”‚ β”‚ role) β”‚ β”‚ β”‚ β€’ Settings β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β€’ etc. β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Collapse β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ Toggle β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ FooterComponent (app-footer) - Optional β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Mobile Behavior (< 768px): β€’ Sidebar becomes overlay (full screen) β€’ Toggle button in header β€’ Sidebar auto-collapses on navigation

πŸ“± Responsive Design Strategy

Breakpoint Behavior Implementation
< 768px (Mobile) Sidebar overlay mode MOBILE_BREAKPOINT constant in layout.component.ts
β‰₯ 768px (Desktop) Sidebar inline mode Collapsible but always visible

🎨 UI Framework Assessment

Aspect Implementation Status
CSS Framework Custom CSS (styles.css ~31KB) Custom
Component Library None (custom components) Partial
Icons Font Awesome (assumed from icon names) Production
Notifications ngx-toastr Production
Charts Chart.js Production
Theming Organization-based colors (deterministic HSL) Production
Animations BrowserAnimationsModule Production
⚠️ UI Component Gap: No third-party UI component library (like Angular Material, NG-ZORRO, or PrimeNG) is used. All components are custom-built. This provides flexibility but requires more development effort for complex components (data tables, date pickers, etc.).

7. API Integration Structure

🌐 HTTP Interceptor Chain

HTTP Request Flow (Interceptors) ═══════════════════════════════════════════════════════════════════════════════ Request β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 1. AuthInterceptor β”‚ β”‚ β€’ Adds Authorization header: Bearer ${jwtToken} β”‚ β”‚ β€’ Skips if no token available β”‚ β”‚ β€’ Skips for public endpoints (login, register) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 2. OrgInterceptor β”‚ β”‚ β€’ Adds X-Active-Organization-Id header β”‚ β”‚ β€’ Critical for SuperAdmin org switching β”‚ β”‚ β€’ Reads from OrgContextService.activeOrgId β”‚ β”‚ β€’ Only applies when activeOrgId is set β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 3. LoadingInterceptor β”‚ β”‚ β€’ Sets loading state to true on request start β”‚ β”‚ β€’ Sets loading state to false on response/error β”‚ β”‚ β€’ Triggers loading spinner overlay β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 4. RetryInterceptor β”‚ β”‚ β€’ Retries failed requests up to 3 times β”‚ β”‚ β€’ Exponential backoff between retries β”‚ β”‚ β€’ Only retries on network errors, not 4xx/5xx β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 5. ErrorInterceptor β”‚ β”‚ β€’ Global error handling β”‚ β”‚ β€’ 401 β†’ triggers token refresh β”‚ β”‚ β€’ 403 β†’ shows access denied notification β”‚ β”‚ β€’ Shows toast notification for errors β”‚ β”‚ ⚠️ Currently basic implementation β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό HTTP Client β†’ Backend API ═══════════════════════════════════════════════════════════════════════════════ Response Flow (Reverse Order): Backend β†’ ErrorInterceptor β†’ RetryInterceptor β†’ LoadingInterceptor β†’ OrgInterceptor β†’ AuthInterceptor β†’ Service

πŸ“‘ Service Architecture

Service Purpose Scope
ApiService Base HTTP wrapper with error handling Core
AuthService Authentication, JWT, tokens Core
OrgContextService Organization context, SuperAdmin switching Core
PermissionService Permission checking Core
OrganizationsService Organization CRUD operations Feature
LoadingService Loading state management Core
NotificationService Toast notifications Core
ExportService Data export functionality Core
SubscriptionStateService Subscription validation Core
DashboardDateRangeService Date range state for dashboard Core

πŸ”Œ API Base URL Configuration

// Environment Configuration // environments/environment.ts export const environment = { production: false, apiUrl: 'https://localhost:5001/api', // Development appName: 'AIUsagePlatform' }; // environments/environment.prod.ts export const environment = { production: true, apiUrl: 'https://api.aiusageplatform.com/api', // Production appName: 'AIUsagePlatform' }; // Usage via APP_CONFIG injection token @Inject(APP_CONFIG) private config: AppConfig // Service usage this.http.get(`${this.config.apiUrl}/users`)

πŸ“€ HTTP Error Handling Strategy

Status Handler Behavior
401 Unauthorized ErrorInterceptor Trigger token refresh, retry request
403 Forbidden ErrorInterceptor Show "Access Denied" toast
404 Not Found ApiService Return null or throw specific error
422 Validation Component Display validation errors in form
500+ Server Error ErrorInterceptor Show generic error toast
Network Error RetryInterceptor Retry 3x with backoff, then fail

8. Current Admin Portal Status

πŸ“Š Admin Portal Feature Matrix

Feature Route Backend API Frontend Status
Dashboard /dashboard βœ… /api/admindashboard βœ… Implemented Production
User Management /users βœ… /api/usermanagement ⚠️ Basic List Partial
Device List /devices βœ… /api/admin/organizations/{id}/devices βœ… Implemented Production
Analytics /analytics βœ… /api/analytics ⚠️ Basic Charts Partial
Billing /billing βœ… /api/admin/organizations/{id}/billing ⚠️ Placeholder Partial
Settings /settings βœ… /api/admin/organizations/{id} βœ… Implemented Production
Agent Management /agents ⚠️ Partial πŸ”² Not Started Planned
Onboarding /onboarding βœ… /api/onboarding πŸ”² Not Started Planned
Fleet Management /fleet ⚠️ Partial πŸ”² Not Started Planned
Export/Reports Various βœ… /api/exportjobs ⚠️ Basic Integration Partial

πŸ—οΈ Admin Portal Implementation Status

βœ… Ready
Dashboard & Devices
⚠️ Partial
Users, Analytics, Billing
πŸ”² Missing
Agents, Onboarding, Fleet
Admin Portal Architecture: The Admin Portal uses a shared DashboardModule that renders different views based on the route and user role. The /dashboard route shows the standard admin dashboard, while /super-admin/dashboard shows the SuperAdmin view.

9. Shared Component Analysis

πŸ“¦ Shared Module Structure

src/app/shared/ β”œβ”€β”€ components/ β”‚ β”œβ”€β”€ page-not-found/ # 404 page component β”‚ β”œβ”€β”€ loading-spinner/ # Global loading indicator β”‚ β”œβ”€β”€ confirm-dialog/ # Confirmation dialog β”‚ └── data-table/ # Reusable data table β”œβ”€β”€ models/ # Shared TypeScript interfaces β”‚ β”œβ”€β”€ user.model.ts β”‚ β”œβ”€β”€ device.model.ts β”‚ β”œβ”€β”€ session.model.ts β”‚ └── api-response.model.ts β”œβ”€β”€ directives/ # Custom directives β”œβ”€β”€ pipes/ # Custom pipes └── shared.module.ts # Exports all shared items

🧩 Reusable Component Inventory

Component Purpose Reusability Status
PageNotFoundComponent 404 error page Single use Production
LoadingSpinnerComponent Global loading overlay High (via service) Production
ConfirmDialogComponent Confirmation modals Medium Partial
DataTableComponent Reusable table with sorting/paging High Partial
⚠️ Component Library Gap: Limited reusable component library. Common enterprise components are missing:
  • Form controls (date picker, multi-select, autocomplete)
  • Advanced data grid (filtering, column resizing)
  • Modal/dialog system
  • Card/layout components
  • Badge, chip, tooltip components

10. Frontend Technical Debt Review

πŸ› Identified Technical Debt

Category Issue Severity Impact
Components Limited reusable component library Medium Duplicate code across modules
UI Framework No component library (Material, PrimeNG, etc.) Medium Custom CSS for every component
Role Implementation Manager and User roles incomplete High Limited role-based features
Error Handling ErrorInterceptor is basic Medium Inconsistent error UX
Admin Pages Several modules are placeholders High Incomplete admin experience
Permissions Fine-grained permissions not fully utilized Low Role-only access control
Testing Limited unit test coverage Medium Regression risk

⚠️ Critical Gaps

High Priority Issues
  1. Incomplete Admin Pages: Agents, Onboarding, Fleet modules exist but are not implemented
  2. Manager Role: No manager-specific views (team management, approvals)
  3. User Self-Service: Standard users only have dashboard and profile
  4. Component Reusability: Data tables, forms duplicated across modules

βœ… Strengths

Well-Implemented Areas
  1. Authentication: Complete JWT flow with refresh tokens
  2. Routing: Proper lazy loading and role guards
  3. Tenant Isolation: OrgInterceptor for SuperAdmin context switching
  4. Architecture: Clean separation of core, shared, and feature modules
  5. HTTP Layer: Comprehensive interceptor chain

11. Frontend Enterprise Readiness Score

πŸ“Š Scoring Matrix

Category Score Status Notes
Routing Architecture 9/10 Excellent Lazy loading, guards, proper hierarchy
Role Governance 7/10 Good Guards complete, but Manager/User roles need work
API Integration 9/10 Excellent Interceptors, error handling, org context
Authentication 9/10 Excellent JWT, refresh, storage strategy
UI Scalability 5/10 Needs Work Missing component library
Tenant Awareness 9/10 Excellent OrgInterceptor, context service
Code Organization 8/10 Good Clean folder structure, module separation
Maintainability 7/10 Good Good patterns, limited test coverage
Documentation 6/10 Fair Inline comments good, external docs limited
Enterprise Readiness 7/10 Good Solid foundation, needs component library

🎯 Overall Assessment

76%
Enterprise Ready
7/10
Average Score
βœ…
Architecture Sound
Verdict: The frontend has a solid architectural foundation suitable for enterprise development. Authentication, routing, and API integration are production-ready. The main gaps are in UI component reusability and completion of some feature modules. Recommended next step: Implement a component library or adopt Angular Material for faster UI development.

πŸ“‹ Recommended Priority Order

  1. Immediate: Complete Admin Portal pages (Agents, Onboarding)
  2. Short-term: Add component library (Angular Material recommended)
  3. Medium-term: Implement Manager role views
  4. Ongoing: Add unit tests for critical services