- 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
337 lines
7.6 KiB
Markdown
337 lines
7.6 KiB
Markdown
# 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)
|