Critical修复: - CI配置MySQL→PostgreSQL对齐架构决策 - 错误码格式统一为分段格式(系统-模块-分类-序号) - 覆盖率指标统一(Domain 90%/Application 80%/新增 90%) Major修复: - 分支策略统一为trunk-based,去掉develop分支 - muse-studio部署描述修正为Vite SPA静态部署 - muse-studio提交类型统一为英文前缀 - API路径统一为/app-api,端口对齐48080 - DROP COLUMN措辞修正为条件性禁止 - 增加规范优先级声明 新增文档: - 05-安全开发规范.md(认证授权/输入校验/AI安全/审计) - 06-日志与可观测性规范.md(日志级别/结构化/链路追踪/监控) - muse-admin测试编写指南
291 lines
10 KiB
Markdown
291 lines
10 KiB
Markdown
# CLAUDE.md — muse-cloud 开发规范
|
||
|
||
## 项目概述
|
||
|
||
muse-cloud 是 Muse 创作平台的后端主仓,fork 自 YunaiV/yudao-cloud。
|
||
|
||
- 技术栈:Java 21 + Spring Boot 3 + Yudao Cloud 框架 + PostgreSQL
|
||
- 定位:微服务/单体聚合后端,承载创作、知识、AI 编排、市场、账户等核心业务
|
||
- 开发模式:AI agent 驱动开发,人类做决策和 review
|
||
- 设计文档仓库:`oh-my-muse/design-docs/`
|
||
|
||
### 关键设计文档索引
|
||
|
||
| 文档 | 内容 |
|
||
|------|------|
|
||
| `后端-01-领域模型与聚合设计.md` | 领域模型、聚合职责、owner module、不变式 |
|
||
| `后端-02-工程结构与模块职责.md` | 工程基线、模块清单、包结构、协作边界 |
|
||
| `后端-03-关键流程实现与接口契约.md` | 核心业务流程、事件协作、接口契约 |
|
||
| `后端-04-统一数据库Schema-v1.md` | 数据库表设计、字段规范、索引策略 |
|
||
| `后端-05-统一API契约-v1.md` | RESTful API 设计、错误码、版本策略 |
|
||
|
||
---
|
||
|
||
## 编码规范
|
||
|
||
### Java 代码风格
|
||
|
||
- 遵循 Yudao Cloud 现有代码风格和命名约定
|
||
- 类、方法、字段必须有中文 Javadoc 注释
|
||
- 关键业务逻辑(状态转换、事务边界、安全校验)必须有详细中文行内注释
|
||
- 方法体超过 20 行时,用注释分段说明逻辑块
|
||
- 禁止魔法数字,必须定义常量并注释含义
|
||
- 异常处理必须注释说明:什么情况会触发、如何恢复
|
||
- 枚举值必须有中文注释说明业务含义
|
||
|
||
示例:
|
||
|
||
```java
|
||
/**
|
||
* 文本块服务 - 负责正文最小编辑单元的读写和版本管理
|
||
*
|
||
* @author muse-agent
|
||
*/
|
||
@Service
|
||
public class BlockServiceImpl implements BlockService {
|
||
|
||
/** 最大单次批量保存数量 */
|
||
private static final int MAX_BATCH_SIZE = 100;
|
||
|
||
/**
|
||
* 保存文本块内容
|
||
*
|
||
* @param workId 作品 ID
|
||
* @param blockId 文本块 ID
|
||
* @param content 正文内容
|
||
* @param expectedRevision 期望版本号,用于乐观锁冲突检测
|
||
* @return 保存后的新版本号
|
||
* @throws BlockConflictException 当 expectedRevision 与数据库当前版本不一致时抛出
|
||
*/
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public Long saveBlock(Long workId, Long blockId, String content, Long expectedRevision) {
|
||
// 1. 校验作品归属和权限
|
||
validateWorkOwnership(workId);
|
||
|
||
// 2. 乐观锁检查:当前版本必须等于期望版本
|
||
BlockDO block = blockMapper.selectById(blockId);
|
||
if (!block.getRevision().equals(expectedRevision)) {
|
||
// 版本冲突:其他客户端已修改此 Block,需要前端合并后重试
|
||
throw new BlockConflictException(blockId, expectedRevision, block.getRevision());
|
||
}
|
||
|
||
// 3. 写入新版本
|
||
block.setContent(content);
|
||
block.setRevision(expectedRevision + 1);
|
||
blockMapper.updateById(block);
|
||
|
||
return block.getRevision();
|
||
}
|
||
}
|
||
```
|
||
|
||
### 包结构约束
|
||
|
||
遵循 DDD 分层,标准模块结构:
|
||
|
||
```
|
||
yudao-module-xxx/
|
||
yudao-module-xxx-api/
|
||
admin/ # 管理后台 DTO 和 facade
|
||
app/ # 用户端 DTO 和 facade
|
||
event/ # 跨模块事件、outbox 消息、回调 DTO
|
||
yudao-module-xxx-server/
|
||
controller/
|
||
admin/ # /admin-api/** 入口
|
||
app/ # /app-api/** 入口
|
||
application/ # 用例编排、事务、幂等、权限摘要
|
||
domain/ # 聚合、不变式、领域服务、状态机
|
||
infrastructure/ # 数据库、Redis、MQ、外部服务、mapper
|
||
```
|
||
|
||
层级约束:
|
||
|
||
- `domain` 不依赖 controller、Yudao Web DTO 或外部 API DTO
|
||
- `application` 编排用例、事务、幂等、权限摘要、跨模块 facade 和 outbox
|
||
- `infrastructure` 接数据库、Redis、MQ、文件、外部服务
|
||
- Controller 只做参数校验、权限入口和响应转换,不拼业务规则
|
||
- 各模块通过 `-api` 模块暴露 facade,禁止跨模块直接依赖实现
|
||
|
||
AI 模块包级隔离:
|
||
|
||
- `ai.grant` 包(admin 写入):Tool Grant 写入、Runtime Permission Envelope 签发、Protection Node
|
||
- `ai.runtime` 包(只读消费):AI 任务执行、候选生成、上下文组装
|
||
- ArchUnit 规则强制:runtime 包禁止调用 grant 包写入接口
|
||
|
||
### 数据库规范
|
||
|
||
- 数据库:PostgreSQL
|
||
- 表名前缀:`muse_`(Muse 业务表);Yudao 平台表保持原前缀
|
||
- 所有 DDL 变更必须通过 Flyway migration
|
||
- Migration 文件命名:`V{版本号}__{描述}.sql`(双下划线分隔)
|
||
- 每个 migration 文件头部注释说明变更目的和影响范围
|
||
- 默认禁止 `DROP COLUMN`。确需清理废弃列时,走全局发布规范场景 C 流程(需人类确认 + 观察期后执行)
|
||
- 索引命名:`idx_{表名}_{字段名}`
|
||
- 唯一约束命名:`uk_{表名}_{字段名}`
|
||
- 外键约束:不使用数据库外键,在应用层保证引用完整性
|
||
- 所有表必须包含:`id`、`creator`、`create_time`、`updater`、`update_time`、`deleted`、`tenant_id`
|
||
|
||
### API 规范
|
||
|
||
- RESTful 风格
|
||
- 版本控制:通过 `X-API-Version` header
|
||
- 统一响应结构:`CommonResult<T>`
|
||
- 错误码分段管理:
|
||
- `1-001-000-000` ~ `1-001-999-999`:Content 模块
|
||
- `1-002-000-000` ~ `1-002-999-999`:Knowledge 模块
|
||
- `1-003-000-000` ~ `1-003-999-999`:AI 模块
|
||
- `1-004-000-000` ~ `1-004-999-999`:Market 模块
|
||
- `1-005-000-000` ~ `1-005-999-999`:Meta 模块
|
||
- `1-006-000-000` ~ `1-006-999-999`:Account/Member 模块
|
||
- 接口方法必须有中文注释说明:用途、参数含义、返回值含义、可能的错误码
|
||
- 分页统一使用 `PageParam`,返回 `PageResult<T>`
|
||
|
||
### 安全约束
|
||
|
||
- 不在代码中硬编码密钥、token、密码
|
||
- 敏感配置通过环境变量或配置中心注入
|
||
- 敏感操作必须有审计日志(操作人、时间、变更内容)
|
||
- AI runtime 不能自授权(包级隔离 + ArchUnit 强制)
|
||
- 跨模块数据访问必须通过 facade 接口,不能直接读写其他模块的数据库表
|
||
- 用户数据隔离:所有查询必须带 tenant_id 和 owner 校验
|
||
|
||
---
|
||
|
||
## 测试规范
|
||
|
||
### 测试分层
|
||
|
||
| 层级 | 测试类型 | 工具 | 覆盖目标 |
|
||
|------|----------|------|----------|
|
||
| Domain | 纯单元测试 | JUnit 5 + AssertJ | 状态转换、不变式、业务规则 |
|
||
| Application | 集成测试 | Testcontainers + PostgreSQL | 事务边界、事件发布、用例编排 |
|
||
| API | 契约测试 | MockMvc + Spring Boot Test | 请求/响应格式、错误码、权限 |
|
||
| E2E | 冒烟测试 | Testcontainers 全栈 | 关键业务流程端到端 |
|
||
|
||
### 测试要求
|
||
|
||
- 新增业务代码必须同时提交对应测试
|
||
- 修改业务代码必须评估现有测试是否需要更新
|
||
- 测试类命名:`{被测类名}Test.java`
|
||
- 测试方法命名:`should_{预期行为}_when_{条件}`
|
||
- 每个测试方法有中文注释说明测试意图
|
||
- 禁止 `@Disabled` 注解长期存在(超过 1 周必须修复或删除)
|
||
- 测试必须能独立运行,不依赖外部状态或执行顺序
|
||
|
||
### 覆盖率要求
|
||
|
||
遵循全局总则 4.4 节定义的覆盖率基线:
|
||
- Domain 层:行覆盖率 >= 90%
|
||
- Application 层:分支覆盖率 >= 80%
|
||
- 新增代码:行覆盖率 >= 90%
|
||
|
||
---
|
||
|
||
## Git 工作流
|
||
|
||
### 分支策略
|
||
|
||
- `main`:稳定基线,只接受 PR 合入
|
||
- `feature/*`:功能开发分支
|
||
- `fix/*`:缺陷修复分支
|
||
- `refactor/*`:重构分支
|
||
- 每个 PR 必须通过 CI(编译 + 测试 + lint + ArchUnit)
|
||
|
||
### 提交规范
|
||
|
||
- 中文提交信息
|
||
- 格式:`{类型}({模块}): {描述}`
|
||
- 类型:`feat` / `fix` / `refactor` / `test` / `docs` / `chore`
|
||
- 模块:`content` / `knowledge` / `ai` / `market` / `meta` / `member` / `infra` / `system`
|
||
- 示例:
|
||
- `feat(content): 实现 Block 保存与版本冲突检测`
|
||
- `fix(ai): 修复候选生成超时未正确回滚的问题`
|
||
- `test(knowledge): 补充知识草稿确认流程集成测试`
|
||
|
||
### PR 规范
|
||
|
||
- 标题简洁(< 70 字符)
|
||
- 描述包含:变更目的、影响范围、测试情况
|
||
- 涉及数据库变更必须标注 `[DB Migration]`
|
||
- 涉及 API 变更必须标注 `[API Change]`
|
||
- 涉及跨模块接口变更必须标注 `[Cross-Module]`
|
||
|
||
---
|
||
|
||
## Agent 行为约束
|
||
|
||
### 编码时
|
||
|
||
- 先读现有代码理解模式和约定,再写新代码
|
||
- 复用现有工具类和基础设施(Yudao framework 提供的能力优先)
|
||
- 每次变更后运行相关测试验证
|
||
- 不修改与当前任务无关的代码
|
||
- 不顺手重构无关代码
|
||
- 代码必须有完整中文注释
|
||
|
||
### 测试时
|
||
|
||
- 新功能必须先写测试再写实现(TDD 优先)
|
||
- 修 bug 必须先写复现测试
|
||
- 测试必须能独立运行,不依赖外部状态
|
||
- 使用 Testcontainers 做集成测试,不 mock 数据库
|
||
|
||
### 提交时
|
||
|
||
- 每个 commit 只做一件事
|
||
- commit 前必须通过本地编译和测试
|
||
- 不提交临时调试代码、注释掉的代码、TODO hack
|
||
- 不提交 IDE 配置文件、本地环境配置
|
||
|
||
### 设计决策时
|
||
|
||
- 涉及新增聚合、新增模块、跨模块接口变更时,先产出设计文档
|
||
- 设计文档路径:`docs/agent-specs/YYYY-MM-DD-主题-审阅版.md`
|
||
- 不接受缝合设计:不从一个 spec 适配对接另一个 spec
|
||
- 不接受孤儿设计:新数据结构必须有完整入口和使用方式
|
||
|
||
---
|
||
|
||
## 构建与运行
|
||
|
||
### 常用命令
|
||
|
||
```bash
|
||
# 编译(跳过测试)
|
||
./mvnw clean compile -DskipTests
|
||
|
||
# 运行全部测试
|
||
./mvnw test
|
||
|
||
# 运行指定模块测试
|
||
./mvnw test -pl yudao-module-content/yudao-module-content-server
|
||
|
||
# 打包
|
||
./mvnw clean package -DskipTests
|
||
|
||
# 启动本地 PostgreSQL(Docker)
|
||
docker compose up -d postgres
|
||
|
||
# Flyway 迁移
|
||
./mvnw flyway:migrate -pl yudao-server
|
||
```
|
||
|
||
### 本地开发依赖
|
||
|
||
- JDK 21(推荐 Eclipse Temurin)
|
||
- PostgreSQL 16+(Docker 或本地安装)
|
||
- Redis 7+(Docker 或本地安装)
|
||
- Docker & Docker Compose(Testcontainers 依赖)
|
||
|
||
---
|
||
|
||
## 关键引用
|
||
|
||
- 设计文档仓库:`oh-my-muse/design-docs/`
|
||
- 架构决策:`design-docs/架构-03-关键决策与原则(ADR).md`(如存在)
|
||
- API 契约:`design-docs/后端-05-统一API契约-v1.md`
|
||
- 数据库 Schema:`design-docs/后端-04-统一数据库Schema-v1.md`
|
||
- 领域模型:`design-docs/后端-01-领域模型与聚合设计.md`
|
||
- 工程结构:`design-docs/后端-02-工程结构与模块职责.md`
|
||
- 关键流程:`design-docs/后端-03-关键流程实现与接口契约.md`
|