docs: add project review and update development guide
Some checks failed
CI / test (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
Security Scan / backend-security (push) Has been cancelled
Security Scan / frontend-security (push) Has been cancelled

- Add comprehensive PROJECT_REVIEW.md with development experience summary
- Update DEV_GUIDE.md with standardized conventions and best practices
- Move audit reports to docs/reports/ and update .gitignore
- Document Windows compatibility issues and solutions
- Add PR checklist and testing standards
This commit is contained in:
User
2026-04-13 06:44:25 +08:00
parent d44fa6b35c
commit 686454bf22
6 changed files with 1471 additions and 275 deletions

View File

@@ -1,346 +1,324 @@
# sub2api 项目开发指南
> 本文档记录项目环境配置、常见坑点和注意事项,供 Claude Code 和团队成员参考。
> 本文档记录项目环境配置、开发规范和常见问题,供 Claude Code 和团队成员参考。
## 一、项目基本信息
| 项目 | 说明 |
|------|------|
| **上游仓库** | Wei-Shaw/sub2api |
| **Fork 仓库** | bayma888/sub2api-bmai |
| **技术栈** | Go 后端 (Ent ORM + Gin) + Vue3 前端 (pnpm) |
| **数据库** | PostgreSQL 16 + Redis |
| **包管理** | 后端: go modules, 前端: **pnpm**(不是 npm |
| **远程仓库** | https://www.tksea.top/pham/tokens-reef |
| **技术栈** | Go 后端 (Ent ORM + Gin) + Vue3 前端 |
| **数据库** | PostgreSQL 15+ + Redis 7+ |
| **包管理** | 后端: go modules, 前端: npm |
## 二、本地环境配置
---
### PostgreSQL 16 (Windows 服务)
## 二、项目规范
### 2.1 代码规范
#### 后端目录结构
```
backend/internal/
├── config/ # 配置管理 (viper)
├── domain/ # 领域模型
├── handler/ # HTTP 处理器
├── service/ # 业务逻辑层
├── repository/ # 数据访问层
├── middleware/ # HTTP 中间件
├── pkg/ # 内部工具包
├── util/ # 工具函数
├── testutil/ # 测试工具和 fixtures
└── web/ # 前端嵌入
```
#### 前端目录结构
```
frontend/src/
├── api/ # API 调用封装
├── components/ # 可复用组件
├── composables/ # Vue 组合式函数
├── stores/ # Pinia 状态管理
├── views/ # 页面视图
├── types/ # TypeScript 类型定义
├── utils/ # 工具函数
└── i18n/ # 国际化
```
### 2.2 命名约定
| 类型 | 约定 | 示例 |
|------|------|------|
| 接口 | PascalCase + 后缀 | `UserService`, `AccountRepository` |
| 实现 | camelCase + 后缀 | `userService`, `accountRepository` |
| 测试文件 | 源文件_test.go | `user_service_test.go` |
| 测试 Stub | stub + 名称 | `stubUserRepo` |
| 前端组件 | PascalCase | `UserList.vue` |
| 前端测试 | __tests__/xxx.spec.ts | `UserList.spec.ts` |
### 2.3 Git 提交规范
**格式**:
```
<type>(<scope>): <subject>
<body>
```
**Type 类型**:
- `feat`: 新功能
- `fix`: Bug 修复
- `docs`: 文档更新
- `refactor`: 重构
- `test`: 测试相关
- `chore`: 构建/工具/清理
- `security`: 安全修复
**示例**:
```
fix(config): resolve Windows path resolution issue
- Add optional configPaths parameter to load()
- Use t.TempDir() for test isolation
```
### 2.4 测试规范
**后端测试**:
```bash
# 单元测试
go test -tags=unit ./...
# 集成测试(需要数据库)
go test -tags=integration ./...
# 特定包
go test -tags=unit ./internal/service/ -v
```
**前端测试**:
```bash
# 运行测试
npm run test:run
# 监听模式
npm run test
# 覆盖率
npm run test:coverage
```
**测试原则**:
1. 测试文件与源码同目录Go: `*_test.go`, Vue: `__tests__/`
2. 使用 `t.TempDir()` 创建隔离临时目录
3. 清理资源:关闭文件、释放锁、重置全局状态
4. Windows 兼容注意路径、pipe、文件锁差异
---
## 三、本地环境配置
### 3.1 PostgreSQL
| 配置项 | 值 |
|--------|-----|
| 端口 | 5432 |
| psql 路径 | `C:\Program Files\PostgreSQL\16\bin\psql.exe` |
| pg_hba.conf | `C:\Program Files\PostgreSQL\16\data\pg_hba.conf` |
| 数据库凭据 | user=`sub2api`, password=`sub2api`, dbname=`sub2api` |
| 超级用户 | user=`postgres`, password=`postgres` |
| 数据库 | sub2api |
| 用户 | sub2api / sub2api |
| 超级用户 | postgres / postgres |
### Redis
### 3.2 Redis
| 配置项 | 值 |
|--------|-----|
| 端口 | 6379 |
| 密码 | 无 |
### 开发工具
### 3.3 开发工具
```bash
# golangci-lint v2.7
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7
# golangci-lint
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
# pnpm (前端包管理)
npm install -g pnpm
```
## 三、CI/CD 流水线
### GitHub Actions Workflows
| Workflow | 触发条件 | 检查内容 |
|----------|----------|----------|
| **backend-ci.yml** | push, pull_request | 单元测试 + 集成测试 + golangci-lint v2.7 |
| **security-scan.yml** | push, pull_request, 每周一 | govulncheck + gosec + pnpm audit |
| **release.yml** | tag `v*` | 构建发布PR 不触发) |
### CI 要求
- Go 版本必须是 **1.25.7**
- 前端使用 `pnpm install --frozen-lockfile`,必须提交 `pnpm-lock.yaml`
### 本地测试命令
```bash
# 后端单元测试
cd backend && go test -tags=unit ./...
# 后端集成测试
cd backend && go test -tags=integration ./...
# 代码质量检查
cd backend && golangci-lint run ./...
# 前端依赖安装(必须用 pnpm
cd frontend && pnpm install
```
## 四、常见坑点 & 解决方案
### 坑 1pnpm-lock.yaml 必须同步提交
**问题**`package.json` 新增依赖后CI 的 `pnpm install --frozen-lockfile` 失败。
**原因**:上游 CI 使用 pnpmlock 文件不同步会报错。
**解决**
```bash
cd frontend
pnpm install # 更新 pnpm-lock.yaml
git add pnpm-lock.yaml
git commit -m "chore: update pnpm-lock.yaml"
# Ent 代码生成
go install entgo.io/ent/cmd/ent@latest
```
---
### 坑 2npm 和 pnpm 的 node_modules 冲突
## 四、常用命令
**问题**:之前用 npm 装过 `node_modules`pnpm install 报 `EPERM` 错误。
### 4.1 后端命令
**解决**
```bash
cd frontend
rm -rf node_modules # 或 PowerShell: Remove-Item -Recurse -Force node_modules
pnpm install
# 运行服务
go run ./cmd/server/
# 构建
go build -o bin/server ./cmd/server/
# 生成 Ent 代码(修改 schema 后必须执行)
go generate ./ent
# 单元测试
go test -tags=unit ./...
# 集成测试
go test -tags=integration ./...
# Lint 检查
golangci-lint run ./...
# 检查所有
go test -tags=unit ./... && golangci-lint run ./...
```
### 4.2 前端命令
```bash
# 安装依赖
npm install
# 开发服务器
npm run dev
# 构建
npm run build
# 类型检查
npx vue-tsc --noEmit
# 测试
npm run test:run
# Lint
npm run lint
```
### 4.3 数据库命令
```bash
# 连接数据库
psql -U sub2api -h 127.0.0.1 -d sub2api
# 执行迁移
psql -U sub2api -h 127.0.0.1 -d sub2api -f migrations/xxx.sql
# 查看表结构
\dt
\d table_name
```
---
### 坑 3PowerShell 中 bcrypt hash 的 `$` 被转义
## 五、常见问题
**问题**bcrypt hash 格式如 `$2a$10$xxx...`PowerShell 把 `$2a` 当变量解析,导致数据丢失。
### 5.1 Ent Schema 修改后不生效
**解决**:将 SQL 写入文件,用 `psql -f` 执行:
**原因**: Ent 是代码生成工具,修改 schema 后需要重新生成
**解决**:
```bash
# 错误示范PowerShell 会吃掉 $
psql -c "INSERT INTO users ... VALUES ('$2a$10$...')"
# 正确做法
echo "INSERT INTO users ... VALUES ('\$2a\$10\$...')" > temp.sql
psql -U sub2api -h 127.0.0.1 -d sub2api -f temp.sql
```
---
### 坑 4psql 不支持中文路径
**问题**`psql -f "D:\中文路径\file.sql"` 报错找不到文件。
**解决**:复制到纯英文路径再执行:
```bash
cp "D:\中文路径\file.sql" "C:\temp.sql"
psql -f "C:\temp.sql"
```
---
### 坑 5PostgreSQL 密码重置流程
**场景**:忘记 PostgreSQL 密码。
**步骤**
1. 修改 `C:\Program Files\PostgreSQL\16\data\pg_hba.conf`
```
# 将 scram-sha-256 改为 trust
host all all 127.0.0.1/32 trust
```
2. 重启 PostgreSQL 服务
```powershell
Restart-Service postgresql-x64-16
```
3. 无密码登录并重置
```bash
psql -U postgres -h 127.0.0.1
ALTER USER sub2api WITH PASSWORD 'sub2api';
ALTER USER postgres WITH PASSWORD 'postgres';
```
4. 改回 `scram-sha-256` 并重启
---
### 坑 6Go interface 新增方法后 test stub 必须补全
**问题**:给 interface 新增方法后,编译报错 `does not implement interface (missing method XXX)`。
**原因**:所有测试文件中实现该 interface 的 stub/mock 都必须补上新方法。
**解决**
```bash
# 搜索所有实现该 interface 的 struct
cd backend
go generate ./ent
git add ent/
```
### 5.2 接口新增方法后编译失败
**原因**: 所有实现该接口的 mock/stub 都需要补全新方法
**解决**:
```bash
# 搜索所有 stub
grep -r "type.*Stub.*struct" internal/
grep -r "type.*Mock.*struct" internal/
# 逐一补全新方法
```
---
### 5.3 Windows 上测试超时
### 坑 7Windows 上 psql 连 localhost 的 IPv6 问题
**原因**: Windows pipe 的 Sync() 会阻塞
**问题**psql 连 `localhost` 先尝试 IPv6 (::1),可能报错后再回退 IPv4。
**建议**:直接用 `127.0.0.1` 代替 `localhost`。
---
### 坑 8Windows 没有 make 命令
**问题**CI 里用 `make test-unit`,本地 Windows 没有 make。
**解决**:直接用 Makefile 里的原始命令:
```bash
# 代替 make test-unit
go test -tags=unit ./...
# 代替 make test-integration
go test -tags=integration ./...
**解决**: 先关闭 write end 再调用 Sync
```go
_ = stdoutW.Close()
_ = stderrW.Close()
Sync()
```
---
### 5.4 配置测试读取了错误的文件
### 坑 9Ent Schema 修改后必须重新生成
**原因**: viper 搜索路径包含意外的配置文件
**问题**:修改 `ent/schema/*.go` 后,代码不生效。
**解决**: 使用可选参数传入测试目录
```go
// 生产
load(false)
**解决**
```bash
cd backend
go generate ./ent # 重新生成 ent 代码
git add ent/ # 生成的文件也要提交
// 测试
load(false, t.TempDir())
```
---
### 5.5 PowerShell 变量转义问题
### 坑 10前端测试看似正常但后端调用失败模型映射被批量误改
**问题**: bcrypt hash 中的 `$` 被解析为变量
**典型现象**
- 前端按钮点测看起来正常;
- 实际通过 API/客户端调用时返回 `Service temporarily unavailable` 或提示无可用账号;
- 常见于 OpenAI 账号(例如 Codex 模型)在批量修改后突然不可用。
**解决**: 使用文件执行 SQL
```bash
echo "INSERT INTO users ... VALUES ('\$2a\$10\$...')" > temp.sql
psql -f temp.sql
```
**根因**
- OpenAI 账号编辑页默认不显式展示映射规则,容易让人误以为“没映射也没关系”;
- 但在**批量修改同时选中不同平台账号**OpenAI + Antigravity/Gemini模型白名单/映射可能被跨平台策略覆盖;
- 结果是 OpenAI 账号的关键模型映射丢失或被改坏,后端选不到可用账号。
### 5.6 psql 不支持中文路径
**修复方案(按优先级)**
1. **快速修复(推荐)**:在批量修改中补回正确的透传映射(例如 `gpt-5.3-codex -> gpt-5.3-codex-spark`)。
2. **彻底重建**:删除并重新添加全部相关账号(最稳但成本高)。
**解决**: 复制到英文路径再执行
```bash
cp "D:\中文\file.sql" "C:\temp.sql"
psql -f "C:\temp.sql"
```
**关键经验**
- 如果某模型已被软件内置默认映射覆盖,通常不需要额外再加透传;
- 但当上游模型更新快于本仓库默认映射时,**手动批量添加透传映射**是最简单、最低风险的临时兜底方案;
- 批量操作前尽量按平台分组,不要混选不同平台账号。
### 5.7 PostgreSQL 密码重置
1. 修改 `pg_hba.conf`,将 `scram-sha-256` 改为 `trust`
2. 重启服务: `Restart-Service postgresql-x64-16`
3. 无密码登录重置密码
4. 改回 `scram-sha-256` 并重启
---
### 坑 11PR 提交前检查清单
## 六、PR 检查清单
提交 PR 前务必本地验证:
提交前务必验证:
- [ ] `go test -tags=unit ./...` 通过
- [ ] `go test -tags=integration ./...` 通过
- [ ] `go test -tags=integration ./...` 通过(如适用)
- [ ] `golangci-lint run ./...` 无新增问题
- [ ] `pnpm-lock.yaml` 已同步(如果改了 package.json
- [ ] 所有 test stub 补全新接口方法(如果改了 interface
- [ ] Ent 生成的代码已提交(如改了 schema
- [ ] `npm run test:run` 通过
- [ ] `npx vue-tsc --noEmit` 无类型错误
- [ ] Ent 生成的代码已提交(如改了 schema
- [ ] 测试 stub 已更新(如改了 interface
- [ ] 无敏感信息泄露
## 五、常用命令速查
---
### 数据库操作
## 七、CI/CD 流水线
```bash
# 连接数据库
psql -U sub2api -h 127.0.0.1 -d sub2api
| Workflow | 触发条件 | 检查内容 |
|----------|----------|----------|
| backend-ci.yml | push, PR | 单元测试 + Lint |
| security-scan.yml | push, PR, 周一 | 安全扫描 |
| release.yml | tag v* | 构建发布 |
# 查看所有用户
psql -U postgres -h 127.0.0.1 -c "\du"
---
# 查看所有数据库
psql -U postgres -h 127.0.0.1 -c "\l"
## 八、参考资源
# 执行 SQL 文件
psql -U sub2api -h 127.0.0.1 -d sub2api -f migration.sql
```
### Git 操作
```bash
# 同步上游
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
# 创建功能分支
git checkout -b feature/xxx
# Rebase 到最新 main
git fetch upstream
git rebase upstream/main
```
### 前端操作
```bash
# 安装依赖(必须用 pnpm
cd frontend
pnpm install
# 开发服务器
pnpm dev
# 构建
pnpm build
```
### 后端操作
```bash
# 运行服务器
cd backend
go run ./cmd/server/
# 生成 Ent 代码
go generate ./ent
# 运行测试
go test -tags=unit ./...
go test -tags=integration ./...
# Lint 检查
golangci-lint run ./...
```
## 六、项目结构速览
```
sub2api-bmai/
├── backend/
│ ├── cmd/server/ # 主程序入口
│ ├── ent/ # Ent ORM 生成代码
│ │ └── schema/ # 数据库 Schema 定义
│ ├── internal/
│ │ ├── handler/ # HTTP 处理器
│ │ ├── service/ # 业务逻辑
│ │ ├── repository/ # 数据访问层
│ │ └── server/ # 服务器配置
│ ├── migrations/ # 数据库迁移脚本
│ └── config.yaml # 配置文件
├── frontend/
│ ├── src/
│ │ ├── api/ # API 调用
│ │ ├── components/ # Vue 组件
│ │ ├── views/ # 页面视图
│ │ ├── types/ # TypeScript 类型
│ │ └── i18n/ # 国际化
│ ├── package.json # 依赖配置
│ └── pnpm-lock.yaml # pnpm 锁文件(必须提交)
└── .claude/
└── CLAUDE.md # 本文档
```
## 七、参考资源
- [上游仓库](https://github.com/Wei-Shaw/sub2api)
- [Ent 文档](https://entgo.io/docs/getting-started)
- [Vue3 文档](https://vuejs.org/)
- [pnpm 文档](https://pnpm.io/)
- [项目复盘总结](docs/PROJECT_REVIEW.md)
- [审查报告](docs/reports/)
- [Ent 文档](https://entgo.io/)
- [Vue 3 文档](https://vuejs.org/)
- [Gin 文档](https://gin-gonic.com/)