Files
tokens-reef/docs/PROJECT_REVIEW.md

337 lines
7.6 KiB
Markdown
Raw Normal View History

# Sub2API 项目复盘总结
**复盘日期**: 2026/04/13
**项目版本**: main (d44fa6b)
**复盘范围**: 全项目开发、测试、部署经验
---
## 一、项目概况
### 1.1 项目定位
**Sub2API** 是一个企业级 AI API 网关平台,核心功能:
- 多平台 AI 服务聚合OpenAI、Gemini、Anthropic、Sora 等)
- API Key 管理与认证
- 用户订阅与计费
- 负载均衡与智能路由
- 运维监控与告警
### 1.2 项目规模
| 指标 | 数量 |
|------|------|
| 后端 Go 文件 | 450+ 个 |
| 后端代码行数 | ~370,000 行 |
| 后端测试文件 | 383 个 |
| 前端 TypeScript/Vue 文件 | 310 个 |
| 前端组件 | 114 个 |
| 前端视图 | 53 个 |
| 前端测试用例 | 301 个 |
| 数据库迁移 | 97 个 |
### 1.3 技术栈
| 层级 | 技术选型 |
|------|----------|
| 后端框架 | Go 1.26+ / Gin |
| ORM | Ent (Facebook) |
| 依赖注入 | Google Wire |
| 前端框架 | Vue 3 + TypeScript |
| 状态管理 | Pinia |
| 样式方案 | TailwindCSS |
| 构建工具 | Vite |
| 数据库 | PostgreSQL 15+ |
| 缓存 | Redis 7+ |
| 容器化 | Docker + Docker Compose |
---
## 二、开发经验总结
### 2.1 测试相关经验
#### 经验 1: Windows 平台测试兼容性
**问题**: 3 个测试包在 Windows 上失败
- `config` 包:配置路径解析差异(`/app/data``D:\app\data`
- `handler` 包:测试 stub 返回值错误
- `logger` 包:`Sync()` 在 pipe 上阻塞
**解决方案**:
```go
// config: 添加可选参数实现测试隔离
func load(allowMissingJWTSecret bool, configPaths ...string) (*Config, error)
// logger: 先关闭 write end 再 Sync
_ = stdoutW.Close()
Sync()
// logger: 添加 Reset() 关闭文件句柄
func Reset() {
if fileCloser != nil {
_ = fileCloser()
}
}
```
**教训**: 跨平台开发必须考虑:
1. 路径分隔符差异
2. 文件锁定机制差异
3. Pipe/Socket 行为差异
#### 经验 2: 测试隔离原则
**问题**: 测试相互干扰,配置文件被意外读取
**最佳实践**:
- 使用 `t.TempDir()` 创建隔离临时目录
- 每个测试独立的配置/数据目录
- Cleanup 函数确保资源释放
- 避免全局状态污染
```go
func TestXXX(t *testing.T) {
tmpDir := t.TempDir() // 自动清理
// 使用 tmpDir 作为测试数据目录
}
```
### 2.2 代码质量经验
#### 经验 3: 接口变更的测试维护
**问题**: 接口新增方法后,所有 mock/stub 编译失败
**解决方案**:
1. 使用 `grep -r "type.*Stub.*struct"` 定位所有 stub
2. 批量补全新方法
3. 考虑使用 mockery 等代码生成工具
#### 经验 4: Ent Schema 变更流程
**问题**: 修改 schema 后代码不生效
**正确流程**:
```bash
# 1. 修改 ent/schema/*.go
# 2. 重新生成
go generate ./ent
# 3. 提交生成的代码
git add ent/
# 4. 可能需要数据库迁移
```
### 2.3 前端开发经验
#### 经验 5: 包管理器一致性
**问题**: 项目使用 pnpm但误用 npm 导致 lock 文件冲突
**解决方案**:
- 统一使用单一包管理器
- 删除 `pnpm-lock.yaml``package-lock.yaml` 其中之一
- CI 必须与本地保持一致
#### 经验 6: 模型映射管理
**问题**: 批量编辑跨平台账号时,模型映射被错误覆盖
**教训**:
- 批量操作按平台分组
- 关键映射变更需二次确认
- 模型映射应有版本/审计追踪
---
## 三、项目规范更新
### 3.1 代码规范
#### Go 后端规范
1. **目录结构**
```
internal/
├── config/ # 配置viper
├── domain/ # 领域模型
├── handler/ # HTTP 处理器
├── service/ # 业务逻辑
├── repository/ # 数据访问
├── pkg/ # 内部工具包
└── testutil/ # 测试工具
```
2. **命名约定**
- 接口:`XXXService`, `XXXRepository`
- 实现:`xxxService`, `xxxRepository`
- 测试文件:`xxx_test.go`
- 测试 stub`stubXXX`, `mockXXX`
3. **错误处理**
- 使用 `internal/pkg/errors` 定义错误码
- 业务错误返回结构化响应
- 日志脱敏敏感信息
4. **测试规范**
- 单元测试:`go test -tags=unit`
- 集成测试:`go test -tags=integration`
- 测试覆盖率目标80%+
#### Vue 前端规范
1. **目录结构**
```
src/
├── api/ # API 调用
├── components/ # 可复用组件
├── composables/ # 组合式函数
├── stores/ # Pinia 状态
├── views/ # 页面视图
├── types/ # TypeScript 类型
└── utils/ # 工具函数
```
2. **测试规范**
- 测试文件:`__tests__/xxx.spec.ts`
- 使用 Vitest 运行测试
- 组件测试关注用户交互
### 3.2 Git 规范
#### 提交信息格式
```
<type>(<scope>): <subject>
<body>
<footer>
```
**Type 类型**:
- `feat`: 新功能
- `fix`: Bug 修复
- `docs`: 文档更新
- `style`: 代码格式
- `refactor`: 重构
- `test`: 测试相关
- `chore`: 构建/工具
**示例**:
```
fix(logger): resolve Sync() blocking on Windows pipes
- Move pipe close before Sync() call
- Add Reset() function for file handle cleanup
Closes #123
```
#### 分支策略
```
main # 主分支,稳定可发布
├── develop # 开发分支
├── feature/* # 功能分支
├── fix/* # 修复分支
└── release/* # 发布分支
```
### 3.3 PR 检查清单
**提交前必须验证**:
- [ ] `go test -tags=unit ./...` 通过
- [ ] `go test -tags=integration ./...` 通过(如适用)
- [ ] `golangci-lint run ./...` 无新增问题
- [ ] `npx vitest run` 通过
- [ ] `npx vue-tsc --noEmit` 无类型错误
- [ ] Ent 生成的代码已提交
- [ ] 测试 stub 已更新
- [ ] 敏感信息已移除
---
## 四、工具与配置
### 4.1 推荐开发工具
| 工具 | 用途 |
|------|------|
| golangci-lint | Go 代码检查 |
| mockery | Mock 代码生成 |
| vue-tsc | TypeScript 检查 |
| vitest | 前端单元测试 |
| pnpm | 前端包管理 |
### 4.2 IDE 配置
**VS Code 推荐扩展**:
- Go
- Vue - Official
- ESLint
- Prettier
- Tailwind CSS IntelliSense
### 4.3 CI/CD 配置
| Workflow | 触发 | 内容 |
|----------|------|------|
| backend-ci.yml | push, PR | 单元测试 + Lint |
| security-scan.yml | push, PR, 周一 | 安全扫描 |
| release.yml | tag v* | 构建发布 |
---
## 五、常见问题速查
### 5.1 环境问题
| 问题 | 解决方案 |
|------|----------|
| pnpm lock 冲突 | 删除 node_modules 后重新安装 |
| PowerShell 变量转义 | 使用文件执行 SQL |
| psql 中文路径 | 复制到英文路径 |
| PostgreSQL 密码重置 | 修改 pg_hba.conf 为 trust |
### 5.2 代码问题
| 问题 | 解决方案 |
|------|----------|
| 接口未实现 | 补全 mock/stub 方法 |
| Ent 代码过期 | `go generate ./ent` |
| 测试超时 | 检查 pipe/锁/资源释放 |
| 路径解析错误 | 使用 filepath 代替硬编码 |
---
## 六、后续改进建议
### 6.1 短期优化
1. **测试覆盖率**: 提升核心业务模块覆盖率至 85%+
2. **文档完善**: 补充 API 文档和架构图
3. **错误码整理**: 统一错误码规范
### 6.2 中期规划
1. **性能优化**: 数据库查询优化、缓存策略
2. **可观测性**: 完善监控指标和告警
3. **安全加固**: 定期依赖扫描、安全审计
### 6.3 长期演进
1. **微服务拆分**: 按业务域拆分服务
2. **多云部署**: 支持多区域部署
3. **API 版本管理**: 版本化 API 设计
---
## 七、参考资源
- [Go 代码审查建议](https://github.com/golang/go/wiki/CodeReviewComments)
- [Vue 风格指南](https://vuejs.org/style-guide/)
- [Ent 文档](https://entgo.io/)
- [Google Wire](https://github.com/google/wire)