Files
dbtool-cli-v1/USABLE_APP_CLI_CONTRACT_SNAPSHOT.md
Paperclip CTO d5f69462b0
Some checks failed
release-smoke / macos-13 / x86_64-apple-darwin (push) Has been cancelled
release-smoke / ubuntu-latest / x86_64-unknown-linux-gnu (push) Has been cancelled
release-smoke / windows-latest / x86_64-pc-windows-msvc (push) Has been cancelled
feat(usable): integrate current dbtool implementation snapshot
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-02 08:26:18 +00:00

7.8 KiB
Raw Blame History

dbtool-usable-v1 Shared App / CLI Contract Snapshot

日期2026-03-27
作者Senior Backend Engineer
对应 issueCMP-46

1. 目标

本文从 dbtool-usable-v1 视角冻结当前 crates/db-appapps/cli 的共享契约、错误边界与当前 gap。

本文不是新的架构提案,只记录当前代码与当前阶段可承诺的 backend 行为边界,供 CTO、Frontend、QA 和 PM 直接引用。

2. 当前后端分层

  • crates/db-core
    • 定义数据库无关的领域对象与基础校验:
      • ConnectionTarget
      • InspectRequest
      • QueryRequest
      • ExportRequest
      • InspectResult
      • QueryResult
  • 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
  • 连接 profileConnectionProfile
  • inspect 请求:InspectRequest
  • query 请求:QueryRequest
  • export 请求:ExportRequest
  • 共享错误:db_app::AppError
  • 共享状态:
    • AppOperation
    • OperationState
    • AppEvent<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
    • schemas
    • tables
    • columns
  • payload.kind=schemasschema item 额外包含:
    • name
    • availabilityready | restricted
    • note:可选 restricted 说明
  • 当前状态语义:
    • 非空集合 => success
    • 空集合 => empty
    • 执行失败 => error
  • PostgreSQL root inspect 现会保留 restricted schema 名称,并通过 schema item 暴露权限可见性
  • 显式 inspect 某个存在但当前连接无权访问的 PostgreSQL schema 时,当前返回 error,不再把 restricted schema 误判为 empty

4.3 Query

  • 输入:QueryRequest
  • 成功结果:QueryResponse
  • result 字段固定包含:
    • columns
    • rows
    • rows_affected
    • row_count
  • 当前状态语义:
    • rows_affected != null => command-style success
    • 返回至少一行 => success
    • 零行且 rows_affected == null => empty
    • 执行失败 => error

4.4 Export

  • 输入:
    • QueryRequest
    • ExportRequest
  • 成功结果:ExportResponse
  • 成功结果固定包含:
    • target
    • source
    • export
    • row_count
  • 当前状态语义:
    • 文件写入成功 => success
    • row_count == 0 仍算 success

5. CLI 当前契约

5.1 命令面

  • connect
  • inspect
  • query
  • export

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

  • validation
  • connection
  • authentication
  • inspect
  • query
  • export

这些错误在 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 envelopekind 固定为 validationstate 固定为 error

这些错误当前仍是字符串错误,不是 AppError,因此不完全受 shared error contract 保护。

7. 当前 gap / blocker 清单

7.1 当前 CLI JSON 状态映射

  • CLI JSON envelope 当前固定包含:
    • status
    • operation
    • state
  • 当前映射规则:
    • envelope 级成功仍返回 status: success
    • envelope 级失败仍返回 status: error
    • 共享应用层状态通过 state 暴露:
      • connectsuccess
      • inspectsuccess | empty
      • querysuccess | empty
      • exportsuccess
      • 所有错误:error

当前判断:

  • 这让 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
  • 当前 restricted-schema 剩余缺口已收敛为:
    • TUI / GUI consumer 侧消费 schema item availability
    • live fixture 权限模型仍需 QA 与 demo 环境配合验证

8. 本轮验证证据

静态核对:

  • crates/db-core/src/lib.rs
  • crates/db-config/src/lib.rs
  • crates/db-drivers/src/lib.rs
  • crates/db-app/src/lib.rs
  • apps/cli/src/main.rs
  • TUI_BACKEND_CONTRACT.md

命令复核:

  • cargo run -q -p dbtool-cli -- inspect --driver sqlite --path /tmp/notfound.sqlite --table accounts --result-format json
    • 实际返回 JSON error envelopekind=validationstate=error
  • cargo run -q -p dbtool-cli -- query --driver sqlite --path /tmp/notfound.sqlite --sql '' --result-format json
    • 实际返回 JSON error envelopekind=validationstate=error
  • 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 envelopekind=validationstate=error
  • 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=successstate=empty
  • cargo test --workspace
    • 当前 runner 经过用户态 Rust + zig cc 补齐后,全工作区测试通过

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 就单独拆单”的阶段