Skip to main content

ADR-056: Container Session UI Architecture

Status

Accepted - January 5, 2026

Context

With ADR-055 (Container Session Lifecycle) implemented in the backend, we need a comprehensive frontend dashboard to:

  1. Visualize container sessions across Docker, Cloud Workstations, and Kubernetes
  2. Manage sessions with role-based access (System Admin, Tenant Admin, Team Manager, User)
  3. Monitor real-time heartbeat status and license utilization
  4. Control session lifecycle (terminate, kick users)

Problem Statement

The existing device-level session UI (B.4.4) is insufficient for:

  • Multi-user containers (Cloud Workstations support 1-100 users per container)
  • Container-type differentiation (Docker vs Workstation vs K8s have different behaviors)
  • Hierarchical multi-tenant visibility (AZ1.AI admins see all tenants)
  • Real-time heartbeat monitoring with countdown timers

Requirements

Functional:

  • FR-01: System Admin views all sessions across all tenants
  • FR-02: Tenant Admin views only their tenant's sessions
  • FR-03: Real-time session status updates (5-second polling, WebSocket upgrade path)
  • FR-04: Terminate container sessions with confirmation
  • FR-05: View/kick individual users within multi-user containers
  • FR-06: License utilization visualization

Non-Functional:

  • NFR-01: Dashboard loads in <2s with 100 sessions
  • NFR-02: Mobile responsive (320px - 1920px+)
  • NFR-03: WCAG 2.1 AA accessibility compliance
  • NFR-04: Offline-resilient with graceful degradation

Decision

Component Architecture

We will implement a 28-component dashboard organized into 5 layers:

┌─────────────────────────────────────────────────────────────────┐
│ CONTAINER SESSION DASHBOARD │
├─────────────────────────────────────────────────────────────────┤
│ Layer 1: Dashboard Shell │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ ContainerSessionDashboard (root orchestrator) ││
│ │ ├── DashboardHeader (breadcrumbs, role selector, refresh) ││
│ │ └── SessionMetrics (3 KPI cards) ││
│ └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│ Layer 2: Filtering & Navigation │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ SessionFilters (combined filter bar) ││
│ │ ├── TenantFilter (System Admin only) ││
│ │ ├── ContainerTypeFilter (Docker/Workstation/K8s) ││
│ │ ├── StatusFilter (Active/Released/Expired) ││
│ │ └── SearchBar (container ID, name, hostname) ││
│ └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│ Layer 3: Session List & Cards │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ ContainerSessionList (grid/table view) ││
│ │ └── ContainerSessionCard[] (individual sessions) ││
│ │ ├── SessionStatusBadge ││
│ │ ├── ContainerTypeIcon ││
│ │ ├── UserCountIndicator ││
│ │ ├── HeartbeatTimer (real-time countdown) ││
│ │ └── ActionMenu (terminate, view details) ││
│ └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│ Layer 4: Detail Views │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ SessionDetailDrawer (drawer/modal) ││
│ │ ├── SessionOverview (metadata tab) ││
│ │ ├── UserSessionManager (users in container) ││
│ │ ├── HeartbeatTimeline (chart) ││
│ │ └── SessionMetadata (JSON viewer) ││
│ └─────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────┤
│ Layer 5: Admin & System Views │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ SystemAdminDashboard (platform-wide for AZ1.AI) ││
│ │ ├── TenantSessionOverview (cross-tenant analytics) ││
│ │ ├── LicenseUtilizationChart ││
│ │ └── SessionAlertsBanner ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

Technology Decisions

DecisionChoiceRationale
FrameworkReact 18Existing codebase standard
LanguageTypeScript (strict)Type safety, maintainability
StylingTailwindCSSExisting design system, utility-first
State (Server)React QueryCaching, polling, mutations
State (UI)ZustandSimple, lightweight global state
ChartsRechartsDeclarative, React-native
Real-timePolling → WebSocketPhase 1: 5s polling, Phase 2: WebSocket

