7.2 KiB
7.2 KiB
拆分后续改进计划
日期:2026-04-21
背景
截至本文档编写时,双应用拆分已完成以下里程碑:
| 里程碑 | 状态 | 关键 commit |
|---|---|---|
| Workspace 结构(三个 crate) | 已完成 | — |
| 平台模块迁入 plc_platform_core | 已完成 | config/db/model/connection/telemetry/event/websocket/service/util/control |
| Web 目录拆分(core/feeder/ops + ServeDir fallback) | 已完成 | — |
| 三面板 UI(运维/应用配置/平台配置) | 已完成 | — |
| Log/Doc handler 迁入 core | 已完成 | — |
| PlatformContext 填充(pool/connection_manager/ws_manager) | 已完成 | 429c2d0 |
| WebSocket 类型去重(feeder 改为从 core 重导出) | 已完成 | 429c2d0 |
| PlatformBuilder 模式(消除 unsafe 初始化) | 已完成 | 429c2d0 |
| 旧 root src/ 删除 | 已完成 | — |
| Ops 应用拥有真实 PlatformContext(含数据库连接) | 已完成 | 429c2d0 |
以下四项改进是 spec(docs/superpowers/specs/2026-04-14-dual-app-shared-core-design.md)中明确要求但尚未完成的工作。
改进 1:平台 Handler 迁入 Core(中优先级)
目标
将不依赖业务状态的 handler 从 app_feeder_distributor 迁入 plc_platform_core::handler,使 ops 也能注册同一套平台 API。
前置条件
- PlatformContext 已包含 pool/connection_manager/ws_manager(已满足)
- Handler 函数签名需改为从
PlatformContext提取状态,而非 feeder 的AppState
待迁移 Handler
| 文件 | 行数 | 依赖分析 | 迁移难度 |
|---|---|---|---|
handler/source.rs |
626 | pool, connection_manager, event_manager | 中 — event_manager 是 feeder 特有的,需拆分或抽象 |
handler/point.rs |
693 | pool, connection_manager, event_manager | 中 — 同上 |
handler/equipment.rs |
335 | pool, event_manager | 中 — 同上 |
handler/tag.rs |
126 | pool | 低 — 纯数据库操作,可直接迁移 |
handler/page.rs |
169 | pool | 低 — 纯数据库操作,可直接迁移 |
不迁移的 Handler
| 文件 | 行数 | 原因 |
|---|---|---|
handler/control.rs |
750 | 完全是投煤器/布料机业务逻辑(unit CRUD、自动控制启停、故障确认) |
建议实施步骤
- 先迁 tag.rs 和 page.rs:只依赖 pool,无 event_manager 依赖,最简单
- Core 的 handler 签名使用
State<PlatformContext>或提取 pool 的 extractor - Feeder 和 ops 的 router 都注册这些路由
- Core 的 handler 签名使用
- 定义平台事件发送 trait:在 core 中定义
PlatformEventSinktrait,feeder 的EventManager实现它- 这样 source/point/equipment handler 可以依赖 trait 而非具体的
EventManager
- 这样 source/point/equipment handler 可以依赖 trait 而非具体的
- 迁移 source.rs、equipment.rs、point.rs:改为依赖
PlatformContext+PlatformEventSink - Ops 注册平台路由:ops router 中注册 source/point/equipment/tag/page 路由
关键设计决策
Handler 迁移后,两个 app 的 router 有两种注册方式:
- 方案 A:Core 提供
pub fn platform_routes() -> Router<PlatformContext>,每个 app merge 进来 - 方案 B:Core 只导出 handler 函数,每个 app 自己
.route()注册
推荐方案 B:更灵活,允许 app 按需选择注册哪些路由。
改进 2:事件命名空间(中优先级)
目标
给所有事件类型加上命名空间前缀(spec §6 要求),使不同业务的事件在同一张 event 表中可按前缀区分。
当前状态
Feeder 的 event.rs 中的事件类型已使用了点分隔命名(如 source.created、unit.auto_control_started),但缺少顶层业务前缀。
目标命名规范
| 前缀 | 含义 | 示例 |
|---|---|---|
platform.* |
平台级通用事件 | platform.source.created, platform.point.batch_created |
feeder.* |
投煤器布料机业务事件 | feeder.unit.auto_control_started, feeder.unit.fault_locked |
ops.* |
运转系统业务事件 | ops.unit.started, ops.interlock.triggered |
建议实施步骤
- 梳理
app_feeder_distributor/src/event.rs中persist_event_if_needed的所有 event_type 字符串 - 将平台通用事件(source., point.batch_)改为
platform.前缀 - 将业务事件(unit.*, equipment.start/stop_command_sent)改为
feeder.前缀 - 前端 JS 中若有事件类型过滤逻辑,同步更新
- 数据库中已有的历史事件不做回填(向前兼容)
改进 3:Ops 注册平台 Handler(中优先级)
目标
让 ops 应用能提供与 feeder 相同的平台配置能力(数据源、点位、设备、标签、页面管理)。
前置条件
- 改进 1(平台 handler 迁入 core)完成
- PlatformContext 已包含 pool(已满足)
当前 Ops Router
/api/health — health check
/api/logs — 日志查询(已从 core 注册)
/api/logs/stream — 日志 SSE 推送(已从 core 注册)
/api/docs/api-md — API 文档
/api/docs/readme-md — README
/ui — 静态页面(web/ops fallback web/core)
目标 Ops Router(改进 1 完成后)
/api/health
/api/logs, /api/logs/stream
/api/docs/api-md, /api/docs/readme-md
/api/source, /api/source/{source_id}, ... — 新增
/api/point, /api/point/{point_id}, ... — 新增
/api/equipment, /api/equipment/{id}, ... — 新增
/api/tag, /api/tag/{tag_id}, ... — 新增
/api/page, /api/page/{page_id}, ... — 新增
/ws/public — 新增(WebSocket 推送)
/ui
注意事项
- Ops 不注册
/api/unit和/api/control路由(那是 feeder 业务) - Ops 的 event_manager 需要独立实现(或先不实现事件广播,只做 CRUD)
- Ops 的 WebSocket handler 可以复用 core 的 WsMessage 类型
改进 4:Ops 业务逻辑(低优先级)
目标
为运转系统应用添加独立的业务能力。
前置条件
- 运转系统业务需求明确
- 改进 1-3 完成
待实现模块
根据 spec §5.2,app_operation_system 需要:
- 运转系统控制逻辑(
control/engine.rs) - 运转系统业务接口(
handler/control.rs) - 运转系统业务页面(
web/ops/扩充) - 业务事件定义(
event.rs,使用ops.*前缀) - 业务运行时状态(
OperationRuntimeStore)
Ops 业务事件示例(来自 spec §6.3)
ops.unit.startedops.unit.stoppedops.phase.changedops.interlock.triggeredops.interlock.released
当前不做的事
- 不把两套业务的控制引擎抽象为通用状态机(spec §12.2 明确约束)
- 不做业务插件化(spec §3 方案 C 已排除)
建议执行顺序
改进 1(handler 迁移)
├── 1a: 迁移 tag.rs + page.rs(纯 pool 依赖)
├── 1b: 定义 PlatformEventSink trait
└── 1c: 迁移 source.rs + equipment.rs + point.rs
改进 2(事件命名空间)── 可与改进 1 并行
改进 3(ops 注册平台路由)── 依赖改进 1 完成
改进 4(ops 业务逻辑)── 依赖改进 3 + 业务需求
改进 1a 和改进 2 可以并行推进,是当前最优先的两个切入点。