创建 Phase 1 基础设施搭建的完整 devflow 文档: - brief.md: 项目背景、目标、范围、技术选型、关键决策 - decisions.md: 6 个架构决策记录 (ADR) - ADR-001: Flyway 数据库版本管理 - ADR-002: 枚举类型存储为 VARCHAR - ADR-003: Redis JSON 序列化 - ADR-004: Spring Data JPA 命名约定 - ADR-005: 会话 TTL 可配置 - ADR-006: 包名暂时混用 - evidence.md: 测试证据、性能指标、编译验证、数据库结构 - 27 个测试全部通过 - 性能指标达标 - 提交记录追踪 - acceptance.md: 验收标准、测试结果、遗留问题 - 20/33 任务完成 - 部分验收通过 更新全局文档: - devflow/index.md: 新增 phase1-infrastructure 项目索引 - devflow/glossary/CONTEXT.md: 新增 8 个术语和 4 条业务规则 Progress: 20/33 tasks completed (61%)
5.1 KiB
Phase 1 基础设施搭建 — Decisions
ADR-001: 采用 Flyway 管理数据库版本
状态: 已接受
日期: 2026-06-23
决策者: zhuyongxin
背景
项目需要版本化管理数据库表结构,支持多环境部署和团队协作。
决策
采用 Flyway 作为数据库迁移工具,JPA ddl-auto 设置为 validate。
理由
- Flyway 提供版本化 SQL 脚本管理
validate模式确保代码与数据库结构一致,防止意外修改- 迁移脚本可版本控制,支持回滚和审计
- 与 Spring Boot 深度集成,配置简单
后果
- 表结构修改必须通过 SQL 迁移脚本
- 开发环境首次启动需要执行 Flyway 迁移
- 生产环境部署自动执行未执行的迁移脚本
ADR-002: 枚举类型存储为 VARCHAR
状态: 已接受
日期: 2026-06-23
决策者: zhuyongxin
背景
JPA 实体类使用 Java 枚举(FaultCategory、DiagnosisStatus、SourceType),数据库列类型为 VARCHAR,Hibernate 校验报错类型不匹配。
决策
在 JPA 实体中明确指定 columnDefinition = "VARCHAR":
@Enumerated(EnumType.STRING)
@Column(name = "fault_category", length = 32, columnDefinition = "VARCHAR(32)")
private FaultCategory faultCategory;
理由
- MySQL 的 ENUM 类型限制灵活性(新增枚举值需要 ALTER TABLE)
- VARCHAR 支持动态扩展枚举值
@Enumerated(EnumType.STRING)存储枚举名称,可读性好columnDefinition明确告知 Hibernate 期望的数据库类型
后果
- 数据库列存储字符串值(如
"EXTERNAL_API") - 枚举值修改不影响数据库结构
- 需要在应用层校验枚举值合法性
ADR-003: Redis 会话管理采用 JSON 序列化
状态: 已接受
日期: 2026-06-23
决策者: zhuyongxin
背景
SessionContext 包含复杂对象(List、LocalDateTime),需要选择合适的序列化方案存储到 Redis。
决策
使用 GenericJackson2JsonRedisSerializer + JavaTimeModule:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY
);
理由
- JSON 格式可读性强,便于调试
- 支持 Java 8 时间类型(LocalDateTime)
- 支持多态反序列化(通过
@class类型信息) - 跨语言友好(如需要其他服务读取 Redis 数据)
后果
- Redis 中存储的是 JSON 字符串
- 增加了
@class元数据字段 - 序列化性能略低于二进制方案(Kryo、Protobuf)
- 对象结构变更需要考虑兼容性
ADR-004: Repository 方法遵循 Spring Data JPA 命名约定
状态: 已接受
日期: 2026-06-23
决策者: zhuyongxin
背景
Repository 需要提供多种查询方法(按 ID、按业务字段、按时间范围等),需要选择查询定义方式。
决策
使用 Spring Data JPA 方法命名约定,不手写 @Query:
Optional<DiagnosisRecord> findByDiagnosisId(String diagnosisId);
List<DiagnosisRecord> findByFaultCategoryAndErrorCode(FaultCategory category, String errorCode);
Page<DiagnosisRecord> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end, Pageable pageable);
理由
- 方法名即查询语义,自解释
- 无需手写 SQL/JPQL,减少语法错误
- Spring Data JPA 自动生成查询实现
- 支持分页、排序等高级特性
后果
- 复杂查询(多表连接、子查询)需要手写
@Query - 方法名可能很长(多条件组合查询)
- 依赖 Spring Data JPA 的命名解析规则
ADR-005: 会话 TTL 可配置,默认由调用方指定
状态: 已接受
日期: 2026-06-23
决策者: zhuyongxin
背景
不同场景的会话过期时间需求不同(短诊断 5 分钟,长会话 1 小时)。
决策
createSession 方法接受 ttlSeconds 参数,由调用方指定过期时间:
String createSession(SessionContext context, long ttlSeconds);
理由
- 灵活控制不同场景的会话时长
- 避免硬编码过期时间
- 支持动态刷新(
refreshSession方法)
后果
- 调用方需要明确指定 TTL
- 需要在业务层统一管理 TTL 策略
- Redis 自动清理过期会话,无需手动删除
ADR-006: 包名暂时混用,Task 4 统一重构
状态: 临时接受
日期: 2026-06-23
决策者: zhuyongxin
背景
- 枚举类在
com.superbiz.agent.domain.enums - 新建实体类在
org.example.domain.entity - 新建 Repository 在
org.example.repository
决策
暂时通过跨包 import 解决编译问题,Task 4 统一重构为 com.superbiz.agent.*。
理由
- Phase 1 重点是功能实现和测试验证
- 包名重构涉及全局修改,风险较高
- Task 4 专门负责代码结构重构,一次性解决
后果
- 当前包名混乱,影响可维护性
- IDE 导航和代码搜索不友好
- Task 4 必须完成,否则技术债累积