fix
This commit is contained in:
313
backend-old/internal/CLAUDE.md
Normal file
313
backend-old/internal/CLAUDE.md
Normal 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),
|
||||
)
|
||||
```
|
||||
|
||||
这个架构设计确保了代码的可维护性、可测试性和可扩展性。遵循这些指导原则,可以构建出高质量的后端服务。
|
||||
Reference in New Issue
Block a user