diff --git a/AGENTS.md b/AGENTS.md index 3ace108..09896f9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,35 +1,112 @@ -# AGENTS.md +# PROJECT KNOWLEDGE BASE -## 项目概述 +**Generated:** 2026-06-28 +**Commit:** 36c8f4a +**Branch:** main -这是一个前后端同仓库维护的 monorepo: +## OVERVIEW -- `application-rs/`:Rust 后端 workspace -- `wechat/`:微信小程序前端 -- `huawei/atomicservice/MFA/`:华为元服务前端 +前后端同仓库维护的 MFA(多因子认证)服务 monorepo。Rust 后端提供 HTTP API,微信/华为前端分别对接微信登录与华为帐号登录,共享同一套后端服务。 -进入对应子目录后,优先遵循该子目录下的 `AGENTS.md`。 +核心栈:Rust / Salvo / SQLx / MySQL;微信原生小程序(TypeScript);华为元服务(ArkTS/ETS)。 -## 子目录规则入口 +## STRUCTURE -- 后端:`application-rs/AGENTS.md` -- 微信前端:`wechat/miniprogram/yansongda/AGENTS.md` -- 华为前端:`huawei/atomicservice/MFA/AGENTS.md` +``` +yansongda-application/ +├── application-rs/ # Rust 后端 workspace +│ ├── application-api/ # HTTP API 二进制入口 +│ ├── application-kernel/ # 配置、日志、错误类型 +│ ├── application-database/ # 数据库访问层(SQLx + 原生 SQL) +│ ├── application-util/ # 第三方 HTTP 对接(微信/华为) +│ └── database/ # SQL 迁移脚本 +├── wechat/miniprogram/ +│ ├── yansongda/ # 主微信小程序(pnpm) +│ └── totp/ # TOTP 独立微信小程序(Deno) +└── huawei/atomicservice/MFA/ # 华为元服务(ohpm / Hvigor) + └── entry/src/main/ets/ # ArkTS 业务代码 +``` -## 协作原则 +## WHERE TO LOOK -- 跨前后端改动时,分别遵循对应目录下的规范,不要用一端的规则约束另一端 -- 尽量小步变更:一次改动聚焦一个问题,避免无关的批量格式化 -- 影响公共 API、配置、数据结构时,说明兼容策略与迁移方式 +| 任务 | 入口 | 详情位置 | +|------|------|----------| +| 后端架构/构建/风格 | `application-rs/application-api/src/bin/api.rs` | `application-rs/AGENTS.md` | +| 后端 API 路由 | `application-rs/application-api/src/routes.rs` | `application-rs/AGENTS.md` | +| 后端错误码/配置 | `application-rs/application-kernel/src/result.rs` | `application-rs/AGENTS.md` | +| 微信主小程序开发 | `wechat/miniprogram/yansongda/src/app.ts` | `wechat/miniprogram/yansongda/AGENTS.md` | +| TOTP 微信小程序开发 | `wechat/miniprogram/totp/src/app.ts` | `wechat/miniprogram/totp/AGENTS.md` | +| 华为元服务开发 | `huawei/atomicservice/MFA/entry/src/main/ets/ability/EntryAbility.ets` | `huawei/atomicservice/MFA/AGENTS.md` | +| CI/CD 配置 | `.github/workflows/` | 本文件 COMMANDS / NOTES | -## 通用提交约束 +## CODE MAP -- 禁止提交:`config.toml`、`*.private.*`、密钥、Token、密码、生产连接串等敏感信息 -- 常见不应提交目录:`target/`、`node_modules/`、`miniprogram_npm/`、`oh_modules/`、`.idea/`、`.vscode/` -- 必须提交对应锁文件:Rust 的 `Cargo.lock`、微信前端的 `pnpm-lock.yaml`、华为前端的 `oh-package-lock.json5` +| Symbol | Type | Location | Role | +|--------|------|----------|------| +| `main` | function | `application-rs/application-api/src/bin/api.rs:7` | Rust API 启动入口 | +| `App` | struct | `application-rs/application-api/src/lib.rs` | 构建 router 与 listener | +| `api_v1` | function | `application-rs/application-api/src/routes.rs:33` | `/api/v1` 路由聚合 | +| `Response` | struct | `application-rs/application-api/src/response.rs:8` | 统一 API 响应体 + Scribe | +| `ApiErr` | struct | `application-rs/application-api/src/response.rs:61` | `Error` → Salvo 响应包装 | +| `Error` | enum | `application-rs/application-kernel/src/result.rs` | 全局错误枚举(1000/2000/9800/9900) | +| `G_CONFIG` | static | `application-rs/application-kernel/src/config.rs` | 全局运行时配置 | +| `Pool` | struct | `application-rs/application-database/src/lib.rs` | MySQL 连接池管理 | +| `Platform` | enum | `application-rs/application-database/src/account/mod.rs` | 平台标识:wechat/huawei | +| `request` | function | `application-rs/application-util/src/http.rs:27` | 通用第三方 HTTP 请求 | +| `login` | function | `application-rs/application-util/src/wechat.rs` | 微信 jscode2session | +| `token` | function | `application-rs/application-util/src/huawei.rs` | 华为 OAuth token | -## 开发建议 +## CONVENTIONS -- 后端相关命令必须在 `application-rs/` 目录下执行 -- 微信前端使用 `pnpm` -- 华为前端优先以工程内现有配置文件与脚本为准 +- 跨前后端改动时,分别遵循对应目录下的 `AGENTS.md`,不要用一端规则约束另一端。 +- 必须提交的锁文件:`Cargo.lock`、`pnpm-lock.yaml`(yansongda)、`deno.lock`(totp)、`oh-package-lock.json5`(华为)。 +- 禁止提交的敏感内容:`config.toml`、`*.private.*`、密钥、Token、密码、生产连接串。 +- 禁止提交的构建/IDE 目录:`target/`、`node_modules/`、`miniprogram_npm/`、`oh_modules/`、`.idea/`、`.vscode/`。 +- 影响公共 API / 配置 / 数据结构时,需说明兼容策略与迁移方式。 +- 尽量小步变更:一次改动聚焦一个问题,避免无关批量格式化。 + +## ANTI-PATTERNS (THIS PROJECT) + +- 不要在日志中记录完整请求/响应头,尤其是 `Authorization` 头。 +- 不要硬编码生产密钥、Token、密码;配置通过 `config.toml` 或 `APP__*` 环境变量注入。 +- 不要在 Rust 生产代码中随意使用 `.unwrap()` / `.unwrap_err()` / `.expect()`(启动期 fail-fast 除外)。 +- 不要引入 ORM;数据库层统一使用 `sqlx` + 原生 SQL。 +- 不要提交 `config.toml`、证书密码、本地绝对路径(华为 `build-profile.json5` 中的签名配置需特别注意)。 + +## UNIQUE STYLES + +- **多包管理器并存**:后端 cargo,微信主小程序 pnpm,TOTP 小程序 Deno,华为 ohpm。 +- **Rust workspace 使用较新的工具链特性**,依赖使用 `~` 约束。 +- **无 ORM 的数据库层**:通过自定义宏(`query_optional!` / `insert!` / `update!` / `delete!`)统一记录 SQL、耗时和参数。 +- **微信/华为前端共享同一后端**,但登录方式不同:微信用 `wx.login` code,华为用 HuaweiID authorizationCode。 +- **后端无 JWT**:access_token / refresh_token 均为 opaque UUID v7,数据库验证。 + +## COMMANDS + +```bash +# 后端(在 application-rs/ 下执行) +cargo check --all-features +cargo clippy -- -D warnings +cargo fmt --all -- --check +cargo test --all-features +cargo build --release + +# 微信主小程序(在 wechat/miniprogram/yansongda/ 下执行) +pnpm i +pnpm biome:check + +# TOTP 微信小程序(在 wechat/miniprogram/totp/ 下执行) +deno install +deno task biome:check +deno task typecheck + +# 华为元服务:通过 DevEco Studio 或 Hvigor CLI 构建/运行 +``` + +## NOTES + +- `application-rs/AGENTS.md` 中已修正:移除不存在的 `application-macro/` 目录;CI 不运行 `cargo test`。 +- `wechat/miniprogram/yansongda/` 当前缺失 `pnpm-lock.yaml`(AGENTS.md 要求提交),请检查是否被 gitignore 或未生成。 +- 华为 `build-profile.json5` 包含本地签名证书路径与明文密码,仅用于本地开发,禁止用于生产。 +- 后端 `middleware.rs` 与 `application-util/src/http.rs` 当前会记录完整 headers,后续需脱敏 `Authorization` 等敏感头。 +- 三个前端均无实际业务测试;Rust 后端仅有少量单元测试,CI 不执行测试。 diff --git a/application-rs/AGENTS.md b/application-rs/AGENTS.md index 4b43a79..ce13f4e 100644 --- a/application-rs/AGENTS.md +++ b/application-rs/AGENTS.md @@ -3,7 +3,7 @@ ## 项目概述 Rust 后端 workspace,提供多因子认证(MFA)服务 API。 -Rust edition 2024,最低版本 1.90.0。Web 框架:Salvo 0.88。数据库:MySQL,通过 SQLx 0.8(原生 SQL)。 +使用 Salvo Web 框架、SQLx 原生 SQL 访问 MySQL。 ## 仓库结构 @@ -12,7 +12,6 @@ application-rs/ application-api/ # HTTP API 二进制入口(src/bin/api.rs) application-kernel/ # 核心库:配置、日志、错误/结果类型 application-database/ # 数据库访问层(MySQL、SQLx) - application-macro/ # 过程宏 application-util/ # HTTP 客户端、第三方平台对接 database/ # SQL 迁移脚本 ``` @@ -24,31 +23,12 @@ application-rs/ 所有 Rust 命令必须在 `application-rs/` 目录下执行。 ```bash -# 编译检查(快速,不生成二进制文件) +# 检查 / 格式化 / 测试 / 构建 cargo check --all-features - -# 格式化(CI 强制检查,合并前必须通过) cargo fmt --all -- --check -cargo fmt --all - -# Lint 检查(CI 强制检查,警告视为错误) cargo clippy -- -D warnings - -# 构建 -cargo build -cargo build --release - -# 运行所有测试 cargo test --all-features - -# 按名称运行单个测试 -cargo test --all-features test_response_success_serialization - -# 运行指定 crate 的测试 -cargo test -p application-api --all-features - -# 按模式匹配运行测试 -cargo test --all-features response +cargo build --release # Docker 构建 docker build -t app -f Dockerfile-application-api . @@ -68,8 +48,7 @@ docker build -t app -f Dockerfile-application-api . ### 格式化 -使用默认 `rustfmt` 规则。提交前运行 `cargo fmt --all`。 -4 空格缩进,无行尾空格。 +使用默认 `rustfmt` 规则;4 空格缩进,无行尾空格。提交前运行 `cargo fmt --all`。 ### Import 组织 @@ -105,12 +84,9 @@ use tracing::{error, info}; ### 类型约定 -- 所有 ID 使用 `u64` -- 时间戳使用 `DateTime` -- 数据库 JSON 列使用 `Json` -- 可空字符串字段使用 `Option` -- 全局静态变量使用 `LazyLock` -- Token 生成使用 `Uuid::now_v7()` +- ID 使用 `u64`;时间戳使用 `DateTime` +- 数据库 JSON 列使用 `Json`;可空字符串使用 `Option` +- 全局静态变量使用 `LazyLock`;Token 生成使用 `Uuid::now_v7()` ### 错误处理 @@ -123,35 +99,24 @@ use tracing::{error, info}; - 9800 系列:第三方服务错误 - 9900 系列:内部/数据库错误 -数据库错误的标准模式:先用 `error!()` 记录日志,再映射为通用错误。 - -```rust -.map_err(|e| { - error!("查询用户失败: {:?}", e); - Error::InternalDatabaseQuery(None) -})?; -``` - -服务层错误使用 `?` 提前返回,或显式 `Err(Error::Variant(None))`。 +数据库错误标准模式:`error!()` 记录日志后映射为通用错误。服务层使用 `?` 提前返回或显式 `Err(Error::Variant(None))`。 ## 架构分层(application-api) ``` -v1/ 处理器层:#[handler] 函数,解析请求,调用 service,返回 Response -service/ 业务层:业务编排、校验逻辑,调用 database crate -request/ DTO 层:请求/响应结构体,Validator trait 实现 +v1/ #[handler] 函数,解析请求,调用 service,返回 Response +service/ 业务编排、校验逻辑,调用 database crate +request/ DTO + Validator trait 实现 response.rs Response、ApiErr、Scribe 实现 ``` -处理器返回 `Resp`,即 `Result>` 的别名。 -请求校验通过 `Validator` trait 的 `validate() -> Result` 方法。 +请求校验通过 `Validator::validate() -> Result` 完成。 ## 数据库层(application-database) -- 使用原生 SQL 字符串 + `sqlx::query_as` / `sqlx::query`,不使用 ORM +- 原生 SQL + `sqlx::query_as` / `sqlx::query`,不使用 ORM - 连接池:`LazyLock>`,通过 `Pool::mysql("account")?` 访问 -- 每个数据库函数都记录耗时、SQL 语句和参数(`tracing::info!`) -- 标准模式:定义 SQL 字符串 -> 记录 `Instant::now()` -> 执行 -> 记录耗时 -> 返回 +- 数据库宏自动记录 SQL、参数和耗时 ## 日志与异步 @@ -160,38 +125,35 @@ response.rs Response、ApiErr、Scribe 实现 - 并发操作使用 `tokio::try_join!` - 非阻塞日志输出使用 `tracing-appender` -每个数据库操作记录耗时: - -```rust -let started_at = Instant::now(); -// ... 执行查询 ... -info!(started_at.elapsed().as_secs_f32(), sql, param1, param2); -``` +每个数据库操作记录 `Instant::now()` 开始时间和耗时。 ## 配置管理 -- 运行时配置通过 `config.toml` 或 `APP__` 前缀环境变量 -- 双下划线 `__` 分隔嵌套键名,例如 `APP__DATABASES__ACCOUNT__URL` -- 全局配置位于 `application-kernel::config` 中的 `G_CONFIG: LazyLock` +- 运行时配置通过 `config.toml` 或 `APP__*` 环境变量(双下划线嵌套,如 `APP__DATABASES__ACCOUNT__URL`) +- 全局配置 `G_CONFIG: LazyLock` 位于 `application-kernel::config` - 禁止提交 `config.toml`,以 `config.toml.example` 为模板 ## 测试 -- 现有测试覆盖率较低 -- 现有测试位于 `application-api/src/response.rs` -- 单元测试使用 `#[cfg(test)] mod tests` 配合 `use super::*` -- 遵循现有模式:构造数据 -> 序列化 -> 断言 JSON 字段 +- 单元测试使用 `#[cfg(test)] mod tests`;现有覆盖率低,CI 不执行 `cargo test`。 +- 遵循模式:构造数据 -> 序列化 -> 断言 JSON 字段。 -## Web 框架(Salvo) +## 反模式(ANTI-PATTERNS) -- 处理器函数使用 `#[handler]` -- JSON 请求体解析使用 `Request::parse_json::()` -- 依赖注入通过 `Depot` -- 路由嵌套使用 `Router::with_path().push()` -- 响应渲染使用自定义 `Scribe` 实现 +- 禁止在生成代码中使用 `.unwrap()` / `.unwrap_err()` / `.expect()`;启动期 fail-fast 除外,统一使用 `Error` 枚举 + `?` 传播。 +- 禁止使用 `lazy_static!`;全局静态变量使用 `std::sync::LazyLock`。 +- 禁止引入 ORM;数据库层统一使用原生 SQL + `sqlx::query_as` / `sqlx::query`。 +- 禁止在日志中记录完整 headers 或 body,尤其是 `Authorization` 头和第三方 API 响应中的密钥/token。 +- 禁止提交 `config.toml`、`*.private.*`、密钥、Token、生产连接串。 +- 禁止 `#[allow(dead_code)]` 不加注释;若确需保留,需说明理由和清理计划。 ## 禁止提交的文件 -- `target/`、`.idea/`、`.vscode/` -- `config.toml`、`*.private.*` +- `target/`、`.idea/`、`.vscode/`、`config.toml`、`*.private.*` - 必须提交:`Cargo.lock` + +## NOTES + +- `application-macro/` 目录已不存在,本文件已移除该条目。 +- `middleware.rs` 与 `application-util/src/http.rs` 当前会记录完整 headers,后续需脱敏 `Authorization` 等敏感头。 +- 测试覆盖率低,CI 仅执行 `cargo check` / `cargo fmt` / `cargo clippy`,不执行 `cargo test`。 diff --git a/huawei/atomicservice/MFA/AGENTS.md b/huawei/atomicservice/MFA/AGENTS.md index 8a42cf0..db9345a 100644 --- a/huawei/atomicservice/MFA/AGENTS.md +++ b/huawei/atomicservice/MFA/AGENTS.md @@ -22,6 +22,7 @@ MFA/ `entry/src/main/ets/` 下常见结构: +- `ability/`:Ability 入口(EntryAbility.ets) - `pages/`:页面 - `components/`:组件 - `api/`:接口调用 @@ -71,3 +72,10 @@ MFA/ - 涉及后端接口联动时,同时参考根目录 `AGENTS.md` 与 `application-rs/AGENTS.md` - 仅修改华为前端时,不需要遵循 Rust 或微信小程序目录下的专属规范 + +## NOTES + +- `entry/src/main/ets/ability/` 目录包含 `EntryAbility.ets`(UIAbility 入口),上表已补充。 +- `code-linter.json5` 包含 `@security/no-unsafe-*` 系列规则,修改加密/安全相关逻辑前请先确认不会触发 lint 错误。 +- `build-profile.json5` 中的签名配置使用本地绝对路径与明文密码,仅用于本地开发,禁止用于生产。 +- 当前仓库 CI 未包含华为前端的构建/lint 检查。 diff --git a/wechat/miniprogram/totp/AGENTS.md b/wechat/miniprogram/totp/AGENTS.md index 9ce9a04..50df24e 100644 --- a/wechat/miniprogram/totp/AGENTS.md +++ b/wechat/miniprogram/totp/AGENTS.md @@ -71,3 +71,8 @@ deno task typecheck # TypeScript 类型检查(tsc --noEmit) - 涉及后端接口联动时,同时参考 `application-rs/AGENTS.md` - 仅修改微信前端时,不需要遵循 Rust 后端的代码风格和构建命令 + +## NOTES + +- 与 `yansongda` 主小程序共享 `utils/error.ts`、`utils/logger.ts`、`utils/string.ts`、`models/error.ts`、`types/http.d.ts` 等代码,但当前无正式共享包,分别独立维护。 +- 当前 CI 仅执行 `deno task biome:check`;`deno task typecheck` 尚未接入 CI,提交前建议本地手动执行。 diff --git a/wechat/miniprogram/totp/project.config.json b/wechat/miniprogram/totp/project.config.json index 0f0fb9c..5e2ce76 100644 --- a/wechat/miniprogram/totp/project.config.json +++ b/wechat/miniprogram/totp/project.config.json @@ -22,7 +22,7 @@ } ], "ignoreDevUnusedFiles": false, - "ignoreUploadUnusedFiles": false, + "ignoreUploadUnusedFiles": true, "condition": false, "es6": true, "compileWorklet": false, diff --git a/wechat/miniprogram/yansongda/AGENTS.md b/wechat/miniprogram/yansongda/AGENTS.md index 5375b56..9e7bdcc 100644 --- a/wechat/miniprogram/yansongda/AGENTS.md +++ b/wechat/miniprogram/yansongda/AGENTS.md @@ -82,3 +82,8 @@ pnpm biome:fix-unsafe - 涉及后端接口联动时,同时参考 `application-rs/AGENTS.md` - 仅修改微信前端时,不需要遵循 Rust 后端的代码风格和构建命令 + +## NOTES + +- 当前目录下未见 `pnpm-lock.yaml`,但 AGENTS.md 要求必须提交;请确认是否已生成并纳入版本控制。 +- 主小程序与 `totp` 小程序共享大量工具/类型/模型代码,但当前无正式共享包,分别独立维护。 diff --git a/wechat/miniprogram/yansongda/project.config.json b/wechat/miniprogram/yansongda/project.config.json index 75a98cf..bee0560 100644 --- a/wechat/miniprogram/yansongda/project.config.json +++ b/wechat/miniprogram/yansongda/project.config.json @@ -3,10 +3,7 @@ "miniprogramRoot": "src/", "compileType": "miniprogram", "setting": { - "useCompilerPlugins": [ - "typescript", - "sass" - ], + "useCompilerPlugins": ["typescript", "sass"], "babelSetting": { "ignore": [], "disablePlugins": [], @@ -25,7 +22,7 @@ } ], "ignoreDevUnusedFiles": false, - "ignoreUploadUnusedFiles": false, + "ignoreUploadUnusedFiles": true, "condition": false, "es6": true, "compileWorklet": false,