Files
H3ConuMS-v2/CLAUDE.md
T
v6ole fe7649ed6e feat: v0.10.0 生产环境优化 — HTTPS、前端生产构建、安全加固
- feat(deploy): 前端多阶段构建 (vite build + nginx:alpine),移除 Vite 开发模式
- feat(deploy): OpenResty HTTPS 配置 (SSL + HSTS + 安全头)
- fix(ws): WebSocket 路由添加 /api 前缀,修正前后端路径不匹配
- security: SSH AutoAddPolicy → WarningPolicy
- security: CORS 来源环境变量化 (CORS_ORIGINS)
- security: 限流器使用 X-Forwarded-For 真实客户端 IP
- perf(db): 数据库连接池配置 (pool_size=20, max_overflow=40)
- refactor: 移除硬编码 URL/IP (NTP、域名、微信代理),改为环境变量
- chore: 更新 .env.example 模板,补充新增配置项
- chore: 清理 .reasonix/、scripts/、guide.md 无用文件
- docs: 更新 CLAUDE.md 至 v0.10.0,补充生产架构文档

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 14:45:48 +08:00

718 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# H3C ONU设备管理系统 - Claude开发指南
## 项目概述
这是一个基于 Python FastAPI + Vue 3 的 H3C OLT 设备监控管理系统,用于监控 4000+ ONU 设备的在线状态。
**当前版本**: v0.10.0
**开发状态**: 生产环境优化完成,运维增强功能持续迭代
**已实现功能**
- ✅ SSH 连接 H3C OLT 设备查询 ONU 状态(支持 More 分页、终端控制字符清理)
- ✅ Excel 数据导入和批量管理
- ✅ 定时自动状态检查(可配置间隔,最小5分钟)+ 手动触发
- ✅ Casdoor 统一认证和 JWT 令牌管理
- ✅ 设备管理(列表、详情、筛选、分页)
- ✅ 统计仪表板(总数、在线、离线)+ 区域分布饼图 + 7天趋势折线图
- ✅ 完整 RBAC 权限管理(角色、权限、用户管理页面)
- ✅ OLT 管理(增删改查、批量导入、区域动态同步)
- ✅ OLT 端口管理(查看端口状态、开关端口)
- ✅ 重复 MAC 检测与清除
- ✅ 新设备发现与信息补全(扫描发现 → 补全信息 → 入库)
- ✅ 快速扫描(多线程并发)
- ✅ 环路检测
- ✅ 系统设置(管理员可配置检查间隔,显示下次扫描时间/扫描中状态)
- ✅ 库存管理模块(物料、序列号设备、出入库、盘点)
- ✅ 每日状态快照(凌晨1点聚合,用于趋势图性能优化)
- ✅ 审计日志(全量操作记录、筛选查询、CSV 导出)
- ✅ 设备更换记录(MAC 地址更换历史,与库存序列号联动)
- ✅ 操作记录日志(查看指定设备的上下线事件历史)
- ✅ OLT 时间同步(NTP 服务器配置同步到所有 OLT)
- ✅ IMC 网管服务集成(ONU 远程重启、光功率查询)
- ✅ 企业微信告警通知(设备离线、全离线学校检测)
- ✅ WebSocket 实时推送(仪表板状态更新、检查进度)
- ✅ iOS PWA 主屏幕支持(standalone 模式 safe area 适配)
- ✅ 生产环境 HTTPS 部署(OpenResty + SSL + 安全头)
- ✅ 前端生产构建(多阶段 Dockerfilenginx:alpine 静态服务)
- ✅ 数据库连接池优化(pool_size=20, max_overflow=40
**技术栈**
- 后端:Python FastAPI + PostgreSQL + Celery + Redis + Paramiko
- 前端:Vue 3 + Element Plus + Pinia + Axios
- 部署:Docker Compose
---
## 已实现的 API 端点
### 认证相关
- `GET /api/auth/login` - 获取 Casdoor 登录 URL
- `POST /api/auth/callback` - Casdoor 登录回调
- `GET /api/auth/profile` - 获取当前用户信息
### 设备管理
- `GET /api/devices` - 获取设备列表(分页、筛选)
- `GET /api/devices/{id}` - 获取设备详情
- `PUT /api/devices/{id}` - 更新设备信息
- `GET /api/devices/{id}/events` - 获取设备上下线事件记录
- `POST /api/devices/{id}/reboot` - 远程重启 ONUIMC
- `GET /api/devices/{id}/optical-power` - 获取 ONU 光功率(IMC
### 状态检查
- `POST /api/check/status` - 手动触发全量状态检查(Celery 异步)
- `GET /api/check/status/{task_id}` - 查询检查任务进度
- `POST /api/check/scan/{olt_id}` - 扫描单台 OLT(预览,不入库)
- `POST /api/check/discover/{olt_id}` - 扫描单台 OLT 并入库新设备
### OLT 管理
- `GET /api/olt/devices` - OLT 设备列表
- `POST /api/olt/devices` - 新增 OLT
- `PUT /api/olt/devices/{id}` - 编辑 OLT
- `DELETE /api/olt/devices/{id}` - 删除 OLT
- `GET /api/olt/regions` - 获取 OLT 区域列表
- `POST /api/olt/quick-scan` - 多线程快速扫描所有 OLT
- `GET /api/olt/ports/{olt_id}` - 获取 OLT 端口状态
- `POST /api/olt/ports/{olt_id}/toggle` - 开关 OLT 端口
- `POST /api/olt/sync-ntp` - 同步 NTP 时间服务器配置
- `POST /api/olt/loopback-detection` - 环路检测
- `GET /api/olt/new-devices` - 获取新发现设备列表
- `PUT /api/olt/new-devices/{id}` - 补全新设备信息
- `DELETE /api/olt/new-devices/{id}` - 忽略新设备
### 数据导入
- `POST /api/import/upload` - 上传并导入 Excel 文件
- `GET /api/import/template` - 下载导入模板
### 统计信息
- `GET /api/stats/summary` - 获取统计摘要
- `GET /api/stats/trend` - 7天趋势数据
- `GET /api/stats/region-distribution` - 区域分布
### 权限管理
- `GET /api/roles` - 角色列表
- `POST /api/roles` - 创建角色
- `PUT /api/roles/{id}` - 编辑角色
- `DELETE /api/roles/{id}` - 删除角色
- `GET /api/permissions` - 权限列表
### 用户管理
- `GET /api/users` - 用户列表
- `PUT /api/users/{id}` - 编辑用户
- `DELETE /api/users/{id}` - 删除用户
### 库存管理
- `GET /api/inventory/materials` - 物料列表
- `POST /api/inventory/materials` - 新增物料
- `GET /api/inventory/serial-devices` - 序列号设备
- `POST /api/inventory/stock-in` - 入库
- `POST /api/inventory/stock-out` - 出库
- `POST /api/inventory/check` - 盘点
### 审计日志
- `GET /api/audit/logs` - 审计日志列表(筛选、分页)
- `GET /api/audit/logs/export` - 导出审计日志 CSV
### 设备更换记录
- `GET /api/devices/{id}/replacements` - 查看设备更换历史
- `GET /api/replacements` - 全量更换记录列表
### 系统设置
- `GET /api/settings` - 获取系统设置
- `PUT /api/settings` - 更新系统设置
### 企业微信
- `GET /api/wechat/callback` - 企业微信回调 URL 验证
- `POST /api/wechat/callback` - 企业微信消息接收
- `POST /api/wechat/menu/create` - 创建企业微信菜单
### WebSocket
- `WS /api/ws/dashboard` - 仪表板实时状态推送(Redis pub/sub
### 任务监控
- `GET /api/monitor/tasks` - 查看正在运行的后台任务
### 系统
- `GET /health` - 健康检查
- `GET /docs` - API 文档(Swagger UI
---
## Rules
### 代码规范
#### Python 后端规范
- 遵循 PEP 8 规范
- 使用 Black 进行代码格式化
- 使用 isort 进行导入排序
- 使用类型注解(Type Hints
- 异步函数使用 async/await
- 错误处理使用自定义异常类
#### Vue 前端规范
- 使用 Composition APIsetup script
- 组件使用 PascalCase 命名
- 使用 TypeScript 类型检查
- 遵循 Vue 官方风格指南
- 使用 ESLint + Prettier 格式化
#### Git 提交规范
使用 Conventional Commits 格式:
```
<type>(<scope>): <subject>
类型:feat, fix, docs, style, refactor, test, chore
示例:feat(device): 添加设备导入功能
```
### 架构规则
#### 后端架构
- **分层架构**API → Service → Model
- **API 层**:仅处理请求/响应,调用 Service
- **Service 层**:业务逻辑,不直接操作数据库
- **Model 层**SQLAlchemy 模型定义
- **异步任务**:耗时操作使用 Celery
#### 前端架构
- **组件分类**
- `components/common/`:通用组件
- `components/business/`:业务组件
- `views/`:页面组件
- **状态管理**:使用 Pinia stores
- **API 调用**:统一在 `api/` 目录封装
### 安全规则
#### 数据安全
- SSH 密码必须加密存储(使用 Fernet 加密)
- 敏感信息通过环境变量配置
- 数据库连接使用 SSL
- 定期备份数据(90天历史记录)
#### 应用安全
- 所有 API 端点需要认证(除登录接口)
- 实现 CSRF 保护
- 输入验证使用 Pydantic
- SQL 注入防护(使用 ORM
- XSS 防护(前端转义)
#### 访问控制
- 基于 RBAC 的权限控制
- 数据级权限过滤(按区域/学校)
- 操作审计日志记录
- 设备信息变更需要审核
### 性能规则
#### 数据库优化
- 为常用查询字段添加索引
- 使用连接池(pool_size=20
- 避免 N+1 查询问题
- 定期清理历史数据(保留90天)
#### 缓存策略
- Redis 缓存热点数据(设备状态)
- 缓存过期时间:30分钟
- 手动刷新有5分钟冷却限制
#### 异步处理
- SSH 状态检查使用 Celery 异步任务
- 批量导入使用后台任务
- 定时任务使用 Celery Beat
### 开发规则
#### 提交前清理
- 每次提交前必须清理项目中不需要的文件
- 包括:测试文件(`test_*.py`)、调试脚本、不再使用的 shell 脚本、冗余 markdown 文档
- 检查是否有硬编码的敏感信息(密码、密钥、token)
- 检查 `.gitignore` 是否覆盖了所有不应提交的文件(`*.pem``.env``__pycache__` 等)
#### 环境配置
- 开发环境使用 `.env.development`
- 生产环境使用 `.env.production`
- 不提交 `.env` 文件到 Git
- 提供 `.env.example` 模板
- 敏感信息(数据库密码、Casdoor 密钥等)仅通过环境变量注入
#### 测试要求
- 核心业务逻辑需要单元测试
- API 端点需要集成测试
- 测试覆盖率目标:≥80%
#### 文档要求
- API 变更及时更新 Swagger 文档
- 复杂业务逻辑添加注释
- 重要配置添加说明
### 部署规则
#### Docker 部署
- 使用 Docker Compose 编排
- 外部 PostgreSQL 和 Redis(不在容器内)
- 日志挂载到宿主机
- 使用 Nginx 反向代理
#### 环境变量
必需配置:
- `DATABASE_URL`PostgreSQL 连接字符串
- `REDIS_URL`Redis 连接字符串
- `CASDOOR_*`Casdoor 认证配置(`ENDPOINT`, `CLIENT_ID`, `CLIENT_SECRET`, `ORG_NAME`, `APP_NAME`
- `CASDOOR_REDIRECT_URL`:Casdoor 登录回调地址(生产必填,无默认值)
- `SECRET_KEY`:应用密钥
可选配置:
- `CORS_ORIGINS`CORS 允许的来源(逗号分隔)
- `FRONTEND_URL`:前端访问地址(用于微信帮助消息等,默认 `https://onu.dhdx.fun`
- `NTP_OLD_SERVER` / `NTP_NEW_SERVER`NTP 同步服务器 IP
- `IMC_API_*`iMC 网管 API 配置(ONU 重启/光功率查询)
- `WECHAT_*`:企业微信告警配置
#### 监控告警
- 健康检查端点:`/health`
- 性能指标端点:`/metrics`
- 日志级别:生产环境使用 INFO
---
## 部署陷阱与经验教训
### 修改代码后必须重新构建镜像
**问题**:修改了宿主机上的源码后,直接 `docker compose up -d``docker compose restart` **不会**让容器使用新代码。容器运行的是构建时打包进镜像的旧代码。
**正确流程**
```bash
# 1. 重新构建镜像(必须加 --no-cache 确保不用旧层)
docker compose build --no-cache backend # 或 frontend,或两者
# 2. 重新创建容器(必须用 rm + up,或 up --force-recreate
docker compose rm -f backend
docker compose up -d backend
# 3. 如有数据库模型变更,执行迁移
docker compose exec backend alembic upgrade head
```
**不要用**
- `docker compose restart`:只重启进程,不更新镜像
- `docker compose up -d`(无 build):容器配置变了会重建,但镜像不变
### 端口被占用导致容器启动但无端口映射
**问题**:如果宿主机端口已被其他容器占用,新容器会启动成功(`docker compose up` 不报错),但端口映射为空 `{}`,外部无法访问。
**排查方法**
```bash
# 检查端口映射是否正常
docker inspect <container> --format '{{json .NetworkSettings.Ports}}'
# 查看谁占用了端口
docker ps | grep <port>
```
**解决方法**:先停掉占用端口的旧容器,再 `docker compose rm -f && docker compose up -d`
### 前端生产构建(v0.10.0+
**问题**:早期版本前端容器运行 `npm run dev`(Vite 开发服务器),存在热更新开销、源码暴露、无压缩等问题。
**生产构建流程**
```dockerfile
# 多阶段构建 — frontend/Dockerfile
# Stage 1: vite build → dist/
# Stage 2: nginx:alpine 静态文件服务
```
**生产模式下不需要 `VITE_*` 环境变量**:前端所有 API 调用使用相对路径 `/api`,由 OpenResty/Nginx 在边缘层代理。Vite 的 proxy 仅用于本地开发。
**前端部署到远程服务器**
```bash
cd frontend
docker build -t h3conums2-frontend:latest .
docker save h3conums2-frontend:latest | ssh -p 7072 root@<remote> "docker load"
ssh -p 7072 root@<remote> "docker stop h3conums2-frontend && docker rm h3conums2-frontend && docker run -d --name h3conums2-frontend --restart always -p 18062:80 h3conums2-frontend:latest"
```
### 生产部署架构(v0.10.0+
**部署拓扑**:前端在远程服务器,后端在本地服务器,通过 frp 隧道通信。
```
用户浏览器 → onu.dhdx.fun (HTTPS)
OpenResty (80/443)
┌───────────┴───────────┐
▼ ▼
前端容器(:18062) frp 隧道(:18060)
nginx:alpine │
静态文件服务 frpc → frps → 本机后端(:8000)
```
**关键配置**
- OpenResty 由 1Panel 管理,配置文件位于 `/opt/1panel/apps/openresty/openresty/conf/conf.d/`
- SSL 证书位于 `/www/sites/onu.dhdx.fun/ssl/`OpenResty 容器内路径)
- 前端容器端口映射:`18062:80`
- frp 后端隧道:远程 `127.0.0.1:18060` → 本机 `127.0.0.1:8000`
### 新增环境变量(v0.10.0
生产环境新增配置项:
```bash
# CORS & 前端
CORS_ORIGINS=http://localhost:5173,http://localhost:18002,https://onu.dhdx.fun
FRONTEND_URL=https://onu.dhdx.fun
# NTP 同步
NTP_OLD_SERVER=172.16.0.254
NTP_NEW_SERVER=172.16.1.252
# iMC 网管 API
IMC_API_URL=https://172.16.1.252:8443
IMC_API_USERNAME=admin
IMC_API_PASSWORD=...
IMC_API_VERIFY_SSL=false
# Casdoor 回调(生产必填,无默认值)
CASDOOR_REDIRECT_URL=https://onu.dhdx.fun/callback
# 企业微信代理(无默认值,按需配置)
WECHAT_PROXY_API_URL=https://api.v6ole.top
```
### 数据库连接池
**配置**`backend/app/core/database.py`):
```python
engine = create_engine(
settings.DATABASE_URL,
pool_pre_ping=True,
pool_size=20,
max_overflow=40,
pool_recycle=3600, # 1小时回收,防 PostgreSQL 断闲置连接
pool_timeout=30,
)
```
### SSH 主机密钥策略
**当前使用 `WarningPolicy`**:记录未知主机密钥警告但允许连接。生产环境 OLT 设备在内网,安全风险可接受。如需严格验证,改为 `RejectPolicy` 并预置 `known_hosts` 文件。
### OpenResty / 1Panel 注意事项
- 配置文件由 1Panel 管理,直接修改文件后需重载:`docker exec openresty openresty -s reload`
- 1Panel 面板重新保存站点配置会覆盖手动修改
- WebSocket 通过 HTTP/1.1 升级,需确保 `/api/` location 传递 `Upgrade``Connection`
- 当前使用自签名证书,可通过 1Panel 面板申请 Let's Encrypt 正式证书
### 新增数据库模型后必须执行迁移
**问题**:新增了 SQLAlchemy 模型(如 `DeviceDailySnapshot``SystemSetting`),重建镜像后如果不执行 `alembic upgrade head`,表不存在会导致 500 错误。
**每次新增模型的完整流程**
```bash
# 1. 创建迁移文件(在宿主机或容器内)
docker compose exec backend alembic revision --autogenerate -m "描述"
# 2. 重建镜像
docker compose build --no-cache backend
# 3. 重启容器
docker compose rm -f backend && docker compose up -d backend
# 4. 执行迁移
docker compose exec backend alembic upgrade head
```
### Alembic 迁移文件 revision ID 不能重复
**问题**:手动创建迁移文件时,如果 `revision` 字段与已有文件重复,`alembic upgrade head` 会报 `Multiple head revisions are present` 错误。
**规则**:手动创建迁移文件时,revision ID 使用不与现有文件冲突的唯一字符串(如 `h8i9j0k1l2m3`),并确认 `down_revision` 指向正确的上一个版本。
### Celery worker 必须重建才能识别新任务
**问题**:新增 Celery 任务模块后,如果只重建 backend 而不重建 celery-workerworker 不会注册新任务,消息会被丢弃并报 `KeyError`
**规则**:新增任务模块后,backend 和 celery-worker 都必须重建:
```bash
docker compose build --no-cache backend celery-worker
docker compose rm -f backend celery-worker
docker compose up -d backend celery-worker
```
验证任务是否注册:
```bash
docker compose exec celery-worker celery -A celery_worker.celery_app inspect registered
```
### 区域管理员多区域过滤必须用 `.in_()` 而非 `==`
**问题**`assigned_area` 字段存储逗号分隔的多个区域(如 `"城区,郊区"`),用 `==` 只能匹配整个字符串,导致多区域管理员只能看到第一个区域的数据。
**规则**:所有涉及 `assigned_area` 的过滤都必须先 split 再用 `.in_()`
```python
areas = [a.strip() for a in current['assigned_area'].split(',') if a.strip()]
query = query.filter(Model.region.in_(areas))
```
### Vite dev server 通过反向代理访问需配置 allowedHosts
**问题**:通过域名反向代理访问 Vite dev server 时,会报 `Blocked request. This host is not allowed`
**解决**:在 `vite.config.js` 中设置:
```js
server: {
allowedHosts: ['all', 'your-domain.com'],
}
```
### iOS PWA standalone 模式与 Safari 的 safe area 差异
**问题**`env(safe-area-inset-top)` 在 Safari 浏览器中为 0(有地址栏占位),在 standalone 模式(添加到主屏幕)下为真实刘海高度(44-59px)。直接使用会导致 Safari 中布局正常但 standalone 中顶栏/弹窗重叠。
**规则**:所有 safe area 相关样式必须包在 `@media (display-mode: standalone)` 中,Safari 不受影响:
```css
@media (display-mode: standalone) {
.mobile-topbar {
height: calc(52px + env(safe-area-inset-top));
}
}
```
`ElMessage` 的 offset 通过 `src/utils/message.js` 封装统一处理,所有页面从该文件导入而非直接从 `element-plus` 导入。
### Docker healthcheck 镜像内无 curl
**问题**backend 镜像基于 Python slim,没有 `curl`healthcheck 用 `curl` 会导致所有依赖服务启动失败。
**规则**healthcheck 使用 Python 内置模块:
```yaml
healthcheck:
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 15s
timeout: 10s
retries: 5
start_period: 40s
```
### More 分页标记清除不能使用 `[^\n]*` 删除整行
**问题**`_clean_output``---- More ----[^\n]*` 会将 `---- More ----` 及其后同行所有内容删除。当 OLT 输出的 More 提示与下一页第一条设备数据出现在同一行时(如 `---- More ----\r\r 1484-778f-aa60 ...`),该设备行会被错误丢弃,导致部分设备扫描不到。
**规则**:仅移除 More 标记文本本身,保留同行后续内容:
```python
# 错误:删除整行
output = re.sub(r'---- More ----[^\n]*', '', output)
# 正确:仅移除标记文本
output = re.sub(r'---- More ----', '', output)
```
此问题在 OLT `172.16.0.18`(大化县新城初中)上发现:93 台设备仅解析出 90 台,丢失 3 台。
---
## 项目结构
```
H3ConuMS2/
├── backend/ # Python 后端
│ ├── app/
│ │ ├── api/v1/ # API 路由
│ │ ├── core/ # 核心配置
│ │ ├── middleware/ # 中间件(权限、审计)
│ │ ├── models/ # 数据模型
│ │ ├── schemas/ # Pydantic 模式
│ │ ├── services/ # 业务逻辑(SSH、IMC、导入等)
│ │ └── tasks/ # Celery 任务
│ ├── alembic/ # 数据库迁移
│ ├── scripts/ # 初始化脚本
│ └── templates/ # Excel 导入模板
├── frontend/ # Vue 3 前端
│ ├── Dockerfile # 多阶段构建(vite build + nginx:alpine
│ ├── nginx.conf # 生产 nginx 配置(Gzip、缓存、SPA fallback
│ └── src/
│ ├── api/ # API 调用封装
│ ├── components/ # 公共组件
│ ├── composables/ # 组合式函数
│ ├── router/ # 路由
│ ├── stores/ # Pinia 状态管理
│ ├── styles/ # 主题样式
│ ├── utils/ # 工具函数
│ └── views/ # 页面组件
├── deploy/ # 部署配置
│ ├── docker-compose.yml
│ ├── openresty/ # OpenResty 站点配置
│ ├── nginx/
│ └── scripts/
├── docs/ # 文档
└── docker-compose.yml # 本地开发 Docker Compose
```
---
## 核心业务逻辑
### SSH 状态检查流程
1. 从数据库获取 OLT 设备配置
2. 建立 SSH 连接(使用连接池)
3. 执行命令:`display onu slot {slot_number}`
4. 解析返回结果:
- 包含 "Up" → 在线
- 包含 "Offline" → 离线
5. 更新设备状态到数据库
6. 记录历史状态
### 权限控制逻辑
- **超级管理员**:所有权限
- **管理员**:管理所有设备和用户
- **区域管理员**:管理指定区域的设备
- **学校管理员**:管理指定学校的设备
- **普通用户**:只读权限
### 数据导入流程
1. 上传 Excel 文件
2. 使用 Pandas 解析数据
3. 数据验证(MAC 地址格式、必填字段)
4. 批量插入数据库
5. 返回导入结果(成功/失败记录)
---
## 开发指南
### 快速启动
**Docker 部署(推荐)**
```bash
# 1. 配置环境变量
cp backend/.env.example backend/.env
# 编辑 .env 填入实际配置
# 2. 启动所有服务
docker compose up -d
# 3. 初始化数据库
docker compose exec backend python scripts/init_db.py
```
**本地开发**
```bash
# 后端
cd backend
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# 前端
cd frontend
npm install && npm run dev
# Celery Worker
cd backend
celery -A celery_worker.celery_app worker --loglevel=info
# Celery Beat
cd backend
celery -A celery_worker.celery_app beat --loglevel=info --schedule=/tmp/celerybeat-schedule
```
### 数据库迁移
```bash
# 创建迁移
alembic revision --autogenerate -m "描述"
# 执行迁移
alembic upgrade head
# 回滚
alembic downgrade -1
```
### 添加新功能
1. **后端 API**
-`app/api/v1/` 创建路由文件
-`app/services/` 创建服务文件
-`app/schemas/` 定义请求/响应模式
-`app/models/` 定义数据模型(如需要)
2. **前端页面**
-`views/` 创建页面组件
-`api/` 添加 API 调用
-`router/` 添加路由配置
-`stores/` 添加状态管理(如需要)
---
## 常见问题
### SSH 连接失败
- 检查网络连通性
- 验证 SSH 凭证
- 检查防火墙设置
- 查看日志:`docker-compose logs backend`
### 数据库连接失败
- 检查 `DATABASE_URL` 配置
- 验证数据库服务状态
- 检查网络权限
### Casdoor 登录失败
- 检查 Casdoor 服务状态
- 验证 `CASDOOR_*` 配置
- 检查回调地址配置
---
## 参考文档
- [FastAPI 文档](https://fastapi.tiangolo.com/)
- [Vue 3 文档](https://vuejs.org/)
- [Element Plus 文档](https://element-plus.org/)
- [Casdoor 文档](https://casdoor.org/)
- [现场ONU故障排查指南](./docs/现场ONU故障排查指南.md)
<!-- code-review-graph MCP tools -->
## MCP Tools: code-review-graph
**IMPORTANT: This project has a knowledge graph. ALWAYS use the
code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore
the codebase.** The graph is faster, cheaper (fewer tokens), and gives
you structural context (callers, dependents, test coverage) that file
scanning cannot.
### When to use graph tools FIRST
- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep
- **Understanding impact**: `get_impact_radius` instead of manually tracing imports
- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files
- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for
- **Architecture questions**: `get_architecture_overview` + `list_communities`
Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need.
### Key Tools
| Tool | Use when |
| ------ | ---------- |
| `detect_changes` | Reviewing code changes — gives risk-scored analysis |
| `get_review_context` | Need source snippets for review — token-efficient |
| `get_impact_radius` | Understanding blast radius of a change |
| `get_affected_flows` | Finding which execution paths are impacted |
| `query_graph` | Tracing callers, callees, imports, tests, dependencies |
| `semantic_search_nodes` | Finding functions/classes by name or keyword |
| `get_architecture_overview` | Understanding high-level codebase structure |
| `refactor_tool` | Planning renames, finding dead code |
### Workflow
1. The graph auto-updates on file changes (via hooks).
2. Use `detect_changes` for code review.
3. Use `get_affected_flows` to understand impact.
4. Use `query_graph` pattern="tests_for" to check coverage.