〇、阅读指南:如何使用本报告
本报告为研发团队提供两套完整的、可直接操作的 AI 开发工作流——一套用于从零开始的新项目(脚手架驱动),一套用于已有代码库的老项目维护(代码考古驱动)。每套工作流均包含完整的操作步骤、实际 Prompt 示例、工具配置和检查清单。
📖 阅读路径建议
所有人必读:第 1 节(前置判断)→ 第 2 节(脚手架体系)
正在启动新项目的团队:第 1-2 节 → Part A(第 3 节)
维护遗留系统的团队:第 1-2 节 → Part B(第 4 节)
技术管理者:全文通读 → 第 5 节(配置速查)→ 第 6 节(落地建议)
一、前置判断:5 秒分流决策
接受任何开发任务后,第一个动作不是打开 IDE,而是回答一个问题。这个问题的答案决定了你接下来几小时/几天使用完全不同的 AI 工作流。
1.1 判断标准
| 判断维度 | 🆕 新项目(Part A) | 🔧 老项目维护(Part B) |
|---|---|---|
| Git 仓库 | 新建空仓库 或 从脚手架模板克隆 | 已有仓库,含提交历史 |
| 代码基数 | 0 行(仅脚手架骨架) | 1 万 ~ 100 万+ 行 |
| AI 生成占比 | 70-90% 代码由 AI 生成 | 15-40% 仅修改区域由 AI 生成 |
| 典型场景 | 新客户项目、新产品线、独立微服务、POC | Bug 修复、功能增强、技术栈升级、性能优化 |
| 核心风险 | AI 生成的代码风格不一致 | AI 不理解历史约定、引入回归 Bug |
| 关键工具 | Claude Code(主力生成)+ open-code-review(规范守护) | DeepSeek(考古)+ Qwen(解读)+ Claude Code(精准修改) |
1.2 边界情况处理
| 场景 | 判定 | 理由 |
|---|---|---|
| 在现有项目中新增一个独立微服务模块,有自己的 build.gradle/pom.xml | Part A | 虽然仓库是老的,但模块完全独立,可以从脚手架起 |
| 从零开发但需要对接 3 个现有内部系统 | Part A | 代码库是新的,集成通过 API 契约管理 |
| 在现有模块中新增一个功能(涉及新增表 + API + 页面) | Part B | 虽然功能是新的,但代码要插入现有模块,必须遵循现有约定 |
| 将 Spring Boot 2.x 升级到 3.x | Part B | 全局变更,需理解所有受影响代码 |
| 重构一个 5000 行的 God Class | Part B | 先考古(理解所有调用方),再动手 |
二、开发脚手架体系(新项目的基础设施)
新项目工作流的起点不是空白目录,而是一个预置了团队全部约定的脚手架仓库。这是 Part A 能够高效运转的前提——没有脚手架,AI 生成的代码将缺乏一致性约束。
2.1 脚手架的四层结构
| 层次 | 名称 | 包含内容 | AI 如何使用 |
|---|---|---|---|
| L1 | 项目骨架 | 目录结构、Maven/Gradle 配置、Dockerfile、CI 流水线(.gitea/workflows/)、Helm Chart、application.yml 多环境配置、logback 配置 | Claude Code 启动时 Read 这些文件,确保生成代码的包路径、依赖版本、配置命名完全对齐 |
| L2 | 架构基类 | BaseController、BaseService、BaseEntity(含审计字段自动填充)、Result<T> 统一返回体、PageQuery 分页基类、GlobalExceptionHandler、AuthInterceptor | 生成的每个 Controller 必须继承 BaseController、每个 Service 必须继承 BaseService、返回类型必须是 Result<T>。基类 = 代码的"法律" |
| L3 | 规范文件 | CLAUDE.md(编码规范+架构约定+Git 工作流)、.claude/design-tokens.md(UI 设计规范)、checkstyle.xml / .eslintrc.js、open-code-review 规则配置 | Claude Code 自动加载 CLAUDE.md 作为系统提示。CI 阶段 open-code-review 二次校验 |
| L4 | 示例模块 | 一个完整的 UserModule(Entity → Mapper → Service → Controller → Test → Vue 页面),含 CRUD + 分页 + 权限校验的完整实现 | 开发者说"参照 UserModule 的模式实现 XxxModule",AI 自动对齐:包结构、命名风格、异常处理、测试模式 |
2.2 脚手架的三种落地形式
| 形式 | 适用团队 | 操作方式 | 优势 |
|---|---|---|---|
| Git 模板仓库 | 所有团队(推荐) | Gitea 上维护一个 spring-boot-scaffold 模板仓库,新项目通过 Gitea「使用模板」创建(仓库设置→勾选"模板仓库") | 零工具依赖、版本可追溯、PR 方式演进、代码不出企业内网 |
| Maven Archetype | 纯 Java 团队 | mvn archetype:generate 交互式生成项目 | 与 Java 工具链无缝集成 |
| 自定义 CLI | 多技术栈大团队 | scaffold create spring-boot my-project 一键生成 | 支持多技术栈、交互式选项、自动注册到 CI |
📐 脚手架的最小可行内容
如果一个团队今天还没有脚手架,一周内可以建好:
- Day 1-2:选一个最近做过的、架构最满意的项目,删除所有业务代码,保留骨架 → 这就是 L1+L2
- Day 3-4:写 CLAUDE.md(参考本知识库的 CLAUDE.md 模板)+ 配置 open-code-review → L3
- Day 5-7:在骨架中手工写一个 UserModule 的完整实现 → L4。这个动作虽然手动,但一次投入,永久复用
2.3 脚手架如何约束 AI 的代码风格
AI 的本质是"模式匹配器"。给出正确的模式,它就能稳定输出正确风格的代码。脚手架通过三种机制确保 AI 生成的代码一致:
| 机制 | 原理 | 示例 |
|---|---|---|
| 继承约束 | 基类定义了必须遵循的接口。AI 生成的类必须继承基类,自然继承了行为模式 | Controller 必须继承 BaseController → 自动获得统一的异常处理、日志格式、权限校验入口 |
| 示例对齐 | 示例模块提供了"正确答案"。AI 被要求参照示例模块的结构来生成同类代码 | "参照 UserController 的结构生成 RoleController" → 生成的代码在分页处理、参数校验、返回格式上与 UserController 一致 |
| CI 守护 | open-code-review 在 CI 阶段检查代码是否符合团队规范。不合规的代码无法合并 | 有人让 AI 写了不带 rollbackFor 的 @Transactional → open-code-review 报错 → 代码无法合并 → 开发者被迫修正 |
三、企业内部基础设施层(双轨共用底座)
在开始任何开发工作流之前,团队依赖一套内部基础设施来支撑代码管理、构建、测试、部署的全链路。以下基础设施是 Part A 和 Part B 的共用底座——没有它们,AI 工作流只能在开发者本地单机运行,无法发挥团队协作和自动化优势。
3.1 基础设施全景
3.2 Gitea — 企业内部代码托管平台
Gitea 是轻量级自托管 Git 服务,替代 GitHub/GitLab 在企业内网部署,代码不出企业网络。同时作为 AI 工作流的"协作中枢"——PR 审查、CI 触发、脚手架模板分发都围绕 Gitea 进行。
| 功能 | 在工作流中的作用 | 配置要点 |
|---|---|---|
| 脚手架模板仓库 | 维护 spring-boot-scaffold 等模板仓库。新项目通过 Gitea 的"使用模板"功能创建 |
仓库设置中勾选"模板仓库"选项;模板仓库的 README 需包含首次使用指南 |
| PR 代码审查 | 所有代码变更通过 Pull Request 提交。Gitea 的 PR 页面是 open-code-review(L1)和人工 Review(L3)的操作界面 | 分支保护规则:main 分支禁止直接 push,必须通过 PR + 至少 1 人 Approve + CI 通过 |
| CI 触发器 | Push / PR 事件触发 Gitea Actions 运行 CI 流水线(lint → test → build → deploy) | 配置文件位于 .gitea/workflows/ci.yml(语法兼容 GitHub Actions) |
| Wiki / 文档 | 每个仓库内置 Wiki,存放项目级文档(架构设计、ADR、API 文档) | Wiki 与代码仓库在同一 Gitea 实例中,权限统一管理 |
🔗 Gitea Actions CI 配置(与 GitHub Actions 兼容)
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# Job 1: 代码规范检查
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: alibaba-group/open-code-review@v1
with:
languages: java,javascript,typescript,vue
severity: error,warning
filter: changed
# Job 2: 构建 + 单元测试
build:
needs: lint
runs-on: ubuntu-latest
services:
mysql:
image: harbor.internal.com/library/mysql:8.0
env:
MYSQL_ROOT_PASSWORD: test123
steps:
- uses: actions/checkout@v4
- name: Build & Test
run: mvn -s .gitea/settings.xml clean test
# Job 3: 构建镜像 + 推送
docker:
needs: build
if: github.ref == 'refs/heads/main'
steps:
- name: Build & Push Image
run: |
docker build -t harbor.internal.com/${{ github.repository }}:latest .
docker push harbor.internal.com/${{ github.repository }}:latest
Gitea 部署与配置
| 部署方式 | 命令 | 适用场景 | 说明 |
|---|---|---|---|
| Docker(推荐) | docker run -d --name gitea -p 3000:3000 -p 2222:22 -v /data/gitea:/data gitea/gitea:latest | 10-200 人团队 | 5 分钟部署,内置 SQLite(可外挂 MySQL)。数据持久化到 /data/gitea |
| Docker Compose | gitea + mysql + redis 三容器编排(见下方完整配置) | 需要高可用的团队(>50 人) | MySQL 替代 SQLite 提升并发,Redis 加速 Session 和缓存 |
| 二进制安装 | wget dl.gitea.com/gitea/1.22/gitea-1.22-linux-amd64 && chmod +x gitea && ./gitea web | 离线环境 / 无 Docker 环境 | 单文件运行,适合在内网堡垒机上部署 |
🐳 推荐:Docker Compose 完整部署(Gitea + MySQL + Redis)
version: '3.8'
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=mysql:3306
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea123
- GITEA__server__DOMAIN=gitea.internal.com
- GITEA__server__ROOT_URL=https://gitea.internal.com
- GITEA__actions__ENABLED=true
ports:
- "3000:3000" # Web UI
- "2222:22" # SSH Git 克隆
volumes:
- /data/gitea:/data
- /etc/timezone:/etc/timezone:ro
depends_on:
- mysql
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=root123
- MYSQL_DATABASE=gitea
- MYSQL_USER=gitea
- MYSQL_PASSWORD=gitea123
volumes:
- /data/gitea-mysql:/var/lib/mysql
redis:
image: redis:7-alpine
restart: always
| 配置项 | 位置 | 建议值 | 原因 |
|---|---|---|---|
| Gitea Actions | app.ini | [actions] ENABLED = true | 启用内置 CI/CD。这是 AI 工作流自动化的核心开关——没有它,open-code-review 无法在 PR 时自动运行 |
| 分支保护 | 仓库设置 | main 分支:禁止直接 push、必须 1 人 Approve、必须 CI 通过 | 确保 AI 生成的代码必须经过审查+CI 验证才能合并 |
| 模板仓库 | 仓库设置 | 脚手架仓库勾选「模板仓库」 | 新项目可通过"使用模板"一键创建,继承全部脚手架配置 |
| Webhook | 仓库设置 | Push 事件 → 通知企业微信/钉钉 | 团队感知代码变更,特别是 AI 批量提交时避免"不知道仓库在变化" |
| Runner | Site Admin | 至少部署 2 个 Gitea Actions Runner(1 个 linux/amd64 + 1 个用于前端构建) | Runner 是执行 CI Job 的工作节点。注册命令:./act_runner register --instance https://gitea.internal.com --token <TOKEN> |
3.3 内部制品仓库(Nexus / Harbor / Verdaccio)
| 仓库类型 | 推荐产品 | 作用 | 配置要点 |
|---|---|---|---|
| Maven 私服 | Nexus Repository OSS | ① 缓存外部依赖(加速构建、离线可用)② 发布内部公共库(如公司自研的 common-utils)③ 避免从外网下载不可信依赖 | 脚手架 settings.xml 中配置 Nexus 镜像;mvn -s .gitea/settings.xml 指向内部私服 |
| npm 私服 | Verdaccio(npm.ycbat.com) | 缓存 npm 依赖,发布内部前端组件库 | 项目根目录 .npmrc 指向 http://npm.ycbat.com/ |
| Docker 镜像仓库 | Harbor | ① 存储 CI 构建的 Docker 镜像 ② 镜像安全扫描(Trivy)③ 作为 K8s 部署的镜像源 | CI Job 构建镜像后 docker push 到 Harbor;K8s 的 imagePullSecret 指向 Harbor |
npm 私服详解:Verdaccio vs Nexus
| 方案 | 适用规模 | 部署耗时 | 优势 | 劣势 |
|---|---|---|---|---|
| Verdaccio | 10-50 人前端团队 | 5 分钟 | 零配置、轻量(Node.js 单进程)、支持代理阿里云 npm 镜像 + 私有包发布、自带 Web UI 浏览包 | 只管理 npm,不覆盖 Maven/Docker 等 |
| Nexus Repository | 全公司统一制品管理 | 30 分钟 | 一站式管理 Maven + npm + Docker + PyPI + Helm、LDAP 集成、权限精细控制 | 资源消耗大(最低 2GB 内存)、配置复杂 |
📦 Verdaccio 安装与配置(推荐小团队快速起步)
npm install -g verdaccio
verdaccio # 启动 → http://localhost:4873
# 方式二:Docker 部署(推荐,适合团队共享)
docker run -d --name verdaccio \
-p 4873:4873 \
-v /data/verdaccio/storage:/verdaccio/storage \
-v /data/verdaccio/config:/verdaccio/conf \
verdaccio/verdaccio
# 方式三:Docker Compose(含 Nginx 反代 + HTTPS)
# 见下方完整配置
🐳 Verdaccio Docker Compose 生产部署(含 HTTPS)
version: '3.8'
services:
verdaccio:
image: verdaccio/verdaccio:latest
container_name: verdaccio
ports:
- "4873:4873"
volumes:
- /data/verdaccio/storage:/verdaccio/storage
- /data/verdaccio/conf:/verdaccio/conf
- ./config.yaml:/verdaccio/conf/config.yaml:ro
# Verdaccio 配置文件 config.yaml
storage: /verdaccio/storage
uplinks:
npmjs:
url: https://registry.npmmirror.com/ # 阿里云镜像
packages:
'@mycompany/*':
access: $all
publish: $authenticated # 仅登录用户可发布私有包
'**':
access: $all
proxy: npmjs # 其他包全部代理到阿里云镜像
如何使用 npm 私服
| 步骤 | 操作 | 命令/配置 | 效果 |
|---|---|---|---|
| 1 | 配置私服地址 | 项目根目录创建 .npmrc:registry=http://npm.ycbat.com/或全局设置: npm config set registry http://npm.ycbat.com/ |
此后 npm install 全部走过私服,首次从阿里云镜像拉取并缓存,后续从私服秒级获取 |
| 2 | 发布私有包 | npm login --registry=http://npm.ycbat.com/npm publish --registry=http://npm.ycbat.com/ |
公司内部组件库(如 @mycompany/ui-kit、@mycompany/utils)发布到私服,全员 npm install 即可使用,告别 npm link 和 file:../ |
| 3 | 脚手架预置 | 在脚手架模板仓库的根目录预置 .npmrc 文件,指向内部 Verdaccio(npm.ycbat.com) |
新项目克隆后直接 npm install,无需每个开发者手动配置。这是新项目 Part A 开箱即用的基础保障 |
🔑 npm 私服在 AI 工作流中的实际价值
场景 1 — 新项目 Part A:Claude Code 生成前端代码,引入 Element Plus、ECharts 等依赖。安装时所有包从内网 Verdaccio 缓存拉取,npm install 从 3 分钟缩短到 15 秒。
场景 2 — 内部组件复用:团队自研的通用组件(权限选择器、审批流面板)发布为 @mycompany/* 包。Claude Code 生成新模块时可以直接 import:import { ApprovalPanel } from '@mycompany/approval-widget',不再需要复制粘贴代码。
场景 3 — CI 加速:Gitea Actions 的 CI Job 中 npm ci 从私服拉取,速度比从外网快 10-50 倍。对于频繁触发 CI 的新项目(每次 push 都跑),累计节省时间显著。
3.4 开发数据库环境
| 环境 | 用途 | 配置 | AI 工作流关联 |
|---|---|---|---|
| 本地开发库 | 开发者本机测试 | Docker Compose 一键启动(MySQL + Redis),数据目录挂载到本地。docker-compose -f .gitea/dev-services.yml up -d |
Claude Code 执行 mvn test 时连接此数据库。脚手架自带 dev-services.yml |
| CI 测试库 | Gitea Actions 中运行集成测试 | Gitea Actions 的 services 块定义(临时容器,Job 结束后销毁)。每个 PR 独立创建 |
open-code-review 通过后自动触发。数据库初始数据来自 Flyway/Liquibase 迁移脚本 |
| 共享测试库 | 测试环境持久化数据库 | 部署在 K8s 测试 Namespace 中的 StatefulSet。含脱敏的生产数据子集(从生产库脱敏导入) | E2E 测试和手工验收时使用。Claude Code 可连接此库进行"真实数据下的查询验证" |
🐳 脚手架中的 dev-services.yml(示例)
version: '3.8'
services:
mysql:
image: harbor.internal.com/library/mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: dev123
MYSQL_DATABASE: srm_dev
ports: ["3306:3306"]
volumes: ["./.gitea/init.sql:/docker-entrypoint-initdb.d/init.sql"]
redis:
image: harbor.internal.com/library/redis:7-alpine
ports: ["6379:6379"]
minio:
image: harbor.internal.com/library/minio:latest
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
ports: ["9000:9000", "9001:9001"]
开发者克隆项目后只需一条命令:docker compose -f .gitea/dev-services.yml up -d,即可获得完整的本地开发环境。这是新人 10 分钟上手的基础保障。
3.5 基础设施在双轨工作流中的角色
| 基础设施 | 🆕 新项目(Part A)中的角色 | 🔧 老项目(Part B)中的角色 |
|---|---|---|
| Gitea | ① 从模板仓库创建新项目 ② 脚手架代码的版本控制 ③ PR 审查 + CI 自动触发 | ① 分析 Commit 历史(考古 L2 的数据源)② 精确的 Blame 追溯 ③ PR 中对比新旧行为 |
| Gitea Actions | 脚手架自带的完整 CI 流水线(lint → test → build → deploy),从第一次提交即生效 | 在现有 CI 中增量添加 open-code-review 步骤。老项目 CI 可能用 Jenkins,需做适配 |
| Nexus | 脚手架 pom.xml 已配置 Nexus 地址。AI 生成代码时引入的依赖从 Nexus 拉取,确保版本受控 | 老项目 pom.xml 可能直连 Maven Central——修改为走 Nexus 代理,增加私服缓存和版本管控 |
| Harbor | CI 构建的镜像推送到 Harbor,K8s 从 Harbor 拉取部署 | 老项目可能用的是手动 docker save/load 方式——引入 Harbor 实现标准化镜像管理 |
| 开发数据库 | 脚手架自带 Flyway 迁移脚本 + dev-services.yml,本地环境和 CI 环境一致 |
老项目的数据库可能没有版本管理(Flyway/Liquibase)——考古阶段需要导出当前 Schema 作为基线 |
| VPN / 内网 | 脚手架中配置的所有内部地址(Gitea/Nexus/Harbor)均通过内网访问。VPN 确保远程办公可达 | DeepSeek/Qwen 调用的 API Key 和内部 LLM 网关地址只能在内网访问。代码分析不离开内网 |
⚠️ 老项目接入基础设施的常见阻力与对策
阻力 1:"老项目的数据库没有 Flyway,Schema 是手管的" → 对策:考古阶段用 mysqldump --no-data 导出当前 Schema 作为基线 V1__baseline.sql,后续变更用 Flyway 管理。不需要一次性改造全部历史。
阻力 2:"老项目用的是 Jenkins,不是 Gitea Actions" → 对策:不需要替换。在 Jenkinsfile 中新增一个 Stage 调用 open-code-review。核心是"CI 中有自动审查",不是"必须用某个 CI 工具"。
阻力 3:"老项目的依赖直接从 Maven Central 拉,没有 Nexus" → 对策:配置 Nexus 为 Mirror Of Central(代理模式)——对老项目透明,不需要改 pom.xml,只要改 settings.xml。
🆕 Part A:新项目开发工作流(脚手架驱动)
以下是从脚手架初始化到部署上线的完整 6 步工作流。每一步都包含操作指南、AI Prompt 示例、预期产出和检查点。整套流程以"供应商管理系统(SRM)"为实操案例贯穿始终。
A.1 脚手架初始化(5 分钟)
| 步骤 | 操作 | 工具 | 耗时 |
|---|---|---|---|
| 1 | 从团队 Gitea 模板仓库创建新项目:在模板仓库页面点击「使用模板」→ 填入新项目名称 → 自动生成新仓库(或 git clone 模板仓库后删除 .git 重新 init) | Gitea / Git CLI | 2 分钟 |
| 2 | 修改项目级配置:artifact ID、application name、数据库名、K8s namespace | IDE 批量替换 | 2 分钟 |
| 3 | 验证脚手架完整性:mvn clean test(或等效命令)确保 L4 示例模块的测试能跑通 | Maven / Gradle | 1 分钟 |
✅ 检查点
- ☑
mvn clean test通过(脚手架自带测试全绿) - ☑ CLAUDE.md 已存在于项目根目录
- ☑ .gitea/workflows/ci.yml 已就绪(open-code-review + 测试)
- ☑ UserModule 示例可以正常访问(/api/users 返回分页数据)
A.2 需求 → 脚手架模块映射(20-30 分钟)
这一步的核心工作是将需求文档中的功能点,映射到脚手架已有模块的扩展点。不做从零设计,做"参照+差异"分析。
💬 对 Claude Code 的 Prompt
我正在进行一个供应商管理系统(SRM)项目,需求文档在 docs/requirements/srm-v1.md。
项目已从脚手架初始化,脚手架结构参考 CLAUDE.md 和 UserModule 示例。
请帮我完成以下工作:
1. 需求模块化拆解
读取需求文档,将功能拆解为独立模块。每个模块标注:
- 是否可以直接复用脚手架模式(如 CRUD 类模块参照 UserModule)
- 是否需要新增脚手架不包含的能力(如审批流、文件上传)
- 预估需要多少 Entity / Service / Controller / 前端页面
2. 模块优先级排序
按依赖关系和交付价值排列开发顺序
3. 输出开发计划
生成 docs/plan/module-plan.md,包含:
- 模块清单 + 复用度评估 + 开发顺序
- 每个模块与 UserModule 的差异点(只需描述"不同之处")
- 需要脚手架新增的通用能力(如审批流引擎)
请先进入 Plan Mode。
✅ 预期产出示例(SRM 项目)
| 模块 | 复用度 | 参照 | 差异点 | 优先级 |
|---|---|---|---|---|
| 供应商主数据 | 90% | UserModule | 多一个"供应商分类"字段、营业执照附件上传 | P0 |
| 供应商评估 | 60% | UserModule + 自定义评分逻辑 | 评分模型(KPI 加权)、评估历史时间线 | P1 |
| 采购询价 | 30% | 需新增审批流 | 询价单→报价→比价→审批流程、报价附件对比 | P1 |
| 合同管理 | 50% | UserModule + 审批流 | 合同模板、电子签章集成、到期提醒 | P2 |
A.3 Plan Mode:生成编码计划(15 分钟/模块)
对每个模块,在动手编码前,必须先让 Claude Code 输出 Plan 并获得确认。Plan 阶段不写代码,只设计"要写哪些文件、每个文件做什么"。
💬 对 Claude Code 的 Prompt(以"供应商主数据"模块为例)
实现供应商主数据模块(FR-SUP-001),参照 UserModule 的模式。
差异点:
1. Supplier 比 User 多一个 supplierCategory(供应商分类)字段
2. 需要支持营业执照附件上传(脚手架目前没有文件上传能力)
3. 查询接口需要按供应商分类和状态筛选
参照文件:
- entity/User.java
- mapper/UserMapper.java
- service/UserService.java
- controller/UserController.java
- vue/views/user/UserList.vue
请进入 Plan Mode,告诉我你计划创建/修改哪些文件,
每个文件的作用是什么。先用 Read 工具读取参照文件,
然后输出计划。
✅ Claude Code Plan 输出示例
Step 1 - 数据层:
READ: entity/User.java, entity/BaseEntity.java
WRITE: entity/Supplier.java (extends BaseEntity, add supplierCategory)
WRITE: mapper/SupplierMapper.java (extends BaseMapper<Supplier>)
WRITE: src/main/resources/db/migration/V1.1__supplier.sql
Step 2 - 业务层:
READ: service/UserService.java
WRITE: service/SupplierService.java (extends BaseService<Supplier>)
WRITE: dto/SupplierQuery.java (extends PageQuery, add category/status)
WRITE: dto/SupplierDTO.java
Step 3 - 接口层:
READ: controller/UserController.java
WRITE: controller/SupplierController.java (extends BaseController)
接口: GET /api/suppliers (分页), GET /api/suppliers/{id},
POST /api/suppliers, PUT /api/suppliers/{id}, DELETE /api/suppliers/{id}
Step 4 - 文件上传:
脚手架缺少文件上传能力。计划:
WRITE: config/FileUploadConfig.java
WRITE: util/FileUploadUtil.java
WRITE: controller/FileController.java
(此为通用能力,放在 common 包下,未来其他模块可复用)
Step 5 - 前端:
READ: vue/views/user/UserList.vue
WRITE: vue/views/supplier/SupplierList.vue
WRITE: vue/views/supplier/SupplierForm.vue
WRITE: vue/api/supplier.js
Step 6 - 测试:
READ: test/.../UserServiceTest.java
WRITE: test/.../SupplierServiceTest.java
WRITE: test/.../SupplierControllerTest.java
涉及文件: 14 个文件(10 新 + 4 读)
预计 Claude Code 编码时间: 20-25 分钟
确认后我开始执行。是否需要调整?
A.4 全量代码生成(20-30 分钟/模块)
Plan 确认后,Claude Code 按计划逐文件生成代码。开发者在此阶段的核心职责是引导方向,而非逐行审查。
| 动作 | 不好的说法 | 好的说法 |
|---|---|---|
| 引用基类 | "写个 SupplierController" | "写 SupplierController,继承 BaseController,返回类型用 Result<T> 包装,异常不要 try-catch(交给 GlobalExceptionHandler)" |
| 给出参照 | "加个供应商列表页面" | "加 SupplierList.vue,表格列、搜索栏、分页组件的用法参照 UserList.vue 的写法,用相同的 <page-table> 组件" |
| 边界前置 | "供应商分类用下拉框" | "供应商分类用下拉框,数据从字典表 sys_dict 的 supplier_category 类型加载。下拉框组件参照 UserForm.vue 中角色选择器的用法" |
| 纠偏 | "这个不对,重写" | "我看到 SupplierController 里你手动写了 try-catch——基类 BaseController 已经统一处理了异常,请去掉这些 try-catch,让它抛出去给 GlobalExceptionHandler" |
⚠️ 新项目编码阶段的常见陷阱
陷阱 1:AI 绕过基类。Claude Code 有时会"忘记"继承 BaseController/BaseService,自己写一套。开发者发现后应立即纠正:"请继承 BaseController,不要自己写异常处理"。纠正 2-3 次后,AI 会形成习惯。
陷阱 2:AI 发明新的返回格式。脚手架统一用 Result<T>,但 AI 可能返回 Map 或自定义对象。纠正方式:"所有接口返回值必须是 Result<T>,参照 UserController 的写法"。
陷阱 3:过度生成。AI 有时会在一个模块中加入不属于该模块的功能。纠正方式:"这个功能属于下一个模块,现在只需要实现 FR-SUP-001 范围的代码"。
示例:Claude Code 生成的 SupplierController.java
@RestController
@RequestMapping("/api/suppliers")
@Slf4j
@RequiredArgsConstructor
public class SupplierController extends BaseController {
private final SupplierService supplierService;
@GetMapping
public Result<PageResult<SupplierDTO>> list(@Valid SupplierQuery query) {
return Result.success(supplierService.page(query));
}
@GetMapping("/{id}")
public Result<SupplierDTO> getById(@PathVariable Long id) {
return Result.success(supplierService.getDetailById(id));
}
@PostMapping
public Result<Long> create(@Valid @RequestBody SupplierCreateDTO dto) {
return Result.success(supplierService.create(dto));
}
@PutMapping("/{id}")
public Result<Void> update(@PathVariable Long id, @Valid @RequestBody SupplierUpdateDTO dto) {
supplierService.update(id, dto);
return Result.success();
}
} // 注意:无 try-catch(由 BaseController 的 GlobalExceptionHandler 统一处理)
// 注意:所有返回值用 Result<T> 包装(与 UserController 完全一致)
// 注意:分页查询用 SupplierQuery extends PageQuery(与 UserQuery 模式一致)
A.5 测试生成与代码审查(15 分钟/模块)
| 步骤 | 操作 | 工具 |
|---|---|---|
| 1. 生成测试 | 对 Claude Code 说:"为 SupplierService 生成单元测试,参照 UserServiceTest 的风格。覆盖:正常 CRUD、参数校验失败、供应商名称重复、分类不存在" | Claude Code |
| 2. 运行测试 | Claude Code 自动执行 mvn test -pl supplier,验证生成的测试通过 | Maven |
| 3. L1 审查 | git push → CI 自动触发 open-code-review。检查代码是否符合阿里规约+团队自定义规则 | open-code-review (CI) |
| 4. L2 审查 | 对 Claude Code 说:"/code-review,审查本次 Supplier 模块的 diff。重点关注:是否绕过了基类、是否有 SQL 注入风险、文件上传的大小限制是否合理" | Claude Code |
✅ 新项目代码审查的特殊关注点
- ☑ 每个 Controller 是否继承了 BaseController?
- ☑ 每个 Service 是否继承了 BaseService?
- ☑ 所有接口返回值是否使用 Result<T>?
- ☑ 分页查询是否继承了 PageQuery?
- ☑ 新增的通用能力(如文件上传)是否放在了 common/util 包而非业务包里?
- ☑ 数据库 DDL 的命名风格是否与脚手架现有表一致(下划线、create_time、update_time、is_deleted)?
A.6 部署上线 + 记忆沉淀(10 分钟)
| 步骤 | 操作 | 工具 |
|---|---|---|
| 1. CI 通过 | PR 合并到 main → Gitea Actions 自动构建 Docker 镜像并推送 Harbor → 自动部署到 K8s 测试环境 | Gitea Actions + Docker + Harbor + K8s |
| 2. 冒烟测试 | 对 Claude Code 说:"为 Supplier 模块生成一个冒烟测试 checklist,覆盖 API 接口的 happy path" | Claude Code |
| 3. API 文档 | 对 Claude Code 说:"读取 SupplierController 的注解和代码,生成 docs/api/supplier-api.md(Markdown 表格格式)" | Claude Code |
| 4. 记忆沉淀 | 对 Claude Code 说:"帮我记住:① 供应商分类从 sys_dict 表加载 ② 营业执照上传限制 5MB、仅支持 jpg/png/pdf ③ 供应商编码规则:SUP-{年份}-{4位序号}" | Claude Code Memory |
| 5. 脚手架反哺 | 如果在开发中新增了通用能力(如 FileUploadUtil),评估是否应该合并回脚手架模板仓库,让后续新项目直接受益 | 人工决策 → PR to scaffold repo |
🔑 脚手架反哺机制
新项目开发中发现的通用能力,应回流到脚手架。示例:SRM 项目开发中新增了 FileUploadUtil + FileController 作为通用文件上传方案。如果团队确认这个方案足够通用,应发 PR 合并到 spring-boot-scaffold 模板仓库。下一个新项目创建时,就自带文件上传能力了。
反哺频率:每个项目结项时,至少提出 1 个脚手架改进 PR。
🔧 Part B:老项目维护工作流(代码考古驱动)
老项目的核心挑战不是"写代码",而是"知道改哪里不会出事"。以下 5 步工作流的核心思想是:先理解、再计划、后动手、必验证。以在一个遗留 MES 系统中新增"工单审批流"为实操案例。
B.1 代码考古:理解现状(30-60 分钟)
在修改任何代码之前,必须先搞清楚三件事:目标区域现在怎么工作的、谁依赖它、有哪些隐式约定(代码里没写但大家都知道的规则)。
考古的三层递进
| 层级 | 分析内容 | 使用工具 | 具体方法 |
|---|---|---|---|
| L1 | 模块边界 | DeepSeek(零成本批量分析) | 将整个模块的 Java 文件列表发给 DeepSeek,让它分析:类之间的依赖关系、循环依赖、God Class 识别、死代码标记 |
| L2 | 业务逻辑 | Qwen(百万 Token 上下文) | 将目标模块的所有源码 + 注释 + 最近 50 条 Commit Message 一次性发给 Qwen,让它输出:模块职责描述、核心业务流程、隐式约定清单 |
| L3 | 精确理解 | Claude Code | Read 目标文件和所有调用方/被调用方文件,进行精确的代码级理解。输出:修改影响分析报告 |
🔍 DeepSeek 考古 Prompt(L1)
你是一位 Java 遗留系统分析专家。以下是 MES 系统中"工单管理"模块
(com.xxx.mes.workorder)下的所有 Java 文件列表:
[列出所有 .java 文件的完整路径,约 30-80 个文件]
请分析:
1. 模块依赖图:这个模块依赖了哪些其他模块?被哪些模块依赖?
2. 循环依赖:有没有 A→B→A 的循环?
3. God Class:有没有超过 500 行的类?标注其职责是否过于臃肿
4. 死代码:有没有明显不再使用的类/方法?(根据命名判断)
5. 重构优先级:如果只能改一个类来改善可维护性,改哪个?
不需要读取文件内容,仅根据文件路径和类名分析。
📖 Qwen 深层解读 Prompt(L2)
你是一位资深 MES 系统架构师。以下是一个遗留 MES 系统"工单管理"模块
的完整源码和最近提交历史。请通读后回答:
1. 模块职责:这个模块到底负责什么?(用一段话总结)
2. 核心流程:工单从创建到关闭经历了哪些状态?
状态转换的触发条件是什么?
3. 隐式约定:代码中有哪些"大家都懂但没写文档"的规则?
(例如:工单状态字段虽然存的是 String,但只有 4 个合法值)
4. 已知坑点:从 Commit Message 中分析,最近修复了哪些 Bug?
这些 Bug 的根因是什么?有没有反复出现的模式?
[粘贴全部源码 + Commit 历史]
Claude Code 精确理解(L3)
💬 对 Claude Code 的精确理解 Prompt
我需要在这个遗留 MES 系统的工单模块中新增审批流功能。
在我动手之前,请帮我做一次"修改前影响分析":
1. READ: com/xxx/mes/workorder/entity/WorkOrder.java
2. READ: com/xxx/mes/workorder/service/WorkOrderService.java
3. READ: com/xxx/mes/workorder/controller/WorkOrderController.java
4. 搜索所有引用 WorkOrder.status 字段的代码
5. 搜索所有调用 WorkOrderService.updateStatus() 方法的代码
6. 搜索项目中是否已有 Flowable/Activiti 依赖
输出:
- 现状描述:工单模块现在的状态流转逻辑
- 调用方清单:所有会修改工单状态的入口(Controller/定时任务/消息监听器)
- 风险点:修改状态流转逻辑后,哪些地方可能被破坏?
- 改造方案:如何以最小侵入性加入审批流?
请先 Read 所有相关文件,然后输出分析报告到 docs/impact/approval-flow.md
B.2 影响分析:修改范围评估(20 分钟)
| 分析维度 | 内容 | 示例(MES 工单审批流) |
|---|---|---|
| 修改文件清单 | 需要改哪些文件,每个文件的改动原因 | WorkOrder.java(新增 2 个状态值)、WorkOrderService.java(修改 updateStatus 方法)、新增 ApprovalService.java、新增 1 张审批记录表 |
| 调用方影响 | 改了方法签名/行为后,哪些调用方需要适配 | WorkOrderController.completeWorkOrder() → 改为提交审批而非直接完成;ScheduledTasks.autoCloseExpiredOrders() → 定时任务需要跳过"审批中"的工单 |
| 数据库影响 | 新增/修改表、是否影响现有查询 | 新增 approval_record 表;work_order 表新增 process_instance_id 字段(可为 null,兼容旧数据);无现有查询受影响 |
| API 兼容性 | 是否改变现有 API 的请求/响应格式 | POST /api/workorder/{id}/complete → 语义变更(从"直接完成"变为"提交审批")。建议新增 POST /api/workorder/{id}/submit-approval,保留旧接口兼容 |
| 测试影响 | 哪些现有测试可能失败 | WorkOrderServiceTest.testCompleteWorkOrder() → 现在不会直接改变状态,需更新测试断言 |
⚠️ 影响分析中的"红灯信号"
如果在分析中发现以下情况,不要继续往下走,先和 Tech Lead 讨论方案:
- 🔴 需要修改的调用方超过 10 个
- 🔴 目标代码没有单元测试,且无法在不改代码的情况下补充(即"不可测试代码")
- 🔴 数据库变更会影响超过 100 万行数据的表(需评估锁表风险)
- 🔴 存在未文档化的外部系统直接读数据库(可能被报表/BI 系统依赖)
B.3 增量修改:测试先行 + 小步提交(1-4 小时)
这是 Part B 最关键的步骤。铁律:先写测试,再改代码;单次 diff 不超过 200 行。
B.3.1 测试先行(保护网)
💬 对 Claude Code 说
我需要修改 WorkOrderService.updateStatus() 方法,加入审批流逻辑。
在修改之前,请先为这个方法生成完整的单元测试,覆盖:
1. 正常路径:每种合法的状态转换
2. 异常路径:非法状态转换(如"已完成→生产中")
3. 边界条件:工单不存在、状态字段为 null
限制:
- 测试必须与现有测试风格一致(使用相同的基类和 Mock 方式)
- 先用 --dry-run 模式跑一遍,确保测试能通过
- 如果现有的 updateStatus() 方法逻辑太复杂导致无法测试,
先告诉我,不要强行 Mock
请在 Plan Mode 中先展示你的测试计划。
✅ 测试先行的好处
① 如果现有代码无法测试(如 500 行的 God Method),你会先知道——这本身就是重要的风险信号
② 测试是"安全网"。后续修改代码时,mvn test 一跑就知道有没有破坏原有行为
③ 测试本身就是文档。后来者(包括 3 个月后的你自己)看测试就能理解这段代码应该怎么工作
B.3.2 小步修改(每步一个 PR)
| PR | 内容 | 文件数 | Diff 行数 | 依赖 | 可独立验证? |
|---|---|---|---|---|---|
| PR1 | 数据库 DDL(新增 approval_record 表 + work_order 表加字段)+ Entity 类更新 | 3 个 | ~50 行 | 无 | ✅ DDL 可独立执行 |
| PR2 | 新增 ApprovalService + ApprovalRecord(纯新增,不修改现有代码) | 4 个 | ~150 行 | PR1 | ✅ 新类无副作用 |
| PR3 | 修改 WorkOrderService.updateStatus() 接入审批流(核心改动) | 2 个 | ~80 行 | PR2 | ✅ 测试已前置 |
| PR4 | 修改定时任务 + Controller 适配新流程 | 3 个 | ~100 行 | PR3 | ✅ 独立功能点 |
⚠️ 老项目修改的"三个绝不"
绝不 1:绝不在一个 PR 中同时"重构+新功能"。重构(改善现有代码结构)和新功能(改变系统行为)必须分开。这是老项目 Bug 的头号来源。
绝不 2:绝不修改超过 5 个文件而不做回归测试。如果改动涉及 6+ 个文件,拆成两个 PR。
绝不 3:绝不绕过现有测试直接改逻辑。如果目标代码没有测试,先补测试(B.3.1),再改代码。没有测试的修改 = 盲飞。
B.4 回归验证与合并(15-30 分钟)
| 步骤 | 操作 | 工具 |
|---|---|---|
| 1. 全量测试 | mvn clean test(确保所有现有测试 + 新增测试全部通过) | Maven |
| 2. L1 增量审查 | open-code-review 在 CI 中只检查本次修改的文件(filter=changed),避免对遗留代码的"历史债务"产生噪音 | open-code-review (CI) |
| 3. L2 语义审查 | 对 Claude Code 说:"/code-review,审查 PR3 的 diff。重点检查:原有状态转换逻辑是否被完整保留?新增的审批流是否与现有定时任务产生竞态条件?" | Claude Code |
| 4. L3 人工审查 | Tech Lead 审查,聚焦业务正确性和架构影响。代码风格已在 L1/L2 阶段解决 | 人工 |
| 5. 合并 | Squash merge to main(4 个 PR 的 commit 被 squash 为 1 个干净的 commit) | Git |
⚙️ 老项目 open-code-review 的增量模式配置
- uses: alibaba-group/open-code-review@v1
with:
languages: java,javascript
severity: error,warning
filter: changed # ← 关键:只检查本次 diff 的文件
baseline: main # ← 与 main 分支对比
注:如果对整个仓库做全量检查,老项目可能产生几百个 Warning——这些"历史债务"淹没了真正需要关注的新问题。增量模式让团队专注在本次改动上。
B.5 知识沉淀:文档补全 + 记忆更新(10 分钟)
老项目的知识往往在"老人"的脑子里。每次修改都是将隐性知识显性化的机会。
| 沉淀内容 | 操作 | 示例 |
|---|---|---|
| ADR | 对 Claude Code 说:"生成 ADR:在遗留 MES 系统中集成 Flowable 审批流。格式:上下文→决策→后果→备选方案" | 为什么选 Flowable 而不是自研状态机?因为项目已有 Flowable 依赖(历史原因),且审批流复杂度已超出状态机能处理的范围 |
| 隐式约定文档化 | 对 Claude Code 说:"把今天发现的隐式约定写入 docs/architecture/implicit-rules.md" | "工单状态字段是 String 类型,但只有 5 个合法值(DRAFT/RELEASED/IN_PROGRESS/COMPLETED/CANCELLED),虽然数据库没有 CHECK 约束" |
| 更新 CLAUDE.md | 对 Claude Code 说:"在 CLAUDE.md 中补充:工单模块的状态流转已改为审批流驱动,修改工单状态必须通过 ApprovalService,禁止直接 update work_order 表" | CLAUDE.md 新增一条规则 → 下次 Claude Code 修改这个模块时会自动遵守 |
| 个人记忆 | 对 Claude Code 说:"帮我记住:① MES 系统的 work_order 表用了 GBK 编码(历史原因),写 SQL 时注意 ② 生产环境的 work_order 表有 2000 万行,任何 DDL 操作都需要在凌晨 2-4 点执行" | Memory → 下次改这个系统时自动加载 |
🔑 老项目知识沉淀的"1% 原则"
每次修改,至少将 1 个隐式约定写下来(ADR/CLAUDE.md/注释/文档)。不要追求一次性补全所有文档——这做不到。但每次改代码时顺手补一个约定,一年后这个项目的文档覆盖率将远超行业平均水平。
六、工具链配置速查
| 配置项 | 🆕 新项目 | 🔧 老项目 |
|---|---|---|
| CLAUDE.md | 脚手架自带,含完整编码规范 + 架构约定 + Git 工作流 | 需手动创建,至少包含:项目技术栈、非标准约定、已知坑点清单 |
| open-code-review | 全量检查模式(filter=all),从第一次提交即启用 | 增量检查模式(filter=changed, baseline=main),避免历史债务噪音 |
| DeepSeek | 仅作为架构方案的"反方辩手"(与 Claude Code 并行评审) | 作为"代码考古学家":批量分析模块依赖、识别死代码和 God Class |
| Qwen | 处理超长招标/需求文档(百万 Token 窗口) | 解读遗留模块:一次性加载全部源码 + Commit 历史,输出模块职责描述 |
| Claude Code Memory | 记录新发现的通用模式(供未来项目复用) | 记录该项目的隐式约定和踩坑经验(供后续维护者使用) |
| CI 流水线 | 脚手架自带完整 CI(lint → test → build → deploy) | 在现有 CI 中新增 open-code-review 步骤(不影响现有步骤) |
七、落地建议:从哪类项目开始
| 阶段 | 项目类型 | 动作 | 原因 |
|---|---|---|---|
| 第 1-2 周 | 新项目(POC) | 选一个内部工具/POC 项目,用 Part A 全流程跑一遍 | 新项目风险低、AI 占比高、可见效快。适合建立团队信心 |
| 第 3-4 周 | 新项目(客户交付) | 选一个正式客户新项目,严格走 Part A 流程 | 验证脚手架和流程在真实交付压力下是否可行 |
| 第 5-6 周 | 老项目(小改动) | 选一个 Bug 修复或小规模功能增强,走 Part B 流程 | 先在小改动上验证"考古→影响分析→小步修改"模式 |
| 第 7-8 周 | 老项目(中改动) | 选一个 3-5 文件、<500 行 diff 的功能增强 | 验证小步提交和回归验证流程的有效性 |
| 第 9-12 周 | 全面推广 | 所有新项目默认走 Part A,所有老项目改动默认走 Part B | 流程已验证,进入常态化 |
⚠️ 不建议从老项目大改动开始
AI 辅助开发最容易失败的模式:在没人完全理解的 10 年老系统上,让 AI 做一个涉及 20+ 个文件的"大重构"。这不是 AI 的问题——人类在这个场景下也会失败。
正确的顺序:先在新项目上建立信心(Part A),再在小改动上验证老项目模式(Part B 的小步),最后才挑战复杂改动。