fix
Some checks failed
部署后端服务 / 🧪 测试后端 (push) Failing after 5m8s
部署后端服务 / 🚀 构建并部署 (push) Has been skipped
部署后端服务 / 🔄 回滚部署 (push) Has been skipped

This commit is contained in:
xujiang
2025-07-10 18:09:11 +08:00
parent 35004f224e
commit 010fe2a8c7
96 changed files with 23709 additions and 19 deletions

View File

@ -0,0 +1,313 @@
# Internal 包 - CLAUDE.md
此文件为 Claude Code 在 internal 包中工作时提供指导。internal 包包含了应用程序的核心业务逻辑,不对外暴露。
## 🎯 模块概览
internal 包采用分层架构设计,包含以下核心层次:
- **API Layer** (`api/`): HTTP 接口层,处理请求和响应
- **Domain Layer** (`domain/`): 领域模型层,定义业务实体和规则
- **Application Layer** (`application/`): 应用服务层,编排业务逻辑
- **Infrastructure Layer** (`infrastructure/`): 基础设施层,外部依赖
- **Shared Layer** (`shared/`): 共享工具和常量
## 📁 目录结构
```
internal/
├── CLAUDE.md # 🔍 当前文件 - Internal 包指南
├── api/ # 🌐 API 接口层
│ ├── CLAUDE.md # API 层开发指南
│ ├── handlers/ # HTTP 处理器
│ ├── middleware/ # 中间件
│ ├── routes/ # 路由配置
│ └── validators/ # 输入验证
├── domain/ # 🏗️ 领域模型层
│ ├── CLAUDE.md # 领域层开发指南
│ ├── entities/ # 业务实体
│ ├── repositories/ # 仓储接口
│ └── services/ # 领域服务接口
├── application/ # 🔧 应用服务层
│ ├── CLAUDE.md # 应用层开发指南
│ ├── dto/ # 数据传输对象
│ └── services/ # 应用服务实现
├── infrastructure/ # 🏭 基础设施层
│ ├── CLAUDE.md # 基础设施指南
│ ├── config/ # 配置管理
│ ├── database/ # 数据库操作
│ ├── cache/ # 缓存服务
│ ├── storage/ # 文件存储
│ └── repositories/ # 仓储实现
└── shared/ # 🔗 共享组件
├── CLAUDE.md # 共享组件指南
├── constants/ # 常量定义
├── errors/ # 错误处理
└── utils/ # 工具函数
```
## 🏗️ 分层架构原则
### 依赖方向
```
API Layer ──→ Application Layer ──→ Domain Layer
↓ ↓ ↑
Infrastructure Layer ──────────────────┘
```
### 层次职责
#### 1. API Layer (api/)
- **职责**: 处理 HTTP 请求和响应
- **依赖**: Application Layer
- **不允许**: 直接调用 Infrastructure Layer 或包含业务逻辑
#### 2. Application Layer (application/)
- **职责**: 编排业务逻辑,协调 Domain Services
- **依赖**: Domain Layer
- **不允许**: 包含具体的基础设施实现
#### 3. Domain Layer (domain/)
- **职责**: 定义业务实体、规则和接口
- **依赖**: 无(最核心层)
- **不允许**: 依赖外部框架或基础设施
#### 4. Infrastructure Layer (infrastructure/)
- **职责**: 实现外部依赖,如数据库、缓存、文件存储
- **依赖**: Domain Layer (实现接口)
- **不允许**: 包含业务逻辑
#### 5. Shared Layer (shared/)
- **职责**: 提供跨层共享的工具和常量
- **依赖**: 最小化依赖
- **原则**: 保持稳定,避免频繁变更
## 🔧 开发规范
### 包导入规则
#### 标准导入顺序
```go
import (
// 1. 标准库
"context"
"fmt"
"time"
// 2. 第三方库
"github.com/gin-gonic/gin"
"gorm.io/gorm"
// 3. 项目内部包 - 按依赖层次
"photography-backend/internal/domain/entities"
"photography-backend/internal/application/dto"
"photography-backend/internal/shared/errors"
)
```
#### 禁止的依赖
- Domain Layer 不能导入 Infrastructure Layer
- Application Layer 不能导入 API Layer
- 下层不能导入上层
### 接口设计原则
#### 1. 依赖倒置
```go
// ✅ 正确:在 domain/repositories 定义接口
type UserRepository interface {
FindByID(id uint) (*entities.User, error)
Save(user *entities.User) error
}
// ✅ 在 infrastructure/repositories 实现接口
type userRepository struct {
db *gorm.DB
}
func (r *userRepository) FindByID(id uint) (*entities.User, error) {
// 实现细节
}
```
#### 2. 接口隔离
```go
// ✅ 正确:小而专注的接口
type UserReader interface {
FindByID(id uint) (*entities.User, error)
FindByEmail(email string) (*entities.User, error)
}
type UserWriter interface {
Save(user *entities.User) error
Delete(id uint) error
}
// ❌ 错误:过大的接口
type UserRepository interface {
// 包含太多方法...
}
```
### 错误处理规范
#### 1. 错误传播
```go
// Domain Layer: 定义业务错误
var ErrUserNotFound = errors.New("user not found")
// Application Layer: 处理和转换错误
func (s *UserService) GetUser(id uint) (*dto.UserResponse, error) {
user, err := s.repo.FindByID(id)
if err != nil {
if errors.Is(err, domain.ErrUserNotFound) {
return nil, shared.ErrUserNotFound
}
return nil, fmt.Errorf("failed to get user: %w", err)
}
return s.toDTO(user), nil
}
// API Layer: 转换为 HTTP 响应
func (h *UserHandler) GetUser(c *gin.Context) {
user, err := h.service.GetUser(id)
if err != nil {
response.HandleError(c, err)
return
}
response.Success(c, user)
}
```
## 🚀 开发工作流
### 1. 新功能开发流程
#### Step 1: Domain Layer
```bash
# 1. 定义实体
vim internal/domain/entities/new_entity.go
# 2. 定义仓储接口
vim internal/domain/repositories/new_repository.go
# 3. 定义领域服务接口(如需要)
vim internal/domain/services/new_service.go
```
#### Step 2: Application Layer
```bash
# 1. 定义 DTO
vim internal/application/dto/request/new_request.go
vim internal/application/dto/response/new_response.go
# 2. 实现应用服务
vim internal/application/services/new_service.go
```
#### Step 3: Infrastructure Layer
```bash
# 1. 实现仓储
vim internal/infrastructure/repositories/new_repository.go
# 2. 实现其他基础设施(如需要)
```
#### Step 4: API Layer
```bash
# 1. 实现处理器
vim internal/api/handlers/new_handler.go
# 2. 添加路由
vim internal/api/routes/api_v1.go
# 3. 添加验证器(如需要)
vim internal/api/validators/new_validator.go
```
### 2. 测试策略
#### 单元测试
- Domain Layer: 测试业务逻辑
- Application Layer: 测试服务编排
- Infrastructure Layer: 测试数据访问
#### 集成测试
- API Layer: 端到端测试
- Repository Layer: 数据库集成测试
#### 测试隔离
```go
// 使用依赖注入便于测试
type UserService struct {
repo domain.UserRepository
}
// 测试时注入 Mock
func TestUserService_GetUser(t *testing.T) {
mockRepo := &MockUserRepository{}
service := NewUserService(mockRepo)
// 测试逻辑
}
```
## 📋 代码审查清单
### 架构合规性
- [ ] 是否遵循分层架构原则
- [ ] 是否违反依赖方向
- [ ] 接口设计是否合理
- [ ] 错误处理是否完善
### 代码质量
- [ ] 命名是否清晰明确
- [ ] 函数是否单一职责
- [ ] 是否有适当的注释
- [ ] 是否有相应的测试
### 性能考虑
- [ ] 是否有 N+1 查询问题
- [ ] 是否需要添加缓存
- [ ] 数据库操作是否高效
## 🎯 最佳实践
### 1. 保持层次清晰
- 每层只关注自己的职责
- 避免跨层直接调用
- 使用接口解耦
### 2. 依赖注入
- 使用构造函数注入
- 避免全局变量
- 便于测试和替换
### 3. 错误处理
- 使用带类型的错误
- 适当包装错误信息
- 保持错误处理一致性
### 4. 性能优化
- 合理使用缓存
- 数据库查询优化
- 避免过度设计
## 🔍 故障排查
### 常见问题
1. **循环依赖**: 检查包导入关系
2. **接口未实现**: 确认所有方法都已实现
3. **依赖注入失败**: 检查构造函数和依赖配置
4. **测试失败**: 确认 Mock 对象配置正确
### 调试技巧
```go
// 使用结构化日志
logger.Debug("Processing request",
logger.String("handler", "UserHandler.GetUser"),
logger.Uint("user_id", userID),
)
```
这个架构设计确保了代码的可维护性、可测试性和可扩展性。遵循这些指导原则,可以构建出高质量的后端服务。