## 主要变更 ### 🏗️ 架构重构 - 采用简洁的四层架构:API → Service → Repository → Model - 遵循 Go 语言最佳实践和命名规范 - 实现依赖注入和接口导向设计 - 统一错误处理和响应格式 ### 📁 目录结构优化 - 删除重复模块 (application/, domain/, infrastructure/ 等) - 规范化命名 (使用 Go 风格的 snake_case) - 清理无关文件 (package.json, node_modules/ 等) - 新增规范化的测试目录结构 ### 📚 文档系统 - 为每个模块创建详细的 CLAUDE.md 指导文件 - 包含开发规范、最佳实践和使用示例 - 支持模块化开发,缩短上下文长度 ### 🔧 开发规范 - 统一接口命名规范 (UserServicer, PhotoRepositoryr) - 标准化错误处理机制 - 完善的测试策略 (单元测试、集成测试、性能测试) - 规范化的配置管理 ### 🗂️ 新增文件 - cmd/server/ - 服务启动入口和配置 - internal/model/ - 数据模型层 (entity, dto, request) - pkg/ - 共享工具包 (logger, response, validator) - tests/ - 完整测试结构 - docs/ - API 文档和架构设计 - .gitignore - Git 忽略文件配置 ### 🗑️ 清理内容 - 删除 Node.js 相关文件 (package.json, node_modules/) - 移除重复的架构目录 - 清理临时文件和构建产物 - 删除重复的文档文件 ## 影响 - 提高代码可维护性和可扩展性 - 统一开发规范,提升团队协作效率 - 优化项目结构,符合 Go 语言生态标准 - 完善文档体系,降低上手难度
313 lines
8.3 KiB
Markdown
313 lines
8.3 KiB
Markdown
# 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),
|
|
)
|
|
```
|
|
|
|
这个架构设计确保了代码的可维护性、可测试性和可扩展性。遵循这些指导原则,可以构建出高质量的后端服务。 |