# 6A工作流 - ALIGNMENT阶段文档

## 任务名称：Server模块Service缓存调整为Vo对象

## 1. 项目上下文分析

### 1.1 项目结构与技术栈
- **项目**: Contract-Manager
- **模块**: server模块
- **技术栈**: Java 21, Spring Boot 3.3.7, Spring Data JPA 3.3.7, Redis (用于缓存), Lombok 1.18.32

### 1.2 现有代码模式
- **接口结构**: IEntityService<T>接口定义了基础的CRUD操作，泛型T当前用于指定实体类类型
- **VoableService接口**: 定义了updateByVo(M model, Vo vo)方法，用于将VO对象的值更新到实体对象
- **Service实现模式**: 多个Service类同时实现IEntityService和VoableService接口，分别指定实体类和VO类的泛型参数
- **缓存配置**: 使用@CacheConfig注解配置缓存名称，方法级缓存使用@Cacheable、@CacheEvict等注解
- **缓存问题**: 当前使用实体类进行缓存，由于Hibernate代理对象序列化问题，可能导致懒加载异常
- **实体类和Vo类**: 都定义在 common 模块中，确保在不同模块之间的引用和使用

### 1.3 架构模式
- 采用经典的三层架构：Controller层、Service层、Repository层
- Service层同时承担业务逻辑和数据转换职责
- 使用Spring Data JPA进行数据访问
- 使用Redis作为缓存层，提高系统性能

## 2. 需求理解确认

### 2.1 原始需求
> server模块中注解了 @CacheConfig的Service，调整接口泛型参数，涉及到Service上各个方法的修改，方法修改相关引用方法的地方也要修改

### 2.1.1 扩展需求
> 使用VO替代实体缓存，因为使用redis服务，需要避免代理对象序列化，彻底规避懒加载问题

### 2.2 边界确认
- **目标范围**: server模块中所有注解了@CacheConfig的Service类
- **修改内容**: 
  - Service类继承IEntityService接口，泛型类型保持为Model（实体类）
  - Service类继承QueryService接口，泛型类型修改为Vo（视图对象）
  - Service类继承VoableService接口，泛型类型保持为Model（实体类）和Vo（视图对象）
  - 实体类继承Voable接口，提供toVo方法实现从实体类到VO的转换

- **影响范围**: 需要同步修改Service类中实现的接口方法的参数和返回类型
- **任务边界**: 不修改接口定义本身，只修改实现类的泛型参数和相关方法实现

### 2.3 需求理解
- 当前Service类同时实现`IEntityService<Entity>`和`QueryService<Vo>`接口，还需实现`VoableService<Entity, Vo>`接口
- 需要调整Service类的接口实现，使IEntityService保持使用实体类类型，QueryService使用Vo类型
- Service类需要同时实现IEntityService<实体类>和QueryService<Vo类>接口，并根据不同接口的要求实现对应的方法，IEntityService和QueryService接口有同名的方法，按各自结构定义实现
- 需要确保缓存注解的键值表达式仍然有效
- 需要保证修改后系统功能正常运行
- 使用VO替代实体类进行缓存，避免Hibernate代理对象序列化问题，彻底规避懒加载异常

## 3. 疑问澄清

1. **数据转换问题**: 如何处理从实体类到VO的转换和从VO到实体类的转换？
   - 实体类应该实现Voable接口，提供toVo方法实现从实体类到VO的转换
   - Service类实现VoableService接口提供updateByVo方法实现从Vo到实体类的转换，参考ProjectQuotationService的updateByVo方法

2. **缓存键表达式**: 修改泛型后，缓存注解中的键表达式（如@CacheEvict(key = "#p0.id")）是否需要修改？
   - 需要确认VO类是否与实体类具有相同的属性结构

3. **依赖影响**: 修改Service泛型后，对调用这些Service的其他组件（如Controller、其他Service）会有什么影响？
   - 需要评估依赖影响范围并考虑如何处理

4. **事务处理**: 修改后事务处理是否会受到影响？
   - 需要确保事务边界正确维护

5. **查询规范**: getSpecification方法如何适配从Entity到Vo的转换？
   - 解决方案：Service类同时实现IEntityService<实体类>和QueryService<Vo类>接口
   - 在IEntityService<实体类>接口中保持getSpecification方法返回基于JPA实体的Specification
   - 在QueryService<Vo类>接口的findAll方法中，先使用基于实体类的Specification查询数据，然后通过map操作将实体转换为Vo
   - 实体类实现Voable<Vo类>接口，提供toVo方法进行转换

6. **缓存对象转换**: 如何确保缓存中存储的是VO对象而不是实体类对象？
   解决方案：通过以下机制确保缓存中存储VO对象：
   - 服务类同时实现IEntityService<实体类>和QueryService<Vo类>接口
   - QueryService接口的方法（如findById）添加@Cacheable注解
   - 在这些缓存方法的实现中，查询实体后通过调用实体类的toVo()方法转换为Vo对象再返回
   - 实体类实现Voable接口，提供toVo()方法进行转换

7. **WebSocket服务影响**: WebSocketServerCallbackManager类直接调用IEntityService接口，由于我们保持IEntityService泛型为实体类，因此对WebSocket服务的影响较小
   - WebSocketServerCallbackManager类中的createNewEntity、findEntityTypeInInterfaces等方法主要依赖于IEntityService的实体类泛型
   - 需要确认这些方法是否兼容当前的实现方式

8. **任务管理影响**: WebSocketServerTaskManager类中处理的任务主要依赖于IEntityService接口，由于我们保持了IEntityService的泛型为实体类，对任务管理的影响应该较小

## 4. 初步决策

基于现有项目代码分析，做出以下初步决策：

1. **泛型修改策略**: 对于每个注解了@CacheConfig的Service类，同时实现IEntityService<实体类>和QueryService<Vo类>接口，保持IEntityService泛型为实体类，QueryService泛型为Vo类

2. **方法适配方案**:
   - IEntityService接口的方法保持基于实体类的实现
   - QueryService接口的方法（如findById、findAll）在内部先查询实体，再通过实体类的toVo()方法转换为Vo对象返回
   - 实体类实现Voable接口，提供toVo()方法进行转换

3. **缓存键处理**: QueryService接口的缓存方法（如findById）使用与实体类相同的ID属性作为缓存键，由于Vo类通常与实体类具有相同的ID属性，因此缓存注解可能不需要修改

4. **依赖处理**: 需要评估并处理所有调用修改后Service的组件，确保它们适应新的接口定义

5. **特殊方法处理**: 对于getSpecification等基于JPA实体的方法，保持在IEntityService接口中返回基于实体类的Specification

6. **缓存策略**: 确保所有标注@Cacheable的方法（主要是QueryService接口中的方法）都返回VO对象，并在存储前完成从实体类到VO的转换，以避免代理对象序列化问题

这些决策将在后续的共识和设计阶段进一步细化和确认。