Component Inventory (28 Total)

Phase 1: Core Dashboard (P0) - Week 1

#ComponentPriorityLOC Est.Files
1ContainerSessionDashboardP0200src/components/containerSessions/ContainerSessionDashboard.tsx
2DashboardHeaderP0150src/components/containerSessions/DashboardHeader.tsx
3SessionMetricsP0250src/components/containerSessions/SessionMetrics.tsx
4SessionStatusBadgeP050src/components/containerSessions/SessionStatusBadge.tsx
5ContainerTypeIconP040src/components/containerSessions/ContainerTypeIcon.tsx
6HeartbeatTimerP080src/components/containerSessions/HeartbeatTimer.tsx
7SessionErrorBoundaryP0100src/components/containerSessions/SessionErrorBoundary.tsx

Phase 2: Filtering & Lists (P1) - Week 2

#ComponentPriorityLOC Est.Files
8SessionFiltersP1200src/components/containerSessions/SessionFilters.tsx
9TenantFilterP180src/components/containerSessions/filters/TenantFilter.tsx
10ContainerTypeFilterP160src/components/containerSessions/filters/ContainerTypeFilter.tsx
11StatusFilterP160src/components/containerSessions/filters/StatusFilter.tsx
12UserCountIndicatorP150src/components/containerSessions/UserCountIndicator.tsx
13ActionMenuP1100src/components/containerSessions/ActionMenu.tsx
14EmptyStateP160src/components/containerSessions/EmptyState.tsx
15NetworkErrorAlertP180src/components/containerSessions/NetworkErrorAlert.tsx

Phase 3: Detail Views (P1) - Week 2-3

#ComponentPriorityLOC Est.Files
16SessionDetailDrawerP1300src/components/containerSessions/SessionDetailDrawer.tsx
17SessionOverviewP1150src/components/containerSessions/SessionOverview.tsx
18HeartbeatTimelineP2200src/components/containerSessions/HeartbeatTimeline.tsx
19SessionMetadataViewerP2100src/components/containerSessions/SessionMetadataViewer.tsx

Phase 4: Admin Features (P1) - Week 3

#ComponentPriorityLOC Est.Files
20SystemAdminDashboardP1300src/components/containerSessions/admin/SystemAdminDashboard.tsx
21TenantSessionOverviewP1250src/components/containerSessions/admin/TenantSessionOverview.tsx
22LicenseUtilizationChartP2200src/components/containerSessions/admin/LicenseUtilizationChart.tsx
23SessionAlertsBannerP2100src/components/containerSessions/admin/SessionAlertsBanner.tsx

Hooks & State (Supporting)

#ComponentPriorityLOC Est.Files
24useContainerSessionsP0150src/hooks/useContainerSessions.ts ✅ COMPLETE
25useDashboardStoreP1150src/stores/dashboardStore.ts

Already Implemented (B.4.5.2-B.4.5.6)

#ComponentStatusFiles
26ContainerSessionList✅ COMPLETEsrc/components/containerSessions/ContainerSessionList.tsx
27ContainerSessionCard✅ COMPLETEsrc/components/containerSessions/ContainerSessionCard.tsx
28UserSessionManager✅ COMPLETEsrc/components/containerSessions/UserSessionManager.tsx

State Management Architecture

// AuthContext - User role and tenant context
interface AuthContextValue {
user: User;
role: UserRole; // system_admin | tenant_admin | team_manager | user
tenant: Tenant | null;
isSystemAdmin: boolean;
}

// Zustand Dashboard Store - UI state
interface DashboardState {
view: 'grid' | 'list';
filters: SessionFilters;
selectedSessionId: string | null;
isDetailDrawerOpen: boolean;
page: number;
sortBy: string;
sortOrder: 'asc' | 'desc';
}

