From 7277b9c5583fd09faa0172f35186a4362494e496 Mon Sep 17 00:00:00 2001 From: zizi Date: Sun, 24 May 2026 11:36:22 +0800 Subject: [PATCH] =?UTF-8?q?fix(baseline):=20=E4=BF=AE=E5=A4=8D=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=9F=BA=E7=BA=BF=E6=96=87=E6=A1=A3=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E9=97=AE=E9=A2=98=E5=B9=B6=E8=A1=A5=E5=85=85=E5=AE=89?= =?UTF-8?q?=E5=85=A8/=E6=97=A5=E5=BF=97=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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测试编写指南 --- docs/dev-baseline/global/01-AI开发管理总则.md | 13 ++- docs/dev-baseline/global/02-跨仓库协作规范.md | 12 +-- docs/dev-baseline/global/03-CI-CD基线配置.md | 11 +- docs/dev-baseline/global/04-发布与部署规范.md | 4 +- docs/dev-baseline/global/05-安全开发规范.md | 66 ++++++++++++ .../global/06-日志与可观测性规范.md | 100 ++++++++++++++++++ .../docs/dev-guide/03-测试编写指南.md | 90 ++++++++++++++++ docs/dev-baseline/muse-cloud/CLAUDE.md | 10 +- docs/dev-baseline/muse-studio/CLAUDE.md | 10 +- .../docs/dev-guide/01-开发环境搭建.md | 12 +-- 10 files changed, 298 insertions(+), 30 deletions(-) create mode 100644 docs/dev-baseline/global/05-安全开发规范.md create mode 100644 docs/dev-baseline/global/06-日志与可观测性规范.md create mode 100644 docs/dev-baseline/muse-admin/docs/dev-guide/03-测试编写指南.md diff --git a/docs/dev-baseline/global/01-AI开发管理总则.md b/docs/dev-baseline/global/01-AI开发管理总则.md index 8dfa56f9..1dc36790 100644 --- a/docs/dev-baseline/global/01-AI开发管理总则.md +++ b/docs/dev-baseline/global/01-AI开发管理总则.md @@ -5,6 +5,15 @@ - 适用范围:muse-cloud / muse-admin / muse-studio / muse-design-docs 四仓全局 - 目标读者:AI agent、人类开发者、架构师、项目管理者 +## 规范优先级 + +当多份文档存在冲突时,按以下优先级执行: +1. 各仓库 CLAUDE.md(最具体的约束) +2. 全局总则和跨仓协作规范(通用规则) +3. dev-guide 开发指南(参考性指导) + +如果发现冲突,应修正低优先级文档使其与高优先级对齐,而非忽略。 + ## 1. 开发模式定义 ### 1.1 职责分工 @@ -67,7 +76,7 @@ 每个仓库遵循各自 CLAUDE.md 中定义的语言和框架规范: - muse-cloud:Java / Spring Boot / MyBatis-Plus 规范 - muse-admin:Vue 3 / TypeScript / Vben Admin 规范 -- muse-studio:React / TypeScript / Next.js 规范 +- muse-studio:React / TypeScript / Vite SPA 规范 - muse-design-docs:Markdown 文档规范 ### 3.2 跨仓一致性约定 @@ -76,7 +85,7 @@ | 约定项 | 统一标准 | 说明 | |---|---|---| -| 错误码格式 | `{模块编号}_{错误编号}`,6 位数字 | 模块编号见后端-02 | +| 错误码格式 | `{系统}-{模块}-{分类}-{序号}` | 系统:1=muse;模块:001=content, 002=ai, 003=knowledge, 004=market, 005=account, 006=meta;分类:000=通用, 001=参数校验, 002=业务规则, 003=权限, 004=外部依赖;序号:000-999。示例:1-001-002-001 表示 content 模块的业务规则错误第 1 号 | | API 路径命名 | 小写 kebab-case | `/app-api/work/text-block` | | 日期时间格式 | ISO 8601(`2026-05-24T10:30:00+08:00`) | 前后端传输统一 | | 分页参数 | `pageNo`(从 1 开始)/ `pageSize`(默认 20,最大 100) | 请求参数 | diff --git a/docs/dev-baseline/global/02-跨仓库协作规范.md b/docs/dev-baseline/global/02-跨仓库协作规范.md index 183d0b6b..cb2b71b5 100644 --- a/docs/dev-baseline/global/02-跨仓库协作规范.md +++ b/docs/dev-baseline/global/02-跨仓库协作规范.md @@ -162,7 +162,7 @@ muse-admin / muse-studio 各自维护错误码到用户提示的映射 ``` 规则: -- 错误码格式:6 位数字,前 3 位模块编号,后 3 位错误编号 +- 错误码格式:`{系统}-{模块}-{分类}-{序号}`(详见全局总则 3.2 节) - 每个模块的错误码范围在 `后端-02` 中分配 - 前端可以合并展示(多个错误码映射到同一用户提示),但不能丢失错误码信息 @@ -178,14 +178,14 @@ muse-admin / muse-studio 各自维护错误码到用户提示的映射 ### 5.1 分支策略 -各仓库统一使用以下分支模型: +各仓库统一采用 trunk-based 开发模式,不使用 develop 分支: | 分支 | 用途 | 保护规则 | |---|---|---| -| `main` | 生产就绪代码 | 禁止直接推送,只能通过 PR 合入 | -| `develop` | 开发集成分支 | PR 合入需通过 CI | -| `feature/{描述}` | 功能开发 | 从 develop 拉出,合回 develop | -| `hotfix/{描述}` | 生产紧急修复 | 从 main 拉出,合回 main + develop | +| `main` | 稳定基线,只接受 PR 合入 | 禁止直接推送,只能通过 PR 合入 | +| `feature/{描述}` | 功能开发 | 从 main 拉出,合入 main | +| `fix/{描述}` | 缺陷修复 | 从 main 拉出,合入 main | +| `release/v{版本号}` | 发布准备(可选) | 从 main 拉出,用于集成测试和修复 | ### 5.2 跨仓协调发布 diff --git a/docs/dev-baseline/global/03-CI-CD基线配置.md b/docs/dev-baseline/global/03-CI-CD基线配置.md index b0f3cd35..944a538e 100644 --- a/docs/dev-baseline/global/03-CI-CD基线配置.md +++ b/docs/dev-baseline/global/03-CI-CD基线配置.md @@ -64,11 +64,14 @@ jobs: # 阶段 3:集成测试 needs: compile services: - mysql: - image: mysql:8.0 + postgres: + image: postgres:16-alpine env: - MYSQL_ROOT_PASSWORD: test - MYSQL_DATABASE: muse_test + POSTGRES_DB: muse_test + POSTGRES_USER: test + POSTGRES_PASSWORD: test + ports: + - 5432:5432 redis: image: redis:7 steps: diff --git a/docs/dev-baseline/global/04-发布与部署规范.md b/docs/dev-baseline/global/04-发布与部署规范.md index c02671ba..82b61793 100644 --- a/docs/dev-baseline/global/04-发布与部署规范.md +++ b/docs/dev-baseline/global/04-发布与部署规范.md @@ -142,7 +142,7 @@ |---|---|---| | muse-cloud | 容器化部署(Docker + K8s/Docker Compose) | 支持滚动更新 | | muse-admin | 静态资源部署(Nginx / CDN) | 构建产物直接部署 | -| muse-studio | 容器化部署(Next.js SSR)或静态导出 | 视 SSR 需求决定 | +| muse-studio | 静态资源部署(Nginx / CDN) | Vite 构建产物为纯静态 SPA | ### 4.2 部署顺序(跨仓协调发布时) @@ -168,7 +168,7 @@ |---|---|---| | muse-cloud | `/actuator/health` | 数据库连接、Redis 连接、关键依赖 | | muse-admin | `/health.html` 或 HTTP 200 | 静态资源可访问 | -| muse-studio | `/api/health` | SSR 渲染正常、API 可达 | +| muse-studio | `/health.html` 或 HTTP 200 | 静态资源可达性检查 | ### 4.4 灰度发布(推荐) diff --git a/docs/dev-baseline/global/05-安全开发规范.md b/docs/dev-baseline/global/05-安全开发规范.md new file mode 100644 index 00000000..2f39774c --- /dev/null +++ b/docs/dev-baseline/global/05-安全开发规范.md @@ -0,0 +1,66 @@ +# 安全开发规范 + +## 1. 认证与授权 + +- 所有 API 必须经过认证(除明确标注的公开接口) +- 权限校验在 Application 层执行,不依赖前端隐藏 +- 管理员操作和普通用户操作走不同 API 前缀(/admin-api vs /app-api) +- AI runtime 不能自授权(包级隔离 + ArchUnit 强制) + +## 2. 输入校验 + +- 所有外部输入必须校验(请求参数、文件上传、WebSocket 消息) +- 使用框架提供的校验注解(@Valid、@NotNull 等),不手写正则 +- 文件上传:校验类型、大小、内容(不只看扩展名) +- SQL 参数化查询,禁止字符串拼接 + +## 3. 数据保护 + +- 敏感字段(密码、token、密钥)不出现在日志、响应、错误信息中 +- 数据库中密码使用 BCrypt 加密存储 +- API 响应中脱敏:手机号中间 4 位、邮箱 @ 前部分、身份证中间段 +- 用户数据隔离:查询必须带 tenant_id / user_id 条件 + +## 4. 密钥管理 + +- 禁止在代码中硬编码密钥、token、密码 +- 开发环境使用 .env.local(已 gitignore) +- 生产环境使用环境变量或密钥管理服务 +- API Key 定期轮换,支持多 key 并存过渡 + +## 5. AI 特有安全 + +- Prompt Injection 防护:用户输入与系统 prompt 严格分离 +- AI 生成内容标记来源(source_version),不伪装为用户原创 +- AI runtime 权限信封(Permission Envelope)由 grant 包签发,runtime 只读 +- 保护节点(Protection Node)不可被 AI 替换或修改 + +## 6. 前端安全 + +- XSS 防护:使用框架自动转义,富文本使用白名单过滤 +- CSRF:使用 token 机制 +- 敏感操作(删除、发布、支付)需要二次确认 +- 本地存储(IndexedDB/localStorage)不存储敏感信息 + +## 7. 审计日志 + +- 所有管理员操作必须记录审计日志 +- 审计日志包含:who(操作人)、what(操作内容)、when(时间)、where(IP/设备)、result(结果) +- 审计日志不可修改、不可删除 +- 敏感操作(权限变更、数据删除、配置发布)额外记录变更前后值 + +## 8. 依赖安全 + +- 使用固定版本号,不使用 ^ 或 ~ 范围 +- 定期检查依赖漏洞(npm audit / mvn dependency-check) +- 新增依赖需评估:维护活跃度、已知漏洞、许可证兼容性 +- 禁止引入来源不明或名称可疑的包 + +## 9. Agent 安全行为规则 + +- 不在代码中硬编码任何密钥或凭据 +- 不跳过权限检查或认证中间件 +- 不信任前端传来的权限声明 +- 不在日志中输出敏感数据 +- 发现安全漏洞时立即报告,不静默修复 +- 不引入已知有安全漏洞的依赖版本 diff --git a/docs/dev-baseline/global/06-日志与可观测性规范.md b/docs/dev-baseline/global/06-日志与可观测性规范.md new file mode 100644 index 00000000..3baff358 --- /dev/null +++ b/docs/dev-baseline/global/06-日志与可观测性规范.md @@ -0,0 +1,100 @@ +# 日志与可观测性规范 + +## 1. 日志级别标准 + +| 级别 | 使用场景 | 示例 | +|------|----------|------| +| ERROR | 需要人工介入的故障 | 数据库连接失败、外部服务不可达、数据不一致 | +| WARN | 异常但可自动恢复 | 重试成功、降级触发、接近阈值 | +| INFO | 关键业务事件 | 用户登录、作品创建、AI 生成完成、支付成功 | +| DEBUG | 开发调试信息 | 方法入参、中间状态、SQL 语句 | + +规则: +- 生产环境默认 INFO 级别 +- ERROR 必须包含异常堆栈和上下文 +- 禁止在循环中打 INFO/WARN 日志 +- DEBUG 日志使用条件判断或 SLF4J 占位符,避免字符串拼接开销 + +## 2. 结构化日志格式 + +后端使用 JSON 格式输出: + +```json +{ + "timestamp": "2024-01-01T12:00:00.000Z", + "level": "INFO", + "traceId": "abc123", + "spanId": "def456", + "service": "muse-cloud", + "module": "content", + "message": "作品创建成功", + "userId": 12345, + "workId": 67890, + "duration": 150 +} +``` + +前端错误上报格式: + +```json +{ + "timestamp": "...", + "level": "ERROR", + "source": "muse-studio", + "page": "/works/123/editor", + "message": "Block 保存失败", + "error": "NetworkError: timeout", + "userId": 12345, + "context": { "blockId": "...", "revision": 5 } +} +``` + +## 3. 敏感信息脱敏 + +日志中禁止出现: +- 密码、token、密钥的明文 +- 完整的身份证号、银行卡号 +- 用户的完整手机号、邮箱 + +脱敏规则: +- 手机号:138****1234 +- 邮箱:u***@example.com +- token:前 4 位 + **** + +## 4. 链路追踪 + +- 使用 traceId 贯穿请求全链路(网关 → 服务 → 数据库 → 外部调用) +- 前端请求携带 X-Request-Id header +- 异步任务继承父任务的 traceId +- SSE 连接使用 connectionId 关联同一会话的所有事件 + +## 5. 前端错误监控 + +- 全局错误边界捕获未处理异常 +- API 请求失败自动上报(排除 4xx 客户端错误中的 401/403) +- 编辑器崩溃单独上报(含 Block 状态快照) +- 性能指标上报:FCP、LCP、CLS + +## 6. 后端监控指标 + +关键指标: +- API 响应时间(P50/P95/P99) +- 错误率(5xx / 总请求) +- AI 生成延迟(首 token 时间、总生成时间) +- 数据库连接池使用率 +- 消息队列积压量 + +告警阈值建议: +- API P99 > 3s:WARN +- API P99 > 10s:ERROR +- 错误率 > 1%:WARN +- 错误率 > 5%:ERROR +- DB 连接池 > 80%:WARN + +## 7. Agent 日志行为规则 + +- 关键业务操作必须打 INFO 日志(创建、修改、删除、状态变更) +- 外部调用(AI API、文件存储、消息队列)必须打日志(入参摘要 + 耗时 + 结果) +- 异常处理必须打 ERROR 日志(含堆栈和上下文) +- 不在日志中输出大段正文内容(截取前 100 字符) +- 不在日志中输出完整的 AI prompt(只记录 token 数和模型名) diff --git a/docs/dev-baseline/muse-admin/docs/dev-guide/03-测试编写指南.md b/docs/dev-baseline/muse-admin/docs/dev-guide/03-测试编写指南.md new file mode 100644 index 00000000..a9938b79 --- /dev/null +++ b/docs/dev-baseline/muse-admin/docs/dev-guide/03-测试编写指南.md @@ -0,0 +1,90 @@ +# muse-admin 测试编写指南 + +## 1. 测试框架 + +- 单元测试:Vitest + Vue Test Utils +- 组件测试:@testing-library/vue(推荐)或 Vue Test Utils +- E2E 测试:Playwright(关键管理流程) + +## 2. 测试文件组织 + +测试文件放在被测文件同目录: + +``` +src/views/muse/governance/ +├── MetaSchemaList.vue +├── MetaSchemaList.test.ts +├── MetaSchemaForm.vue +└── MetaSchemaForm.test.ts +``` + +## 3. 组件测试模板 + +```typescript +import { describe, it, expect, vi } from 'vitest' +import { mount } from '@vue/test-utils' +import MetaSchemaList from './MetaSchemaList.vue' + +// Mock API +vi.mock('@/api/muse/governance', () => ({ + getMetaSchemaPage: vi.fn().mockResolvedValue({ + list: [{ id: 1, name: '角色属性', version: 'v3' }], + total: 1 + }) +})) + +describe('MetaSchemaList 元结构列表', () => { + it('应该正确渲染列表数据', async () => { + const wrapper = mount(MetaSchemaList) + await flushPromises() + expect(wrapper.text()).toContain('角色属性') + }) + + it('应该在点击新增时打开表单弹窗', async () => { + const wrapper = mount(MetaSchemaList) + await wrapper.find('[data-test="btn-create"]').trigger('click') + expect(wrapper.find('[data-test="form-dialog"]').exists()).toBe(true) + }) +}) +``` + +## 4. Composable 测试模板 + +```typescript +import { describe, it, expect } from 'vitest' +import { useMetaSchemaVersion } from './useMetaSchemaVersion' + +describe('useMetaSchemaVersion 版本兼容性检查', () => { + it('应该检测到不兼容的版本变更', () => { + const { isCompatible } = useMetaSchemaVersion() + const result = isCompatible('v2', 'v3', { removedFields: ['age'] }) + expect(result).toBe(false) + }) +}) +``` + +## 5. API Mock 策略 + +使用 vi.mock 模拟 API 模块: +- 列表接口返回固定数据 +- 创建/更新接口返回成功响应 +- 错误场景单独测试(网络错误、权限不足、数据冲突) + +## 6. 测试覆盖率 + +- 新增页面组件:行覆盖率 >= 70% +- 新增 composable/hook:分支覆盖率 >= 80% +- 关键业务逻辑(权限判断、状态转换):分支覆盖率 >= 90% + +## 7. E2E 测试(关键流程) + +只覆盖高风险管理流程: +- MetaSchema 发布流程(创建 → 编辑 → 发布 → 验证生效) +- 市场资产审核流程(提交 → 审核 → 上架/驳回) +- 权限配置流程(创建角色 → 分配权限 → 验证生效) + +## 8. 测试命名规范 + +- 测试文件:{组件名}.test.ts +- describe:中文描述被测对象 +- it:中文描述预期行为,格式"应该{预期行为}" diff --git a/docs/dev-baseline/muse-cloud/CLAUDE.md b/docs/dev-baseline/muse-cloud/CLAUDE.md index aa96cf50..ab30394d 100644 --- a/docs/dev-baseline/muse-cloud/CLAUDE.md +++ b/docs/dev-baseline/muse-cloud/CLAUDE.md @@ -119,7 +119,7 @@ AI 模块包级隔离: - 所有 DDL 变更必须通过 Flyway migration - Migration 文件命名:`V{版本号}__{描述}.sql`(双下划线分隔) - 每个 migration 文件头部注释说明变更目的和影响范围 -- 禁止在 migration 中使用 `DROP COLUMN`(用 `ALTER COLUMN SET DEFAULT` + 应用层忽略) +- 默认禁止 `DROP COLUMN`。确需清理废弃列时,走全局发布规范场景 C 流程(需人类确认 + 观察期后执行) - 索引命名:`idx_{表名}_{字段名}` - 唯一约束命名:`uk_{表名}_{字段名}` - 外键约束:不使用数据库外键,在应用层保证引用完整性 @@ -174,10 +174,10 @@ AI 模块包级隔离: ### 覆盖率要求 -- Domain 层:行覆盖率 >= 80% -- Application 层:分支覆盖率 >= 70% -- 新增代码:行覆盖率 >= 85% -- CI 中通过 JaCoCo 强制检查 +遵循全局总则 4.4 节定义的覆盖率基线: +- Domain 层:行覆盖率 >= 90% +- Application 层:分支覆盖率 >= 80% +- 新增代码:行覆盖率 >= 90% --- diff --git a/docs/dev-baseline/muse-studio/CLAUDE.md b/docs/dev-baseline/muse-studio/CLAUDE.md index 558c2b20..2bf36ead 100644 --- a/docs/dev-baseline/muse-studio/CLAUDE.md +++ b/docs/dev-baseline/muse-studio/CLAUDE.md @@ -419,15 +419,15 @@ describe('SceneCard 场景卡片', () => { ### 提交信息格式 ``` -{类型}({模块}): {描述} +{类型}({模块}): {中文描述} -类型:功能 | 修复 | 重构 | 样式 | 测试 | 文档 | 构建 | 杂务 +类型:feat | fix | refactor | style | test | docs | chore 模块:editor | agent | knowledge | market | account | common | api 示例: -功能(editor): 实现场景自动保存与 IndexedDB 缓存 -修复(agent): 修复 SSE 断线后未自动重连的问题 -测试(knowledge): 补充知识库上传组件单元测试 +feat(editor): 实现场景自动保存与 IndexedDB 缓存 +fix(agent): 修复 SSE 断线后未自动重连的问题 +test(knowledge): 补充知识库上传组件单元测试 ``` ### 分支命名 diff --git a/docs/dev-baseline/muse-studio/docs/dev-guide/01-开发环境搭建.md b/docs/dev-baseline/muse-studio/docs/dev-guide/01-开发环境搭建.md index 19617c28..fe0d2fbb 100644 --- a/docs/dev-baseline/muse-studio/docs/dev-guide/01-开发环境搭建.md +++ b/docs/dev-baseline/muse-studio/docs/dev-guide/01-开发环境搭建.md @@ -54,10 +54,10 @@ cp .env.example .env.local ```bash # API 基础地址(开发环境指向本地或测试服务器) -VITE_API_BASE_URL=http://localhost:8080/api/v1 +VITE_API_BASE_URL=http://localhost:48080/app-api # SSE 事件流地址 -VITE_SSE_BASE_URL=http://localhost:8080/sse +VITE_SSE_BASE_URL=http://localhost:48080/sse # 是否启用 MSW Mock(true 时拦截所有 API 请求) VITE_ENABLE_MSW=true @@ -106,13 +106,13 @@ export default defineConfig({ port: 5173, proxy: { // API 请求代理到后端服务 - '/api': { - target: 'http://localhost:8080', + '/app-api': { + target: 'http://localhost:48080', changeOrigin: true, }, // SSE 事件流代理(注意 WebSocket 升级) '/sse': { - target: 'http://localhost:8080', + target: 'http://localhost:48080', changeOrigin: true, // SSE 需要禁用响应缓冲 configure: (proxy) => { @@ -124,7 +124,7 @@ export default defineConfig({ }, // 静态资源代理(开发环境) '/uploads': { - target: 'http://localhost:8080', + target: 'http://localhost:48080', changeOrigin: true, }, },