--- name: openlark-code-standards description: OpenLark 项目代码规范检查技能。用于快速审查仓库内的架构一致性、API 实现套路、参数校验、命名与导出规范,并输出可执行检查清单与证据路径。Triggers: code review / consistency check / architecture audit / 规范检查 / 风格一致性 / 体检 / 对齐约定。项目锚点见 AGENTS.md#CONVENTIONS 与 AGENTS.md#ANTI-PATTERNS。 argument-hint: "[crate-name|path]" allowed-tools: Read, Grep, Glob, Bash --- # OpenLark 代码规范检查(Skill) ## 适用场景 - 用户要求“检查项目代码规范” - 新增 API 前想确认实现套路是否一致 - 评审 PR 时需要快速验证是否遵循 OpenLark 既有约定 - 发现模块风格漂移,想做一次统一体检 ## 目标 输出一份可落地的规范检查结果,包含: - 规范结论(通过/风险) - 规则-证据对(每条规则附 `path:line`) - 风险分级(P0/P1/P2) - 新 API 最小检查清单(可直接用于 PR Review) ## 检查范围 覆盖全部 `crates/openlark-*`(按 `AGENTS.md#STRUCTURE` 有 18 个业务/基础设施 crate)。 - 重点核审:核心基础设施(`openlark-core`、`openlark-client`、`openlark-protocol`)与高频业务 crate(`openlark-docs`、`openlark-communication`、`openlark-hr`)。 - Client 命名(`XxxClient`)权威映射表见 `docs/CLIENT_NAMING_CONVENTION.md` 的「当前映射」,命名核审以此为准。 - 可按参数缩小为某个 crate 或目录(如 `openlark-mail`、`crates/openlark-hr/src/`)。 ## 核心检查项 ### 1) API 实现套路一致性 - 是否使用 `Request/Response + Builder` 模式 - 是否提供 `execute()` 与 `execute_with_options(RequestOption)` - 是否通过 `Transport::request(...)` 发送请求 **🔴 硬规则(grep 命中即 P0 违规):** - 业务 crate(除 `openlark-core` 与 **`openlark-webhook`**)**不得出现 `reqwest::Client::new()`**——一旦命中,说明有端点绕过了 `Transport`,必为不一致源头。检查命令: ```bash rg "reqwest::Client::new" crates/ --type rust -g '!openlark-core/**' -g '!openlark-webhook/**' ``` - **白名单说明:`openlark-webhook` 是有意例外**——自定义机器人不是飞书开放平台 API(目标 URL 为用户配置的绝对地址、用 URL 携带签名密钥鉴权、响应体为非标准 `{code,msg}`),不适用 `Transport` 的 `/open-apis/` 基址与 token 注入,故保留独立 reqwest 路径(见 issue #214 调研结论,注释位于 `crates/openlark-webhook/src/robot/v1/send.rs:13-26`)。**勿改 webhook 的 reqwest 用法**。 - **不得手工 `Authorization` 头 / `get_app_token`**(token 由 `Transport` 自动注入) - **`Service`/`Request` 不得持有 HTTP client 字段**(只持 `Config`) **🟡 R 语义检查(防止双重嵌套陷阱):** - `ApiRequest` 的 `R` 应是响应 `data` 字段的**内容类型**,不是外层包装。 - 可疑信号:某个 `XxxResponse` struct 带 `data: Option<...>` 字段、同时又作为 `ApiRequest` 的泛型——大概率双重嵌套(core 已把 `R` 当作 data 内容解析)。 - 详细契约见 `Skill(openlark-api)` 的"🔒 核心契约"。 ### 2) 端点定义规范 - 是否使用 **per-crate 类型安全端点枚举**:每个 crate 在 `src/common/api_endpoints.rs` 定义各自的 `ApiV1` 枚举,并实现 `pub fn to_url(&self) -> String`(注意 `to_url()` 返回的是相对路径 `String`,形如 `/open-apis/mail/v1/...`,不带基址)。 - 是否避免手写业务 URL(统一走枚举 `to_url()`) - 命名注意:枚举名是 `ApiV1`,`Domain` **通常但并非总是**等于 crate 名——以现况为准: - 与 crate 同名:`MailApiV1`(`crates/openlark-mail/src/common/api_endpoints.rs:5`)、`DocsApiV1`(`crates/openlark-docs/src/common/api_endpoints.rs:440`)、`HelpdeskApiV1`、`AppApiV1`(application)。 - 与 crate 名不同:`VcApiV1`(meeting,`crates/openlark-meeting/src/common/api_endpoints.rs:224`)、`TaskApiV1`/`BoardApiV1`(workflow)、`AdminApiV1`(platform)、`AuthenApiV1`(auth)、HR 多枚举(`AttendanceApiV1`/`HireApiV1`/`OkrApiV1`/...)、Docs 多枚举(`BitableApiV1`/`WikiApiV1`/`DocxApiV1`/`MinutesApiV1`/...)。 - 新增端点时改枚举与 `to_url()` match 分支,不要在 Request/Builder 里手写 URL 字面量。 ### 3) 参数校验规范 - 必填校验是否统一用 `openlark_core::validate_required!` - 字符串是否优先 `trim()` 后再校验 - 列表字段是否校验非空与长度上限(如 `validate_required_list!`) **🟡 Token 类型与 Config 形态:** - token 类型是否与接口文档「请求头 → Authorization」标注一致——`ApiRequest` 默认 `[User, Tenant]`;仅当文档要求 `app_access_token`(→ `App`)等非默认凭证时才显式 `.with_supported_access_token_types(...)`。注意 `App` = `app_access_token` ≠ `tenant_access_token`(→ `Tenant`),不要把要求 `tenant_access_token` 的接口设成 `App`(详见 #511)。 - `Request`/`Service` 是否用 owned `Config`(非 `Arc`)——新代码与重构以 owned 为准(`openlark-docs` 历史用 `Arc` 属例外)。 **🟡 `RequestOption`(单数)vs `RequestOptions`(复数)切勿混用:** - `openlark_core::req_option::RequestOption`(**单数**,`crates/openlark-core/src/req_option.rs:7`)——`Transport`/`execute_with_options` 实际接受的类型(token、tenant_key、file_upload/download 等运行时请求控制),业务 crate 调用 `execute_with_options(RequestOption::default())`。 - `openlark_client::types::client::RequestOptions`(**复数**,`crates/openlark-client/src/types/client.rs:180`)——高级客户端的 timeout/retry_count/headers 构造参数,语义不同。 - 二者字段集合完全不同,**不得互相替代或导出混名**;业务 crate 写 Builder 时用单数 `RequestOption`。 ### 4) 命名与公开 API 表达 - `Client/Service/Resource/Request/Builder` 命名是否语义清晰 - 对外入口是否统一(避免同义入口并存) - meta 调用链命名是否与仓库约定一致 ### 5) 导出与 feature gating - `mod.rs` 与 `prelude` 是否完整导出新增 API - `Cargo.toml` feature 与 `#[cfg(feature = "...")]` 是否对齐 - 是否存在导出但不可编译或不可访问路径 ### 6) CI 与测试门控(#228 审核闭环) > 详细背景见 `docs/CI_TEST_TARGET_COVERAGE.md`(相关 issue:#228 / #246 / #248 / #250 / #251;PR:#247 / #249 / #252 / #253 / #254)。 - **测试/`#[cfg(test)]` 改动后必跑 `just lint`**:`just lint` = `cargo clippy --workspace --all-targets --all-features`(justfile:12-14)。CI 在 **all-features / no-default-features / 各 feature 组合** 三个维度都用 `--all-targets`,因此 `#[cfg(test)]` 类 lint 回归(如 #248 的未用 `use super::*`)会被 CI 直接拦住,不只依赖本地。 - **`tests/*.rs` feature 门控约定**(#251):文件引用 feature-gated 模块时,文件顶部加 `#![cfg(feature = "...")]`;且 **`//!` 模块文档必须在 `#![cfg]` 之上**(顺序反了会触发 clippy `missing_docs`)。 - **`examples/*.rs` 禁用 `#![cfg]`**(#251):feature 门控走 `Cargo.toml` 的 `[[example]] required-features`。example 里写 `#![cfg]` 会把文件清空成无 `main`,报 **`E0601`**。 - **event 模块(`openlark-communication`)不违规**:event 在 `tools/api_priority.toml` 标为 **P2**(非 P0 核心业务),按基础设施类对待(与 WebSocket `LarkWsClient` 同类),**有意不经统一 client `declare_client!` re-export**(#228 决策)。审查时勿把它当作「漏 re-export 的违规」上报。 ## 输出模板(必须) 1. 结论概览(3-6 条) 2. 规则-证据对(至少 8 条) - 规则 - 证据(`path:line`) - 风险等级(P0/P1/P2) - 修复建议 3. 新 API 最小检查清单(5-8 条) 4. 建议行动项(按优先级排序) ## 推荐执行顺序 1. 先读 `AGENTS.md` 与目标 crate 的 `AGENTS.md/CLAUDE.md` 2. 再扫规则高频证据:`api_endpoints`、`execute_with_options`、`validate_required`、`prelude`、`mod.rs` 3. 最后输出规则-证据对与整改建议 ## 重点提醒 - 结论必须基于代码证据,不做“纯经验判断” - 证据至少精确到文件路径,推荐精确到 `path:line` - 不在规范检查中进行大规模重构,先给出可执行清单 ## 与其他技能的关系 - 需要审查整体架构与公共 API:`openlark-design-review` - 只聚焦校验写法统一:`openlark-validation-style` - 需要新增/重构具体 API:`openlark-api` - 需要做覆盖率统计:`openlark-api-validation` ## 技能分流决策表 | 场景 | 优先技能 | 何时转交 | |---|---|---| | 只想做一次项目规范体检(给出规则-证据对和风险清单) | `openlark-code-standards` | 若发现架构级冲突/公共 API 设计分歧,转 `openlark-design-review` | | 重点是架构收敛、范式选型、兼容策略(含 breaking 评估) | `openlark-design-review` | 若需要补充全仓规范一致性证据,可回补 `openlark-code-standards` | | 只处理 `validate()`、`validate_required!`、空白字符串与校验聚合 | `openlark-validation-style` | 若校验问题已扩展到命名/导出/端点体系,转 `openlark-code-standards` | | 新增或重构某个具体 API 文件(Request/Response/Builder/导出) | `openlark-api` | 若实现前需先做规范体检,先跑 `openlark-code-standards` | | 关注 API 覆盖率、实现数量、缺失清单 | `openlark-api-validation` | 若覆盖率问题背后是设计不一致,转 `openlark-design-review` | ### 快速判断 - 问题是“这个项目现在规范是否一致” → `openlark-code-standards` - 问题是“这个设计该怎么收敛” → `openlark-design-review` - 问题是“这个校验写法到底怎么统一” → `openlark-validation-style` - 问题是“我现在就要实现某个 API” → `openlark-api` ## 关键词触发映射 | 用户关键词/表述 | 建议技能 | |---|---| | 代码规范、规范检查、风格一致性、体检、对齐约定 | `openlark-code-standards` | | 架构设计、public API、收敛方案、feature gating、兼容策略、breaking change | `openlark-design-review` | | validate、必填校验、validate_required、空白字符串、校验聚合 | `openlark-validation-style` | | 新增 API、重构 API、Builder、Request/Response、mod.rs 导出 | `openlark-api` | | 覆盖率、实现数量、缺失 API、统计、对比 CSV | `openlark-api-validation` | ### 组合关键词优先级 - 同时出现“规范检查 + 覆盖率”时,先用 `openlark-api-validation` 产出缺失清单,再用 `openlark-code-standards` 做规范归因。 - 同时出现“规范检查 + 架构收敛”时,先用 `openlark-code-standards` 做现状证据,再转 `openlark-design-review` 定迁移方案。 - 同时出现“新增 API + 校验统一”时,实现阶段用 `openlark-api`,校验规则判定用 `openlark-validation-style`。