feat: introduce spec system + dashboard + health pipeline (AgentsMeeting template)

This commit is contained in:
hmo
2026-07-19 10:50:34 +08:00
parent 81c6dd2314
commit 747fdfe467
19 changed files with 1826 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
# MoFin — Dashboard API 参考
> 版本: v1.0 | 端口: 5804 | 入口: http://192.168.1.246:5804
---
## Tab 结构
```
MoFin Dashboard
├── Services — 服务状态总览(MoFin API / Dashboard / 知微 Gateway / ejabberd / DB
└── 开发原则
├── G 规范 — 开发规范 + Spec 文档
└── F 健康 — 系统健康监控(Tier1/Tier2
```
---
## API 端点清单
### 服务监控
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/services` | 所有注册服务状态(含健康检查结果) |
| GET | `/api/expected` | 期望状态矩阵(含实际状态对比) |
| GET | `/api/monitor` | 聚合监控数据(tasks + Tier1 + Tier2 |
| GET | `/api/health` | Dashboard 自身健康检查 |
### 知识管理
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/module-spec/<module>` | 读取 `specs/{module}.json`?§ 按钮后端) |
### 响应格式
**GET /api/services**:
```json
{
"services": [
{
"name": "mofin_api",
"label": "MoFin API",
"port": 8899,
"type": "http",
"layer": "核心服务",
"critical": true,
"health": {"ok": true},
"detail": "HTTP 200"
}
],
"summary": {"ok": 5, "total": 5}
}
```
**GET /api/monitor**:
```json
{
"tasks": [
{"name": "agents-health-check", "status": "cron_ok"},
{"name": "agents-daily-health", "status": "not_deployed"},
{"name": "dashboard", "status": "running", "detail": "services: 5/5"}
],
"tier1": {"summary": {"ok": 5, "total": 5}, "services": [...]},
"tier2": {"summary": {"ok": 0, "total": 0}, "services": []},
"generated_at": "2026-07-19 10:00:00"
}
```
---
## 前端架构
- 纯 HTML/CSS/JS(无框架)
- 深色主题(GitHub Dark 风格)
- 5 秒自动轮询(Services Tab
- ?§ Spec 系统(human_help + ai_spec
### Spec 系统(?§ 按钮)
每个有 spec 的模块在 UI 上显示两个按钮:
- `?` → 读取 `human_help` → 人类可读的帮助文档
- `§` → 读取 `ai_spec` → AI 可用的接口/约束/依赖
**Spec 文件位置**: `specs/{module}.json`
**API 端点**: `GET /api/module-spec/{module}`
---
## 数据流
```
crontab (每 5 分钟)
└── agents_health_check.py → last_health_check.json
Dashboard (:5804)
├── /api/services ← 实时 TCP/HTTP 检测
├── /api/monitor ← 聚合读取 health check JSON
└── /api/module-spec/<module> ← 读取 specs/
前端 (dashboard.html)
├── 5s 轮询 /api/services
└── 按需请求 /api/monitorF Tab 打开时)
```
+99
View File
@@ -0,0 +1,99 @@
# MoFin — 部署指南
> 版本: v1.0 | 部署目标: Linux 192.168.1.246
---
## 部署概览
| 组件 | 守护方式 | 端口 | 说明 |
|------|---------|------|------|
| **server.py** | systemd `mofin-api` | 8899 | 持仓情报 API(已有,不动) |
| **dashboard.py** | systemd `mofin-dashboard` | 5804 | 管理门户(新增) |
| **health_check** | crontab `*/5 * * * *` | — | Tier1 健康检查(新增) |
---
## 1. Dashboard 部署
### 1.1 创建 systemd 服务
```bash
sudo tee /etc/systemd/system/mofin-dashboard.service << 'EOF'
[Unit]
Description=MoFin Dashboard
After=network.target
[Service]
Type=simple
User=hmo
WorkingDirectory=/home/hmo/MoFin
Environment=MOFIN_ROOT=/home/hmo/MoFin
ExecStart=/usr/bin/python3 /home/hmo/MoFin/dashboard.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
```
### 1.2 启动
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now mofin-dashboard
sudo systemctl status mofin-dashboard
```
### 1.3 验证
```bash
curl http://127.0.0.1:5804/api/health
curl http://127.0.0.1:5804/api/services | python3 -m json.tool
# 浏览器访问: http://192.168.1.246:5804
```
---
## 2. 健康管线部署
```bash
# 添加到 crontab
(crontab -l 2>/dev/null; echo '# MoFin health pipeline'; echo '*/5 * * * * cd /home/hmo/MoFin && /usr/bin/python3 agents_health_check.py >> gateway/logs/health_check_cron.log 2>&1') | crontab -
# 验证
crontab -l | grep health
```
---
## 3. 防火墙
```bash
sudo ufw status | grep -E '8899|5804'
# 如果未开放:
# sudo ufw allow 5804/tcp
```
---
## 4. 部署后验证清单
- [ ] `curl http://127.0.0.1:5804/api/health``{"status":"ok"}`
- [ ] `curl http://127.0.0.1:5804/api/services` → 返回 5 个服务状态
- [ ] 浏览器打开 `http://192.168.1.246:5804` → Services Tab 显示服务状态
- [ ] Dashboard F 健康 Tab → 定时任务状态显示正常
- [ ] 点击各模块 ?§ 按钮 → 弹出 spec 帮助内容
- [ ] `python3 agents_health_check.py` → 无输出(全正常)
---
## 5. 故障恢复
| 问题 | 命令 |
|------|------|
| Dashboard 挂了 | `ssh hmo@246 'sudo systemctl restart mofin-dashboard'` |
| 健康检查不运行 | `ssh hmo@246 'crontab -l \| grep health'` |
| MoFin API 挂了 | `ssh hmo@246 'sudo systemctl restart mofin-api'` |
| 知微 Gateway 挂了 | `ssh hmo@246 'sudo systemctl restart hermes-gateway@zhiwei'` |
+111
View File
@@ -0,0 +1,111 @@
# MoFin — 健康监控管线
> 版本: v1.0 | 部署目标: Linux 246
---
## 概述
两层监控,通过 crontab 调度,聚合到 Dashboard F Tab。
```
┌─────────────────────────────────┐
│ Dashboard F Tab │
│ /api/monitor 聚合展示 │
└──────────┬──────────────────────┘
│ 读取报告文件
┌──────────┴──────────┐
│ │
┌────▼─────┐ ┌────▼─────┐
│ Tier 1 │ │ Tier 2 │
│ 每 5 分钟 │ │ 每天 8:00│
└──────────┘ └──────────┘
│ │
agents_health_check agents_daily_health
│ (规划中)
┌────▼─────┐
│ TODO 文件 │
│ .jsonl │
└──────────┘
```
---
## Tier 1: 快速健康检查(每 5 分钟)
**脚本**: `agents_health_check.py`
**调度**: `crontab: */5 * * * *`
**检查内容**:
- 5 个服务:MoFin API (:8899) / Dashboard (:5804) / 知微 Gateway (:8643) / ejabberd (:5222) / MoFin DB
- 检查方式:socket 端口 + HTTP /health + SQLite connect
- 全正常时静默(不输出、不写日志)
**异常处理**:
- 写入 `gateway/temp/health_todos.jsonl`
- 每条 TODO 包含:服务名、失败原因、时间戳
- 写入 `gateway/temp/last_health_check.json` 供 Dashboard 读取
**日志**: `gateway/logs/health_check.log`
**报告**: `gateway/temp/last_health_check.json`
---
## Tier 2: 每日全面检查(规划中)
**计划脚本**: `agents_daily_health.py`
**计划调度**: `crontab: 0 8 * * * 1-5`(交易日 8:00
**计划检查内容**:
- 在 Tier 1 基础上增加:
- 磁盘空间检查(阈值 10G 警告 / 2G 严重)
- crontab 存活检查(验证关键定时任务)
- MoFin DB 大小和新鲜度检查
- 生成结构化 JSON 报告
**注意**: MoFin 已有 `system_health_check.py`(每日 9:00)和 `morning_health_check.py`(交易日 8:00,8层48项),Tier2 将与现有检查互补,不重复。
---
## Dashboard 集成
### /api/monitor 端点
聚合展示两层数据:
```json
{
"tasks": [
{"name": "agents-health-check", "status": "cron_ok"},
{"name": "agents-daily-health", "status": "not_deployed"},
{"name": "dashboard", "status": "running"}
],
"tier1": { "services": [...], "summary": {"ok": 5, "total": 5} },
"tier2": { "services": [...], "summary": {"ok": 0, "total": 0} }
}
```
### F Tab 展示
- 系统概览(Tier1 通过率)
- 定时任务状态(绿色=正常,黄色=未部署,红色=异常)
- Tier1 服务详情
---
## 如何新增监控
1. **添加服务到 Tier 1** — 编辑 `agents_health_check.py``SERVICES` 列表
2. **更新 Dashboard** — 在 `dashboard.py``SERVICES` 中同步添加
3. **写 Spec** — 在 `specs/` 创建或更新对应模块的 JSON
---
## 故障排查
| 现象 | 检查 |
|------|------|
| F Tab 无数据 | `cat ~/MoFin/gateway/temp/last_health_check.json` 确认文件存在 |
| Tier1 任务显示"未部署" | `crontab -l \| grep health` 确认 crontab 条目 |
| TODO 堆积 | 手动检查失败服务的实际状态 |
| Dashboard 不显示新服务 | 确认 dashboard.py 的 SERVICES 列表和 health_check 同步 |
+86
View File
@@ -0,0 +1,86 @@
# MoFin — 快速操作手册
> 生产环境: Linux 192.168.1.246 | 端口: API 8899 / Dashboard 5804
---
## 日常检查
```bash
# 打开 Dashboard 看全局
http://192.168.1.246:5804
# 命令行快速状态
ssh hmo@192.168.1.246 "curl -s http://127.0.0.1:5804/api/services | python3 -m json.tool | head -20"
```
---
## Dashboard
```bash
# 查看状态
ssh hmo@192.168.1.246 "sudo systemctl status mofin-dashboard"
# 重启
ssh hmo@192.168.1.246 "sudo systemctl restart mofin-dashboard"
# 查看日志
ssh hmo@192.168.1.246 "tail -50 ~/MoFin/gateway/logs/dashboard.log"
```
---
## MoFin API
```bash
# 查看状态
ssh hmo@192.168.1.246 "sudo systemctl status mofin-api"
# 重启
ssh hmo@192.168.1.246 "sudo systemctl restart mofin-api"
# 测试 API
curl http://192.168.1.246:8899/api/portfolio
```
---
## 健康检查
```bash
# 查看定时任务
ssh hmo@192.168.1.246 "crontab -l | grep health"
# 手动运行(无输出 = 全正常)
ssh hmo@192.168.1.246 "cd ~/MoFin && python3 agents_health_check.py"
# 查看最近报告
ssh hmo@192.168.1.246 "cat ~/MoFin/gateway/temp/last_health_check.json | python3 -m json.tool"
```
---
## 部署更新
```bash
# 1. 拉代码
ssh hmo@192.168.1.246 "cd ~/MoFin && git pull --rebase"
# 2. 重启受影响的服务
ssh hmo@192.168.1.246 "sudo systemctl restart mofin-dashboard"
# 3. 验证
ssh hmo@192.168.1.246 "curl -s http://127.0.0.1:5804/api/health"
```
---
## 常见问题
| 现象 | 操作 |
|------|------|
| Dashboard 不响应 | `ssh hmo@246 sudo systemctl restart mofin-dashboard` |
| F Tab 定时任务显示"未部署" | `ssh hmo@246 crontab -l \| grep health` 确认 |
| MoFin API 不响应 | `ssh hmo@246 sudo systemctl restart mofin-api` |
| 数据库查询失败 | `ssh hmo@246 'ls -la /home/hmo/web-dashboard/data/mofin.db'` |
@@ -0,0 +1,26 @@
# 决策: 引入 spec 体系 + Dashboard
## Context
MoFin 项目已运行数月,有 30 个 API 端点、38 个 cron 任务、完善的编码规范(DEVELOPMENT_STANDARDS.md)和架构文档(SYSTEM_ARCHITECTURE.md)。但缺少:
- 统一的模块可见性("不可见即不存在")
- AI 和人类共享的接口文档(spec 过期即等于没写)
- 系统健康状态的一站式监控面板
## Decision
参照 AgentsMeeting 样板,为 MoFin 引入:
1. **spec 双轨体系** — 每个模块的 `specs/{module}.json`human_help + ai_spec
2. **Dashboard** — 独立 `dashboard.py`(端口 5804),深色主题 Web UI + ?§ 按钮
3. **健康管线** — Tier15min+ Tier2(日检),聚合到 Dashboard F Tab
4. **开发规范**`docs/dev-spec.md`(五条红线)
不改动任何现有业务代码(server.py :8899 保持不变)。
## Consequences
- 新增 Dashboard 维护负担(但代码最小化,复用 AgentsMeeting 模板)
- AI 开发前必须先读 spec,短期可能感觉慢,长期减少架构理解错误
- 健康检查需要纳入 crontab,增加系统负载(但轻量级,可忽略)
## Alternatives Considered
- **方案 A**: 在现有 server.py 中嵌入 Dashboard(被否 — 改动运行中业务代码风险大)
- **方案 B**: 不做 Dashboard,只补文档(被否 — "不可见即不存在",没有面板等于没做)
- **方案 C**: 独立 dashboard.py(✅ 选择 — 零风险,不影响现有服务)
+29
View File
@@ -0,0 +1,29 @@
# 架构决策日志
每次架构决策(引入新组件、增加抽象层、变更接口)记录在此目录下。
## 格式
文件名: `YYYY-MM-DD-简短描述.md`
```markdown
# 决策: [标题]
## Context
为什么需要做这个决策?当前状态是什么?
## Decision
做了什么选择?
## Consequences
这个选择的影响和后果是什么?
## Alternatives Considered
考虑了哪些替代方案?为什么没选?
```
## 已有决策
| 日期 | 决策 | 文件 |
|------|------|------|
| 2026-07-19 | 引入 spec 体系 + Dashboard(参照 AgentsMeeting 样板) | `2026-07-19-spec-and-dashboard.md` |
+214
View File
@@ -0,0 +1,214 @@
# MoFin 开发规范
> 版本: v1.0 | 更新: 2026-07-19 | 基于 AgentsMeeting 样板重构
>
> 📋 样板参考: [AgentsMeeting TEMPLATE-GUIDE.md](../AgentsMeeting/docs/TEMPLATE-GUIDE.md)
---
## 五条红线
1. **先读/写 Spec,再写代码** — 新增功能先写 spec 再实现;修改已有功能先读对应 spec 了解架构和约束再动手。没有 spec 的模块在 Dashboard 不可见,视为未完成
2. **部署必验** — 部署后不打开 Dashboard F Tab 验证 = 部署未完成
3. **不可见即不存在** — 组件不在 Dashboard 中显示 = 等于没部署。离线不告警 = 监控缺陷
4. **实现后同步 Spec** — 每轮开发完毕后,必须将 `specs/{module}.json` 更新为与实际实现一致的状态。文档过期 = 等于没写
5. **部署目标即验收标准** — 所有代码必须以部署目标环境(Linux 246)为基准编写和测试。禁止使用 Windows 专属 API`tasklist``netstat``schtasks``wmic`)在 246 部署的代码中
---
## 一、双轨同源规范体系
每新增/修改一个独立功能模块,必须先写 `specs/{module}.json`
一个来源同时产出两套文档:
```
specs/{module}.json
├── human_help → ? 按钮(人类看说明/排错)
└── ai_spec → § 按钮(AI 看接口/约束/依赖)
```
### 什么算一个模块
满足以下任一条件即视为独立模块,必须写 spec:
- 暴露独立的 HTTP API 端点
- 在 Dashboard 上有独立 UI 面板(`?` + `§` 按钮)
- 有独立的配置文件 / 数据文件
- 可独立部署(如定时任务、数据采集脚本)
### Spec 字段标准
```json
{
"module": "模块名(与 Dashboard 引用名一致)",
"version": "1.0",
"purpose": "一句话说明这个模块干什么",
"human_help": {
"title": "面向人类的标题",
"description": ["说明段落数组"],
"usage": ["使用步骤数组"],
"troubleshooting": ["常见问题数组"]
},
"ai_spec": {
"apis": [
{"method": "GET", "path": "/api/xxx", "returns": "返回值说明"}
],
"dependencies": ["依赖的服务或文件"],
"constraints": ["AI 必须遵守的约束"],
"must_not": ["AI 绝对不能做的事"],
"tests": [{"id": "T1", "name": "测试用例名"}],
"related_files": ["实现文件路径"]
}
}
```
### 当前模块清单
| 模块 | spec 路径 | 说明 | 状态 |
|------|----------|------|------|
| portfolio | `specs/portfolio.json` | 持仓数据 + 总览 | ✅ |
| watchlist | `specs/watchlist.json` | 自选股管理 | ✅ |
| decisions | `specs/decisions.json` | 策略决策库 | ✅ |
| market | `specs/market.json` | 市场观察数据 | ✅ |
| signals | `specs/signals.json` | 信号 + 小果扫描 | ✅ |
| evaluation | `specs/evaluation.json` | 策略评估 | ✅ |
| dashboard | `specs/dashboard.json` | Dashboard 自身 | ✅ |
| health | `specs/health.json` | 健康监控管线 | ✅ |
| price_monitor | `specs/price_monitor.json` | 价格监控 cron | 📋 |
| strategy_lifecycle | `specs/strategy_lifecycle.json` | 策略生命周期 | 📋 |
> 状态: ✅ = spec 已完成 | 📋 = 待编写
---
## 二、验证闭环
```
┌────────────┐ ┌──────────┐ ┌──────────┐
│ G: 规范体系 │────→│ K: 测试 │────→│ F: 健康 │
│ 定义期望 │ │ 验证实现 │ │ 持续监控 │
└────────────┘ └──────────┘ └──────────┘
↑ ↑ │
└────────────────┼────────────────┘
┌────────┴────────┐
│ F 异常 → 触发 K │
│ K 失败 → 更新 G │
└─────────────────┘
```
### 核心反馈链路
| 方向 | 触发条件 | 动作 |
|------|---------|------|
| G → K | 新增/修改 spec | 对应测试 ID 必须新增/更新 |
| K → F | 测试全部通过 | F Tab 组件标记为已验证 |
| **F → K** | **F Tab 发现异常** | 触发对应测试重跑,确认是服务故障还是测试过期 |
| **F → G** | **F Tab 持续异常但测试通过** | 期望矩阵或 spec 过时,应更新 G 和对应 spec |
### F — 系统健康度(Dashboard F Tab
- **期望矩阵**:应该运行的服务 vs 实际状态
- **监控数据**Tier15min)/ Tier2(日报)作为实时状态输入
- **服务拓扑**:所有服务的健康、端口状态
- **?§ 覆盖**:F Tab 中的每条服务必须有对应的 ?human_help)和 §(ai_spec)按钮
---
## 三、开发流程
### 新增功能流程
```
确定模块边界
├─ 1. 创建 specs/{module}.json
│ human_help + ai_spec
├─ 2. 实现功能代码
│ 包含 /health 端点 + PID 锁(proc_guard
├─ 3. 注册到系统
│ - 端口注册
│ - 添加到期望矩阵(F Tab 自动检测)
├─ 4. 编写测试
│ - ai_spec.tests 添加对应测试标识
├─ 5. 同步更新 Spec
│ - 将 specs/{module}.json 更新为与实际实现一致
└─ 6. 提交 → 部署 → 验证
```
### 修改已有功能流程
```
识别要修改的模块(查看模块清单确定 module 名)
├─ 1. 读 specs/{module}.json
│ 重点读 ai_specapis / constraints / dependencies / must_not
├─ 2. 确认理解
│ - 如果 spec 描述与代码实际行为不一致,优先怀疑 spec 过期
├─ 3. 修改功能代码
│ 只改动需求直接涉及的部分,不顺手优化无关代码
├─ 4. 同步更新 Spec
└─ 5. 提交 → 部署 → 验证
```
### Git 操作规范
| # | 规则 | 说明 |
|---|------|------|
| 1 | 开工前必 pull | `git pull --rebase` |
| 2 | 改完即 commit | 一个逻辑单元一次提交。禁止含密钥 |
| 3 | 推前必拉 + 配代理 | push 前 `git pull --rebase`。远程操作前配 `:15000` 代理 |
| 4 | trunk-based | 日常在 main。仅长周期大改开分支 |
### 已有编码规范
MoFin 已有的编码规范见 `docs/DEVELOPMENT_STANDARDS.md`,包含:
- 代码结构(mo_models → mo_data → mofin_db 三层)
- 数据规范(币种、汇率、数据源)
- DB 规范(表设计、迁移)
- LLM Prompt 规范
- Cron 规范(独立运行、幂等性)
- 测试要求(`run_all_tests.py`
以上规范与本文件互补,不冲突。本文件侧重"先 spec 后代码"和"通过 Dashboard 保证可见性"。
---
## 四、部署环境
| 项目 | 值 |
|------|-----|
| **生产环境** | Linux 192.168.1.246 |
| **代码目录** | `/home/hmo/MoFin/` |
| **数据库** | `/home/hmo/web-dashboard/data/mofin.db`SQLite |
| **Flask API** | `server.py``:8899` |
| **Dashboard** | `dashboard.py``:5804`(新增) |
| **Python** | 系统 Python 3 |
---
## 五、文档索引
| 文档 | 用途 |
|------|------|
| `docs/dev-spec.md` | 本文件 — 开发规范(含五条红线) |
| `docs/DEVELOPMENT_STANDARDS.md` | 编码规范(已有) |
| `SYSTEM_ARCHITECTURE.md` | 系统架构(已有) |
| `docs/cron-catalog.md` | Cron 任务清单(已有) |
| `docs/DEPLOY.md` | 部署指南 |
| `docs/QUICKSTART.md` | 快速操作 |
| `docs/DASHBOARD.md` | Dashboard API 参考 |
| `docs/HEALTH-PIPELINE.md` | 健康管线文档 |
| `docs/learned.md` | 经验教训记录 |
| `docs/decisions/` | 架构决策日志 |
+12
View File
@@ -0,0 +1,12 @@
# 经验教训记录
每次被纠正后追加一条记录。每次新任务前先扫一遍本文档。
## 格式
- [YYYY-MM-DD] 问题: xxx | 根因: xxx | 正确做法: xxx
---
## 记录
- [2026-07-19] 问题: MoFin 缺少 spec 体系和 Dashboard,功能模块不可见、不可监控 | 根因: 项目早期未引入"不可见即不存在"原则 | 正确做法: 参照 AgentsMeeting 样板重构,先建立 dev-spec.md + spec 体系 + Dashboard,再逐步迁移