Compare commits
2 Commits
37ccef2f12
...
1c7288b778
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c7288b778 | ||
|
|
7accc66710 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
|||||||
* text=auto eol=lf
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -18,7 +18,7 @@ coverage
|
|||||||
/cypress/screenshots/
|
/cypress/screenshots/
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
.idea
|
.idea
|
||||||
*.suo
|
*.suo
|
||||||
@@ -28,3 +28,6 @@ coverage
|
|||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
.env
|
||||||
|
CLAUDE.md
|
||||||
9
.vscode/extensions.json
vendored
9
.vscode/extensions.json
vendored
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"Vue.volar",
|
|
||||||
"vitest.explorer",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"EditorConfig.EditorConfig",
|
|
||||||
"esbenp.prettier-vscode"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
19
AGENTS.md
19
AGENTS.md
@@ -1,19 +0,0 @@
|
|||||||
# Repository Guidelines
|
|
||||||
|
|
||||||
## Project Structure & Module Organization
|
|
||||||
The Vue 3 frontend lives under `src/`. `main.ts` wires the router and Pinia, while `App.vue` hosts global layout. Page-level views sit in `src/views/` (e.g. `AnalyticsView.vue`), with shared widgets under `src/components/`. Pinia logic is grouped in `src/stores/` (one file per domain such as `energy.ts` or `room.ts`), and API/WebSocket helpers in `src/services/`. Reusable hooks belong in `src/composables/`. Static files and icons stay in `public/` or `src/assets/`. Keep demo tooling like `test-websocket.html` at the repo root; production builds land in `dist/`.
|
|
||||||
|
|
||||||
## Build, Test, and Development Commands
|
|
||||||
Run `npm install` once after cloning. `npm run dev` starts Vite locally; use `npm run dev-server` when you need LAN access. `npm run build` performs a type-safe production build (calls `npm run type-check` plus `vite build`). `npm run preview` serves the built bundle. Execute `npm run test:unit` for Vitest suites, `npm run lint` for ESLint (auto-fix enabled), and `npm run format` to apply Prettier to `src/`.
|
|
||||||
|
|
||||||
## Coding Style & Naming Conventions
|
|
||||||
Follow the ESLint + Prettier flat config: 2-space indentation, single quotes in TS, and script setup in Vue SFCs when practical. Name Vue files in PascalCase (`EnergyOverviewCard.vue`), stores in camelCase (`energy.ts` exporting `useEnergyStore`), and composables with the `use` prefix. Keep Tailwind utility classes readable by grouping per concern. Avoid unchecked `console.log`; prefer the logging helpers already present in stores.
|
|
||||||
|
|
||||||
## Testing Guidelines
|
|
||||||
Vitest with the `jsdom` environment powers unit tests; place suites alongside features in `src/**/__tests__/` using `*.spec.ts`. Mock API and WebSocket calls by leveraging Pinia store injection or `vi.mock('../services/api')`. Every new store action or view-level computed branch should gain coverage. Run `npm run test:unit -- --run --coverage` before opening a PR if you add complex domain logic.
|
|
||||||
|
|
||||||
## Commit & Pull Request Guidelines
|
|
||||||
Commits use short, imperative summaries without prefixes (see `git log`). Keep subject lines under ~70 characters and include the affected area, e.g., `Refine room status badges`. Squash fixups locally rather than pushing noisy history. PRs should link to Jira/GitHub issues when relevant, include screenshots or GIFs for UI changes, list test commands run, and call out backend dependencies (e.g., new API fields).
|
|
||||||
|
|
||||||
## Environment & Configuration
|
|
||||||
Frontend defaults to `http://localhost:8000`; override with `VITE_API_BASE_URL` in a `.env.local`. Document new environment flags in `README.md`. Never commit real credentials—use the provided TypeScript definitions in `env.d.ts` to keep variable access typed.
|
|
||||||
189
CLAUDE.md
189
CLAUDE.md
@@ -1,189 +0,0 @@
|
|||||||
# 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<sensorId, SensorDevice>` for all devices
|
|
||||||
- Tracks `latestReadings` as `Map<sensorId, SensorReading>`
|
|
||||||
- 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<boolean>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 `<script setup>`
|
|
||||||
- **TypeScript** - Type-safe development
|
|
||||||
- **Pinia** - State management
|
|
||||||
- **Vue Router** - Client-side routing
|
|
||||||
- **Vite** - Build tool with HMR
|
|
||||||
- **Tailwind CSS** - Utility-first styling
|
|
||||||
- **ECharts** - Primary charting library
|
|
||||||
- **Vitest** - Unit testing framework
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- **Node.js 20.19.0+ or 22.12.0+**
|
|
||||||
- **Redis** on `localhost:6379` (for real-time data)
|
|
||||||
- **Backend** on `localhost:8000` (monolithic or API Gateway)
|
|
||||||
15
Tasks.md
Normal file
15
Tasks.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
Medium
|
||||||
|
- Replace `any` usage with specific types to satisfy lint checks in src/main.ts:27, src/stores/room.ts:315, src/stores/room.ts:319, src/views/ModelsView.vue:707, src/views/ModelsView.vue:714
|
||||||
|
Low
|
||||||
|
- Remove or use unused Vue emits and lifecycle hooks flagged by lint in src/components/cards/DetailedSensorCard.vue:177, src/components/cards/SimpleSensorCard.vue:83, src/components/modals/RoomManagementModal.vue:175, src/components/modals/RoomManagementModal.vue:181, src/main.ts:21, src/stores/energy.ts:19, src/views/AnalyticsView.vue:324, src/views/SensorManagementView.vue:260
|
||||||
|
|
||||||
|
Possible Features
|
||||||
|
- Add real-time toast notifications for critical events surfaced by analyticsApi.getEvents
|
||||||
|
- Provide comparative trend dashboards with configurable periods and benchmarks
|
||||||
|
- Introduce role-based access control screens for managing API tokens and room permissions
|
||||||
|
|
||||||
|
Database Enhancements
|
||||||
|
- Persist user dashboard preferences (selected rooms, time ranges, chart settings) for personalized views
|
||||||
|
- Track sensor metadata history (calibration, firmware updates, maintenance logs) to power diagnostics
|
||||||
|
- Store aggregated room efficiency scores and anomaly flags to speed up analytics queries
|
||||||
Reference in New Issue
Block a user