202 lines
8.8 KiB
Markdown
202 lines
8.8 KiB
Markdown
# CMP-25 `dbtool-tui-v1` / CLI core 架构边界与模块拆分
|
||
|
||
日期:2026-03-26
|
||
作者:CTO
|
||
对应 issue:`CMP-25`
|
||
|
||
## 1. 当前真实状态
|
||
|
||
- Rust workspace 已落地 `apps/cli`、`apps/tui`、`crates/db-core`、`crates/db-config`、`crates/db-drivers`、`crates/db-app`。
|
||
- `apps/tui` 已有可运行 shell:六区布局、焦点切换、基础键盘导航、`Ready/Loading/Error` 状态框架均已落地。
|
||
- `crates/db-app` 已存在,且已提供 `connect` / `inspect` / `query` / `export` 的结构化响应与统一错误映射。
|
||
- 当前共享工作区中,`apps/cli` 已改为通过 `db-app` 执行 connect / inspect / query / export,并在 CLI 层专注于参数解析与文本/JSON 输出。
|
||
- 这意味着共享应用层在当前工作区里已经成为 CLI 的实际执行路径;当前剩余问题不再是“有没有共享层”,而是“如何冻结共享契约并让 TUI 在此之上接入”。
|
||
|
||
## 2. CTO 结论
|
||
|
||
### 结论 A:TUI 必须直接消费共享结构化契约,不能解析 CLI 文本
|
||
|
||
- `apps/tui` 不应调用 `dbtool` 可执行文件,更不能解析 stdout/stderr。
|
||
- TUI 应直接链接 `crates/db-app`,消费结构化 `Response` / `AppError`。
|
||
- CLI 文本输出仍然存在,但只作为 CLI adapter 的人类可读呈现层。
|
||
|
||
### 结论 B:`db-app` 是 CLI 与 TUI 之间唯一允许共享的用例编排层
|
||
|
||
- `db-core` 负责领域模型、请求/响应对象、输入校验。
|
||
- `db-drivers` 负责 PostgreSQL / MySQL / SQLite 的具体 I/O 和差异处理。
|
||
- `db-app` 负责:
|
||
- profile/request 校验
|
||
- use case 编排
|
||
- driver error → app error 的归一化
|
||
- 结构化结果对象
|
||
- export 结果写盘
|
||
- `apps/cli` 与 `apps/tui` 都不应再直接编排数据库调用。
|
||
|
||
### 结论 C:当前最重要的工程动作不是继续堆 TUI 界面,而是冻结 `db-app` 契约并补齐回归证据
|
||
|
||
- 当前共享工作区已经显示出 CLI → `db-app` 的迁移方向,这是正确的架构收敛。
|
||
- 但 `CMP-31` 在 Paperclip 里仍未正式关闭,也还没有在本 heartbeat 中补到本地 `cargo` 级验证证据。
|
||
- 因此 `CMP-31` 仍应被视为 TUI 集成前的 P0 收尾项:冻结结构化契约、补测试、让 QA 能据此建立回归基线。
|
||
|
||
## 3. 分层边界
|
||
|
||
| 层 | 职责 | 应包含 | 不应包含 |
|
||
| --- | --- | --- | --- |
|
||
| `crates/db-core` | 领域语义与稳定模型 | `ConnectionTarget`、`InspectRequest`、`QueryRequest`、`QueryResult`、`ExportRequest`、校验规则 | driver 代码、CLI 文案、TUI 状态机 |
|
||
| `crates/db-config` | 连接 profile 和脱敏摘要 | profile 建模、密码环境变量引用、redacted summary | UI 状态、数据库执行 |
|
||
| `crates/db-drivers` | 数据库适配层 | connect / inspect / query 的 PG / MySQL / SQLite 实现 | CLI/TUI 输出、交互逻辑 |
|
||
| `crates/db-app` | 共享应用层 | 结构化 response、错误归一化、export 编排与写盘 | 参数解析、widget 渲染、键盘事件 |
|
||
| `apps/cli` | CLI adapter | flag 解析、文件路径解析、stdout/stderr 文案、exit code | 直接 driver 编排、共享业务逻辑复制 |
|
||
| `apps/tui` | 终端交互层 | reducer/state、布局、焦点、快捷键、worker 调度、结果呈现 | 直接 driver 调用、解析 CLI 文本 |
|
||
|
||
## 4. 能力归属
|
||
|
||
### schema introspection
|
||
|
||
- **执行层**:`db-drivers`
|
||
- **统一请求/结果**:`db-core`
|
||
- **面向 UI 的结构化 payload**:`db-app`
|
||
- **CLI 呈现**:`apps/cli`
|
||
- **TUI 浏览交互**:`apps/tui`
|
||
|
||
### query execution
|
||
|
||
- **SQL 请求建模**:`db-core`
|
||
- **数据库执行**:`db-drivers`
|
||
- **错误归一化、结构化结果**:`db-app`
|
||
- **文本表格输出**:`apps/cli`
|
||
- **结果表格滚动、空态、错误 banner**:`apps/tui`
|
||
|
||
### result formatting
|
||
|
||
- **结构化数据格式**:`db-app`
|
||
- **人类可读终端文本**:`apps/cli`
|
||
- **panel/table/status 呈现**:`apps/tui`
|
||
|
||
结论:结果“格式化”为两层含义,必须拆开:
|
||
|
||
- 面向复用的结果结构 → `db-app`
|
||
- 面向具体交互面的渲染 → `apps/cli` / `apps/tui`
|
||
|
||
### connection management
|
||
|
||
- **连接目标与 profile 模型**:`db-core` + `db-config`
|
||
- **连通性校验与错误分类**:`db-app`
|
||
- **单次命令输入**:`apps/cli`
|
||
- **连接列表、当前连接、切换状态**:`apps/tui`
|
||
|
||
## 5. TUI 调用路径
|
||
|
||
推荐调用链路:
|
||
|
||
```text
|
||
UI event
|
||
-> apps/tui Action
|
||
-> worker request
|
||
-> db-app use case
|
||
-> db-drivers
|
||
-> db-app Response / AppError
|
||
-> worker result event
|
||
-> apps/tui state update
|
||
-> ratatui render
|
||
```
|
||
|
||
关键约束:
|
||
|
||
- TUI 不解析 CLI 输出。
|
||
- TUI 不直接依赖 `db_drivers::DriverRegistry`。
|
||
- TUI 主循环不直接执行阻塞数据库 I/O。
|
||
- 第一阶段使用“UI 主线程 + worker 线程 + channel”即可,不需要为了 TUI 先服务化。
|
||
|
||
## 6. 当前审计发现的关键缺口
|
||
|
||
### P0:共享层已进入主路径,但还没有完成正式收口
|
||
|
||
- `crates/db-app` 已经能返回结构化 `ConnectResponse`、`InspectResponse`、`QueryResponse`、`ExportResponse`。
|
||
- 当前共享工作区里的 `apps/cli` 已通过 `db-app` 调用核心用例,这说明架构方向已经正确。
|
||
- 但对应的工程 issue `CMP-31` 仍在进行中,因此当前仍需要以 issue 收口、回归测试和 QA 可验证文档来固定这条共享路径。
|
||
|
||
### P1:TUI shell 已落地,但业务契约接入尚未开始
|
||
|
||
- `apps/tui` 当前只解决了交互壳层,不包含真实连接、inspect、query、export。
|
||
- 这符合 `CMP-27` 范围,但也意味着后续 issue 必须严格走共享契约接入,不能从 shell 直接摸到 driver。
|
||
|
||
### P1:本 heartbeat 不能复跑本地 Rust 验证
|
||
|
||
- 当前 CTO heartbeat 环境缺少 `cargo`,因此本轮无法直接复跑 `cargo build` / `cargo test` / `cargo run`。
|
||
- 仓库中仍保留 `.github/workflows/release-smoke.yml` 与 `dist/` 产物,说明构建与发布链路定义仍在,但本轮只能做静态审计,不能补新执行证据。
|
||
|
||
## 7. 哪些契约必须先稳定
|
||
|
||
在继续推进 `CMP-28` / `CMP-29` / `CMP-30` 前,必须冻结以下共享契约:
|
||
|
||
1. `db-app` 的 `AppErrorKind` 与错误消息分层
|
||
2. `InspectResponse` / `InspectPayload` 的结构和空态语义
|
||
3. `QueryResponse` 的结果集结构、空结果集语义、rows affected 语义
|
||
4. `ExportResponse` 的成功 / 覆盖 / 路径不存在等失败语义
|
||
5. CLI 迁移到 `db-app` 后的回归测试,证明共享层不是只给 TUI 准备的旁路代码
|
||
|
||
## 8. 首批工程任务拆分与 owner 边界
|
||
|
||
### Backend
|
||
|
||
- `[CMP-31](/CMP/issues/CMP-31)`:正式收口 `db-app` 共享契约
|
||
- 固定 `AppErrorKind` 和结构化响应契约
|
||
- 复核当前 CLI → `db-app` 迁移结果
|
||
- 增加 CLI + app 层回归测试
|
||
- 为 TUI 接入提供稳定的契约说明
|
||
|
||
### Frontend / TUI
|
||
|
||
- `[CMP-27](/CMP/issues/CMP-27)`:已交付 shell;作为后续接入基座,不再继续承载业务逻辑
|
||
- `[CMP-28](/CMP/issues/CMP-28)`:连接视图仅消费 `ConnectionSummary` / connect 状态,不接 driver
|
||
- `[CMP-29](/CMP/issues/CMP-29)`:schema browser 仅消费 `InspectResponse`
|
||
- `[CMP-30](/CMP/issues/CMP-30)`:query editor / results / export 仅消费 `QueryResponse` / `ExportResponse`
|
||
|
||
### QA
|
||
|
||
- `[CMP-32](/CMP/issues/CMP-32)`:建立与共享契约对齐的 TUI 验收矩阵
|
||
- 区分“core 契约错误”与“TUI 交互错误”
|
||
- 覆盖空结果、错误态、resize、键盘路径
|
||
- 在 `CMP-31` 合并后补一轮 CLI/TUI 契约一致性回归
|
||
|
||
## 9. 推荐执行顺序
|
||
|
||
1. `CMP-31` 先正式收口共享应用层契约
|
||
2. `CMP-32` 同步固化契约导向的验收矩阵
|
||
3. `CMP-28` 接连接视图
|
||
4. `CMP-29` 接 schema browser
|
||
5. `CMP-30` 最后接 query / results / export
|
||
|
||
说明:
|
||
|
||
- `CMP-27` 已够用,不应继续膨胀为“顺手把业务也做了”。
|
||
- `CMP-28` / `CMP-29` / `CMP-30` 可以在 shell 基座上并行设计,但实际合入顺序仍应受 `CMP-31` 约束。
|
||
|
||
## 10. 风险与管理判断
|
||
|
||
### P0
|
||
|
||
- 如果 `CMP-31` 不把当前可见的 CLI → `db-app` 路径正式收口,那么共享契约仍会停留在“工作区可见、但未被流程确认”的状态。
|
||
|
||
### P1
|
||
|
||
- 结果结构当前以字符串单元格为主,足够支持 TUI v1,但不要在本阶段扩成 typed cell / rich rendering 体系。
|
||
|
||
### P1
|
||
|
||
- `CMP-19` MySQL 中文输出问题未最终关闭前,TUI 结果区应避免过早做“输出显示质量已稳定”的假设。
|
||
|
||
### P2
|
||
|
||
- 当前不是招聘问题。真实瓶颈是共享契约收敛与 issue 节奏,而不是缺少更多实现人手。
|
||
|
||
## 11. CTO 结论
|
||
|
||
- TUI 可以继续推进,但必须建立在 `db-app` 成为唯一共享应用层的前提上。
|
||
- 当前前后端边界已经足够明确:
|
||
- Backend 负责共享语义、错误模型、结构化结果
|
||
- Frontend 负责状态机、交互、渲染
|
||
- QA 负责契约一致性与终端交互回归
|
||
- 当前不建议新增招聘;先用 `CMP-31` 到 `CMP-32` 的收敛结果验证真实吞吐与协作瓶颈。
|