oh-my-muse/docs/superpowers/plans/2026-05-24-Muse四仓执行计划.md
zizi f6f85e431d feat(plan): 添加 Muse 四仓主执行计划(Phase 0 完整 + P1-P4 概要)
Phase 0 含 11 个 Task:6 模块 OpenAPI 契约 + 类型生成 + 完整性校验
2026-05-24 14:00:44 +08:00

2791 lines
75 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Muse 四仓开发 — 主执行计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**目标:** 从零搭建 Muse 四仓muse-cloud / muse-studio / muse-admin实现 6 个业务模块全量 API + 双前端,完成集成切换和质量加固。
**架构:** API-first + 三仓并行。Phase 0 在本仓产出 OpenAPI 3.0 契约文件Phase 1 三仓并行开发(后端逐步产出真实 API前端先 Mock 独立开发Phase 2 按模块逐个切换真实 API 并完成质量加固。
**技术栈:** Java 21 + Spring Boot 3 + PostgreSQL 16 + Yudao Cloud后端| React + Vite + TypeScript + TanStack Query + Tiptap用户端| Vue 3 + Vben Admin + TypeScript管理端
---
## 子计划索引
本计划覆盖 18 周、4 个代码仓库。按子系统拆分为 5 个子计划:
| # | 子计划 | 仓库 | 周期 | 状态 |
|---|--------|------|------|------|
| P0 | [API 契约冻结](#phase-0-api-契约冻结) | muse-design-docs | Week 1-2 | 就绪 |
| P1 | [muse-cloud 后端搭建](docs/superpowers/plans/2026-05-24-P1-muse-cloud.md)(待创建) | muse-cloud | Week 3-16 | P0 完成后 |
| P2 | [muse-studio 用户端搭建](docs/superpowers/plans/2026-05-24-P2-muse-studio.md)(待创建) | muse-studio | Week 3-16 | P0 完成后 |
| P3 | [muse-admin 管理端搭建](docs/superpowers/plans/2026-05-24-P3-muse-admin.md)(待创建) | muse-admin | Week 3-16 | P0 完成后 |
| P4 | [集成切换 + 质量加固](docs/superpowers/plans/2026-05-24-P4-集成切换.md)(待创建) | 四仓联合 | Week 9-18 | P1-P3 部分完成后 |
**依赖关系:**
```mermaid
graph TD
P0[P0: API 契约冻结] --> P1[P1: muse-cloud 后端]
P0 --> P2[P2: muse-studio 用户端]
P0 --> P3[P3: muse-admin 管理端]
P1 --> P4[P4: 集成切换]
P2 --> P4
P3 --> P4
```
---
## 前置条件
- [x] Spec: `docs/superpowers/specs/2026-05-24-Muse四仓开发计划-design.md`
- [x] 设计文档 SSOT: `design-docs/` 下 30+ 份正式文档
- [x] AI 开发管理基线: `docs/dev-baseline/` 下各仓规范
- [x] muse-cloud fork 完成Yudao Cloud
- [x] muse-admin fork 完成Vben Admin
- [ ] muse-studio 需从零创建
---
## Phase 0: API 契约冻结
**仓库:** muse-design-docs本仓
**周期:** Week 1-2
**输入:** `design-docs/后端-05-统一API契约-v1.md`767 行146+ 接口)
**输出:** 6 个模块的 OpenAPI 3.0 YAML + TypeScript 类型包 + Java DTO 骨架
### Task 0.0: 准备工作
**文件:**
- 创建: `docs/api-contracts/openapi-base.yaml`
- 创建: `docs/api-contracts/content/openapi.yaml`
- 创建: `docs/api-contracts/ai/openapi.yaml`
- 创建: `docs/api-contracts/knowledge/openapi.yaml`
- 创建: `docs/api-contracts/market/openapi.yaml`
- 创建: `docs/api-contracts/account/openapi.yaml`
- 创建: `docs/api-contracts/meta/openapi.yaml`
- 创建: `docs/api-contracts/generated/typescript/.gitkeep`
- 创建: `docs/api-contracts/generated/java/.gitkeep`
- [ ] **Step 1: 创建目录结构**
```bash
mkdir -p docs/api-contracts/{content,ai,knowledge,market,account,meta,generated/typescript,generated/java}
```
- [ ] **Step 2: 提交空目录结构(含 .gitkeep**
```bash
touch docs/api-contracts/generated/typescript/.gitkeep
touch docs/api-contracts/generated/java/.gitkeep
git add docs/api-contracts/
git commit -m "feat(api): 初始化 API 契约目录结构"
```
### Task 0.1: 编写 openapi-base.yaml全局配置
**文件:**
- 创建: `docs/api-contracts/openapi-base.yaml`
- 参考: `design-docs/后端-05-统一API契约-v1.md` 全局约定章节
- 参考: `design-docs/架构-03-关键决策与原则(ADR).md` ADR-010 (API 版本)
- [ ] **Step 1: 从设计文档提取全局配置信息**
阅读 `后端-05` 中的:
- 认证方式Bearer Token / OAuth2
- 分页格式pageNo + pageSizeCommonResult<T> 包裹)
- 错误格式system-module-category-sequence 四段式错误码)
- API 版本策略X-API-Version Header
- 通用响应格式code + message + data
- [ ] **Step 2: 编写 openapi-base.yaml**
```yaml
openapi: 3.0.3
info:
title: Muse API
description: |
Muse AI 驱动长篇创作平台统一 API 契约。
所有接口通过 X-API-Version Header 进行版本控制。
version: 1.0.0
contact:
name: Muse Team
servers:
- url: http://localhost:48080
description: 本地开发环境
security:
- bearerAuth: []
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
用户端使用 app-api token管理端使用 admin-api token。
两个端点的认证域独立token 不互通。
parameters:
XApiVersion:
name: X-API-Version
in: header
required: false
schema:
type: string
default: "2026-05-01"
description: API 版本号,格式 YYYY-MM-DD
pageNo:
name: pageNo
in: query
required: false
schema:
type: integer
minimum: 1
default: 1
description: 页码,从 1 开始
pageSize:
name: pageSize
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: 每页条数,上限 100
schemas:
CommonResult:
type: object
required: [code, message]
properties:
code:
type: integer
description: 业务状态码0 表示成功
example: 0
message:
type: string
description: 提示信息
example: "操作成功"
data:
description: 响应数据,类型视具体接口而定
PaginatedResult:
type: object
required: [total, pageNo, pageSize, list]
properties:
total:
type: integer
description: 总记录数
example: 150
pageNo:
type: integer
description: 当前页码
example: 1
pageSize:
type: integer
description: 每页条数
example: 20
list:
type: array
description: 当前页数据列表
ErrorResponse:
type: object
required: [code, message]
properties:
code:
type: string
description: |
错误码格式: {system}-{module}-{category}-{sequence}
示例: MUSE-CONTENT-001-0001
example: "MUSE-CONTENT-001-0001"
message:
type: string
description: 人类可读的错误描述
detail:
type: string
description: 详细错误信息(仅开发环境返回)
# 通用时间戳字段
TimestampMixin:
type: object
properties:
createdAt:
type: string
format: date-time
description: 创建时间
updatedAt:
type: string
format: date-time
description: 最后更新时间
responses:
BadRequest:
description: 请求参数有误
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: 未认证或 token 过期
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Forbidden:
description: 无权限
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: 资源不存在
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Conflict:
description: 资源冲突
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
InternalError:
description: 服务器内部错误
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
tags:
- name: Content
description: 作品、章节、Block、导出
- name: AI
description: AI 生成、候选管理、智能体、质量门控
- name: Knowledge
description: 知识实体、关系、草稿、确认
- name: Market
description: 资产发布、安装绑定、审核
- name: Account
description: 权益、配额、用量、安全事件
- name: Meta
description: MetaSchema 字段定义、版本、scope
```
- [ ] **Step 3: 提交**
```bash
git add docs/api-contracts/openapi-base.yaml
git commit -m "feat(api): 添加 OpenAPI 全局基础配置(认证/分页/错误格式/版本)"
```
### Task 0.2: 编写 Content 模块 OpenAPI
**文件:**
- 创建: `docs/api-contracts/content/openapi.yaml`
- 参考: `design-docs/后端-05-统一API契约-v1.md` Content 模块章节
- [ ] **Step 1: 从 API 契约文档提取 Content 模块接口列表**
Content 模块包含:
- 作品(Work) CRUD
- 章节(Chapter) CRUD + 排序
- Block CRUD + 分割/合并
- 导出TXT/EPUB/DOCX
- [ ] **Step 2: 编写 content/openapi.yaml**
```yaml
openapi: 3.0.3
info:
title: Muse Content API
version: 1.0.0
paths:
# ========== 作品(Work) ==========
/app-api/content/works:
get:
tags: [Content]
summary: 获取作品列表
operationId: listWorks
parameters:
- $ref: '../openapi-base.yaml#/components/parameters/pageNo'
- $ref: '../openapi-base.yaml#/components/parameters/pageSize'
- name: status
in: query
schema:
type: string
enum: [draft, active, archived]
description: 作品状态过滤
responses:
'200':
description: 作品分页列表
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/PaginatedResult'
- type: object
properties:
list:
type: array
items:
$ref: '#/components/schemas/WorkSummary'
post:
tags: [Content]
summary: 创建新作品
operationId: createWork
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [title]
properties:
title:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 2000
genre:
type: string
coverImageUrl:
type: string
format: uri
responses:
'201':
description: 作品创建成功
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/Work'
/app-api/content/works/{workId}:
get:
tags: [Content]
summary: 获取作品详情
operationId: getWork
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 作品详情
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/Work'
put:
tags: [Content]
summary: 更新作品
operationId: updateWork
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
maxLength: 200
description:
type: string
maxLength: 2000
genre:
type: string
coverImageUrl:
type: string
format: uri
status:
type: string
enum: [draft, active, archived]
responses:
'200':
description: 更新成功
content:
application/json:
schema:
$ref: '../openapi-base.yaml#/components/schemas/CommonResult'
delete:
tags: [Content]
summary: 删除作品
operationId: deleteWork
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 删除成功
'404':
$ref: '../openapi-base.yaml#/components/responses/NotFound'
# ========== 章节(Chapter) ==========
/app-api/content/works/{workId}/chapters:
get:
tags: [Content]
summary: 获取作品章节列表
operationId: listChapters
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 章节列表(按 sortOrder 排序)
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Chapter'
post:
tags: [Content]
summary: 创建章节
operationId: createChapter
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [title]
properties:
title:
type: string
minLength: 1
maxLength: 500
sortOrder:
type: integer
description: 插入位置,默认追加到末尾
responses:
'201':
description: 创建成功
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/Chapter'
/app-api/content/chapters/{chapterId}:
get:
tags: [Content]
summary: 获取章节详情
operationId: getChapter
parameters:
- name: chapterId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 章节详情(含 Block 列表)
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/ChapterDetail'
put:
tags: [Content]
summary: 更新章节
operationId: updateChapter
parameters:
- name: chapterId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
maxLength: 500
sortOrder:
type: integer
status:
type: string
enum: [draft, completed]
responses:
'200':
description: 更新成功
delete:
tags: [Content]
summary: 删除章节
operationId: deleteChapter
parameters:
- name: chapterId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 删除成功
/app-api/content/chapters/{chapterId}/reorder:
put:
tags: [Content]
summary: 调整章节排序
operationId: reorderChapters
parameters:
- name: chapterId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [newSortOrder]
properties:
newSortOrder:
type: integer
minimum: 0
responses:
'200':
description: 排序更新成功
# ========== Block ==========
/app-api/content/chapters/{chapterId}/blocks:
get:
tags: [Content]
summary: 获取章节 Block 列表
operationId: listBlocks
parameters:
- name: chapterId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Block 列表
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Block'
post:
tags: [Content]
summary: 创建 Block
operationId: createBlock
parameters:
- name: chapterId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [content, blockType]
properties:
content:
type: string
description: Block 正文内容JSON 格式的 ProseMirror 文档)
blockType:
type: string
enum: [scene, section, note]
description: Block 类型
sortOrder:
type: integer
title:
type: string
maxLength: 500
responses:
'201':
description: 创建成功
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/Block'
/app-api/content/blocks/{blockId}:
get:
tags: [Content]
summary: 获取 Block 详情
operationId: getBlock
parameters:
- name: blockId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Block 详情
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/Block'
put:
tags: [Content]
summary: 保存 Block 正文
operationId: saveBlock
parameters:
- name: blockId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [content, sourceVersion]
properties:
content:
type: string
description: Block 正文ProseMirror JSON
sourceVersion:
type: integer
description: 客户端持有的版本号,用于乐观锁冲突检测
responses:
'200':
description: 保存成功
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
type: object
properties:
newVersion:
type: integer
description: 保存后的新版本号
'409':
description: 版本冲突,需客户端处理
content:
application/json:
schema:
$ref: '../openapi-base.yaml#/components/schemas/ErrorResponse'
delete:
tags: [Content]
summary: 删除 Block
operationId: deleteBlock
parameters:
- name: blockId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 删除成功
/app-api/content/blocks/{blockId}/split:
post:
tags: [Content]
summary: 分割 Block
operationId: splitBlock
parameters:
- name: blockId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [splitPosition]
properties:
splitPosition:
type: integer
description: 分割位置(字符偏移量)
responses:
'200':
description: 分割成功,返回两个新 Block
/app-api/content/blocks/{blockId}/merge:
post:
tags: [Content]
summary: 合并 Block
operationId: mergeBlocks
parameters:
- name: blockId
in: path
required: true
schema:
type: string
format: uuid
description: 与下一个 Block 合并
responses:
'200':
description: 合并成功
# ========== 导出 ==========
/app-api/content/works/{workId}/export:
post:
tags: [Content]
summary: 导出作品
operationId: exportWork
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [format]
properties:
format:
type: string
enum: [txt, epub, docx]
includeChapters:
type: array
items:
type: string
format: uuid
description: 指定导出章节,空数组表示导出全部
responses:
'200':
description: 导出任务已创建,返回任务 ID 供轮询
'202':
description: 导出文件二进制流(小文件直接返回)
components:
schemas:
Work:
type: object
required: [id, title, status, createdAt, updatedAt]
properties:
id:
type: string
format: uuid
title:
type: string
description:
type: string
genre:
type: string
coverImageUrl:
type: string
format: uri
status:
type: string
enum: [draft, active, archived]
wordCount:
type: integer
description: 总字数
chapterCount:
type: integer
description: 章节数
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
WorkSummary:
type: object
required: [id, title, status, updatedAt]
properties:
id:
type: string
format: uuid
title:
type: string
genre:
type: string
status:
type: string
enum: [draft, active, archived]
wordCount:
type: integer
chapterCount:
type: integer
updatedAt:
type: string
format: date-time
Chapter:
type: object
required: [id, workId, title, sortOrder, status, createdAt, updatedAt]
properties:
id:
type: string
format: uuid
workId:
type: string
format: uuid
title:
type: string
sortOrder:
type: integer
status:
type: string
enum: [draft, completed]
wordCount:
type: integer
blockCount:
type: integer
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
ChapterDetail:
allOf:
- $ref: '#/components/schemas/Chapter'
- type: object
properties:
blocks:
type: array
items:
$ref: '#/components/schemas/Block'
Block:
type: object
required: [id, chapterId, blockType, content, sortOrder, version, createdAt, updatedAt]
properties:
id:
type: string
format: uuid
chapterId:
type: string
format: uuid
blockType:
type: string
enum: [scene, section, note]
title:
type: string
content:
type: string
description: ProseMirror JSON 格式的正文内容
sortOrder:
type: integer
version:
type: integer
description: 乐观锁版本号,每次保存 +1
wordCount:
type: integer
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
```
- [ ] **Step 3: 提交**
```bash
git add docs/api-contracts/content/openapi.yaml
git commit -m "feat(api): 添加 Content 模块 OpenAPI 契约(作品/章节/Block/导出)"
```
### Task 0.3: 编写 AI 模块 OpenAPI
**文件:**
- 创建: `docs/api-contracts/ai/openapi.yaml`
- 参考: `design-docs/后端-05-统一API契约-v1.md` AI 模块章节
- 参考: `design-docs/专题-03-AI编排上下文与质量评测实现规范.md`
- [ ] **Step 1: 提取 AI 模块接口**
AI 模块包含:
- 生成请求(提交生成任务)
- 候选(Candidate)管理(列表、详情、接受/拒绝)
- SSE 流式传输AI stream 独立端点)
- 智能体(Agent)管理(创建、配置、槽位绑定)
- 质量门控配置
- [ ] **Step 2: 编写 ai/openapi.yaml**
```yaml
openapi: 3.0.3
info:
title: Muse AI API
version: 1.0.0
paths:
# ========== AI 生成 ==========
/app-api/ai/generations:
post:
tags: [AI]
summary: 提交 AI 生成请求
operationId: requestGeneration
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [blockId, agentId]
properties:
blockId:
type: string
format: uuid
description: 目标 Block
agentId:
type: string
format: uuid
description: 使用的智能体
prompt:
type: string
description: 用户附加的提示词
contextBlocks:
type: array
items:
type: string
format: uuid
description: 上下文 Block ID 列表
responses:
'202':
description: 生成任务已提交
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
type: object
properties:
generationId:
type: string
format: uuid
/app-api/ai/generations/{generationId}:
get:
tags: [AI]
summary: 获取生成任务状态
operationId: getGenerationStatus
parameters:
- name: generationId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 生成状态
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/Generation'
# ========== SSE: AI Stream独立连接 ==========
/app-api/ai/generations/{generationId}/stream:
get:
tags: [AI]
summary: AI 生成 SSE 流
operationId: streamGeneration
parameters:
- name: generationId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: SSE 事件流
content:
text/event-stream:
schema:
type: string
description: |
事件类型:
- chunk: { "content": "文本片段", "sequenceNo": 1 }
- quality_check: { "dimension": "fluency", "score": 0.92, "passed": true }
- done: { "generationId": "uuid", "candidateId": "uuid" }
- error: { "code": "...", "message": "..." }
# ========== 候选(Candidate)管理 ==========
/app-api/ai/candidates:
get:
tags: [AI]
summary: 获取候选列表
operationId: listCandidates
parameters:
- name: blockId
in: query
required: true
schema:
type: string
format: uuid
- name: status
in: query
schema:
type: string
enum: [pending, accepted, rejected]
responses:
'200':
description: 候选列表
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Candidate'
/app-api/ai/candidates/{candidateId}:
get:
tags: [AI]
summary: 获取候选详情
operationId: getCandidate
parameters:
- name: candidateId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 候选详情(含生成内容 diff
/app-api/ai/candidates/{candidateId}/accept:
post:
tags: [AI]
summary: 接受候选
operationId: acceptCandidate
parameters:
- name: candidateId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
content:
application/json:
schema:
type: object
properties:
modifications:
type: string
description: 用户在接受前对候选内容的手动修改
responses:
'200':
description: 候选已接受Block 正文更新
'409':
description: 源版本已变更,需重新对比
$ref: '../openapi-base.yaml#/components/responses/Conflict'
/app-api/ai/candidates/{candidateId}/reject:
post:
tags: [AI]
summary: 拒绝候选
operationId: rejectCandidate
parameters:
- name: candidateId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
content:
application/json:
schema:
type: object
properties:
reason:
type: string
description: 拒绝原因(可选,用于改进生成质量)
responses:
'200':
description: 已拒绝
# ========== 智能体(Agent) ==========
/app-api/ai/agents:
get:
tags: [AI]
summary: 获取智能体列表
operationId: listAgents
parameters:
- $ref: '../openapi-base.yaml#/components/parameters/pageNo'
- $ref: '../openapi-base.yaml#/components/parameters/pageSize'
- name: type
in: query
schema:
type: string
enum: [config, custom]
description: 智能体类型
responses:
'200':
description: 智能体分页列表
post:
tags: [AI]
summary: 创建自定义智能体
operationId: createAgent
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name]
properties:
name:
type: string
maxLength: 100
description:
type: string
maxLength: 1000
promptTemplate:
type: string
description: 系统提示词模板
slotBindings:
type: object
description: 槽位绑定配置(知识库/MetaSchema/模型参数)
responses:
'201':
description: 创建成功
/app-api/ai/agents/{agentId}:
get:
tags: [AI]
summary: 获取智能体详情
operationId: getAgent
parameters:
- name: agentId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 智能体详情
put:
tags: [AI]
summary: 更新智能体配置
operationId: updateAgent
parameters:
- name: agentId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description:
type: string
promptTemplate:
type: string
slotBindings:
type: object
status:
type: string
enum: [active, archived]
responses:
'200':
description: 更新成功
delete:
tags: [AI]
summary: 删除自定义智能体
operationId: deleteAgent
parameters:
- name: agentId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 删除成功
# ========== 管理端: Prompt 模板管理 ==========
/admin-api/ai/prompt-templates:
get:
tags: [AI]
summary: 获取 Prompt 模板列表(管理端)
operationId: adminListPromptTemplates
parameters:
- $ref: '../openapi-base.yaml#/components/parameters/pageNo'
- $ref: '../openapi-base.yaml#/components/parameters/pageSize'
responses:
'200':
description: 模板分页列表
post:
tags: [AI]
summary: 创建 Prompt 模板(管理端)
operationId: adminCreatePromptTemplate
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, template]
properties:
name:
type: string
template:
type: string
variables:
type: array
items:
type: object
properties:
name:
type: string
type:
type: string
enum: [string, number, boolean]
required:
type: boolean
defaultValue:
type: string
responses:
'201':
description: 创建成功
/admin-api/ai/prompt-templates/{templateId}:
put:
tags: [AI]
summary: 更新 Prompt 模板(管理端)
operationId: adminUpdatePromptTemplate
parameters:
- name: templateId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 更新成功
delete:
tags: [AI]
summary: 删除 Prompt 模板(管理端)
operationId: adminDeletePromptTemplate
parameters:
- name: templateId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 删除成功
# ========== 管理端: 质量门控配置 ==========
/admin-api/ai/quality-gates:
get:
tags: [AI]
summary: 获取质量门控维度列表
operationId: adminListQualityGates
responses:
'200':
description: 质量门控维度列表
post:
tags: [AI]
summary: 创建质量门控维度
operationId: adminCreateQualityGate
responses:
'201':
description: 创建成功
/admin-api/ai/protection-nodes:
get:
tags: [AI]
summary: 获取保护节点列表
operationId: adminListProtectionNodes
responses:
'200':
description: 保护节点列表
post:
tags: [AI]
summary: 注册保护节点
operationId: adminCreateProtectionNode
responses:
'201':
description: 注册成功
components:
schemas:
Generation:
type: object
required: [id, blockId, agentId, status, createdAt]
properties:
id:
type: string
format: uuid
blockId:
type: string
format: uuid
agentId:
type: string
format: uuid
status:
type: string
enum: [pending, streaming, completed, failed]
candidateId:
type: string
format: uuid
description: 生成完成后关联的候选 ID
errorMessage:
type: string
createdAt:
type: string
format: date-time
Candidate:
type: object
required: [id, blockId, generationId, status, createdAt]
properties:
id:
type: string
format: uuid
blockId:
type: string
format: uuid
generationId:
type: string
format: uuid
agentId:
type: string
format: uuid
agentName:
type: string
status:
type: string
enum: [pending, accepted, rejected]
sourceVersion:
type: integer
description: 生成时的源 Block 版本号
diffSummary:
type: string
description: 变更摘要
qualityScores:
type: object
description: 各质量维度的评分
createdAt:
type: string
format: date-time
```
- [ ] **Step 3: 提交**
```bash
git add docs/api-contracts/ai/openapi.yaml
git commit -m "feat(api): 添加 AI 模块 OpenAPI 契约(生成/候选/SSE/智能体/管理端配置)"
```
### Task 0.4: 编写 Knowledge 模块 OpenAPI
**文件:**
- 创建: `docs/api-contracts/knowledge/openapi.yaml`
- 参考: `design-docs/后端-05-统一API契约-v1.md` Knowledge 模块章节
- [ ] **Step 1: 提取 Knowledge 模块接口**
Knowledge 模块包含:
- 知识实体(Entity) CRUD
- 知识关系(Relation) CRUD
- 知识草稿(Draft)管理
- 自动确认 + 手动确认
- 实体/关系可视化数据
- 知识来源管理
- [ ] **Step 2: 编写 knowledge/openapi.yaml**
```yaml
openapi: 3.0.3
info:
title: Muse Knowledge API
version: 1.0.0
paths:
# ========== 知识实体(Entity) ==========
/app-api/knowledge/works/{workId}/entities:
get:
tags: [Knowledge]
summary: 获取作品知识实体列表
operationId: listEntities
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
- name: status
in: query
schema:
type: string
enum: [confirmed, draft, conflicted]
- name: type
in: query
schema:
type: string
enum: [character, location, event, item, concept, note]
responses:
'200':
description: 实体列表
/app-api/knowledge/entities/{entityId}:
get:
tags: [Knowledge]
summary: 获取知识实体详情
operationId: getEntity
parameters:
- name: entityId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 实体详情(含关联关系和来源引用)
put:
tags: [Knowledge]
summary: 更新知识实体
operationId: updateEntity
parameters:
- name: entityId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description:
type: string
attributes:
type: object
description: 自定义属性键值对
responses:
'200':
description: 更新成功
# ========== 知识确认 ==========
/app-api/knowledge/entities/{entityId}/confirm:
post:
tags: [Knowledge]
summary: 手动确认知识实体
operationId: confirmEntity
description: |
知识实体的默认确认规则:
- 无冲突 + 非外部来源 + 置信度 > 阈值 → 自动确认
- 有冲突 或 外部来源 或 低置信度 → 需手动确认
parameters:
- name: entityId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
content:
application/json:
schema:
type: object
properties:
overrides:
type: object
description: 手动修正的属性值
responses:
'200':
description: 确认成功
/app-api/knowledge/entities/{entityId}/reject:
post:
tags: [Knowledge]
summary: 拒绝知识实体草稿
operationId: rejectEntity
parameters:
- name: entityId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
content:
application/json:
schema:
type: object
properties:
reason:
type: string
responses:
'200':
description: 已拒绝
# ========== 知识关系(Relation) ==========
/app-api/knowledge/entities/{entityId}/relations:
get:
tags: [Knowledge]
summary: 获取实体关联关系
operationId: listRelations
parameters:
- name: entityId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 关系列表
post:
tags: [Knowledge]
summary: 创建知识关系
operationId: createRelation
parameters:
- name: entityId
in: path
required: true
schema:
type: string
format: uuid
description: 源实体
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [targetEntityId, relationType]
properties:
targetEntityId:
type: string
format: uuid
relationType:
type: string
example: "knows"
description:
type: string
responses:
'201':
description: 创建成功
# ========== 知识图谱可视化 ==========
/app-api/knowledge/works/{workId}/graph:
get:
tags: [Knowledge]
summary: 获取知识图谱数据
operationId: getKnowledgeGraph
description: 返回节点和边的 JSON用于前端可视化渲染
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
- name: depth
in: query
schema:
type: integer
minimum: 1
maximum: 3
default: 2
description: 图谱展开深度
responses:
'200':
description: 图谱数据nodes + edges
# ========== 知识草稿(Draft) ==========
/app-api/knowledge/works/{workId}/drafts:
get:
tags: [Knowledge]
summary: 获取待处理知识草稿列表
operationId: listDrafts
parameters:
- name: workId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 草稿列表
```
- [ ] **Step 3: 提交**
```bash
git add docs/api-contracts/knowledge/openapi.yaml
git commit -m "feat(api): 添加 Knowledge 模块 OpenAPI 契约(实体/关系/草稿/确认/图谱)"
```
### Task 0.5: 编写 Market 模块 OpenAPI
**文件:**
- 创建: `docs/api-contracts/market/openapi.yaml`
- 参考: `design-docs/后端-05-统一API契约-v1.md` Market 模块章节
- [ ] **Step 1: 提取 Market 模块接口**
Market 模块包含:
- 资产(Asset)浏览、搜索、安装
- 资产发布(用户端提交 + 管理端审核)
- 绑定管理
- 管理端审核(上架/驳回/下架/召回)
- [ ] **Step 2: 编写 market/openapi.yaml**
```yaml
openapi: 3.0.3
info:
title: Muse Market API
version: 1.0.0
paths:
# ========== 用户端: 市场浏览 ==========
/app-api/market/assets:
get:
tags: [Market]
summary: 浏览市场资产
operationId: listAssets
parameters:
- $ref: '../openapi-base.yaml#/components/parameters/pageNo'
- $ref: '../openapi-base.yaml#/components/parameters/pageSize'
- name: type
in: query
schema:
type: string
enum: [agent, prompt_template, knowledge_source, metaschema]
- name: keyword
in: query
schema:
type: string
description: 搜索关键词
- name: sortBy
in: query
schema:
type: string
enum: [popular, newest, rating]
default: popular
responses:
'200':
description: 资产分页列表
/app-api/market/assets/{assetId}:
get:
tags: [Market]
summary: 获取资产详情
operationId: getAsset
parameters:
- name: assetId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 资产详情
# ========== 用户端: 安装与绑定 ==========
/app-api/market/assets/{assetId}/install:
post:
tags: [Market]
summary: 安装资产到我的工作区
operationId: installAsset
parameters:
- name: assetId
in: path
required: true
schema:
type: string
format: uuid
responses:
'201':
description: 安装成功
/app-api/market/installations:
get:
tags: [Market]
summary: 获取我的已安装资产
operationId: listInstallations
responses:
'200':
description: 已安装资产列表
/app-api/market/installations/{installationId}/bindings:
post:
tags: [Market]
summary: 绑定已安装资产到作品
operationId: bindInstallation
parameters:
- name: installationId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [workId]
properties:
workId:
type: string
format: uuid
slotConfig:
type: object
description: 槽位配置
responses:
'201':
description: 绑定成功
get:
tags: [Market]
summary: 获取资产的作品绑定列表
operationId: listBindings
parameters:
- name: installationId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 绑定列表
# ========== 用户端: 资产发布 ==========
/app-api/market/publish:
post:
tags: [Market]
summary: 发布资产到市场
operationId: publishAsset
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, type, sourceId]
properties:
name:
type: string
maxLength: 200
description:
type: string
maxLength: 5000
type:
type: string
enum: [agent, prompt_template, knowledge_source, metaschema]
sourceId:
type: string
format: uuid
description: 来源对象 ID
tags:
type: array
items:
type: string
coverImageUrl:
type: string
format: uri
responses:
'201':
description: 发布申请已提交,待审核
# ========== 管理端: 资产审核 ==========
/admin-api/market/reviews:
get:
tags: [Market]
summary: 获取待审核资产列表
operationId: adminListReviews
parameters:
- $ref: '../openapi-base.yaml#/components/parameters/pageNo'
- $ref: '../openapi-base.yaml#/components/parameters/pageSize'
- name: status
in: query
schema:
type: string
enum: [pending, approved, rejected]
responses:
'200':
description: 审核列表
/admin-api/market/reviews/{reviewId}/approve:
post:
tags: [Market]
summary: 审核通过
operationId: adminApproveAsset
parameters:
- name: reviewId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
content:
application/json:
schema:
type: object
properties:
note:
type: string
responses:
'200':
description: 已上架
/admin-api/market/reviews/{reviewId}/reject:
post:
tags: [Market]
summary: 审核驳回
operationId: adminRejectAsset
parameters:
- name: reviewId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [reason]
properties:
reason:
type: string
responses:
'200':
description: 已驳回
/admin-api/market/assets/{assetId}/delist:
post:
tags: [Market]
summary: 下架资产
operationId: adminDelistAsset
parameters:
- name: assetId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [reason]
properties:
reason:
type: string
responses:
'200':
description: 已下架
/admin-api/market/assets/{assetId}/recall:
post:
tags: [Market]
summary: 召回已安装资产
operationId: adminRecallAsset
parameters:
- name: assetId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [reason]
properties:
reason:
type: string
responses:
'200':
description: 已触发召回
```
- [ ] **Step 3: 提交**
```bash
git add docs/api-contracts/market/openapi.yaml
git commit -m "feat(api): 添加 Market 模块 OpenAPI 契约(浏览/安装/绑定/审核)"
```
### Task 0.6: 编写 Account 模块 OpenAPI
**文件:**
- 创建: `docs/api-contracts/account/openapi.yaml`
- 参考: `design-docs/后端-05-统一API契约-v1.md` Account 模块章节
- [ ] **Step 1: 提取 Account 模块接口**
Account 模块包含:
- 权益(Entitlement)查询
- 配额(Quota)查询 + 消费
- Token 用量统计
- 安全事件记录
- [ ] **Step 2: 编写 account/openapi.yaml**
```yaml
openapi: 3.0.3
info:
title: Muse Account API
version: 1.0.0
paths:
# ========== 权益(Entitlement) ==========
/app-api/account/entitlements:
get:
tags: [Account]
summary: 获取当前用户权益列表
operationId: listEntitlements
responses:
'200':
description: 权益列表
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Entitlement'
# ========== 配额(Quota) ==========
/app-api/account/quotas:
get:
tags: [Account]
summary: 获取当前用户配额
operationId: listQuotas
responses:
'200':
description: 配额列表
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Quota'
# ========== 用量(Usage) ==========
/app-api/account/usage/summary:
get:
tags: [Account]
summary: 获取用量摘要
operationId: getUsageSummary
parameters:
- name: period
in: query
schema:
type: string
enum: [today, week, month, billing_cycle]
default: month
responses:
'200':
description: 用量摘要
content:
application/json:
schema:
allOf:
- $ref: '../openapi-base.yaml#/components/schemas/CommonResult'
- type: object
properties:
data:
$ref: '#/components/schemas/UsageSummary'
/app-api/account/usage/tokens:
get:
tags: [Account]
summary: 获取 Token 用量明细
operationId: getTokenUsage
parameters:
- name: startDate
in: query
schema:
type: string
format: date
- name: endDate
in: query
schema:
type: string
format: date
responses:
'200':
description: Token 用量明细
# ========== 安全事件 ==========
/app-api/account/security-events:
get:
tags: [Account]
summary: 获取安全事件列表
operationId: listSecurityEvents
parameters:
- $ref: '../openapi-base.yaml#/components/parameters/pageNo'
- $ref: '../openapi-base.yaml#/components/parameters/pageSize'
responses:
'200':
description: 安全事件分页列表
# ========== 管理端 ==========
/admin-api/account/entitlements/{userId}:
get:
tags: [Account]
summary: 查看用户权益(管理端)
operationId: adminGetUserEntitlements
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 用户权益详情
put:
tags: [Account]
summary: 修改用户权益(管理端)
operationId: adminUpdateUserEntitlements
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [entitlements]
properties:
entitlements:
type: array
items:
type: object
properties:
resourceType:
type: string
limit:
type: integer
expiresAt:
type: string
format: date-time
reason:
type: string
description: 变更原因(写入审计日志)
responses:
'200':
description: 更新成功
components:
schemas:
Entitlement:
type: object
required: [id, resourceType, limit, used, expiresAt]
properties:
id:
type: string
format: uuid
resourceType:
type: string
description: 权益资源类型
limit:
type: integer
description: 额度上限(-1 表示无限制)
used:
type: integer
description: 已使用量
expiresAt:
type: string
format: date-time
Quota:
type: object
required: [id, resourceType, total, remaining, resetAt]
properties:
id:
type: string
format: uuid
resourceType:
type: string
total:
type: integer
remaining:
type: integer
resetAt:
type: string
format: date-time
description: 配额重置时间
UsageSummary:
type: object
properties:
totalTokens:
type: integer
totalGenerations:
type: integer
byModel:
type: object
description: 按模型的用量分布
byDate:
type: array
items:
type: object
properties:
date:
type: string
format: date
tokens:
type: integer
generations:
type: integer
```
- [ ] **Step 3: 提交**
```bash
git add docs/api-contracts/account/openapi.yaml
git commit -m "feat(api): 添加 Account 模块 OpenAPI 契约(权益/配额/用量/安全事件)"
```
### Task 0.7: 编写 Meta 模块 OpenAPI
**文件:**
- 创建: `docs/api-contracts/meta/openapi.yaml`
- 参考: `design-docs/后端-05-统一API契约-v1.md` Meta 模块章节
- [ ] **Step 1: 提取 Meta 模块接口**
Meta 模块包含 MetaSchema 的完整管理:
- 字段定义 CRUD
- 版本管理
- Scope 配置(全局/租户/用户/作品)
- [ ] **Step 2: 编写 meta/openapi.yaml**
```yaml
openapi: 3.0.3
info:
title: Muse MetaSchema API
version: 1.0.0
paths:
# ========== 字段定义 ==========
/admin-api/meta/schemas:
get:
tags: [Meta]
summary: 获取 MetaSchema 列表
operationId: adminListSchemas
parameters:
- $ref: '../openapi-base.yaml#/components/parameters/pageNo'
- $ref: '../openapi-base.yaml#/components/parameters/pageSize'
- name: scope
in: query
schema:
type: string
enum: [global, tenant, user, work]
responses:
'200':
description: MetaSchema 分页列表
post:
tags: [Meta]
summary: 创建 MetaSchema 定义
operationId: adminCreateSchema
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, fieldType, scope]
properties:
name:
type: string
description: 字段名(英文标识)
displayName:
type: string
description: 显示名称
fieldType:
type: string
enum: [string, text, number, boolean, date, enum, relation, json]
scope:
type: string
enum: [global, tenant, user, work]
description: 作用域
defaultValue:
description: 默认值
required:
type: boolean
default: false
enumValues:
type: array
items:
type: string
description: fieldType=enum 时的可选值
validationRules:
type: object
description: 校验规则min/max/pattern 等)
responses:
'201':
description: 创建成功
/admin-api/meta/schemas/{schemaId}:
get:
tags: [Meta]
summary: 获取 MetaSchema 详情
operationId: adminGetSchema
parameters:
- name: schemaId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: MetaSchema 详情(含版本历史)
put:
tags: [Meta]
summary: 更新 MetaSchema 定义
operationId: adminUpdateSchema
parameters:
- name: schemaId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
displayName:
type: string
defaultValue:
description: 默认值
required:
type: boolean
enumValues:
type: array
items:
type: string
validationRules:
type: object
responses:
'200':
description: 更新成功(自动创建新版本)
delete:
tags: [Meta]
summary: 删除 MetaSchema 定义
operationId: adminDeleteSchema
parameters:
- name: schemaId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 删除成功(软删除,已有数据不受影响)
'409':
description: 有数据引用时不允许删除
$ref: '../openapi-base.yaml#/components/responses/Conflict'
# ========== 版本管理 ==========
/admin-api/meta/schemas/{schemaId}/versions:
get:
tags: [Meta]
summary: 获取 MetaSchema 版本历史
operationId: adminListSchemaVersions
parameters:
- name: schemaId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 版本历史列表
/admin-api/meta/schemas/{schemaId}/versions/{version}:
get:
tags: [Meta]
summary: 获取指定版本详情
operationId: adminGetSchemaVersion
parameters:
- name: schemaId
in: path
required: true
schema:
type: string
format: uuid
- name: version
in: path
required: true
schema:
type: integer
responses:
'200':
description: 版本详情
/admin-api/meta/schemas/{schemaId}/rollback:
post:
tags: [Meta]
summary: 回滚到指定版本
operationId: adminRollbackSchema
parameters:
- name: schemaId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [targetVersion]
properties:
targetVersion:
type: integer
reason:
type: string
responses:
'200':
description: 回滚成功,创建新版本指向目标版本配置
```
- [ ] **Step 3: 提交**
```bash
git add docs/api-contracts/meta/openapi.yaml
git commit -m "feat(api): 添加 Meta 模块 OpenAPI 契约MetaSchema CRUD/版本/回滚)"
```
### Task 0.8: 契约完整性校验
- [ ] **Step 1: 接口数量验证**
统计各模块接口数,与 `后端-05` 设计文档对照:
```bash
echo "=== Content ===" && grep -c "operationId:" docs/api-contracts/content/openapi.yaml
echo "=== AI ===" && grep -c "operationId:" docs/api-contracts/ai/openapi.yaml
echo "=== Knowledge ===" && grep -c "operationId:" docs/api-contracts/knowledge/openapi.yaml
echo "=== Market ===" && grep -c "operationId:" docs/api-contracts/market/openapi.yaml
echo "=== Account ===" && grep -c "operationId:" docs/api-contracts/account/openapi.yaml
echo "=== Meta ===" && grep -c "operationId:" docs/api-contracts/meta/openapi.yaml
echo "=== Total ===" && grep -r "operationId:" docs/api-contracts/*/openapi.yaml docs/api-contracts/openapi-base.yaml 2>/dev/null | wc -l
```
- [ ] **Step 2: YAML 语法校验**
```bash
# 使用 Python 校验所有 YAML 文件
python3 -c "
import yaml, sys, glob
errors = []
for f in glob.glob('docs/api-contracts/**/*.yaml', recursive=True):
try:
with open(f) as fh:
yaml.safe_load(fh)
print(f'OK: {f}')
except Exception as e:
errors.append(f'{f}: {e}')
print(f'FAIL: {f}: {e}')
if errors:
print(f'\n{len(errors)} file(s) failed')
sys.exit(1)
else:
print('\nAll files valid')
"
```
- [ ] **Step 3: 交叉引用检查**
确认各模块 YAML 中的 `$ref` 路径正确指向 `openapi-base.yaml`,且被引用的 schema/response/parameter 确实存在。
- [ ] **Step 4: 与设计文档一致性复查**
逐模块对比 `后端-05-统一API契约-v1.md`
- 接口路径是否一致
- HTTP 方法是否一致
- 路径参数名是否一致
- Request/Response body 字段是否覆盖
- [ ] **Step 5: 提交**
```bash
git add docs/api-contracts/
git commit -m "feat(api): 完成 6 个模块 OpenAPI 契约文件 + 完整性校验通过"
```
### Task 0.9: 生成 TypeScript 类型包
**文件:**
- 创建: `docs/api-contracts/generated/typescript/` 下的类型文件
- 工具: `openapi-typescript` + `openapi-fetch`
- [ ] **Step 1: 安装代码生成工具**
```bash
# 在仓库根目录安装(或使用 npx
npm init -y --prefix /tmp/muse-api-gen
cd /tmp/muse-api-gen
npm install openapi-typescript @hey-api/openapi-ts
```
- [ ] **Step 2: 合并所有模块 YAML 为单一入口**
```bash
# 创建合并入口文件
cat > /tmp/muse-api-gen/openapi-merged.yaml << 'YAMLEND'
openapi: 3.0.3
info:
title: Muse API (Merged)
version: 1.0.0
paths: {}
components:
schemas: {}
YAMLEND
# 使用 yq 或手动合并各模块 paths
# 此处用简单方式:为每个模块分别生成类型,再合并 index.ts
```
- [ ] **Step 3: 为每个模块生成 TypeScript 类型**
```bash
cd /tmp/muse-api-gen
for module in content ai knowledge market account meta; do
npx openapi-typescript \
"/Users/qingse/Sync/local-git/oh-my-muse/docs/api-contracts/${module}/openapi.yaml" \
--output "/Users/qingse/Sync/local-git/oh-my-muse/docs/api-contracts/generated/typescript/${module}.ts"
done
```
- [ ] **Step 4: 生成共享组件类型**
```bash
npx openapi-typescript \
"/Users/qingse/Sync/local-git/oh-my-muse/docs/api-contracts/openapi-base.yaml" \
--output "/Users/qingse/Sync/local-git/oh-my-muse/docs/api-contracts/generated/typescript/base.ts"
```
- [ ] **Step 5: 编写 barrel 导出文件**
```typescript
// docs/api-contracts/generated/typescript/index.ts
// Muse API TypeScript 类型包入口
// 自动生成于 OpenAPI 3.0 契约文件,请勿手动编辑
export * from './base';
export * from './content';
export * from './ai';
export * from './knowledge';
export * from './market';
export * from './account';
export * from './meta';
// 重新导出通用工具类型
export type {
CommonResult,
PaginatedResult,
ErrorResponse,
TimestampMixin,
} from './base';
```
- [ ] **Step 6: 提交**
```bash
git add docs/api-contracts/generated/typescript/
git commit -m "feat(api): 从 OpenAPI 生成 TypeScript 类型包6 模块 + base"
```
### Task 0.10: 生成 Java DTO 骨架
**文件:**
- 创建: `docs/api-contracts/generated/java/` 下的 DTO 类
- 工具: `openapi-generator-cli`
- [ ] **Step 1: 准备 OpenAPI Generator 配置**
```bash
# 创建生成器配置
cat > /tmp/muse-api-gen/openapi-generator-config.yaml << 'EOF'
# OpenAPI Generator 配置 for Java DTO
generatorName: spring
library: spring-boot
inputSpec: /tmp/muse-api-gen/openapi-merged.yaml
outputDir: /Users/qingse/Sync/local-git/oh-my-muse/docs/api-contracts/generated/java
apiPackage: com.muse.api
modelPackage: com.muse.dto
generateApis: false
generateModels: true
generateApiTests: false
generateModelTests: false
generateApiDocumentation: false
generateModelDocumentation: false
skipValidateSpec: true
additionalProperties:
java21: true
useSpringBoot3: true
useJakartaEe: true
dateLibrary: java8
serializableModel: true
openApiNullable: false
EOF
```
- [ ] **Step 2: 执行代码生成**
```bash
npx @openapitools/openapi-generator-cli generate \
-c /tmp/muse-api-gen/openapi-generator-config.yaml
```
- [ ] **Step 3: 清理不需要的生成文件**
```bash
# 只保留 model/DTO 类,删除 API 接口和测试文件
rm -rf docs/api-contracts/generated/java/api/
rm -rf docs/api-contracts/generated/java/test/
rm -f docs/api-contracts/generated/java/pom.xml
rm -f docs/api-contracts/generated/java/README.md
```
- [ ] **Step 4: 提交**
```bash
git add docs/api-contracts/generated/java/
git commit -m "feat(api): 从 OpenAPI 生成 Java DTO 骨架6 模块)"
```
---
## Phase 0 完成标准
- [ ] 6 个模块的 openapi.yaml 全部通过 YAML 语法校验
- [ ] 接口总数 ≥ 146与设计文档对齐
- [ ] 交叉引用 $ref 路径全部有效
- [ ] TypeScript 类型包生成无报错
- [ ] Java DTO 骨架生成无报错
- [ ] 所有提交已推送到 gitea
---
## Phase 1-2 子计划概览
以下子计划在 Phase 0 完成后分别在各仓创建和展开:
### P1: muse-cloud 后端搭建Week 3-16
| Step | 内容 | 周期 | 关键输出 |
|------|------|------|----------|
| 1.1 | Yudao Cloud 基础调整包名、Docker Compose、.idea | Week 3 | 可启动的开发环境 |
| 1.2 | 数据库 Migration全量 DDL + Flyway | Week 3-4 | 建表 SQL 已执行 |
| 1.3 | 6 个业务模块骨架 | Week 5-8 | pom.xml + 包结构 + API 接口定义 |
| 1.4 | API 实现 Phase 1.1: content + account | Week 9-10 | 作品/章节/Block/权益/配额 API |
| 1.5 | API 实现 Phase 1.2: meta | Week 11 | MetaSchema CRUD API |
| 1.6 | API 实现 Phase 1.3: ai + knowledge | Week 12-14 | AI 生成/候选/智能体 + 知识实体/关系 |
| 1.7 | API 实现 Phase 1.4: market | Week 15-16 | 市场浏览/发布/审核 API |
### P2: muse-studio 用户端搭建Week 3-16
| Step | 内容 | 周期 | 关键输出 |
|------|------|------|----------|
| 2.1 | 工程脚手架Vite + React + TS + Tailwind + 路由) | Week 3-4 | 可启动的空 SPA |
| 2.2 | 核心基础设施MSW + SSE + IndexedDB + Zustand | Week 5-8 | Mock API 全覆盖 |
| 2.3 | 写作台(编辑器 + AI 生成 + 候选面板) | Week 9-12 | 核心创作流程 |
| 2.4 | 我的作品 + 工作台(列表/章节/Block | Week 13-14 | 作品管理 |
| 2.5 | 知识库 + 智能体 + 市场 + 个人中心 | Week 15-16 | 辅助功能 |
### P3: muse-admin 管理端搭建Week 3-16
| Step | 内容 | 周期 | 关键输出 |
|------|------|------|----------|
| 3.1 | 工程脚手架Vben Admin + 目录组织 + Mock | Week 3-4 | 可启动的管理端 |
| 3.2 | MetaSchema 管理页面 | Week 5-8 | 字段定义/版本/回滚 |
| 3.3 | 系统治理页面 | Week 9-12 | 用户/角色/审计 |
| 3.4 | AI 配置 + 市场治理 + 全局知识 | Week 13-16 | 管理端完整 |
### P4: 集成切换 + 质量加固Week 9-18
| Step | 内容 | 周期 |
|------|------|------|
| 4.1 | content+account 集成切换 | Week 9-10 |
| 4.2 | meta 集成切换 | Week 11 |
| 4.3 | ai+knowledge 集成切换 | Week 12-14 |
| 4.4 | market 集成切换 | Week 15-16 |
| 4.5 | 全量质量加固(测试/CI/安全) | Week 17-18 |
---
## 下一步
Phase 0 执行完成后:
1. 输出 6 个模块的 OpenAPI YAML + TypeScript 类型 + Java DTO
2. 创建 P1-P4 子计划(在各仓分别展开为详细任务)
3. 三仓并行启动 Phase 1