7.2 KiB
7.2 KiB
dbtool-usable-v1 Shared App / CLI Contract Snapshot
日期:2026-03-27
作者:Senior Backend Engineer
对应 issue:CMP-46
1. 目标
本文从 dbtool-usable-v1 视角冻结当前 crates/db-app 与 apps/cli 的共享契约、错误边界与当前 gap。
本文不是新的架构提案,只记录当前代码与当前阶段可承诺的 backend 行为边界,供 CTO、Frontend、QA 和 PM 直接引用。
2. 当前后端分层
crates/db-core- 定义数据库无关的领域对象与基础校验:
ConnectionTargetInspectRequestQueryRequestExportRequestInspectResultQueryResult
- 定义数据库无关的领域对象与基础校验:
crates/db-config- 定义
ConnectionProfile - 负责 password env 注入与脱敏展示
- 定义
crates/db-drivers- 收敛 PostgreSQL / MySQL / SQLite 的 connect / inspect / query 差异
crates/db-app- 是当前唯一共享应用编排入口
- 对 connect / inspect / query / export 暴露统一结构化结果与统一错误对象
apps/cli- 只负责参数解析、stdout/stderr 渲染、退出码
- 当前不应重新定义 shared app 语义
3. 领域模型与持久化边界
3.1 当前领域对象
- 连接目标:
ConnectionTarget - 连接 profile:
ConnectionProfile - inspect 请求:
InspectRequest - query 请求:
QueryRequest - export 请求:
ExportRequest - 共享错误:
db_app::AppError - 共享状态:
AppOperationOperationStateAppEvent<T>
3.2 当前持久化边界
- 当前产品仍是单次命令执行模型
- backend 当前不引入:
- profile 持久化库
- 历史记录库
- 本地状态库
- 后台 daemon / session 存储
- 当前可见写路径只有:
- 用户显式指定的 export 输出文件
- 用户显式选择的 SQLite 数据库文件
3.3 迁移结论
- 当前阶段没有 backend 自身的持久化 schema,因此没有迁移脚本或迁移兼容问题
- usable-v1 当前不需要新增 migration 策略
- 若未来引入本地状态存储,必须先单独定义存储边界与兼容策略,再进入实现
4. db-app 当前稳定契约
4.1 Connect
- 输入:
ConnectionProfile - 成功结果:
ConnectResponse - 当前状态语义:
success- 不存在
empty
4.2 Inspect
- 输入:
InspectRequest - 成功结果:
InspectResponse payload.kind:schemastablescolumns
- 当前状态语义:
- 非空集合 =>
success - 空集合 =>
empty - 执行失败 =>
error
- 非空集合 =>
4.3 Query
- 输入:
QueryRequest - 成功结果:
QueryResponse result字段固定包含:columnsrowsrows_affectedrow_count
- 当前状态语义:
rows_affected != null=> command-style success- 返回至少一行 =>
success - 零行且
rows_affected == null=>empty - 执行失败 =>
error
4.4 Export
- 输入:
QueryRequestExportRequest
- 成功结果:
ExportResponse - 成功结果固定包含:
targetsourceexportrow_count
- 当前状态语义:
- 文件写入成功 =>
success row_count == 0仍算 success
- 文件写入成功 =>
5. CLI 当前契约
5.1 命令面
connectinspectqueryexport
5.2 输出模式
--result-format text--result-format json
5.3 成功输出
- text:面向人工阅读
- json:返回 envelope
{
"status": "success",
"operation": "query",
"state": "success",
"data": {}
}
5.4 当前退出码约定
- 成功:
0 - 当前 CLI 错误统一返回:
2
6. 错误边界矩阵
6.1 共享应用层已统一的错误
当请求已经进入 db-app 后,当前错误会统一收敛为 AppError:
validationconnectionauthenticationinspectqueryexport
这些错误在 CLI --result-format json 下当前会输出结构化 error envelope,并显式带出 state: error。
6.2 当前实际存在的 CLI 前置错误层
在进入 db-app 之前,apps/cli 仍有一层前置错误来源:
- CLI 参数缺失 / 非法
ConnectionTarget组装失败ConnectionProfile组装失败InspectRequest构造失败QueryRequest构造失败ExportRequest构造失败- SQL 文件读取失败
- password env 缺失
但在当前源码下,只要用户显式传入 --result-format json,这组前置错误也会统一包裹成 JSON error envelope,kind 固定为 validation,state 固定为 error。
这些错误当前仍是字符串错误,不是 AppError,因此不完全受 shared error contract 保护。
7. 当前 gap / blocker 清单
7.1 当前 CLI JSON 状态映射
- CLI JSON envelope 当前固定包含:
statusoperationstate
- 当前映射规则:
- envelope 级成功仍返回
status: success - envelope 级失败仍返回
status: error - 共享应用层状态通过
state暴露:connect:successinspect:success | emptyquery:success | emptyexport:success- 所有错误:
error
- envelope 级成功仍返回
当前判断:
- 这让 CLI JSON 回归样本能显式区分
empty - 同时不破坏既有
status=success/error的 envelope 语义
7.2 运行环境说明
- 当前 runner 默认缺少
cargo/rustc/cc - 本轮通过用户态 Rust toolchain 与
zig cc/zig ar包装器完成了源码重建与测试 - 这属于运行环境债务,不是 backend contract defect
7.3 Blocker 判断
- 当前没有新的持久化 blocker
- 当前没有 migration blocker
- 当前没有新的 shared contract blocker
- 当前没有新的 backend contract blocker
8. 本轮验证证据
静态核对:
crates/db-core/src/lib.rscrates/db-config/src/lib.rscrates/db-drivers/src/lib.rscrates/db-app/src/lib.rsapps/cli/src/main.rsTUI_BACKEND_CONTRACT.md
命令复核:
cargo run -q -p dbtool-cli -- inspect --driver sqlite --path /tmp/notfound.sqlite --table accounts --result-format json- 实际返回 JSON error envelope,
kind=validation,state=error
- 实际返回 JSON error envelope,
cargo run -q -p dbtool-cli -- query --driver sqlite --path /tmp/notfound.sqlite --sql '' --result-format json- 实际返回 JSON error envelope,
kind=validation,state=error
- 实际返回 JSON error envelope,
cargo run -q -p dbtool-cli -- connect --driver postgres --host 127.0.0.1 --port 5432 --database demo --username demo --password-env MISSING_ENV --result-format json- 实际返回 JSON error envelope,
kind=validation,state=error
- 实际返回 JSON error envelope,
cargo run -q -p dbtool-cli -- query --driver sqlite --path <seeded-db> --sql 'SELECT ticket_id FROM tickets WHERE status = ?1' --param missing --result-format json- 实际返回
status=success且state=empty
- 实际返回
cargo test --workspace- 当前 runner 经过用户态 Rust +
zig cc补齐后,全工作区测试通过
- 当前 runner 经过用户态 Rust +
9. 当前结论
- usable-v1 当前 shared app 主契约可继续冻结在
db-app - 当前 CLI 主体没有重新发明 shared domain 语义
- 当前源码已经补齐 CLI JSON 模式下的前置 validation error 一致性
- 当前源码已经补齐 CLI JSON 对共享
empty状态的显式映射 - 当前 backend 这条 contract snapshot 主线没有新增 open blocker
- 当前 backend 更像进入“保持 snapshot 与源码一致 + 发现 defect 就单独拆单”的阶段