Complete IoT monitoring platform for Acuvim II power meters via ESP32. Firmware (Phases 1-7): - ESP32-WROVER-B (TTGO T-Call v1.4) with RS485 Modbus RTU - WiFi STA+AP concurrent mode with GSM/GPRS failover - Transport abstraction layer with 4 priority modes - MQTT protocol with 20 commands, LWT, QoS, exponential backoff - SD card offline buffering with JSONL rotation and non-blocking drain - OTA firmware updates with dual partition rollback protection - Watchdog timer, crash loop detection, Acuvim health monitoring - Captive portal provisioning with AP mode Console backend (Phase 8): - .NET 10 minimal API with PostgreSQL + EF Core - JWT authentication, SignalR real-time updates - MQTTnet 5.x bridge service with health monitoring - Device, telemetry, firmware, alert, group management - Rate limiting, security headers, Swagger/OpenAPI Frontend (Phase 9): - React 18 + TypeScript + Vite with Ant Design 5 - ECharts telemetry visualization, TanStack Query - SignalR live updates, device management UI - Dashboard, fleet management, firmware deployment Testing & Production (Phase 10): - 28 firmware unit tests (Modbus, JSON, config, version) - 23 xUnit backend tests (device, telemetry, command, alert) - Docker Compose with nginx, TLS MQTT, PostgreSQL - Production deployment, commissioning, and troubleshooting docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
522 lines
28 KiB
Markdown
522 lines
28 KiB
Markdown
# Phase 9: Console Application Frontend
|
||
|
||
## Objective
|
||
|
||
Build the web-based frontend dashboard for the console application. The frontend provides device fleet management, real-time telemetry visualization, remote configuration, OTA firmware deployment, and alert management. It connects to the backend API (Phase 8) and uses SignalR for real-time updates.
|
||
|
||
## Prerequisites
|
||
|
||
- Phase 8 complete (backend API running)
|
||
- Node.js 18+ (for frontend build tooling)
|
||
- Design system chosen
|
||
|
||
## Deliverables
|
||
|
||
1. React SPA with responsive dashboard
|
||
2. Device fleet overview with status indicators
|
||
3. Individual device detail page (telemetry, config, health)
|
||
4. Real-time telemetry charts
|
||
5. Remote configuration interface
|
||
6. Firmware management and deployment UI
|
||
7. Alert management dashboard
|
||
8. User authentication flow
|
||
|
||
---
|
||
|
||
## 9.1 Technology Stack
|
||
|
||
| Component | Technology | Justification |
|
||
|-----------|-----------|---------------|
|
||
| Framework | React 18 | Component-based, large ecosystem |
|
||
| Language | TypeScript | Type safety, better DX |
|
||
| Build | Vite | Fast HMR, modern bundling |
|
||
| Routing | React Router v6 | Standard React routing |
|
||
| State | TanStack Query (React Query) | Server state caching, auto-refresh |
|
||
| UI Library | Ant Design 5 | Complete component set, tables, forms, charts |
|
||
| Charts | Apache ECharts (via echarts-for-react) | High-performance, rich chart types |
|
||
| Real-time | @microsoft/signalr | SignalR client for live updates |
|
||
| HTTP | Axios | HTTP client with interceptors |
|
||
| Forms | Ant Design Form | Built-in validation |
|
||
| Icons | Ant Design Icons | Consistent with UI library |
|
||
|
||
## 9.2 Project Structure
|
||
|
||
```
|
||
console/
|
||
├── frontend/
|
||
│ ├── package.json
|
||
│ ├── tsconfig.json
|
||
│ ├── vite.config.ts
|
||
│ ├── index.html
|
||
│ ├── public/
|
||
│ │ └── favicon.ico
|
||
│ └── src/
|
||
│ ├── main.tsx
|
||
│ ├── App.tsx
|
||
│ ├── api/
|
||
│ │ ├── client.ts # Axios instance with auth interceptor
|
||
│ │ ├── devices.ts # Device API calls
|
||
│ │ ├── telemetry.ts # Telemetry API calls
|
||
│ │ ├── firmware.ts # Firmware API calls
|
||
│ │ ├── alerts.ts # Alert API calls
|
||
│ │ ├── auth.ts # Auth API calls
|
||
│ │ └── commands.ts # Command API calls
|
||
│ ├── hooks/
|
||
│ │ ├── useDevices.ts
|
||
│ │ ├── useTelemetry.ts
|
||
│ │ ├── useSignalR.ts
|
||
│ │ └── useAuth.ts
|
||
│ ├── pages/
|
||
│ │ ├── LoginPage.tsx
|
||
│ │ ├── DashboardPage.tsx
|
||
│ │ ├── DeviceListPage.tsx
|
||
│ │ ├── DeviceDetailPage.tsx
|
||
│ │ ├── FirmwarePage.tsx
|
||
│ │ ├── AlertsPage.tsx
|
||
│ │ ├── GroupsPage.tsx
|
||
│ │ └── SettingsPage.tsx
|
||
│ ├── components/
|
||
│ │ ├── layout/
|
||
│ │ │ ├── AppLayout.tsx
|
||
│ │ │ ├── Sidebar.tsx
|
||
│ │ │ └── Header.tsx
|
||
│ │ ├── devices/
|
||
│ │ │ ├── DeviceTable.tsx
|
||
│ │ │ ├── DeviceCard.tsx
|
||
│ │ │ ├── DeviceStatusBadge.tsx
|
||
│ │ │ ├── DeviceConfigForm.tsx
|
||
│ │ │ ├── WifiScanModal.tsx
|
||
│ │ │ └── CommandModal.tsx
|
||
│ │ ├── telemetry/
|
||
│ │ │ ├── TelemetryChart.tsx
|
||
│ │ │ ├── LiveReadings.tsx
|
||
│ │ │ ├── PowerGauge.tsx
|
||
│ │ │ └── EnergyCounter.tsx
|
||
│ │ ├── firmware/
|
||
│ │ │ ├── FirmwareUpload.tsx
|
||
│ │ │ ├── FirmwareTable.tsx
|
||
│ │ │ └── DeployModal.tsx
|
||
│ │ ├── alerts/
|
||
│ │ │ ├── AlertTable.tsx
|
||
│ │ │ └── AlertBadge.tsx
|
||
│ │ └── dashboard/
|
||
│ │ ├── FleetSummary.tsx
|
||
│ │ ├── DeviceMap.tsx
|
||
│ │ └── RecentAlerts.tsx
|
||
│ ├── types/
|
||
│ │ ├── device.ts
|
||
│ │ ├── telemetry.ts
|
||
│ │ ├── firmware.ts
|
||
│ │ └── alert.ts
|
||
│ └── utils/
|
||
│ ├── formatters.ts
|
||
│ └── constants.ts
|
||
```
|
||
|
||
## 9.3 Page Layouts
|
||
|
||
### Dashboard (Home)
|
||
|
||
Fleet-level overview — the first thing operators see.
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ ☰ Tau Acuvim Console admin ▼ [Logout] │
|
||
├──────┬──────────────────────────────────────────────────────┤
|
||
│ │ │
|
||
│ Nav │ Fleet Overview │
|
||
│ │ ┌──────────┬──────────┬──────────┬──────────┐ │
|
||
│ 📊 │ │ Total │ Online │ Degraded │ Offline │ │
|
||
│Dash │ │ 24 │ 21 │ 1 │ 2 │ │
|
||
│ │ └──────────┴──────────┴──────────┴──────────┘ │
|
||
│ 📱 │ │
|
||
│Devs │ ┌────────────────────┬──────────────────────┐ │
|
||
│ │ │ Recent Alerts │ Fleet Power │ │
|
||
│ 📦 │ │ ⚠ Overvoltage │ ┌─────────────────┐ │ │
|
||
│FW │ │ ACV-001 2m ago │ │ Line chart │ │ │
|
||
│ │ │ ⚠ Modbus error │ │ (total kW over │ │ │
|
||
│ 🔔 │ │ ACV-015 5m ago │ │ last 24h) │ │ │
|
||
│Alert │ │ ● Device offline │ └─────────────────┘ │ │
|
||
│ │ │ ACV-008 1h ago │ │ │
|
||
│ ⚙ │ └────────────────────┴──────────────────────┘ │
|
||
│Sets │ │
|
||
│ │ Device Status Grid │
|
||
│ │ ┌──────┬──────┬──────┬──────┬──────┬──────┐ │
|
||
│ │ │●001 │●002 │●003 │●004 │●005 │●006 │ │
|
||
│ │ │230V │231V │229V │232V │ OFF │230V │ │
|
||
│ │ │10kW │12kW │9kW │11kW │ -- │8kW │ │
|
||
│ │ └──────┴──────┴──────┴──────┴──────┴──────┘ │
|
||
│ │ │
|
||
└──────┴──────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Device List
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ Devices [+ Add Group] [⚡ Deploy] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Filter: [All ▼] [Online ▼] [Group ▼] Search: [________] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Status │ Device ID │ Name │ FW │ Conn │ P │
|
||
│────────┼─────────────────┼───────────────┼───────┼──────┼────│
|
||
│ ● │ ACV-AABBCCDDEEFF│ Building A │ 1.0.0 │ WiFi │10kW│
|
||
│ ● │ ACV-112233445566│ Building B │ 1.0.0 │ GSM │12kW│
|
||
│ ◐ │ ACV-FFEEDDCCBBAA│ Warehouse │ 0.9.0 │ WiFi │ 9kW│
|
||
│ ○ │ ACV-998877665544│ Solar Farm │ 1.0.0 │ -- │ -- │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Showing 1-20 of 24 devices < 1 2 > │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
|
||
Status indicators: ● Online ◐ Degraded ○ Offline
|
||
```
|
||
|
||
### Device Detail
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ ← Devices / ACV-AABBCCDDEEFF - Building A │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ [Overview] [Telemetry] [Config] [Alerts] [Commands] [OTA] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ── Overview Tab ── │
|
||
│ │
|
||
│ Device Info │ Connection │
|
||
│ ID: ACV-AABBCCDDEEFF │ Type: WiFi │
|
||
│ Name: Building A │ SSID: MyNetwork │
|
||
│ Hardware: TTGO T-Call v1.4 │ RSSI: -45 dBm │
|
||
│ Firmware: v1.0.0 │ IP: 192.168.1.100 │
|
||
│ Uptime: 3d 2h 15m │ MQTT: Connected │
|
||
│ Boot count: 12 │ GSM: Available (standby) │
|
||
│ Last heartbeat: 30s ago │ SD: 4GB (0.1% used) │
|
||
│ │ │
|
||
│ ┌──────────────────────────────────────────────────────┐ │
|
||
│ │ Live Readings ● LIVE │ │
|
||
│ │ │ │
|
||
│ │ Phase Voltages Phase Currents │ │
|
||
│ │ Va: 230.1 V Ia: 15.2 A │ │
|
||
│ │ Vb: 231.4 V Ib: 14.8 A │ │
|
||
│ │ Vc: 229.8 V Ic: 15.5 A │ │
|
||
│ │ │ │
|
||
│ │ Power Energy │ │
|
||
│ │ Active: 10.5 kW Import: 12,345.6 kWh │ │
|
||
│ │ Reactive: 2.1 kVAR Export: 0.0 kWh │ │
|
||
│ │ Apparent: 10.7 kVA PF: 0.98 │ │
|
||
│ │ Freq: 50.01 Hz │ │
|
||
│ └──────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ [Restart] [WiFi Scan] [Send Command] │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Device Detail - Telemetry Tab
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ [Overview] [Telemetry] [Config] [Alerts] [Commands] [OTA] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Time Range: [Last 24h ▼] [Custom Range] [Export CSV] │
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Phase Voltages (V) │ │
|
||
│ │ 240 ┤ │ │
|
||
│ │ 235 ┤ ╭─╮ │ │
|
||
│ │ 230 ┤───╯ ╰──────────────────────────────────── │ │
|
||
│ │ 225 ┤ │ │
|
||
│ │ 220 ┤ │ │
|
||
│ │ └──┬────┬────┬────┬────┬────┬────┬────┬────┬── │ │
|
||
│ │ 00 03 06 09 12 15 18 21 24 │ │
|
||
│ │ ── Va ── Vb ── Vc │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Active Power (kW) │ │
|
||
│ │ 15 ┤ ╭───╮ │ │
|
||
│ │ 10 ┤────╮ ╯ ╰───────╮ │ │
|
||
│ │ 5 ┤ ╰──╯ ╰────── │ │
|
||
│ │ 0 ┤ │ │
|
||
│ │ └──┬────┬────┬────┬────┬────┬────┬────┬────┬── │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Power Factor & Frequency │ │
|
||
│ │ ... similar chart ... │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Device Detail - Config Tab
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ [Overview] [Telemetry] [Config] [Alerts] [Commands] [OTA] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ WiFi Configuration │ MQTT Configuration │
|
||
│ SSID: [MyNetwork____] │ Broker: [broker.example.com] │
|
||
│ Password: [**********] │ Port: [1883] │
|
||
│ Enabled: [✓] │ Username: [device1] │
|
||
│ [Scan Networks] [Save] │ Password: [**********] │
|
||
│ │ Topic: [acuvim] │
|
||
│ GSM Configuration │ TLS: [ ] │
|
||
│ APN: [internet] │ [Test] [Save] │
|
||
│ Enabled: [✓] │ │
|
||
│ Priority: [WiFi first ▼] │ Sleep Configuration │
|
||
│ [Save] │ Enabled: [ ] │
|
||
│ │ Sleep: [15] min │
|
||
│ Modbus Configuration │ Wake: [300] sec │
|
||
│ Slave Address: [1] │ [Save] │
|
||
│ Baud Rate: [9600 ▼] │ │
|
||
│ Poll Interval: [5] sec │ Console URL │
|
||
│ [Save] │ [https://console.example.com] │
|
||
│ │ [Save] │
|
||
│ │
|
||
│ ⚠ Changes are pushed to the device immediately via MQTT. │
|
||
│ The device will apply settings and reconnect as needed. │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Firmware Management Page
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ Firmware Management [Upload New] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Version │ Size │ Date │ Devices │ Status │ Action │
|
||
│─────────┼────────┼──────────────┼─────────┼────────┼─────────│
|
||
│ v1.2.0 │ 1.2 MB │ May 16, 2026 │ 0 / 24 │ Active │ [Deploy]│
|
||
│ v1.1.0 │ 1.1 MB │ May 10, 2026 │ 3 / 24 │ Active │ [Deploy]│
|
||
│ v1.0.0 │ 1.0 MB │ May 01, 2026 │ 21 / 24 │ Active │ [Deploy]│
|
||
│ v0.9.0 │ 0.9 MB │ Apr 15, 2026 │ 0 / 24 │ Archived│ │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Deploy v1.2.0 to: │
|
||
│ ( ) All devices (24) │
|
||
│ ( ) Group: [Building A ▼] (8 devices) │
|
||
│ (●) Select devices: │
|
||
│ [✓] ACV-001 - Building A (v1.0.0) │
|
||
│ [✓] ACV-002 - Building B (v1.0.0) │
|
||
│ [ ] ACV-003 - Warehouse (v0.9.0) │
|
||
│ │
|
||
│ Release Notes: │
|
||
│ Added THD monitoring improvements │
|
||
│ │
|
||
│ [Deploy to 2 devices] │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Alerts Page
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ Alerts Unresolved: 5 [Mark All Read] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Filter: [All ▼] [Warning ▼] [Active ▼] Search: [________] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Sev │ Device │ Alert │ Value │ Time │ Ack │
|
||
│─────┼───────────┼────────────────┼─────────┼─────────┼───────│
|
||
│ ⚠ │ ACV-001 │ Overvoltage │ 265.3V │ 2m ago │ [ ] │
|
||
│ ⚠ │ ACV-015 │ Modbus errors │ 12% │ 5m ago │ [ ] │
|
||
│ ● │ ACV-008 │ Device offline │ -- │ 1h ago │ [ ] │
|
||
│ ℹ │ ACV-003 │ Low PF │ 0.82 │ 2h ago │ [✓] │
|
||
│ ⚠ │ ACV-001 │ Undervoltage │ 198V │ 3h ago │ [✓] │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ Showing 1-20 of 45 alerts < 1 2 3 > │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
|
||
Severity: ● Critical ⚠ Warning ℹ Info
|
||
```
|
||
|
||
## 9.4 SignalR Integration
|
||
|
||
### Real-Time Hook
|
||
|
||
```typescript
|
||
// useSignalR.ts
|
||
function useSignalR() {
|
||
const connection = new HubConnectionBuilder()
|
||
.withUrl("/hubs/devices", { accessTokenFactory: () => getToken() })
|
||
.withAutomaticReconnect()
|
||
.build();
|
||
|
||
useEffect(() => {
|
||
connection.start();
|
||
|
||
connection.on("DeviceStatusChanged", (deviceId, status) => {
|
||
queryClient.invalidateQueries(["devices"]);
|
||
});
|
||
|
||
connection.on("TelemetryReceived", (deviceId, data) => {
|
||
queryClient.setQueryData(["telemetry", deviceId, "latest"], data);
|
||
});
|
||
|
||
connection.on("AlertCreated", (deviceId, alert) => {
|
||
queryClient.invalidateQueries(["alerts"]);
|
||
notification.warning({ message: alert.message });
|
||
});
|
||
|
||
return () => connection.stop();
|
||
}, []);
|
||
}
|
||
```
|
||
|
||
### Live Data Updates
|
||
|
||
- Device status badges update in real-time (no page refresh)
|
||
- Telemetry readings update live on device detail page
|
||
- New alerts appear as toast notifications
|
||
- Dashboard counters update automatically
|
||
|
||
## 9.5 Authentication Flow
|
||
|
||
### Login Page
|
||
|
||
```
|
||
┌──────────────────────────────────────┐
|
||
│ │
|
||
│ Tau Acuvim Console │
|
||
│ │
|
||
│ Email: [________________] │
|
||
│ Password: [________________] │
|
||
│ │
|
||
│ [Login] │
|
||
│ │
|
||
│ Forgot password? │
|
||
│ │
|
||
└──────────────────────────────────────┘
|
||
```
|
||
|
||
### Auth Implementation
|
||
|
||
```typescript
|
||
// Protected route wrapper
|
||
function ProtectedRoute({ children }) {
|
||
const { isAuthenticated } = useAuth();
|
||
|
||
if (!isAuthenticated) {
|
||
return <Navigate to="/login" />;
|
||
}
|
||
|
||
return children;
|
||
}
|
||
```
|
||
|
||
- JWT token stored in memory (not localStorage) for security
|
||
- Refresh token in httpOnly cookie
|
||
- Axios interceptor adds `Authorization` header automatically
|
||
- On 401 response: redirect to login
|
||
|
||
## 9.6 Responsive Design
|
||
|
||
- **Desktop (>1200px):** Full sidebar + content layout
|
||
- **Tablet (768-1200px):** Collapsible sidebar, adjusted grid
|
||
- **Mobile (<768px):** Bottom navigation, stacked cards, simplified tables
|
||
|
||
Ant Design's grid system handles responsive breakpoints. Charts resize automatically using ECharts' responsive mode.
|
||
|
||
## 9.7 Build and Deploy
|
||
|
||
### Development
|
||
|
||
```bash
|
||
cd console/frontend
|
||
npm install
|
||
npm run dev # Vite dev server with HMR (port 5173)
|
||
```
|
||
|
||
### Production Build
|
||
|
||
```bash
|
||
npm run build # Output to dist/
|
||
```
|
||
|
||
### Integration with Backend
|
||
|
||
- In development: Vite proxy forwards `/api` and `/hubs` to the .NET backend
|
||
- In production: the .NET backend serves the built frontend files from `wwwroot/`
|
||
- `vite.config.ts` configures the proxy for development
|
||
|
||
```typescript
|
||
// vite.config.ts
|
||
export default defineConfig({
|
||
server: {
|
||
proxy: {
|
||
'/api': 'http://localhost:5000',
|
||
'/hubs': {
|
||
target: 'http://localhost:5000',
|
||
ws: true
|
||
}
|
||
}
|
||
}
|
||
});
|
||
```
|
||
|
||
### Docker Integration
|
||
|
||
Add to the Phase 8 Dockerfile:
|
||
|
||
```dockerfile
|
||
# Build frontend
|
||
FROM node:18 AS frontend
|
||
WORKDIR /app/frontend
|
||
COPY console/frontend/package*.json ./
|
||
RUN npm ci
|
||
COPY console/frontend/ ./
|
||
RUN npm run build
|
||
|
||
# Build backend
|
||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS backend
|
||
# ... build steps ...
|
||
|
||
# Runtime
|
||
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||
# ... copy backend build ...
|
||
COPY --from=frontend /app/frontend/dist ./wwwroot/
|
||
```
|
||
|
||
## 9.8 Testing & Validation
|
||
|
||
| Test | Method | Pass Criteria |
|
||
|------|--------|---------------|
|
||
| Login | Enter valid credentials | Redirected to dashboard |
|
||
| Dashboard loads | Navigate to / | Summary cards, alerts, grid visible |
|
||
| Device list | Navigate to /devices | All devices listed with status |
|
||
| Device detail | Click a device | Overview tab shows live data |
|
||
| Telemetry charts | Select Telemetry tab | Charts render with historical data |
|
||
| Time range | Change to Last 7 days | Charts update with correct range |
|
||
| Config push | Edit WiFi settings, save | Config sent to device via MQTT |
|
||
| WiFi scan | Click Scan Networks | Networks returned and displayed |
|
||
| Firmware upload | Upload a .bin file | File uploaded, appears in list |
|
||
| Firmware deploy | Deploy to selected devices | OTA commands sent |
|
||
| Alert display | Trigger alert from device | Alert appears in list and as toast |
|
||
| Alert acknowledge | Click acknowledge | Alert marked as acknowledged |
|
||
| Real-time update | Watch dashboard while device publishes | Values update without refresh |
|
||
| Responsive | Resize browser to mobile | Layout adapts correctly |
|
||
| Auth protection | Access /devices without login | Redirected to /login |
|
||
| CSV export | Export telemetry | Valid CSV downloaded |
|
||
| Send command | Send restart command | Device restarts, response received |
|
||
|
||
## 9.9 Phase 9 Completion Criteria
|
||
|
||
- [ ] React frontend builds and serves
|
||
- [ ] Login/logout flow with JWT authentication
|
||
- [ ] Dashboard shows fleet summary, alerts, device grid
|
||
- [ ] Device list with filtering, search, pagination
|
||
- [ ] Device detail with tabs: Overview, Telemetry, Config, Alerts, Commands, OTA
|
||
- [ ] Live telemetry readings update via SignalR
|
||
- [ ] Historical telemetry charts with time range selection
|
||
- [ ] Remote configuration push (WiFi, MQTT, GSM, sleep, Modbus)
|
||
- [ ] WiFi scan triggered from console and results displayed
|
||
- [ ] Firmware upload and deployment UI
|
||
- [ ] Alert management (list, filter, acknowledge)
|
||
- [ ] Responsive design (desktop, tablet, mobile)
|
||
- [ ] Integrated into .NET backend for production deployment
|
||
|
||
---
|
||
|
||
**Previous Phase:** [Phase 8 — Console Application Backend](acuvim-spec-08.md)
|
||
**Next Phase:** [Phase 10 — Integration Testing & Production Hardening](acuvim-spec-10.md)
|