Update from Sync Service

This commit is contained in:
FNS Service
2026-06-22 11:30:51 +08:00
parent eb80b7a8c1
commit 682e3e52df
52 changed files with 10099 additions and 191 deletions

View File

@@ -0,0 +1,692 @@
# 第16-19页开发实现续篇技术规格 + 打样 + 多任务 + 核心Loop
> 章节02 开发实现(续)
> 核心问题:技术规格如何编写?如何让 AI 抄作业?如何多任务同步开发?核心 Loop 如何运转?
---
## 第16页技术规格如何编写
### 原文内容
**技术规格的5个模块**DSL 驱动):
| 模块 | 表达标准 | 格式 | 产出内容 | 约束/规范 |
|------|---------|------|---------|----------|
| **领域模型** | PlantUML/Smart Domain | .puml | 实体、属性、关系ER/类图) | 必须表达实体关系;字段需与数据库一致;标注聚合关系 |
| **数据库** | SQL DDL/DBML/Flyway 脚本 | .sql | 表结构、索引、约束 | 必须可执行;包含索引和外键;字段与领域模型一致 |
| **API** | OpenAPI 3.x | .yaml/.json | 接口定义、请求/响应结构 | 必须定义 schema禁止只写接口说明字段与模型一致 |
| **时序图** | PlantUML | .puml | 调用流程、系统交互 | 必须反映真实调用链建议包含异常分支alt |
| **专题设计** | Markdown | .md | 架构策略(权限/事务/缓存等) | 只写"策略与规则",不重复 API/DDL强调设计决策 |
### 深入解读
**为什么用 DSL**
- **可执行**DDL 可以直接运行OpenAPI 可以生成代码
- **AI 友好**LLM 对 DSL 的理解比自然语言更精确
- **一致性保证**DSL 有语法规则,不容易产生歧义
**领域模型详解**
**PlantUML 示例**
```plantuml
@startuml
entity User {
* id : Long <<PK>>
--
* username : String(50)
* email : String(100)
* role_id : Long <<FK>>
}
entity Role {
* id : Long <<PK>>
--
* name : String(20)
}
User }o--|| Role : "拥有"
note right of User : 聚合根
@enduml
```
**约束要求**
- 必须表达实体关系1:1, 1:N, M:N
- 字段需与数据库一致(类型、长度、默认值)
- 标注聚合关系(哪些是聚合根)
**数据库设计详解**
**SQL DDL 示例**
```sql
-- Flyway migration: V1__create_users_table.sql
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role_id BIGINT NOT NULL,
status TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_email (email),
CONSTRAINT fk_user_role FOREIGN KEY (role_id) REFERENCES roles(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**必须可执行**
- DDL 必须可以直接在数据库中运行
- 使用 Flyway/Liquibase 管理版本
- 包含索引(查询性能)和外键(数据完整性)
**API 设计详解**
**OpenAPI 3.x 示例**
```yaml
openapi: 3.0.3
info:
title: User API
version: 1.0.0
paths:
/api/v1/users:
post:
summary: 创建用户
tags: [User]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: 创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
description: 参数错误
components:
schemas:
CreateUserRequest:
type: object
required: [username, email, password]
properties:
username:
type: string
minLength: 3
maxLength: 50
description: 登录用户名,唯一
email:
type: string
format: email
description: 电子邮箱,唯一
password:
type: string
minLength: 8
description: 密码≥8位含大小写
UserResponse:
type: object
properties:
id:
type: integer
format: int64
username:
type: string
email:
type: string
role:
type: string
enum: [admin, user]
status:
type: boolean
```
**约束要求**
- 必须定义 schema请求和响应的结构
- 禁止只写接口说明("返回用户列表"这种描述不够)
- 字段与领域模型一致(类型、名称、约束)
**时序图详解**
**PlantUML 时序图示例**
```plantuml
@startuml
actor User
participant "UserController" as C
participant "UserService" as S
participant "UserRepository" as R
database "MySQL" as DB
User -> C: POST /api/v1/users
C -> C: 参数校验
C -> S: createUser(CreateUserRequest)
S -> S: 业务规则校验
S -> R: save(User)
R -> DB: INSERT INTO users ...
DB --> R: 返回结果
R --> S: 返回 User
S --> C: 返回 UserResponse
C --> User: 201 Created
alt 用户名已存在
S --> C: throw DuplicateException
C --> User: 409 Conflict
end
@enduml
```
**约束要求**
- 必须反映真实调用链
- 建议包含异常分支alt
- 标注关键步骤(参数校验、业务规则校验)
**专题设计详解**
**专题设计示例**
```markdown
# 权限设计方案
## 策略
- 使用 RBAC基于角色的访问控制
- 权限注解:@RequirePermission("user:create")
- 默认拒绝所有未授权的请求
## 规则
1. 管理员角色拥有所有权限
2. 普通用户只能操作自己的数据
3. 敏感操作需要二次确认
## 设计决策
- 选择 RBAC 而非 ABAC业务场景简单角色固定
- 权限存储在 Redis减少数据库查询
- 权限变更实时生效:通过 Redis Pub/Sub 通知
```
**约束要求**
- 只写"策略与规则"
- 不重复 API/DDL避免信息冗余
- 强调设计决策(为什么选择这个方案)
### 实践建议
- 使用 DSL统一技术规格的表示方式
- 保持一致性领域模型、数据库、API 要一致
- AI 辅助生成:让 AI 根据规格生成代码
- 版本控制:技术规格纳入 Git 管理
---
## 第17页打样工程如何让 AI 抄作业?
### 原文内容
**参考代码**https://github.com/domain-driven-design/ddd-microservices
**原则**
1. 约定大于配置
2. 编排逻辑和原子能力分离
3. 操作者和被操作对象分离
**常见 CQRUD 操作的工序**
**1. 简单 CRUD**
```
Controller + Command → AppService → Repository → Response 对象
```
**2. 复杂或有复用逻辑的 CRUD**
```
Controller + Command → AppService → DomainService → Repository → Response 对象
```
**3. 复杂的查询操作**
```
Controller + Query 对象 → AppService → QueryPO或复用 PO→ Response 对象
```
### 深入解读
**什么是打样工程?**
- 定义:提供代码模版和示例,让 AI 参考生成代码
- 目的:保证代码风格统一、质量稳定
- 核心理念:让 AI "抄作业",而不是自由发挥
**为什么需要打样工程?**
- AI 生成的代码质量不稳定
- 不同 AI 工具生成的代码风格不同
- AI 可能不知道项目的最佳实践
**打样工程的优势**
1. 提高代码质量:基于模版生成,质量有保障
2. 统一代码风格:所有代码遵循相同的风格
3. 减少 Review 成本代码符合规范Review 更快
4. 知识沉淀:最佳实践沉淀在模版中
**三层架构详解**
**Controller 层**
- 职责:接收请求、参数校验、调用 Service
- 输入Command/Query 对象
- 输出Response 对象
- 不包含业务逻辑
**Service 层**
- 职责:编排业务逻辑、调用 DomainService/Repository
- AppService应用服务编排逻辑
- DomainService领域服务复杂业务逻辑
- Repository数据访问
**Repository 层**
- 职责:数据持久化
- 输入:实体对象
- 输出:实体对象或 POPersistent Object
**工序详解**
**简单 CRUD无复用逻辑**
```java
// Controller
@PostMapping("/users")
public Response<UserResponse> createUser(@Valid @RequestBody CreateUserCommand cmd) {
return Response.success(userAppService.create(cmd));
}
// AppService
public UserResponse create(CreateUserCommand cmd) {
User user = userRepository.save(User.from(cmd));
return UserResponse.from(user);
}
// Repository
public User save(User user) {
userMapper.insert(user);
return user;
}
```
**复杂 CRUD有复用逻辑**
```java
// AppService - 编排逻辑
public UserResponse create(CreateUserCommand cmd) {
// 1. 校验用户名唯一
domainService.checkUsernameUnique(cmd.getUsername());
// 2. 加密密码
String encryptedPassword = domainService.encryptPassword(cmd.getPassword());
// 3. 保存用户
User user = User.from(cmd, encryptedPassword);
userRepository.save(user);
// 4. 发送欢迎邮件
domainService.sendWelcomeEmail(user);
return UserResponse.from(user);
}
// DomainService - 原子能力
public void checkUsernameUnique(String username) {
if (userRepository.existsByUsername(username)) {
throw new BusinessException("用户名已存在");
}
}
```
**复杂查询**
```java
// Controller
@GetMapping("/users")
public Response<Page<UserResponse>> listUsers(@Valid UserQuery query) {
return Response.success(userAppService.list(query));
}
// AppService
public Page<UserResponse> list(UserQuery query) {
Page<UserPO> page = userRepository.findByQuery(query);
return page.map(UserResponse::from);
}
// Repository
public Page<UserPO> findByQuery(UserQuery query) {
// 构建查询条件
// 执行分页查询
// 返回分页结果
}
```
### 实践建议
- 建立打样工程:提供标准的代码模版
- 分层清晰Controller、Service、Repository 职责明确
- 工序标准化:简单 CRUD、复杂 CRUD、复杂查询各有标准
- AI 参考打样:让 AI 根据打样工程生成代码
---
## 第18页如何多任务同步开发
### 原文内容
使用 git 的 Worktree 功能同时把一个仓库的多个分支映射到不同文件夹。Claude Code、Codex、Cursor 等已经自动支持使用 subagent 创建 Worktree加速开发。
```bash
# 基于已有分支创建
git worktree add ../feature-login feature/login
# 创建新分支 + 工作区(最常用)
git worktree add -b feature-payment ../feature-payment
# 查看所有 worktree
git worktree list
# 删除工作区
git worktree remove ../feature-login
```
### 深入解读
**什么是 Git Worktree**
- 定义Git 的一个功能,允许你从同一个仓库检出多个工作目录
- 每个工作目录都是一个独立的分支
- 共享同一个 .git 目录(节省磁盘空间)
**为什么需要 Worktree**
- AI 编程时,经常需要同时开发多个功能
- 传统方式:切换分支,容易丢失上下文
- Worktree每个功能在独立的目录互不干扰
**Worktree 的优势**
1. 并行开发:多个 AI 实例可以同时工作在不同分支
2. 上下文隔离:每个功能的上下文独立,不会混淆
3. 快速切换:不需要 `git checkout`,直接切换目录
4. 节省空间:共享 .git 目录
**使用场景**
**场景1多 AI 实例并行开发**
```bash
# 主工作区:开发功能 A
cd /project/feature-a
claude-code # 启动 Claude Code
# 新开终端:开发功能 B
cd /project/feature-b
claude-code # 启动另一个 Claude Code 实例
# 再开终端:开发功能 C
cd /project/feature-c
claude-code # 启动第三个 Claude Code 实例
```
**场景2AI + 人工并行开发**
```bash
# AI 在 feature-a 开发
cd /project/feature-a
claude-code
# 人工在 main 分支修复紧急 bug
cd /project/main
# 手动修复 bug
```
**场景3Code Review 时继续开发**
```bash
# 主工作区feature-a 提交 PR等待 review
# 新开工作区:继续开发 feature-b
git worktree add -b feature-b ../feature-b
cd ../feature-b
claude-code
```
**Worktree 管理**
**列出所有工作区**
```bash
git worktree list
# 输出:
# /project/main abc1234 [main]
# /project/feature-a def5678 [feature-a]
# /project/feature-b ghi9012 [feature-b]
```
**清理工作区**
```bash
# 删除工作区(会自动删除目录)
git worktree remove ../feature-a
# 强制删除(即使有未提交的更改)
git worktree remove --force ../feature-a
# 清理已删除的工作区记录
git worktree prune
```
**AI 工具自动支持**
- Claude Code自动创建 Worktree 进行并行开发
- Codex CLI支持在独立工作区运行
- Cursor可以在多个窗口打开不同 Worktree
### 实践建议
- 使用 Worktree 并行开发:提高开发效率
- 命名规范:工作区目录名与分支名一致
- 及时清理:完成的功能及时删除 Worktree
- AI 工具支持:利用 AI 工具的自动 Worktree 功能
---
## 第19页完整的核心 Loop 过程(研发自测)
### 原文内容
**核心理念**:通过 TDD/浏览器调试前端AI 自治运行
**Loop 流程图**
```
开始进入循环
[Chat] 进入 Plan 模式
装载需求规格,给出指令进行 Plan
[Chat] 符合要求,退出 Plan 模式,开始执行?
↓ 是
[模型] 读取 Plan
创建 API 测试,实现代码
[模型] 运行测试/浏览器调试,是否成功?
↓ 否
重复多次 / 白天持续很久 / 夜间
↓ 是
[模型] 退出循环
(给予 ByPass 权限)
```
**核心思想**
1. Plan 阶段尽可能锁定上下文到 Plan 中,关闭所有的开放性问题
2. Plan 中记录实现状态,让任务可以分批完成或者重试
3. 需要给出确定性的验收方式:例如通过所有的 API 测试,让 AI 能建立自我修复标准
**Loop 规则API 为例,放到 AGENTS.md 作为开发流程要求)**
1. **Plan 等待确认**:在 docs/plans 下根据模版创建 Plan
2. **编写 API 测试**:根据 Plan 实现 API 测试,运行成功并断言失败
3. **编写实现**:编写单元测试 + 实现代码,通过编译
4. **运行 API 测试**:运行测试,并修复失败的测试和其他错误
### 深入解读
**什么是核心 Loop**
- 定义AI 自治运行的开发循环
- 目标:通过 TDD 驱动AI 自动实现需求并修复问题
- 特点Plan 阶段人机协作,执行阶段 AI 自治
**Loop 的三个阶段**
**阶段1Plan规划**
- 输入:需求规格、技术规格
- 输出:实现方案、任务列表
- 关键:关闭所有开放性问题
- 人工介入:确认 Plan 是否合理
**阶段2执行Implementation**
- 输入Plan
- 输出API 测试、实现代码
- 关键:按照 Plan 逐步实现
- AI 自治:无需人工介入
**阶段3验证Verification**
- 输入API 测试、实现代码
- 输出:测试结果、修复建议
- 关键:所有测试通过
- AI 自治:自动运行测试,自动修复
**Plan 模版示例**
```markdown
# Plan: 实现用户注册功能
## 目标
实现用户注册 API支持邮箱验证
## 任务列表
- [ ] 1. 创建数据库表 users
- [ ] 2. 实现 POST /api/v1/users API
- [ ] 3. 实现邮箱验证逻辑
- [ ] 4. 编写单元测试
- [ ] 5. 编写 API 测试
## 实现方案
1. 使用 Flyway 创建 users 表
2. Controller 接收 CreateUserCommand
3. AppService 调用 UserRepository 保存
4. 发送验证邮件(使用 JavaMail
## 验收标准
- 所有单元测试通过
- 所有 API 测试通过
- 代码符合阿里巴巴 Java 开发手册
## 状态
- 开始时间2026-06-20 10:00
- 预计完成2026-06-20 12:00
- 实际完成:待更新
```
**TDD 驱动详解**
**步骤1编写 API 测试**
```java
@Test
public void testCreateUser() {
CreateUserRequest request = new CreateUserRequest();
request.setUsername("testuser");
request.setEmail("test@example.com");
request.setPassword("Password123");
Response<UserResponse> response = userClient.create(request);
assertEquals(201, response.getCode());
assertNotNull(response.getData().getId());
assertEquals("testuser", response.getData().getUsername());
}
@Test
public void testCreateUser_DuplicateUsername() {
// 先创建一个用户
CreateUserRequest request1 = new CreateUserRequest();
request1.setUsername("testuser");
request1.setEmail("test1@example.com");
request1.setPassword("Password123");
userClient.create(request1);
// 再创建一个同名用户
CreateUserRequest request2 = new CreateUserRequest();
request2.setUsername("testuser");
request2.setEmail("test2@example.com");
request2.setPassword("Password123");
Response<UserResponse> response = userClient.create(request2);
assertEquals(409, response.getCode());
assertEquals("用户名已存在", response.getMessage());
}
```
**步骤2运行测试断言失败**
```bash
mvn test -Dtest=UserApiTest
# 预期:测试失败(因为没有实现)
```
**步骤3编写实现代码**
```java
// Controller
@PostMapping("/users")
public Response<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
return Response.success(userAppService.create(request));
}
// AppService
public UserResponse create(CreateUserRequest request) {
// 校验用户名唯一
if (userRepository.existsByUsername(request.getUsername())) {
throw new BusinessException(409, "用户名已存在");
}
// 加密密码
String encryptedPassword = passwordEncoder.encode(request.getPassword());
// 保存用户
User user = User.from(request, encryptedPassword);
userRepository.save(user);
// 发送验证邮件
emailService.sendVerificationEmail(user);
return UserResponse.from(user);
}
```
**步骤4运行测试通过**
```bash
mvn test -Dtest=UserApiTest
# 预期:所有测试通过
```
**ByPass 权限**
- 定义AI 在某些情况下可以跳过某些步骤
- 场景:
- 测试环境不可用
- 第三方服务不可用
- 紧急修复
- 控制:在 AGENTS.md 中定义 ByPass 规则
**Loop 的退出条件**
1. 所有 API 测试通过
2. 所有单元测试通过
3. 代码符合规范Lint 通过)
4. 没有编译错误
### 实践建议
- Plan 阶段充分沟通:关闭所有开放性问题
- TDD 驱动:先写测试再写代码
- AI 自治运行:执行阶段无需人工介入
- 记录实现状态:方便复盘和优化
- ByPass 权限控制:紧急情况可以跳过某些步骤
---
## 本章小结
**开发实现的核心要点**
1. 让 AI 听话:规则、规格、技能三要素
2. 构建上下文体系:区分过程方案和事实方案
3. 调用外部工具MCP、Skills、CLI
4. 选择合适的工具命令行类、AI IDE、增强插件
5. SDD 框架BMAD、Spec Kit、OpenSpec、Kiro
6. 技术规格 DSL 驱动领域模型、数据库、API、时序图、专题设计
7. 打样工程:让 AI 抄作业
8. 多任务同步开发Git Worktree
9. 核心 LoopPlan → TDD → 验证
**关键工具**
- Claude Code、Cursor、Kiro
- MCP Server、Skills
- PlantUML、OpenAPI
- Git Worktree
**最佳实践**
- AGENTS.md 作为宪法
- 区分 Plans过程和 Designs事实
- 使用 DSL 编写技术规格
- 建立打样工程
- TDD 驱动开发