Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 100 additions & 23 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -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<D>` | 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 不执行测试。
104 changes: 33 additions & 71 deletions application-rs/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

## 仓库结构

Expand All @@ -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 迁移脚本
```
Expand All @@ -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 .
Expand All @@ -68,8 +48,7 @@ docker build -t app -f Dockerfile-application-api .

### 格式化

使用默认 `rustfmt` 规则。提交前运行 `cargo fmt --all`。
4 空格缩进,无行尾空格。
使用默认 `rustfmt` 规则;4 空格缩进,无行尾空格。提交前运行 `cargo fmt --all`。

### Import 组织

Expand Down Expand Up @@ -105,12 +84,9 @@ use tracing::{error, info};

### 类型约定

- 所有 ID 使用 `u64`
- 时间戳使用 `DateTime<Local>`
- 数据库 JSON 列使用 `Json<T>`
- 可空字符串字段使用 `Option<String>`
- 全局静态变量使用 `LazyLock`
- Token 生成使用 `Uuid::now_v7()`
- ID 使用 `u64`;时间戳使用 `DateTime<Local>`
- 数据库 JSON 列使用 `Json<T>`;可空字符串使用 `Option<String>`
- 全局静态变量使用 `LazyLock`;Token 生成使用 `Uuid::now_v7()`

### 错误处理

Expand All @@ -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<D>、ApiErr、Scribe 实现
```

处理器返回 `Resp<T>`,即 `Result<Response<T>>` 的别名。
请求校验通过 `Validator` trait 的 `validate() -> Result<Self::Data>` 方法。
请求校验通过 `Validator::validate() -> Result<Self::Data>` 完成。

## 数据库层(application-database)

- 使用原生 SQL 字符串 + `sqlx::query_as` / `sqlx::query`,不使用 ORM
- 原生 SQL + `sqlx::query_as` / `sqlx::query`,不使用 ORM
- 连接池:`LazyLock<HashMap<&str, MySqlPool>>`,通过 `Pool::mysql("account")?` 访问
- 每个数据库函数都记录耗时、SQL 语句和参数(`tracing::info!`)
- 标准模式:定义 SQL 字符串 -> 记录 `Instant::now()` -> 执行 -> 记录耗时 -> 返回
- 数据库宏自动记录 SQL、参数和耗时

## 日志与异步

Expand All @@ -160,38 +125,35 @@ response.rs Response<D>、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>`
- 运行时配置通过 `config.toml` 或 `APP__*` 环境变量(双下划线嵌套,如 `APP__DATABASES__ACCOUNT__URL`)
- 全局配置 `G_CONFIG: LazyLock<Config>` 位于 `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::<T>()`
- 依赖注入通过 `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`。
8 changes: 8 additions & 0 deletions huawei/atomicservice/MFA/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ MFA/

`entry/src/main/ets/` 下常见结构:

- `ability/`:Ability 入口(EntryAbility.ets)
- `pages/`:页面
- `components/`:组件
- `api/`:接口调用
Expand Down Expand Up @@ -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 检查。
5 changes: 5 additions & 0 deletions wechat/miniprogram/totp/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,提交前建议本地手动执行。
2 changes: 1 addition & 1 deletion wechat/miniprogram/totp/project.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
}
],
"ignoreDevUnusedFiles": false,
"ignoreUploadUnusedFiles": false,
"ignoreUploadUnusedFiles": true,
"condition": false,
"es6": true,
"compileWorklet": false,
Expand Down
5 changes: 5 additions & 0 deletions wechat/miniprogram/yansongda/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,8 @@ pnpm biome:fix-unsafe

- 涉及后端接口联动时,同时参考 `application-rs/AGENTS.md`
- 仅修改微信前端时,不需要遵循 Rust 后端的代码风格和构建命令

## NOTES

- 当前目录下未见 `pnpm-lock.yaml`,但 AGENTS.md 要求必须提交;请确认是否已生成并纳入版本控制。
- 主小程序与 `totp` 小程序共享大量工具/类型/模型代码,但当前无正式共享包,分别独立维护。
7 changes: 2 additions & 5 deletions wechat/miniprogram/yansongda/project.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
"miniprogramRoot": "src/",
"compileType": "miniprogram",
"setting": {
"useCompilerPlugins": [
"typescript",
"sass"
],
"useCompilerPlugins": ["typescript", "sass"],
"babelSetting": {
"ignore": [],
"disablePlugins": [],
Expand All @@ -25,7 +22,7 @@
}
],
"ignoreDevUnusedFiles": false,
"ignoreUploadUnusedFiles": false,
"ignoreUploadUnusedFiles": true,
"condition": false,
"es6": true,
"compileWorklet": false,
Expand Down