重构项目心跳数据结构为Redis LIST,更新相关文档和OpenSpec规范。主要变更包括: - 将项目心跳从STRING改为LIST类型 - 更新后端服务以支持LIST操作 - 同步更新文档和OpenSpec规范 - 统一后端端口为3001 - 添加部署指南和Windows部署文档 修复前端API请求路径,移除硬编码的localhost地址。添加PM2和Nginx配置文件模板,完善部署流程文档。更新Redis集成协议文档,明确LIST数据结构和外部项目对接规范。
6.6 KiB
现状差异(需要补齐的点)
-
项目心跳目前在代码/文档/测试里都按 STRING(JSON 数组)读取与写入:见 migrateHeartbeatData.js、projects.js、redis-data-structure.md。与你的需求“改成 Redis LIST”不一致。 -
后端端口存在不一致:源码后端固定 19910(server.js),但 Vite 代理与 OpenAPI/README 默认指向 3001(vite.config.js、openapi.yaml),而实际上后端是19070。
-
OpenSpec/文档存在历史漂移:command capability 仍描述“发命令到 Redis 队列”,而当前实现为 HTTP 调用(openspec/specs/command/spec.md、commands.js)。
目标(按你的新需求对齐)
-
外部项目把心跳写入 Redis DB15 的
项目心跳(LIST)。 -
心跳记录结构为:
{"projectName":"...","apiBaseUrl":"...","lastActiveAt":1768566165572};后端读取后形成数组视图(逻辑上的[{...}])。 -
外部项目把日志写入
${projectName}_项目控制台(LIST),本项目 console 界面展示这些内容(现已实现轮询/api/logs+LRANGE,只需确保心跳/项目列表读写契约一致)。 -
任何与上述不符的 OpenSpec / 文档 / 代码统一修改并保持一致。
设计决策(LIST 语义)
-
项目心跳(LIST)中每个元素为“一个项目的一条心跳记录”的 JSON 字符串。 -
为兼容你给出的
[{...}]这种数组表达,后端解析时将支持两种元素格式:-
元素是对象 JSON:
{"projectName":...} -
元素是数组 JSON:
[{"projectName":...}](会被 flatten)
-
-
若多个外部项目反复
RPUSH会产生重复记录:后端在读取时会按projectName去重,保留lastActiveAt最新的一条。 -
过渡期兼容:不允许有
项目心跳仍为 STRING(旧格式),后端不可读取,所有文档/OpenSpec/实际代码修改为 将以 LIST 为唯一指定。
OpenSpec 调整方案
-
新建一个 change(建议 change-id:
update-heartbeat-key-to-list),在openspec/changes/下补齐 proposal/tasks/specs delta。 -
修改 capabilities:
-
openspec/specs/redis-connection/spec.md:把项目心跳数据类型从 STRING 改为 LIST,并补充“去重/解析”场景。 -
openspec/specs/logging/spec.md:确认日志读取来自${projectName}_项目控制台(LIST),并在 API 响应中保持现有字段。 -
openspec/specs/command/spec.md:把“发送到 Redis 控制队列”的描述改为“通过 HTTP 调用目标项目 API”(与当前实现一致),避免规范漂移。
-
代码改造方案(后端为主)
-
统一端口:将 src/backend/server.js 改为
process.env.PORT || 3001,与 Vite 代理/OpenAPI/README 对齐。 -
getProjectsList():-
先用
TYPE 项目心跳判断类型:-
list →
LRANGE 0 -1并解析每个元素 JSON(支持对象/数组),再去重。 -
string →
GET并解析 JSON 数组(旧格式兼容),再去重。 -
none/其他 → 返回 []。
-
-
-
migrateHeartbeatData():- 不从
*_项目心跳(STRING)读取,改为从项目心跳(LIST)读取每条心跳记录 JSON。
- 不从
-
必须彻底删除
*_项目心跳相关的所有内容,包括项目文档和代码逻辑,全面改为用项目心跳(LIST)里的值。 -
updateProjectHeartbeat():改为写入 LIST(实现为:读取→去重→重建 LIST;用于内部工具/未来扩展)。 -
相关路由(projects.js、logs.js、commands.js)无需改 API 形状,只要底层心跳读取逻辑更新即可。
前端调整方案
-
预计不需要改动:前端只依赖
/api/projects与/api/logs,后端适配 LIST 后前端会自动工作。 -
如需更明确提示,可在 ProjectSelector 里优化“暂无连接/Redis 未就绪”的文案,但这不是必须项。
文档对齐方案
-
更新 docs/redis-integration-protocol.md:
-
将
项目心跳类型改为 LIST,并给出外部项目写入示例(RPUSH 项目心跳 '<json>')。 -
明确 DB 固定 15。
-
删除/改写“STRING 覆盖风险/WATCH”段落,替换为“LIST 可能重复,控制台会按 projectName 去重”。
-
-
更新 docs/redis-data-structure.md:
-
同步
项目心跳为 LIST。 -
将“项目控制指令
{projectName}_控制”标注为历史/不再使用(当前实现为 HTTP 调用)。
-
-
同步 docs/openapi.yaml 的 server URL/示例端口(与 3001 保持一致)。
-
README 与
openspec/project.md中如有测试框架/端口等描述漂移,一并纠正。
测试与验证方案
-
更新 fake redis(fakeRedis.js)以支持
RPUSH/LPUSH/LRANGE/DEL的 list 存储。 -
更新集成测试(projects.integration.test.js):
-
GET /api/projects场景改为基于 LIST 的项目心跳。 -
POST /api/projects/migrate场景验证迁移写入 LIST。
-
-
本地跑
npm test,并做一次手工冒烟:启动前后端后,往 Redis DB15 写入一条心跳 + 一条日志,确认 UI 能看到项目与日志。
如果你确认这个计划,我将按上述顺序:先补 OpenSpec change 与 specs 对齐,再改后端读取/迁移逻辑与端口,最后更新文档与测试,保证“需求=规范=实现=文档”一致。