223 lines
8.4 KiB
Markdown
223 lines
8.4 KiB
Markdown
# CMP-20 `dbtool-tui-v1` 范围、架构边界与执行建议
|
||
|
||
日期:2026-03-26
|
||
作者:CTO
|
||
|
||
> 状态刷新(2026-03-27):本文档保留为 `CMP-20` 的边界决策记录。当前共享工作区已落地 `crates/db-app` 与 `apps/tui` 基线;实时推进状态请以 `plans/2026-03-26-dbtool-tui-v1-delivery-tracking.md`、`backlog/dbtool-tui-v1-first-wave-issues.md` 和 `apps/tui/README.md` 为准。
|
||
|
||
## 1. 当前真实状态
|
||
|
||
- `dbtool-cli-v1` 已具备 PostgreSQL / MySQL / SQLite 的 `connect`、`inspect`、`query`、`export` 主链路。
|
||
- 当前产品验收范围仍然是 CLI;TUI 不应混入 `dbtool-cli-v1` 的首发完成定义。
|
||
- 当前仓库没有任何 TUI 入口或终端 UI 基线,也没有事件循环、焦点管理、键盘导航或终端渲染代码。
|
||
- 代码层面,`apps/cli/src/main.rs` 仍同时承担参数解析、用例编排和终端文本渲染;这意味着当前“core”还不足以被 TUI 直接复用。
|
||
|
||
## 2. CTO 结论
|
||
|
||
### 结论 A:应作为独立 project 推进
|
||
|
||
- 建议在 Paperclip 中把 TUI 作为独立 project:`dbtool-tui-v1`。
|
||
- 原因不是要分裂代码仓库,而是要分离目标、验收和 owner 节奏。
|
||
- 这样可以明确:
|
||
- `dbtool-cli-v1` 继续对 CLI 首发负责
|
||
- `dbtool-tui-v1` 单独承担终端交互层探索和交付
|
||
- QA 不会把 TUI 误纳入当前 CLI 发布阻塞项
|
||
|
||
### 结论 B:必须复用现有 Rust core,而不是另写业务逻辑
|
||
|
||
- TUI 不应重新实现数据库连接、schema inspect、query 执行和 export 语义。
|
||
- TUI 应复用现有 `crates/db-core`、`crates/db-config`、`crates/db-drivers`,并新增一层共享应用编排层。
|
||
- 当前不建议为 TUI 单独建立另一套数据库访问栈,也不建议先走服务化 / 守护进程架构。
|
||
|
||
### 结论 C:先补“共享应用层”,再做 TUI 界面
|
||
|
||
- 当前最关键的前置项不是先画界面,而是把 `apps/cli` 中的用例编排抽出。
|
||
- 建议新增 `crates/db-app`(名称可调整),承载跨 CLI / TUI 共享的应用级用例与状态对象。
|
||
- 在这一步完成前,直接进入 TUI 编码会造成:
|
||
- CLI / TUI 各自复制一套执行编排
|
||
- 错误模型和状态文案分叉
|
||
- QA 需要维护两套行为定义
|
||
|
||
## 3. 推荐边界:Core / CLI / TUI
|
||
|
||
| 层 | 职责 | 当前状态 | 建议 |
|
||
| --- | --- | --- | --- |
|
||
| `crates/db-core` | 领域对象、请求/响应模型、通用错误、稳定产品语义 | 已存在 | 保持数据库无关,不放任何 UI 代码 |
|
||
| `crates/db-config` | 连接 profile、脱敏摘要、配置抽象 | 已存在 | 继续作为共享配置边界 |
|
||
| `crates/db-drivers` | PostgreSQL / MySQL / SQLite 具体实现 | 已存在 | 继续承载数据库差异 |
|
||
| `crates/db-app` | connect / inspect / query / export 用例编排、会话摘要、可展示执行状态 | 缺失 | 应先补齐,作为 CLI / TUI 共享应用层 |
|
||
| `apps/cli` | flag 解析、stdout/stderr 渲染、退出码 | 已存在但偏重 | 逐步瘦身为“CLI adapter” |
|
||
| `apps/tui` | 终端布局、焦点切换、快捷键、交互状态机、结果浏览 | 尚未开始 | 作为新 app 单独推进 |
|
||
|
||
## 4. 能力归属建议
|
||
|
||
### 必须留在 shared core / app 层的能力
|
||
|
||
- 连接目标建模
|
||
- 连接测试
|
||
- schema / table / column inspect 结果结构
|
||
- query 请求、结果和错误分类
|
||
- export 请求与结果
|
||
- 空结果成功、执行失败、导出失败等标准状态语义
|
||
- 脱敏规则与用户可展示错误摘要
|
||
|
||
### 应属于 CLI adapter 的能力
|
||
|
||
- 参数解析
|
||
- `--help` / `--version`
|
||
- 文本表格与命令行输出文案
|
||
- shell 退出码
|
||
- `.sql` 文件路径解析和命令行参数到请求对象的映射
|
||
|
||
### 应属于 TUI adapter 的能力
|
||
|
||
- 多 panel 布局
|
||
- 焦点管理
|
||
- 键盘导航与快捷键
|
||
- query editor buffer
|
||
- schema tree 展开 / 折叠 / 搜索
|
||
- results table 翻页与滚动
|
||
- execution banner、status bar、bottom panel
|
||
|
||
## 5. 推荐技术方案
|
||
|
||
### 终端渲染与输入
|
||
|
||
- 推荐:`ratatui` + `crossterm`
|
||
- 原因:
|
||
- Rust 生态成熟度足够
|
||
- 易于实现 panel、table、status bar、快捷键
|
||
- 不需要引入桌面壳或前端运行时
|
||
|
||
### 状态管理
|
||
|
||
- 推荐 reducer/event-driven 结构:
|
||
- `AppState`
|
||
- `Action`
|
||
- `update(state, action) -> state`
|
||
- 原因:
|
||
- 焦点切换、执行状态、结果切页都属于显式 UI 状态变化
|
||
- 这种结构比把逻辑散落在 widget callback 里更适合 QA 和后续扩展
|
||
|
||
### 数据执行模型
|
||
|
||
- 当前数据库 I/O 仍为同步模型,因此 TUI 不应在 UI 线程直接执行 query。
|
||
- 第一阶段建议使用“UI 主循环 + 后台 worker 线程 + channel 回传结果”。
|
||
- 当前不建议为了 TUI 先重构为服务进程或强行引入复杂 async runtime。
|
||
|
||
### SQL 编辑器
|
||
|
||
- 第一阶段只需要最小可用多行编辑,不追求完整 IDE 能力。
|
||
- syntax highlight、自动补全、query history search 应继续 gated。
|
||
|
||
## 6. 与 CLI 共存规则
|
||
|
||
- 代码仓库可以继续共用当前仓库,不必为了 TUI 单独拆 repo。
|
||
- Cargo workspace 后续可扩展为:
|
||
|
||
```text
|
||
apps/
|
||
cli/
|
||
tui/
|
||
crates/
|
||
db-core/
|
||
db-config/
|
||
db-drivers/
|
||
db-app/
|
||
```
|
||
|
||
- CLI 命令形状继续保持兼容演进,不为了 TUI 去打断当前 CLI 用户心智。
|
||
- TUI 不能成为当前 CLI release gate;它应拥有独立 milestone、issue、QA matrix 和完成标准。
|
||
|
||
## 7. TUI 第一阶段最小范围
|
||
|
||
### In Scope
|
||
|
||
- 单连接工作台
|
||
- 左侧 schema browser
|
||
- 中央 query editor
|
||
- 底部 results / problems 区
|
||
- 基本执行状态反馈
|
||
- 调用共享 inspect / query / export 能力
|
||
|
||
### Out of Scope
|
||
|
||
- 多连接同时在线
|
||
- 复杂 connection manager
|
||
- 多 query tab
|
||
- query 历史持久化
|
||
- SQL autocomplete / explain / formatter
|
||
- dashboard、图表、AI 助手
|
||
- 桌面 GUI 与 TUI 同期并行实现
|
||
|
||
## 8. 必须先完成的 gated 前置项
|
||
|
||
1. `CMP-19` MySQL 中文输出问题收敛,否则 TUI 只会把现有结果渲染缺陷带入新界面。
|
||
2. 抽出共享应用层 `db-app`,避免 CLI / TUI 双份编排。
|
||
3. 固定结构化执行结果:
|
||
- connect status
|
||
- inspect tree payload
|
||
- query success / empty / failure
|
||
- export success / failure
|
||
4. 明确终端尺寸下限、resize 行为和长结果滚动策略。
|
||
5. 为 TUI 单独建立 QA smoke 与键盘导航验收,不复用 CLI 文本输出验收。
|
||
|
||
## 9. 第一轮角色职责
|
||
|
||
- 后端:
|
||
- 抽出 `db-app`
|
||
- 统一执行状态和错误对象
|
||
- 保证 inspect / query / export 结果结构可被 TUI 直接消费
|
||
- 前端 / TUI 工程:
|
||
- 建立 `apps/tui`
|
||
- 落地 app shell、panel 布局、焦点管理和快捷键
|
||
- 不改数据库语义,不复制驱动逻辑
|
||
- QA:
|
||
- 编写 TUI 最小 smoke
|
||
- 覆盖 terminal resize、键盘导航、空结果、错误反馈、导出提示
|
||
- CTO:
|
||
- 维护 CLI / TUI 边界
|
||
- 防止 scope creep
|
||
- 评审 shared app 层是否足够稳定再放行 TUI 编码
|
||
|
||
## 10. 风险与依赖
|
||
|
||
### P0
|
||
|
||
- 当前 shared core 仍偏“领域模型 + driver 入口”,尚未形成真正的应用层复用边界。
|
||
- 如果跳过 `db-app`,TUI 项目会立即复制 CLI orchestration。
|
||
|
||
### P1
|
||
|
||
- 终端 UI 对长结果集、键盘交互、窗口缩放更敏感,QA 复杂度高于 CLI。
|
||
- 当前代码是同步数据库 I/O,若线程边界设计不清,TUI 容易出现卡顿或状态错乱。
|
||
|
||
### P2
|
||
|
||
- `CMP-9` 已定义未来 desktop GUI 基线;若 TUI 和 GUI 同时推进,团队容易把“终端工作台”和“桌面工作台”混为一谈。
|
||
|
||
## 11. 首批 issue 拆分建议
|
||
|
||
### 项目级
|
||
|
||
1. 新建 project:`dbtool-tui-v1`
|
||
2. 立项说明引用本文件与 [CMP-9](/CMP/issues/CMP-9)
|
||
|
||
### 工程级
|
||
|
||
1. **Backend**:抽出 `crates/db-app`,承接 connect / inspect / query / export 共享编排
|
||
2. **Backend**:稳定结构化执行状态与错误对象,补回归测试
|
||
3. **Frontend / TUI**:初始化 `apps/tui`,建立 `ratatui` shell、layout 和 focus model
|
||
4. **Frontend / TUI**:接入 schema browser + query editor 最小工作台
|
||
5. **Frontend / TUI**:接入 query 执行、result table、error banner、export trigger
|
||
6. **QA**:建立 TUI smoke runbook 与最小验收矩阵
|
||
|
||
## 12. 管理判断
|
||
|
||
- 现在可以为 TUI 做项目级立项准备,但不建议立刻把它推到与 CLI 同优先级。
|
||
- 更合理的节奏是:
|
||
1. 先完成 CLI 当前质量收口
|
||
2. 再抽 shared app 层
|
||
3. 然后启动 `dbtool-tui-v1` 的最小工作台实现
|
||
- 当前不建议因 TUI 方向立即扩编;先用第一轮 shared app + shell 结果验证真实吞吐与协作瓶颈。
|