// React Query - Server state
// useContainerSessions(filters) - List with 5s polling
// useContainerSession(id) - Single session with 5s polling
// useContainerSessionStats() - Dashboard stats with 30s polling
// useTerminateSession() - Mutation with optimistic update
// useKickUser() - Mutation with optimistic update

Real-time Update Strategy

Phase 1 (Immediate): Polling

  • Session list: 5-second intervals
  • Session detail: 5-second intervals
  • Dashboard stats: 30-second intervals
  • Heartbeat timer: 1-second local countdown

Phase 2 (Future): WebSocket Upgrade

  • Django Channels backend
  • WebSocket events: session.created, session.updated, session.released, user.joined, user.left
  • Fallback to polling if WebSocket fails

Role-Based UI Rendering

UI ElementSystem AdminTenant AdminTeam ManagerUser
TenantFilter
All SessionsTenant onlyTeam onlyOwn only
Terminate Action
Kick User Action
SystemAdminDashboard
License Utilization

API Integration

All components use the Container Session API (ADR-055):

EndpointMethodComponent Usage
/api/v1/sessions/GETContainerSessionList
/api/v1/sessions/{id}/GETSessionDetailDrawer
/api/v1/sessions/stats/GETSessionMetrics
/api/v1/sessions/validate/POST(Client SDK only)
/api/v1/sessions/heartbeat/POST(Client SDK only)
/api/v1/sessions/release/POST(Client SDK only)
/api/v1/sessions/{id}/DELETEActionMenu (terminate)
/api/v1/sessions/{id}/users/{user_id}/DELETEUserSessionManager (kick)

Consequences

Positive

  1. Complete Visibility - Admins can monitor all container sessions
  2. Real-time Monitoring - Live heartbeat status and countdown timers
  3. Role-appropriate Access - Each role sees only what they need
  4. Extensible Architecture - Easy to add new container types or views
  5. Production-ready - Error handling, loading states, accessibility

Negative

  1. Complexity - 28 components requires significant development effort (~3 weeks)
  2. Polling Overhead - 5-second polling may strain API at scale (mitigated by WebSocket upgrade path)
  3. State Synchronization - Multiple data sources (React Query + Zustand) require careful coordination

Risks

RiskProbabilityImpactMitigation
Performance degradation with 500+ sessionsMediumHighImplement virtualized lists, pagination
WebSocket upgrade complexityLowMediumRobust polling fallback
Role-based logic bugsMediumMediumComprehensive E2E tests per role

Implementation Roadmap

Week 1: Core Dashboard

  • B.4.5.7: ContainerSessionDashboard
  • B.4.5.8: DashboardHeader
  • B.4.5.9: SessionMetrics (3 cards)
  • B.4.5.10-12: Supporting components (StatusBadge, TypeIcon, Timer)
  • B.4.5.13: SessionErrorBoundary

Week 2: Filters & Detail Views

  • B.4.5.14: SessionFilters (combined)
  • B.4.5.15-17: Individual filters (Tenant, Type, Status)
  • B.4.5.18: SessionDetailDrawer
  • B.4.5.19: SessionOverview
  • B.4.5.20: useDashboardStore (Zustand)

Week 3: Admin & Polish

  • B.4.5.21: SystemAdminDashboard
  • B.4.5.22: TenantSessionOverview
  • B.4.5.23: LicenseUtilizationChart
  • B.4.5.24: SessionAlertsBanner
  • B.4.5.25-27: Error states (Empty, Network, Boundary)
  • B.4.5.28: HeartbeatTimeline chart

Compliance

  • ADR-054: Task IDs follow Track.Section.Task format (B.4.5.x)
  • ADR-055: Uses Container Session API endpoints
  • CODITECT-STANDARD: TailwindCSS, TypeScript strict mode, React Query

References

Revision History

VersionDateAuthorChanges
1.0.02026-01-05Claude (ADR-056)Initial architecture decision