# business-logic-layering Specification

## Purpose
TBD - created by archiving change refactor-business-logic-layering. Update Purpose after archive.
## Requirements
### Requirement: 服务层接口标准化
- **说明**: 服务层方法现在 **MUST** 只接收数据传输对象 (DTO) 或基本参数，并 **MUST** 只返回 DTO 或业务领域对象，不再直接暴露数据库模型。
- **理由**: 减少服务层与持久化细节的耦合，提高接口的抽象性和稳定性。
- **影响**: 高。所有调用服务层的方法都需要调整。
- **受影响的模块**: `monitor`, `device`, `pig-farm`, `plan`, `user`。

#### Scenario: 服务层方法接收 DTO 作为输入
- **假如**: `UserService` 的 `CreateUser` 方法被调用。
- **当**: `CreateUser` 方法接收 `dto.CreateUserRequest` 作为参数。
- **那么**: `UserService` 内部负责将 `dto.CreateUserRequest` 转换为 `models.User` 进行处理。

#### Scenario: 服务层方法返回 DTO 作为输出
- **假如**: `UserService` 的 `CreateUser` 方法执行成功。
- **当**: `CreateUser` 方法返回 `*dto.CreateUserResponse`。
- **那么**: 调用方可以直接使用 `dto.CreateUserResponse`，无需进行额外的模型转换。

### Requirement: 控制器层职责收敛
- **说明**: 控制器层现在 **MUST** 仅负责 HTTP 请求的参数绑定与校验、调用服务层方法，并将服务层返回的 DTO 转换为 HTTP 响应。所有业务逻辑、领域对象的创建与验证、以及与仓库层的直接交互都 **MUST** 从控制器层移除并下沉到服务层。
- **理由**: 遵循“关注点分离”原则，使控制器层专注于 HTTP 协议处理，提高代码的可维护性和可测试性。
- **影响**: 高。所有控制器方法都需要大幅简化。
- **受影响的模块**: `monitor`, `device`, `pig-farm`, `plan`, `user`。

#### Scenario: 控制器不再直接进行领域模型内部字段的序列化/反序列化
- **假如**: `DeviceController` 的 `CreateDevice` 方法被调用。
- **当**: `CreateDevice` 方法不再包含 `json.Marshal` 或 `json.Unmarshal` 等操作来处理 `Properties` 等字段。
- **那么**: 这些序列化/反序列化逻辑已下沉到 `DeviceService` 中。

#### Scenario: 控制器不再直接实例化领域模型对象
- **假如**: `UserController` 的 `CreateUser` 方法被调用。
- **当**: `CreateUser` 方法不再包含 `&models.User{...}` 这样的代码。
- **那么**: 领域模型的创建已通过 `UserService` 完成。

#### Scenario: 控制器不再直接调用仓库层方法
- **假如**: `PlanController` 的 `ListPlans` 方法被调用。
- **当**: `ListPlans` 方法不再直接调用 `planRepo.ListPlans`。
- **那么**: `PlanService` 负责协调 `PlanRepository`。

#### Scenario: 控制器不再直接进行业务规则判断
- **假如**: `PlanController` 的 `UpdatePlan` 方法被调用。
- **当**: `UpdatePlan` 方法不再包含对计划类型、状态或 `ContentType` 的直接判断逻辑。
- **那么**: 这些业务规则判断已下沉到 `PlanService` 中。

### Requirement: DTO 转换逻辑下沉
- **说明**: 数据库模型与 DTO 之间的转换逻辑 **MUST** 从控制器层移动到服务层内部或专门的转换器中。
- **理由**: 确保数据转换逻辑与业务逻辑紧密结合，避免控制器层承担不必要的职责。
- **影响**: 中。主要影响数据流转和转换点。
- **受影响的模块**: `monitor`, `device`, `pig-farm`, `plan`, `user`。

#### Scenario: 服务层负责将数据库模型转换为响应 DTO
- **假如**: `PigFarmService` 的 `GetPigHouseByID` 方法从 `repository` 获取到 `models.PigHouse`。
- **当**: `GetPigHouseByID` 方法在返回前将 `models.PigHouse` 转换为 `dto.PigHouseResponse`。
- **那么**: 控制器直接接收 `dto.PigHouseResponse`。

### Requirement: 业务错误处理优化
- **说明**: 服务层现在 **MUST** 返回更抽象的业务错误，控制器层 **MUST** 根据这些抽象错误进行统一的 HTTP 响应处理，避免直接依赖仓库层或服务层内部的具体错误类型或错误信息。
- **理由**: 提高错误处理的一致性和可维护性，解耦控制器与底层错误实现。
- **影响**: 中。影响错误处理流程。
- **受影响的模块**: `monitor`, `device`, `pig-farm`, `plan`, `user`。

#### Scenario: 服务层返回抽象业务错误
- **假如**: `UserService` 的 `CreateUser` 方法因用户名重复而失败。
- **当**: `UserService` 返回一个表示“用户名已存在”的抽象错误（例如自定义错误类型或包装后的错误）。
- **那么**: `UserController` 接收到此抽象错误后，可以统一转换为相应的 HTTP 状态码和错误信息，而无需解析底层 `gorm.ErrDuplicatedKey` 等具体错误。

