主要更新: - 添加生产部署信息(容器名称、端口、部署位置) - 更新 Docker 部署命令(反映真实的 vsp-service 容器) - 数据库从 SQLite 改为腾讯云 MySQL - 补充关键接口说明(边缘端上报、前端访问、WebSocket) - 移除过时的 MQTT 相关说明 - 强调使用 python -m app.main 作为入口 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
144 lines
6.3 KiB
Markdown
144 lines
6.3 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## 项目概述
|
||
|
||
AI 告警平台后端服务,基于 FastAPI 构建。接收边缘 AI 设备通过 HTTP 上报的告警,存储截图到腾讯云 COS,通过 WebSocket 实时推送告警事件,为芋道 Vue 3 前端提供 REST API。
|
||
|
||
**生产部署信息:**
|
||
- **容器名称:** `vsp-service`
|
||
- **端口映射:** 8000:8000
|
||
- **部署位置:** 腾讯云服务器 `/opt/vsp-platform`
|
||
- **存储:** 腾讯云 MySQL + 腾讯云 COS
|
||
- **访问地址:** http://服务器IP:8000
|
||
|
||
## 常用命令
|
||
|
||
### 本地开发
|
||
```bash
|
||
# 安装依赖
|
||
pip install -r requirements.txt
|
||
|
||
# 环境配置
|
||
cp .env.example .env
|
||
# 编辑 .env:
|
||
# DATABASE_URL=mysql+pymysql://user:pass@localhost/dbname
|
||
# COS_SECRET_ID=your_secret_id
|
||
# COS_SECRET_KEY=your_secret_key
|
||
# COS_BUCKET=your-bucket
|
||
# COS_REGION=ap-beijing
|
||
|
||
# 运行开发服务器(自动重载,监听 8000 端口)
|
||
python -m app.main
|
||
|
||
# API 文档:http://localhost:8000/docs
|
||
# 健康检查:http://localhost:8000/health
|
||
```
|
||
|
||
### Docker 部署(生产环境)
|
||
```bash
|
||
# 构建镜像
|
||
docker build -t vsp-service:latest .
|
||
|
||
# 运行容器
|
||
docker run -d \
|
||
--name vsp-service \
|
||
-p 8000:8000 \
|
||
-e DATABASE_URL=mysql+pymysql://user:pass@云端MySQL/dbname \
|
||
-e COS_BUCKET=腾讯云COS桶名 \
|
||
-e COS_REGION=ap-beijing \
|
||
-e COS_SECRET_ID=your_id \
|
||
-e COS_SECRET_KEY=your_key \
|
||
vsp-service:latest
|
||
|
||
# 查看日志
|
||
docker logs -f vsp-service
|
||
|
||
# 重启容器
|
||
docker restart vsp-service
|
||
|
||
# 进入容器调试
|
||
docker exec -it vsp-service /bin/bash
|
||
```
|
||
|
||
### 测试
|
||
```bash
|
||
# 如果添加测试,使用 pytest
|
||
pytest tests/
|
||
```
|
||
|
||
**重要提示:** 根目录的 `main.py` 是 PyCharm 模板文件,不是真正的入口。**务必使用 `python -m app.main` 启动服务**。
|
||
|
||
## Architecture
|
||
|
||
### Data Flow
|
||
|
||
```
|
||
Edge Devices ──MQTT──→ EMQX Broker ──subscribe──→ MQTTService ──→ AlertService ──→ DB
|
||
│
|
||
Edge Devices ──HTTP POST──→ /api/v1/alerts ────────────→│
|
||
↓
|
||
NotificationService ──WebSocket──→ Frontend
|
||
```
|
||
|
||
### Dual API Surface
|
||
|
||
The app exposes two parallel API layers hitting the same services and database:
|
||
|
||
1. **Native API** (`/api/v1/`) — endpoints defined inline in `app/main.py`. Standard REST responses.
|
||
2. **Yudao-compat API** (`/admin-api/`) — routers in `app/routers/yudao_alert.py` and `yudao_auth.py`. Wraps responses in `{"code": 0, "data": ..., "msg": ""}` format expected by the Yudao Vue frontend. Auth/permissions handled by `app/yudao_compat.py` (stub in dev mode: `DEV_MODE=true` skips token validation, returns mock admin).
|
||
|
||
### Services (Global Singletons)
|
||
|
||
All services are instantiated as module-level singletons, not injected via FastAPI `Depends()`. Access them via factory functions (`get_alert_service()`, `get_mqtt_service()`, etc.) or import the global directly.
|
||
|
||
- **AlertService** (`app/services/alert_service.py`) — CRUD, filtering/pagination, statistics, AI analysis update. Handles both HTTP (`create_alert`) and MQTT (`create_alert_from_mqtt`) creation paths. Alert numbers: `ALT` + timestamp + uuid fragment.
|
||
- **MQTTService** (`app/services/mqtt_service.py`) — paho-mqtt client subscribing to `edge/alert/#`. Routes messages to registered callbacks for alerts vs heartbeats. Compatible with paho-mqtt 1.x and 2.x APIs.
|
||
- **DeviceService** (`app/services/device_service.py`) — Tracks edge device status from MQTT heartbeats. In-memory cache + DB persistence. Marks devices offline after 90s without heartbeat.
|
||
- **NotificationService** (`app/services/notification_service.py`) — WebSocket connection manager + broadcast. Bridges sync MQTT callbacks to async WebSocket sends via `asyncio.run_coroutine_threadsafe()`.
|
||
- **OSSStorage** (`app/services/oss_storage.py`) — Image storage. Currently local-only (`uploads/` dir); Aliyun OSS stubbed but not implemented.
|
||
- **AIAnalyzer** (`app/services/ai_analyzer.py`) — Async httpx client for optional big-model analysis. Fire-and-forget via `asyncio.create_task()`.
|
||
|
||
### Lifecycle (`app/main.py` lifespan)
|
||
|
||
Startup: init DB → set async event loop on NotificationService → register MQTT handlers → start MQTT.
|
||
Shutdown: stop MQTT.
|
||
|
||
### Database(生产环境使用腾讯云 MySQL)
|
||
|
||
三个核心 ORM 模型在 `app/models.py`:
|
||
|
||
- **AlarmEvent** — 告警事件主表。字段:alarm_id (PK), alarm_type, device_id, scene_id, event_time, alarm_level (1-4), alarm_status (NEW/CONFIRMED/RESOLVED), handle_status, snapshot_url 等。索引:alarm_id, device_id, alarm_status, event_time。
|
||
- **AlarmEventExt** — 告警扩展信息表。存储 ext_data JSON 字段(边缘端上报的 bbox, bind_id 等)。
|
||
- **AlarmLlmAnalysis** — 大模型分析结果表(可选功能)。
|
||
- **EdgeDevice** — 边缘设备表(用于设备列表展示,无心跳机制)。
|
||
|
||
数据库连接通过 `get_session()` 获取。服务层使用 try/finally 管理会话生命周期。
|
||
|
||
### Config
|
||
|
||
`app/config.py` — dataclass-based config loaded from `.env` via `os.getenv()`. Sections: `DatabaseConfig`, `OSSConfig`, `AppConfig` (includes `dev_mode`), `AIModelConfig`, `MQTTConfig`. Global `settings` instance created at module load.
|
||
|
||
### 关键接口
|
||
|
||
**边缘端告警上报(无需认证):**
|
||
- `POST /api/ai/alert/edge/report` — 边缘端告警上报
|
||
- 请求体:`{alarm_id, alarm_type, device_id, scene_id, event_time, alarm_level, snapshot_url, confidence_score, ext_data}`
|
||
- 幂等性:相同 alarm_id 会跳过创建
|
||
- 成功后触发 WebSocket 推送
|
||
|
||
- `POST /api/ai/alert/edge/resolve` — 告警结束通知(离岗算法)
|
||
- 请求体:`{alarm_id, duration_ms, last_frame_time, resolve_type}`
|
||
- 更新告警持续时长和结束时间
|
||
|
||
**前端访问接口(需要认证,通过 aiot-gateway 48080 访问):**
|
||
- `GET /admin-api/aiot/alarm/event/page` — 分页查询告警事件
|
||
- `GET /admin-api/aiot/alarm/event/get` — 获取告警详情
|
||
- `PUT /admin-api/aiot/alarm/event/handle` — 处理告警
|
||
- `GET /admin-api/aiot/alarm/event/statistics` — 告警统计
|
||
- `GET /admin-api/aiot/edge/device/page` — 分页查询边缘设备
|
||
|
||
**WebSocket 实时推送:**
|
||
- `ws://服务器IP:8000/ws/alerts` — 实时告警推送
|