refactor: move server rs workspace entries into crates

This commit is contained in:
2026-04-21 11:01:25 +08:00
parent 5a60ab3972
commit f6bf5f665e
47 changed files with 244 additions and 233 deletions

View File

@@ -0,0 +1,96 @@
# api-server 主工程 crate 占位说明
日期:`2026-04-20`
## 1. crate 职责
`api-server` 是新后端的 Axum 主工程 crate后续负责
1. `main.rs` 启动入口
2. `Router` 装配
3. `with_state` 共享状态注入
4. 中间件挂载
5. `/healthz``/api/*`、SSE 与静态资源兼容层装配
6.`../../scripts/dev.ps1``../../scripts/dev.sh` 驱动的本地开发启动链路
7.`../../scripts/test.ps1``../../scripts/test.sh` 驱动的本地测试链路
8.`../../scripts/check.ps1``../../scripts/check.sh` 驱动的本地统一检查链路
9.`../../scripts/smoke.ps1``../../scripts/smoke.sh` 驱动的本地启动与协议冒烟链路
## 2. 当前阶段说明
当前目录已经完成以下基础骨架:
1. 目录占位
2. `Cargo.toml`
3. `src/main.rs`
4. `src/app.rs`
5. `src/state.rs`
6. `src/config.rs`
7. `src/logging.rs`
8. 基础 `TraceLayer` 挂载与 `tracing subscriber` 初始化
后续与本 crate 直接相关的任务包括:
1. [x] 接入统一日志与 tracing
2. [x] 接入 `request_id`
3. [x] 接入统一错误处理中间件
4. [x] 接入 response envelope
5. [x] 接入 `/healthz`
当前 tracing 约定:
1. 进程启动时统一初始化 `tracing subscriber`
2. 默认日志过滤器来自 `GENARRATIVE_API_LOG`,未提供时回落到 `info,tower_http=info`
3. HTTP 访问日志统一通过 Axum 路由层的 `TraceLayer` 输出,后续 `request_id`、响应头与错误中间件继续在同一层扩展。
当前 request context 约定:
1. 中间件优先读取来访 `x-request-id`,未提供时生成新的 UUID。
2. `request_id` 会统一写入请求 `extensions` 与请求头,供 tracing、错误处理中间件和响应头层复用。
3. 最终响应会回写同一个 `x-request-id`,保证调用方、日志链路和后续 envelope `meta.requestId` 可对齐。
当前错误处理中间件约定:
1. 对 Axum 默认产生的空 `4xx / 5xx` 响应,统一归一化为 legacy 兼容 JSON 错误体:`{ error: { code, message, details? } }`
2. 已经带 `content-type` 的业务错误响应不会被覆盖,避免抢走后续 response envelope 的职责。
3. 统一错误日志会复用当前请求的 `request_id`便于后续和响应头、envelope 元信息串联。
当前 response envelope 约定:
1. `RequestContext` 已记录 `request_id`、请求开始时间、默认 `operation` 与 envelope 协商结果。
2. `json_success_body(...)` / `json_error_body(...)` 会根据 `x-genarrative-response-envelope` 自动在“裸数据 / 标准 envelope / legacy error + meta”之间切换。
3. `meta.apiVersion``meta.requestId``meta.routeVersion``meta.operation``meta.latencyMs``meta.timestamp` 已按当前前端契约生成,响应头回写仍留给后续独立任务。
当前基础响应头约定:
1. 所有响应都会回写 `x-request-id`
2. 所有响应都会回写固定的 `x-api-version`,当前值与 body `meta.apiVersion` 保持一致。
3. 所有响应都会回写 `x-route-version`,当前阶段默认与 `x-api-version` 保持一致,后续再按路由粒度细分。
4. 所有响应都会回写 `x-response-time-ms`,值来源于 `RequestContext` 内记录的请求开始时间。
当前 `/healthz` 约定:
1. 路径固定为 `/healthz`
2. 裸响应继续返回 `{ ok: true, service: "genarrative-node-server" }`,保持与当前 Node 工程兼容。
3. 当请求携带 `x-genarrative-response-envelope` 时,`/healthz` 会返回标准 success envelope。
4. `x-request-id``x-api-version``x-route-version``x-response-time-ms` 会在 `/healthz` 响应中一并回写。
当前本地检查链路约定:
1. `../../scripts/check.ps1``../../scripts/check.sh` 统一串联 `cargo fmt --all --check``cargo clippy``cargo check``cargo test`
2. 默认检查整个 `server-rs` workspace确保后续多 crate 扩容时仍然保持统一口径。
3. 当只需聚焦单个 crate 时,可通过 `-Package``SERVER_RS_CHECK_PACKAGE` 收窄 `clippy / check / test` 目标。
4. `cargo fmt --all --check` 仍固定覆盖整个 workspace避免多 crate 下格式基线漂移。
当前本地 smoke 链路约定:
1. `../../scripts/smoke.ps1``../../scripts/smoke.sh` 会先构建 `api-server`,再拉起临时本地进程完成冒烟验证。
2. smoke 当前固定校验 `/healthz` 的 raw 响应、envelope 响应以及 `x-request-id``x-api-version``x-route-version``x-response-time-ms` 头。
3. smoke 通过后可作为“Axum 服务可独立启动且基础 contract 可联通”的本地自动化证据。
## 3. 边界约束
1. `api-server` 负责 HTTP、SSE、Cookie、Header、路由与协议装配。
2. 业务逻辑优先通过独立模块 crate 暴露能力,再由主工程组合。
3. 外部副作用通过 `platform-auth``platform-oss``platform-llm` 与各模块 crate 的应用层完成。
4. 不把领域规则直接堆在 handler 中。