8.0 KiB
8.0 KiB
name, overview, todos
| name | overview | todos | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| legacy-ecommerce-demo-repo | 创建一个 Java Spring Boot 电商订单系统的"烂代码"演示仓库,涵盖理解老代码、重构、补测试、修Bug、技术栈升级、添加新功能等6大AI辅助场景,约12-15个文件,适合30-45分钟培训实战。 |
|
用户需求
为一线开发团队制作一个用于AI编码培训的"传统烂代码"演示仓库,让学员在培训过程中跟着实操,学习如何用AI辅助老旧项目维护。
产品概述
一个刻意设计为"遗留系统"风格的Java Spring Boot电商订单管理后端,包含订单创建、查询、取消等基本功能。代码刻意引入典型遗留系统问题:上帝类、长函数、重复代码、SQL注入风险、硬编码、无测试、无异常处理等。支持一键启动(H2内存数据库),学员无需配置环境即可运行。
核心功能
- 订单CRUD REST API(创建、查询、取消、列表)
- H2内存数据库,零配置启动
- 预留6大AI辅助实操场景
六大培训场景设计
- 理解老代码+添加注释:学员面对无注释、命名混乱的代码,用AI快速理解业务逻辑并生成文档
- 重构(拆分大函数/消除重复):OrderService中故意放置200+行方法和3处重复的价格计算逻辑
- 补单元测试:项目零测试覆盖,学员用AI为关键路径生成JUnit测试
- 修Bug(埋典型bug):预埋SQL注入、并发竞态、空指针、整型溢出、日期比较错误共5个bug
- 技术栈升级:从Spring Boot 2.1.x + Java 8 迁移到 Spring Boot 3.x + Java 17(或更高)
- 添加新功能:在烂代码基础上增加订单退款、优惠券等新需求
技术栈选择
- 语言: Java 8(刻意使用旧版本,为升级场景留空间)
- 框架: Spring Boot 2.1.18.RELEASE
- 构建工具: Maven 3.6+
- 数据库: H2(内存模式,零配置)
- 数据访问: 原始JDBC + 手动连接管理(不使用任何ORM)
- 依赖: spring-boot-starter-web, h2, spring-boot-starter-jdbc
实现方案
整体策略
创建一个刻意劣化的Spring Boot应用,每个文件都包含典型遗留代码特征。关键设计原则:
- 不用ORM:直接JDBC操作,手动管理连接,SQL字符串拼接
- 不分层:Controller直接调用DAO,Service是上帝类
- 不写测试:整个项目零测试文件
- 不用现代API:java.util.Date、旧式for循环、避免Stream/Lambda
- 全局状态:使用static可变字段管理订单号序列
遗留代码特征清单
| 特征 | 体现位置 | 培训价值 |
|---|---|---|
| 上帝类 | OrderService.java (400+行) | 演示AI拆分大类的过程 |
| 长方法 | createOrder() 200+行 | 演示AI提取方法 |
| 重复代码 | 价格计算在3处重复 | 演示AI消除重复 |
| SQL拼接 | OrderDao.java | 演示AI发现安全漏洞 |
| 硬编码 | 税率0.17、连接串 | 演示AI提取配置 |
| 无日志 | 全部System.out | 演示AI添加日志框架 |
| 无异常处理 | 整个项目 | 演示AI添加异常处理 |
| 静态可变状态 | orderNumberSequence | 演示AI发现并发问题 |
预埋Bug清单
- SQL注入:OrderDao.getOrderByName()使用字符串拼接用户输入
- 并发竞态:OrderService中static int orderNumberSequence++无同步
- 空指针异常:computeTotalPrice()未检查OrderItem列表是否为空
- 整型溢出:折扣计算 int discount = price * discountPercent / 100(price可为大值)
- 日期比较错误:使用java.util.Date的before/after而非推荐方式,跨年场景有边界问题
项目结构
legacy-order-system/
├── pom.xml # [NEW] Maven配置,Spring Boot 2.1.18 + H2
├── README.md # [NEW] 培训指南,含6大场景操作说明
└── src/main/
├── java/com/legacy/order/
│ ├── LegacyOrderApplication.java # [NEW] 主启动类,无任何配置分离
│ ├── controller/
│ │ └── OrderController.java # [NEW] REST控制器,600+行,混合了校验、业务、DAO调用
│ ├── service/
│ │ └── OrderService.java # [NEW] 上帝类,400+行,包含所有业务逻辑
│ ├── dao/
│ │ └── OrderDao.java # [NEW] 原始JDBC操作,SQL拼接,连接手动管理
│ ├── model/
│ │ ├── Order.java # [NEW] 订单实体,java.util.Date,无Lombok
│ │ ├── OrderItem.java # [NEW] 订单项实体
│ │ └── OrderStatus.java # [NEW] 订单状态枚举
│ └── util/
│ └── DbUtil.java # [NEW] 硬编码连接工具类,单例模式
└── resources/
├── application.properties # [NEW] 最小化配置,H2内存库
└── schema.sql # [NEW] 建表DDL,自动执行
数据流架构
graph LR
A[HTTP Request] --> B[OrderController]
B --> C[OrderService<br/>上帝类/全局状态]
C --> D[OrderDao<br/>原始JDBC/SQL拼接]
D --> E[H2内存数据库]
C -.-> F[DbUtil<br/>硬编码连接]
F -.-> E
API设计
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/orders | 创建订单 |
| GET | /api/orders/{id} | 查询单个订单 |
| GET | /api/orders | 列出所有订单 |
| PUT | /api/orders/{id}/cancel | 取消订单 |
| GET | /api/orders/search?name=xxx | 按商品名搜索(含SQL注入风险) |
实现注意事项
- 性能:H2内存库保证启动速度(<2秒),学员无需安装任何外部依赖
- 可移植性:纯Maven项目,克隆后mvn spring-boot:run即可启动
- 日志:刻意使用System.out.println模拟旧项目无日志框架的情况
- 编码规范:刻意使用坏命名(如tmp、data、list、flag等)、魔法数字、无注释
- 向后兼容:使用Java 8语法,避免模块化系统,兼容JDK 8-17
使用的扩展
SubAgent
- code-explorer
- 用途:验证生成的仓库文件结构完整性和代码一致性
- 预期结果:确认所有文件存在、包引用正确、Maven配置有效