第一部分 · 工程结构规范
第二部分 · 编码规范
第三部分 · 数据库规范
第四部分 · 接口与可观测规范
第五部分 · 稳定性与性能规范
第六部分 · 安全规范
第七部分 · 测试规范
第八部分 · 版本管理与 AI 协作规范
第九部分 · 部署规范
统一采用 MVC 三层结构:接口写在 Controller,业务逻辑写在 Service,数据库查询写在 Mapper。
project-name/
└── src/main/java/com/company/project/
├── controller/ # 接口层:参数接收与校验、调用 Service、返回结果
│ ├── OrderController.java
│ └── UserController.java
├── service/ # 业务层:接口定义 + 实现,承载全部业务逻辑
│ ├── OrderService.java # 订单业务接口类
│ ├── UserService.java # 用户业务接口类
│ └── impl/
│ ├── OrderServiceImpl.java
│ └── UserServiceImpl.java
├── mapper/ # 数据层:数据库查询,不含业务逻辑
│ ├── OrderMapper.java
│ └── UserMapper.java
├── model/
│ ├── entity/ # 实体类
│ ├── dto/ # 入参对象
│ └── vo/ # 返回对象
├── enums/ # 枚举类
├── config/ # 配置类
├── common/ # 常量、统一返回体、全局异常处理
└── Application.java
| 层 | 只做 | 禁止 |
|---|---|---|
| Controller | 接收/校验参数、调用 Service、组装返回结果 | 写 if-else 业务逻辑、直接调 Mapper、直接操作数据库 |
| Service | 全部业务逻辑、事务控制、多表编排、规则校验 | 处理 HTTP 协议细节(request/response 对象) |
| Mapper | 单表/关联 SQL 查询与写入 | 写业务判断逻辑、循环调用数据库 |
// ── Controller:只做参数接收与调用 ──
@RestController
@RequestMapping("/api/v1/order")
public class OrderController {
@Resource
private OrderService orderService;
/**
* 创建订单接口
*/
@PostMapping("/create")
public Result<OrderDetailVO> createOrder(@RequestBody @Valid OrderCreateDTO dto) {
return Result.success(orderService.createOrder(dto));
}
}
// ── Service 接口类:订单业务契约 ──
public interface OrderService {
/**
* 创建订单
*/
OrderDetailVO createOrder(OrderCreateDTO dto);
/**
* 根据订单号查询订单详情
*/
OrderDetailVO getOrderDetailByOrderNo(String orderNo);
}
// ── ServiceImpl:业务逻辑全部在此 ──
@Service
public class OrderServiceImpl implements OrderService { ... }
// ── Mapper:只写数据库查询 ──
@Mapper
public interface OrderMapper {
/**
* 新增订单
*/
int insert(OrderInfo order);
/**
* 根据订单号查询订单
*/
OrderInfo selectByOrderNo(@Param("orderNo") String orderNo);
}
| 规则项 | 要求 |
|---|---|
| 写法 | UpperCamelCase(大驼峰):每个单词首字母大写,其余小写 |
| 构成 | 名词或名词短语,体现类的职责 |
| 禁止 | 下划线(User_Order)、全小写(userorder)、拼音(ZhangHu)、数字结尾(Util2) |
| 类型 | 后缀约定 | 正确示例 | 错误示例 |
|---|---|---|---|
| 控制器 | Controller | OrderController | OrderApi、orderController |
| 业务接口 | Service | OrderService | IOrderService |
| 业务实现 | ServiceImpl | OrderServiceImpl | OrderServiceImple |
| 数据访问 | Mapper | OrderMapper | OrderDao、OrderDB |
| 实体类 | 领域名词 | OrderInfo、UserInfo | OrderEntityPO |
| 枚举类 | Enum 结尾 | OrderStatusEnum | OrderStatus(与实体混淆) |
| 工具类 | Util 结尾 | DateUtil | Tools、Helper |
| 异常类 | Exception 结尾 | BusinessException | MyError |
| 常量类 | Constant 结尾 | OrderConstant | Const |
// 正确:大驼峰,职责清晰
public class OrderPayService { }
// 错误:下划线、拼音、全小写
public class Order_Pay_Service { }
public class DingDanFuWu { }
方法名使用小驼峰(lowerCamelCase),必须能表达方法意图——看方法名即可知道它做什么,不需要读实现。
| 操作类型 | 命名公式 | 示例 |
|---|---|---|
| 查询 | get / find / query + 对象 + 条件 | getOrderById、findPaidOrdersByUserId |
| 新增 | save / add / create + 对象 | saveOrder、createPaymentRecord |
| 修改 | update + 对象 + 变更点 | updateOrderStatus、updateUserPhone |
| 删除 | delete / remove + 对象 | deleteOrderById |
| 校验 | check / validate + 校验点 | checkOrderPayable、validatePhone |
| 判断 | is / has / exists + 条件 | isVipUser、hasUnpaidOrder |
| 转换 | 对象A + to + 对象B | orderToDTO、dtoToEntity |
| 统计 | count / sum + 维度 | countTodayOrders |
// 错误:看不出意图,需要读实现才知道干什么
public void handle(Order order) { }
public List<Order> query1(Long userId) { }
public boolean doCheck(Object o) { }
// 正确:方法名即文档
public void payOrder(Order order) { }
public List<Order> queryUnpaidOrdersByUserId(Long userId) { }
public boolean checkOrderWithinPayDeadline(Order order) { }
handle / process / do / execute / a1 / query1 等无意图词时,要求重命名后再合入。order_info → 实体 OrderInfo。order_no → orderNo。@Data 同时可变共享(多线程场景);推荐 @Getter/@Setter 显式控制。| 数据库表 | 实体类(Entity) | 传输对象(DTO) | 返回对象(VO) |
|---|---|---|---|
order_info | OrderInfo | OrderCreateDTO | OrderDetailVO |
user_info | UserInfo | UserRegisterDTO | UserBaseVO |
必须每个实体类具备完整注释:类注释 + 全部字段注释,字段注释与数据库字段 COMMENT 保持一致。
/**
* 订单信息实体
* 对应表:order_info
*
* @author zhangsan
* @date 2026-08-24
*/
@Data
@TableName("order_info")
public class OrderInfo {
/** 主键ID(雪花算法生成) */
private Long id;
/** 订单编号(业务唯一) */
private String orderNo;
/** 用户ID(关联 user_info.id) */
private Long userId;
/** 订单金额(单位:分) */
private Long orderAmount;
/** 订单状态 0-待支付 1-已支付 2-已取消 3-已完成(见 OrderStatusEnum) */
private Integer orderStatus;
/** 创建时间 */
private Date createTime;
/** 更新时间 */
private Date updateTime;
/** 逻辑删除标识 0-正常 1-已删除 */
private Integer isDeleted;
}
| 字段类型 | 注释必须说明 |
|---|---|
| 状态/类型字段 | 枚举全部取值含义,并标注对应枚举类 |
| 金额字段 | 单位(分/元),避免歧义 |
| 外键关联字段 | 关联的表与字段 |
| 时间字段 | 业务含义(创建/支付/完成时间) |
| 布尔/标识字段 | 每个取值的含义 |
必须所有方法具备 Javadoc 注释:说明用途、参数、返回值、异常。
/**
* 根据用户ID查询未支付订单列表
*
* @param userId 用户ID,不可为空
* @param pageNum 页码,从 1 开始
* @param pageSize 每页条数,最大 100
* @return 未支付订单分页结果,无数据时返回空分页对象
* @throws BusinessException 用户不存在时抛出(错误码 20001)
*/
public Page<OrderInfo> queryUnpaidOrdersByUserId(Long userId, int pageNum, int pageSize) { }
必须核心业务方法(订单创建、支付回调、状态流转等)在方法内部按步骤编号写清业务流程,步骤注释使用 STEP x: 格式:
/**
* 创建订单(核心业务)
* 业务流程:参数校验 → 商品与价格校验 → 幂等校验 → 生成订单 → 扣减库存 → 发送延迟取消消息
*/
@Transactional(rollbackFor = Exception.class)
public OrderInfo createOrder(OrderCreateDTO dto) {
// STEP 1: 参数基础校验(商品、数量、地址非空)
checkCreateOrderParams(dto);
// STEP 2: 查询商品信息并校验上架状态、价格以服务端为准(防止前端篡改价格)
ProductInfo product = productMapper.selectById(dto.getProductId());
checkProductSellable(product);
// STEP 3: 幂等校验,同一幂等键的重复请求直接返回已存在订单
OrderInfo existOrder = queryOrderByIdempotentKey(dto.getIdempotentKey());
if (existOrder != null) {
return existOrder;
}
// STEP 4: 生成订单编号并落库(金额单位为分,取服务端价格计算)
OrderInfo order = buildOrder(dto, product);
orderMapper.insert(order);
// STEP 5: 扣减库存(库存不足抛业务异常,事务回滚订单)
productMapper.deductStock(product.getId(), dto.getProductCount());
// STEP 6: 发送延迟消息,超时未支付自动取消订单(消息发送失败仅告警,不回滚)
sendDelayCancelMessage(order);
return order;
}
| 方法类型 | 注释要求 |
|---|---|
| Controller 层接口 | Javadoc:接口用途 + 参数 + 返回 + 示例说明 |
| Service 公共方法 | Javadoc 完整四要素(用途/参数/返回/异常) |
| 核心业务方法 | Javadoc + 方法体内 STEP 分步流程注释 |
| 私有工具方法 | 至少一行说明用途;复杂算法需说明思路 |
| Getter/Setter | Lombok 生成,无需注释 |
| 规则 | 要求 |
|---|---|
| 单个方法体行数上限 | 不能超过 300 行;超过即视为设计缺陷,必须拆分 |
| 重复代码 | 相同/相似的代码块出现 2 次以上,必须抽离成公共方法 |
| 公共方法归属 | 仅本类用 → 私有方法;跨类复用 → 工具类(Util)或公共 Service |
| 建议目标 | 普通方法控制在 80 行内;超 300 行为硬性红线 |
// 错误:一个方法 400+ 行,参数校验、金额计算、落库、通知全部堆在一起
public void createOrder(OrderCreateDTO dto) {
// ...300 行混合逻辑...
}
// 正确:按业务步骤抽成私有方法,主方法只保留流程骨架
public void createOrder(OrderCreateDTO dto) {
checkCreateOrderParams(dto); // 抽离:参数校验
OrderInfo order = buildOrder(dto); // 抽离:组装订单(金额计算复用 calcOrderAmount)
saveOrder(order); // 抽离:订单落库
notifyUserOrderCreated(order); // 抽离:用户通知
}
// 抽离出的公共方法:多处复用的金额计算
private Long calcOrderAmount(Long unitPrice, Integer count, Long discountAmount) {
return unitPrice * count - discountAmount;
}
魔法值(Magic Value)指代码中直接硬编码的数字或字符串常量。必须用枚举类或常量类替代。
// 错误:魔法值,1、2、"PAID" 散落各处,含义不明、改不动
if (order.getStatus() == 2) { ... }
if ("PAID".equals(payResult)) { ... }
// 正确:枚举统一收口
if (OrderStatusEnum.PAID.getCode().equals(order.getOrderStatus())) { ... }
if (PayResultEnum.PAID.getCode().equals(payResult)) { ... }
/**
* 订单状态枚举
*
* @author zhangsan
* @date 2026-08-24
*/
@Getter
@AllArgsConstructor
public enum OrderStatusEnum {
/** 待支付 */
UNPAID(0, "待支付"),
/** 已支付 */
PAID(1, "已支付"),
/** 已取消 */
CANCELED(2, "已取消"),
/** 已完成 */
FINISHED(3, "已完成");
/** 状态码(对应 order_info.order_status) */
private final Integer code;
/** 状态描述 */
private final String desc;
/**
* 根据 code 获取枚举
*/
public static OrderStatusEnum getByCode(Integer code) {
for (OrderStatusEnum e : values()) {
if (e.code.equals(code)) {
return e;
}
}
return null;
}
}
| 场景 | 处理方式 |
|---|---|
| 状态、类型、渠道等有固定取值集 | 必须枚举类,含 code + desc + getByCode |
| 纯数值阈值(重试次数、超时时间) | 常量类 static final 或配置项 |
| Redis Key 前缀、MQ Topic | 常量类统一收口,禁止散落 |
| 循环下标 i/j/k、坐标 0/1 | 允许,不算魔法值 |
| 规则项 | 要求 |
|---|---|
| 字符编码 | 统一 UTF-8(MySQL 使用 utf8mb4,可存储 emoji),全库统一排序规则 |
| 主键 | 不使用自增长(auto_increment),统一使用分布式 ID(雪花算法);避免分库分表冲突与爬库风险 |
| 外键 | 不使用物理外键(FOREIGN KEY),关联关系由应用层维护;只建索引加速关联查询 |
| 字段长度 | 所有字段必须显式设置长度(varchar 按实际业务上限设置;int 考虑 tinyint/smallint/int 精确选型),禁止不设长度 |
| 必备字段 | id、create_time、update_time、is_deleted(逻辑删除) |
| 注释 | 表和字段必须写 COMMENT,与实体类注释保持一致 |
| 禁止 | 存储过程、触发器、数据库层业务逻辑 |
CREATE TABLE `order_info` (
`id` bigint(20) NOT NULL COMMENT '主键ID(雪花算法生成)',
`order_no` varchar(32) NOT NULL COMMENT '订单编号(业务唯一)',
`user_id` bigint(20) NOT NULL COMMENT '用户ID(逻辑关联 user_info.id,无物理外键)',
`order_amount` bigint(20) NOT NULL DEFAULT 0 COMMENT '订单金额(单位:分)',
`order_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '订单状态 0-待支付 1-已支付 2-已取消 3-已完成',
`remark` varchar(256) DEFAULT NULL COMMENT '订单备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint(4) NOT NULL DEFAULT 0 COMMENT '逻辑删除 0-正常 1-已删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_no` (`order_no`),
KEY `idx_user_id` (`user_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单信息表';
| 数据 | 推荐类型与长度 |
|---|---|
| 主键 / 用户ID / 订单ID | bigint(20),雪花算法生成 |
| 订单编号 | varchar(32) |
| 手机号 | varchar(16) |
| 邮箱 | varchar(64) |
| 状态/类型 | tinyint(4),对应枚举 code |
| 金额 | bigint(20),单位分;或 decimal(12,2) |
| URL / 图片地址 | varchar(512) |
| 备注/描述 | varchar(256) / varchar(1024),超长用 text 拆扩展表 |
| 禁项 | 要求 |
|---|---|
| SELECT * | 禁止;显式列出所需字段 |
| 循环内查库(N+1) | 禁止在 for / while / stream 等循环代码块内查询数据库(逐条 select/update/insert);改为一次性批量查询后在内存组装 |
| 复杂 SQL / 多表 JOIN | 尽量减少复杂 SQL 查询;关联查询 JOIN 表数原则上不超过 5 张,超过 5 张必须拆分为多次查询 + 内存组装 |
| 大表全表查询 | 大数据量表(订单、日志、流水等)禁止无 WHERE 条件或条件不命中索引的全表查询;必须带索引条件并限制返回行数 |
| 深分页 OFFSET | 大表翻页用游标:WHERE id > #{lastId} LIMIT n |
| 无索引条件查询 | WHERE / ORDER BY 字段必须命中索引,上线前 EXPLAIN 验证 |
| 左模糊 LIKE '%xxx' | 不走索引;需求存在时用 ES 或全文索引方案 |
| 批量操作无上限 | foreach 单批 ≤ 500 条,大批量分批提交 |
// 错误:循环内逐条查库(N+1 问题)
for (OrderItem item : items) {
ProductInfo p = productMapper.selectById(item.getProductId()); // 禁止:循环代码块内查询数据库
}
// 正确:一次批量查询 + 内存组装
List<Long> productIds = items.stream().map(OrderItem::getProductId).collect(Collectors.toList());
Map<Long, ProductInfo> productMap = productMapper.selectBatchByIds(productIds)
.stream().collect(Collectors.toMap(ProductInfo::getId, Function.identity()));
// 错误:一张 SQL 关联 7 张表,难以维护、易超时,禁止
SELECT o.*, u.*, p.*, c.*, s.*, a.*, r.*
FROM order_info o
JOIN user_info u ON o.user_id = u.id
JOIN product_info p ON o.product_id = p.id
// ... 继续 JOIN 至 7 张表(超过 5 张,禁止)
// 正确:拆分为多次单表/少量关联查询,内存组装结果
OrderInfo order = orderMapper.selectByOrderNo(orderNo);
UserInfo user = userMapper.selectById(order.getUserId());
ProductInfo product = productMapper.selectById(order.getProductId());
// 错误:大表无 WHERE 条件的全表查询,禁止
SELECT * FROM order_info; // 全表扫描,大表直接拖垮 DB
// 正确:带索引条件 + 限制返回行数
SELECT id, order_no, order_status FROM order_info
WHERE user_id = #{userId} AND create_time >= #{startTime}
ORDER BY id DESC LIMIT 50;
必须所有接口统一返回 Result<T> 结构,禁止 Controller 各写各的返回格式。
{
"code": 0, // 0=成功,非0=错误码(见12.3错误码分段)
"message": "success", // 提示信息,可直接展示给用户
"data": { } // 业务数据,失败时为 null
}
Result 定义在 common 模块,全工程唯一,禁止每个服务自定义一套;data = { list, total, pageNum, pageSize };Result.success(data),失败抛 BusinessException 由全局异常处理器转 Result,Controller 内禁止手写 try-catch 拼 error 返回。必须使用 @RestControllerAdvice 全局异常处理器统一捕获,Controller / Service 内禁止散落 try-catch 拼 JSON。
| 类型 | 说明 | 处理方式 |
|---|---|---|
| BusinessException | 可预期业务异常(参数错、状态非法) | 抛出 → 全局捕获 → 返回错误码 + 友好提示 |
| ValidationException | 参数校验异常 | 由 @Valid 触发,全局捕获返回字段级提示 |
| ThirdPartyException | 第三方/RPC 调用失败 | 封装为业务异常,核心链路配降级 |
| 其他 RuntimeException | 不可预期系统异常 | 全局兜底,记 ERROR 日志,返回"系统繁忙" |
log.error("msg:{}", ctx, e);catch (Exception e) 后吞掉不处理、不打日志;| 码段 | 含义 | 示例 |
|---|---|---|
| 0 | 成功 | — |
| 1xxxx | 通用错误(参数/鉴权/限流) | 10001 参数缺失 |
| 2xxxx | 用户域 | 20001 用户不存在 |
| 3xxxx | 订单域 | 30001 订单状态非法 |
| 4xxxx | 支付域 | 40001 支付超时 |
| 5xxxx | 第三方服务 | 50001 短信通道失败 |
| 9xxxx | 系统级 | 99999 系统繁忙 |
@Slf4j 注解声明;必须禁止 System.out.println;| 级别 | 使用场景 |
|---|---|
| ERROR | 系统异常、影响业务的错误、第三方调用失败 |
| WARN | 可恢复异常、降级、容错、敏感操作警告 |
| INFO | 关键业务节点(下单、支付、登录),带业务上下文 |
| DEBUG | 调试细节,生产默认关闭;禁止循环内打 INFO |
// 错误:拼接 + 无上下文 + 丢堆栈
log.info("下单成功");
log.error("错误:" + e.getMessage());
// 正确:占位符 + 业务标记 + 上下文 + 完整堆栈
log.info("[ORDER_CREATE] userId={}, productId={}, amount={}", userId, productId, amount);
log.error("[ORDER_CREATE] create failed, dto={}", dto, e);
[业务标记] 前缀,便于按场景检索;new Thread(),统一通过 ThreadPoolExecutor 显式创建,禁止 Executors.newFixedThreadPool / newCachedThreadPool(无界队列 OOM 风险);order-pay-pool-%d),便于线程栈排查;ConcurrentHashMap 等并发容器;SimpleDateFormat 换 DateTimeFormatter。ThreadPoolExecutor executor = new ThreadPoolExecutor(
4, 8, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000),
new ThreadFactoryBuilder().setNameFormat("order-pay-pool-%d").build(),
new ThreadPoolExecutor.CallerRunsPolicy());
UPDATE ... SET version = version + 1 WHERE id = ? AND version = ?。@RequiresPermissions("order:cancel");// 错误:只校验登录,未校验归属 → 水平越权
public OrderDetailVO getOrderDetail(String orderNo) {
return orderMapper.selectByOrderNo(orderNo); // 任意登录用户可查任意订单
}
// 正确:归属校验
public OrderDetailVO getOrderDetail(Long userId, String orderNo) {
OrderInfo order = orderMapper.selectByOrderNo(orderNo);
if (order == null || !userId.equals(order.getUserId())) {
throw new BusinessException(OrderErrorCode.ORDER_NOT_EXIST);
}
return convert(order);
}
| 风险点 | 防护要求 |
|---|---|
| SQL 注入 | MyBatis 统一 #{} 预编译;${} 禁用(动态表名/排序字段除外,且必须白名单校验) |
| XSS | 入参富文本白名单过滤,输出转义 |
| 文件上传 | 类型/大小校验、重命名存储、上传与访问域名隔离 |
| 反序列化 | 禁止反序列化不可信数据,统一 JSON |
| 命令注入 | 禁止 Runtime.exec 拼接外部输入 |
原类名 + Test(OrderServiceImplTest);createOrder_shouldThrow_whenProductOffShelf;[订单] feat: 新增取消接口(含单测)。| 要求 | 说明 |
|---|---|
| 每日必须提交 | 代码每日必须提交 Git,禁止长期本地囤积;下班前将当日可编译通过的代码推送远端 |
| 提交粒度 | 按功能点提交,一次提交对应一个明确改动;禁止一天改动堆成一个大提交 |
| 可编译 | 提交到共享分支(dev/release)的代码必须可编译、可启动 |
备注必须写清修改内容,格式:[模块] 类型: 修改内容
| 类型 | 含义 | 示例 |
|---|---|---|
| feat | 新功能 | [订单] feat: 新增订单创建接口 |
| fix | 缺陷修复 | [订单] fix: 修复订单金额计算溢出问题 |
| refactor | 重构 | [用户] refactor: 抽离手机号校验公共方法 |
| db | 数据库变更 | [订单] db: order_info 新增支付渠道字段(附DDL) |
| config | 配置变更 | [订单] config: 更新nacos订单超时配置(附配置文件) |
// 错误:无法追溯
git commit -m "修改"
git commit -m "fix bug"
git commit -m "更新代码"
// 正确:模块 + 类型 + 具体内容
git commit -m "[订单] feat: 新增订单取消接口,超时未支付自动取消"
git commit -m "[用户] fix: 修复登录token刷新并发覆盖问题"
必须凡是涉及数据库修改(新增表、加字段、改索引等),DDL 脚本必须与代码同一次提交入库:
doc/sql/(或 sql/ddl/)目录,按日期 + 序号命名:20260824_01_add_pay_channel_to_order_info.sql-- 20260824_01_add_pay_channel_to_order_info.sql
-- 变更:order_info 新增支付渠道字段
ALTER TABLE `order_info`
ADD COLUMN `pay_channel` tinyint(4) NOT NULL DEFAULT 0 COMMENT '支付渠道 0-微信 1-支付宝 2-余额' AFTER `order_status`;
-- 回滚
ALTER TABLE `order_info` DROP COLUMN `pay_channel`;
必须凡是使用 Nacos 配置中心,修改配置后必须同步提交配置文件到代码库:
doc/nacos/{dev|test|prod}/xxx-service.yaml,与 Nacos 控制台内容保持一致config 类型与改动项必须AI 编写新功能点时,必须先生成开发文档,人工确认文档没问题后,再生成代码。禁止跳过文档直接产出代码。
需求输入
│
▼
① AI 生成开发文档(接口设计、表结构、业务流程、影响范围)
│
▼
② 人工评审开发文档 ── 不通过 ──→ 补充/修正文档,重新评审
│ 通过
▼
③ AI 按已确认的文档生成代码
│
▼
④ 人工 Code Review + 测试验证
| 章节 | 要求 |
|---|---|
| 功能概述 | 背景、目标、用户故事 |
| 接口设计 | URL、方法、入参/出参字段表、错误码 |
| 数据库设计 | 新表 DDL / 变更字段 DDL(含回滚语句,遵循第九条规范) |
| 业务流程 | 核心流程步骤说明(与代码 STEP 注释一一对应) |
| 枚举与状态 | 新增/变更的枚举定义(遵循第八条规范) |
| 影响范围 | 涉及的模块、上下游接口、Nacos 配置变更项 |
必须AI 修改已有功能时,必须先修改开发文档,文档确认没问题后,再修改代码,保证文档与代码始终一致。
必须AI 编写的开发文档与代码一并提交到 Git,纳入版本管理,与代码同仓库、同分支、同节奏。
| 类型 | 路径约定 |
|---|---|
| 功能开发文档 | doc/design/{模块}_{功能}_{日期}.md,例:doc/design/order_cancel_20260824.md |
| 数据库 DDL | doc/sql/(按第十九条规范,与文档引用的 DDL 为同一份) |
| Nacos 配置归档 | doc/nacos/{env}/(按第十九条规范) |
[订单] feat: 新增订单取消接口(含开发文档 doc/design/order_cancel_20260824.md)必须项目部署必须编写部署文档,与项目同仓库归档(doc/deploy/{项目名}_{环境}_部署文档.md)。部署文档是项目可交付的一部分:任何一名新成员仅凭该文档即可完成部署、排障与恢复,禁止"只在部署者脑中"的隐性部署知识。
| 章节 | 要求 |
|---|---|
| 项目部署路径 | 项目(应用包、前端资源)在服务器上的完整部署路径,例:/opt/java/app.jar、/opt/web/dist;注明所属服务器 IP 与用途 |
| 组件部署路径 | 所有依赖组件(Nginx、MySQL、Redis、MQ、JDK、Nacos 等)的安装/数据/配置文件路径,例:/etc/nginx/nginx.conf、/etc/redis.conf、/etc/my.cnf、docker 容器名 |
| 版本号 | 项目版本(jar 版本 / 镜像 tag / 分支 commit)与各组件版本(JDK、MySQL、Redis、Nginx、Nacos),升级须同步更新 |
| 启动/停止命令 | 项目和各组件的启动、停止、重启、查看状态、查看日志命令;docker 部署写明容器名与 docker run 完整参数或 compose 文件路径 |
| 账号密码 | 服务器 SSH 账号、数据库账号密码、Redis 密码、中间件控制台账号等;敏感信息在文档中脱敏,明文密码存放于受控的密码管理渠道,文档中写明获取方式 |
| 注意事项 | 部署前置条件(DDL 执行顺序、Nacos 配置项)、端口开放、防火墙、启动依赖顺序、已知坑与回滚方案 |
# {项目名} 部署文档
## 1. 基本信息
- 服务器:{IP}(用途:生产/测试)
- 项目版本:v1.2.0(分支 master / commit abc1234)
- 组件版本:JDK 1.8 / MySQL 8.0 / Redis 6.2 / Nginx 1.24 / Nacos 2.2
## 2. 部署路径
| 对象 | 路径 | 说明 |
|---|---|---|
| 应用 jar | /opt/java/app.jar | Spring Boot 应用 |
| 前端资源 | /opt/web/dist | Vue 构建产物 |
| Nginx 配置 | /etc/nginx/nginx.conf | 反向代理 |
| MySQL | docker 容器 mysql-8.0,数据 /data/mysql | 持久化目录 |
| Redis | docker 容器 redis,配置 /etc/redis.conf | 密码见第5节 |
## 3. 启动与停止
- 应用启动:cd /opt/java && nohup java -jar app.jar --spring.profiles.active=prod > app.log 2>&1 &
- 应用停止:ps -ef | grep app.jar | grep -v grep | awk '{print $2}' | xargs kill
- 组件重启:docker restart mysql-8.0 / docker restart redis
- 日志查看:tail -f /opt/java/app.log;docker logs -f --tail 200 mysql-8.0
## 4. 端口与依赖
- 端口:80(Nginx)、8080(应用)、3306(MySQL)、6379(Redis)
- 启动顺序:MySQL → Redis → Nacos → 应用 → Nginx
## 5. 账号密码(脱敏,明文见密码管理渠道 {渠道名})
- SSH:devops / ********
- MySQL:root / ********(业务库 {db_name})
- Redis:requirepass ********
## 6. 注意事项
- 部署前先执行 doc/sql/ 下新增 DDL(按文件名日期顺序)
- 新增 Nacos 配置项需同步更新 doc/nacos/prod/ 归档
- 回滚:保留上一版本 app.jar.bak,替换后重启即可
| 序号 | 检查项 | 级别 |
|---|---|---|
| 一、工程结构 | ||
| 1 | Controller 无业务逻辑;业务逻辑在 Service;SQL 在 Mapper | 必须 |
| 二、编码规范 | ||
| 2 | 类名、实体类名为标准大驼峰,见名知意 | 必须 |
| 3 | 方法名能表达意图,无 handle/query1 类无意义命名 | 必须 |
| 4 | 实体类有类注释 + 全部字段注释,状态字段标注枚举取值 | 必须 |
| 5 | 方法有完整 Javadoc;核心业务有 STEP 分步流程注释 | 必须 |
| 6 | 单方法体 ≤ 300 行;重复代码已抽公共方法 | 必须 |
| 7 | 无魔法值;状态/类型已收口到枚举类 | 必须 |
| 三、数据库规范 | ||
| 8 | 建表 UTF-8(utf8mb4)、无外键、字段长度显式、主键非自增(雪花ID) | 必须 |
| 9 | 无 SELECT *、无循环内查库、JOIN 不超过 5 张表、大表禁止全表查询、深分页用游标、条件命中索引 | 必须 |
| 四、接口与可观测 | ||
| 10 | 接口统一返回 Result<T>,分页结构统一 | 必须 |
| 11 | 异常由全局处理器统一捕获,错误码分段,无散落 try-catch | 必须 |
| 12 | 日志占位符写法、带业务标记与上下文、敏感字段脱敏 | 必须 |
| 五、稳定性与性能 | ||
| 13 | 无裸 new Thread,线程池命名 + 显式参数 + 有界队列 | 必须 |
| 14 | 创建类接口 / 回调 / MQ 消费已实现幂等 | 必须 |
| 六、安全规范 | ||
| 15 | 接口已鉴权,按 ID 操作资源已做归属校验(防越权) | 必须 |
| 16 | SQL 全部 #{} 预编译,${} 动态字段已白名单校验 | 必须 |
| 七、测试规范 | ||
| 17 | 核心业务有单测,覆盖率 ≥ 70%,随代码同提交 | 必须 |
| 八、版本管理与 AI 协作 | ||
| 18 | 每日代码已提交 Git,commit 备注写明修改内容 | 必须 |
| 19 | 数据库变更有 DDL 脚本同步提交(含回滚语句) | 必须 |
| 20 | Nacos 配置变更已同步归档配置文件(敏感项脱敏) | 必须 |
| 21 | AI 新功能:开发文档已人工确认后才生成的代码 | 必须 |
| 22 | AI 修改功能:开发文档已先于代码更新并确认,文档与实现一致 | 必须 |
| 九、部署规范 | ||
| 23 | 部署文档完整(部署路径/组件路径/版本号/启动命令/账号密码/注意事项),结构变更时与代码同提交,密码已脱敏 | 必须 |
新功能:需求 → ① AI生成开发文档 → ② 人工确认文档 → ③ AI生成代码 → ④ Code Review → ⑤ 文档+DDL+配置+代码 一并提交 Git
修改功能:变更需求 → ① AI先改开发文档 → ② 人工确认文档 → ③ AI按文档改代码 → ④ Review核对文档与实现一致 → ⑤ 一并提交 Git