# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Vue.js 3 frontend for a **Real-Time Energy Monitoring Dashboard** that displays sensor data, room metrics, air quality monitoring, and energy analytics for smart buildings. The frontend connects to either a monolithic backend or microservices architecture via WebSocket and REST APIs. ## Development Commands ```bash # Development npm run dev # Start dev server (http://localhost:5173) npm run dev-server # Dev server with host binding # Building npm run build # Full production build (type-check + build) npm run build-only # Vite build without type checking npm run type-check # TypeScript validation only # Testing & Quality npm run test:unit # Run Vitest unit tests npm run lint # ESLint with auto-fix npm run format # Prettier code formatting ``` ## Architecture ### State Management (Pinia Stores) The application uses **5 specialized Pinia stores** with clear separation of concerns: 1. **`websocket.ts`** - WebSocket connection management - Connects to `ws://localhost:8000/ws` or `ws://localhost:8007/ws` - Buffers incoming messages to prevent UI blocking - Handles proxy info messages for microservices routing - Delegates data processing to sensor/room stores 2. **`sensor.ts`** - Sensor device management - Maintains `Map` for all devices - Tracks `latestReadings` as `Map` - Provides aggregated CO2 metrics (`averageCO2Level`, `maxCO2Level`) - API integration with auth retry logic via `WindowWithAuth` pattern 3. **`room.ts`** - Room-based metrics aggregation - Groups sensor data by room into `RoomMetrics` - Calculates per-room energy consumption and CO2 levels - Provides CO2 status classification (good/moderate/poor/critical) - Estimates occupancy based on environmental data 4. **`energy.ts`** - Energy-specific aggregations - Delegates to other stores (sensor, room, analytics, websocket) - Maintains energy history with configurable `MAX_HISTORY_POINTS` - Provides convenience functions for legacy AnalyticsView compatibility 5. **`analytics.ts`** - System-wide analytics - Fetches analytics summaries from backend API - Tracks system-wide health status - Provides aggregated metrics across all sensors/rooms 6. **`auth.ts`** - JWT authentication - Token generation, validation, and lifecycle management - LocalStorage persistence with expiry checking - Exposed globally via `window.__AUTH_STORE__` for API clients ### API Services (`src/services/`) Service layer organized by domain: - **`api.ts`** - Base API client with types and health checks - **`sensorsApi.ts`** - Sensor CRUD operations - **`roomsApi.ts`** - Room management and data queries - **`analyticsApi.ts`** - Analytics summaries and trends - **`authApi.ts`** - Token generation and validation - **`index.ts`** - Central export point All services use the `WindowWithAuth` pattern to access auth store without circular dependencies. ### Data Flow **Real-time updates:** 1. WebSocket receives sensor reading from backend 2. `websocket.ts` buffers and processes message 3. Data sent to `sensor.ts` (individual readings) AND `room.ts` (aggregations) 4. Vue components react to store changes via computed properties **API data fetching:** 1. Component calls store action (e.g., `sensorStore.fetchApiSensors()`) 2. Store delegates to API service (e.g., `sensorsApi.getSensors()`) 3. Service includes auth header via `useAuthStore().getAuthHeader()` 4. On 401 error, service calls `window.__AUTH_STORE__.ensureAuthenticated()` 5. Retries request with new token ### WindowWithAuth Pattern To avoid circular imports when stores need authentication, the auth store is attached to the global window object: ```typescript // In main.ts (window as any).__AUTH_STORE__ = authStore // In other stores/services interface WindowWithAuth extends Window { __AUTH_STORE__?: { ensureAuthenticated: () => Promise } } const authStore = (window as WindowWithAuth).__AUTH_STORE__ if (authStore) await authStore.ensureAuthenticated() ``` Used in: `sensor.ts`, `room.ts`, `analytics.ts`, `api.ts` ## Data Models ### Dual Format Support The system handles two data formats for backward compatibility: **Legacy Format (energy only):** ```typescript { sensorId: string, timestamp: number, value: number, unit: string } ``` **Multi-Metric Format (current):** ```typescript { sensor_id: string room: string timestamp: number energy: { value: number, unit: string } co2: { value: number, unit: string } temperature?: { value: number, unit: string } } ``` ### Partial Reading Support The system now supports **partial sensor readings** where a single message may contain only energy OR only CO2 data. **Implementation:** - `src/stores/room.ts:44-121` - `updateRoomData()` accepts partial readings and aggregates by metric type - `src/stores/websocket.ts:118-144` - Processes any reading with a room field - Energy metrics aggregate from sensors with `energy.value !== undefined` - CO2 metrics aggregate from sensors with `co2.value !== undefined` This allows `data_simulator_enhanced.py` to send single-metric readings while still populating room-level aggregations correctly. ## Routing 5 main views in `src/router/index.ts`: - `/` - HomeView (dashboard overview) - `/sensors` - SensorManagementView (sensor CRUD) - `/ai-optimization` - AIOptimizationView (AI features) - `/analytics` - AnalyticsView (detailed analytics) - `/settings` - SettingsView (configuration) ## Backend Integration **WebSocket endpoints:** - Monolithic: `ws://localhost:8000/ws` - Microservices: `ws://localhost:8007/ws` (sensor service direct) **REST API:** `http://localhost:8000` (API Gateway for microservices) **Authentication:** JWT tokens via Token Service (port 8001) ## Component Structure **Views:** Page-level components in `/views/` **Cards:** Reusable metric cards in `/components/cards/` **Charts:** Visualization components (multiple chart libraries: ApexCharts, Chart.js, ECharts) ## Key Technologies - **Vue 3** - Composition API with `