786 lines
36 KiB
HTML
Raw Permalink 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.

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>muse-cloud 架构讲解包</title>
<link rel="stylesheet" href="assets/styles.css" />
</head>
<body>
<header class="site-header">
<div>
<p class="eyebrow">muse-cloud P1R Explainer</p>
<h1>muse-cloud 架构讲解包</h1>
<p class="lead">
面向初级后端工程师的主阅读入口:从真实 API 标准、OpenAPI 合同路径、请求生命周期、领域 owner、
P1R 阶段地图到排障流程,一次读完整。
</p>
</div>
<div class="header-facts" aria-label="关键口径">
<span>HTML authoritative</span>
<span>X-API-Version: 1</span>
<span>code/data/msg</span>
</div>
</header>
<div class="page-shell">
<nav class="side-nav" aria-label="讲解目录">
<a href="#overview">阅读口径</a>
<a href="#architecture">目标架构</a>
<a href="#openapi">OpenAPI 路径</a>
<a href="#lifecycle">请求生命周期</a>
<a href="#owners">领域 owner</a>
<a href="#stages">P1R 阶段</a>
<a href="#troubleshooting">快速排障</a>
<a href="#maintenance">维护规则</a>
</nav>
<aside class="quick-panel" aria-labelledby="quick-triage-title">
<div class="quick-panel-inner">
<p class="eyebrow">Quick triage</p>
<h2 id="quick-triage-title">先按症状缩小层级</h2>
<p>
选择症状会只显示匹配诊断项。移动端这里会出现在正文前,便于现场排障时先定位。
</p>
<div class="triage-actions" role="group" aria-label="诊断筛选">
<button type="button" data-filter="404">404</button>
<button type="button" data-filter="400">400</button>
<button type="button" data-filter="401-403">401/403</button>
<button type="button" data-filter="409">409</button>
<button type="button" data-filter="empty-list">空列表</button>
<button type="button" data-filter="accepted">accepted</button>
<button type="button" data-filter="adapter-failure">外部失败</button>
<button type="button" data-filter="response-shape">响应字段</button>
<button class="clear-filter" type="button" data-clear-filter>清除筛选</button>
</div>
<p class="quick-status" data-filter-status aria-live="polite">当前显示全部诊断项。</p>
</div>
</aside>
<main class="content">
<section
id="overview"
class="manual-section"
data-section
data-source="content/sources.md"
data-upstream="P1R real API design section 5 and README"
>
<div class="section-heading">
<p class="eyebrow">阅读口径</p>
<h2>这是讲解包,不是 API 完成证明</h2>
</div>
<p>
本页解释 P1R 阶段 muse-cloud 应如何落到真实后端架构。它可以帮助你读代码、查合同、定位问题,
但不能替代 API 完成矩阵、测试报告、真实环境验收记录。
</p>
<div class="warning-band" role="note">
<strong>以下形态不能算 P1R 完成:</strong>
catch-all 合同入口兜底、通用持久化响应替代领域服务、placeholder SSE 或固定事件、
空列表替代真实读模型、accepted task 没有进入成功/失败/取消/超时终态。
</div>
<dl class="definition-grid">
<div>
<dt>已验证事实</dt>
<dd>来自 OpenAPI 合同、当前 Java 类、规格文档或校验命令。</dd>
</div>
<div>
<dt>推断</dt>
<dd>基于架构规则给出的合理排障方向,仍需用代码、日志或测试证明。</dd>
</div>
<div>
<dt>维护备注</dt>
<dd><code>content/*.md</code> 只用于维护对照,不是权威正文。</dd>
</div>
</dl>
<p class="source-note">
来源:<code>content/sources.md</code>上游P1R real API design section 5 and README。
</p>
</section>
<section
id="architecture"
class="manual-section"
data-section
data-source="content/architecture.md"
data-upstream="P1R real API design section 7"
>
<div class="section-heading">
<p class="eyebrow">Architecture</p>
<h2>系统分层先看责任边界</h2>
</div>
<p>
P1R 的真实 API 不靠 Controller 直接拼响应,也不靠通用持久化层伪造完成。每一层都有明确职责、
禁止事项和定位证据。
</p>
<div class="architecture-flow" aria-label="muse-cloud 目标架构流向">
<span>Controller</span>
<span>Application Service</span>
<span>Domain</span>
<span>Persistence / Adapter</span>
<span>Assembler</span>
<span>CommonResult</span>
</div>
<div class="architecture-grid">
<article class="architecture-layer">
<h3>Controller</h3>
<dl>
<dt>负责什么</dt>
<dd>鉴权入口、参数校验、<code>X-API-Version: 1</code> 校验、DTO 转换和统一响应封装。</dd>
<dt>不应负责什么</dt>
<dd>业务规则、数据库访问、外部服务调用、手写业务 JSON。</dd>
<dt>定位证据</dt>
<dd>Controller 路由映射、OpenAPI operationId、版本头参数、响应类型断言。</dd>
</dl>
</article>
<article class="architecture-layer">
<h3>Application Service</h3>
<dl>
<dt>负责什么</dt>
<dd>用例编排、事务、幂等、权限摘要、跨模块 facade、任务创建、错误归一和响应组装。</dd>
<dt>不应负责什么</dt>
<dd>绕过领域 owner 直接写其他模块事实,或把通用 operation record 当业务结果。</dd>
<dt>定位证据</dt>
<dd><code>ContentAppService</code>、实现类、事务边界、幂等记录和用例测试。</dd>
</dl>
</article>
<article class="architecture-layer">
<h3>Domain</h3>
<dl>
<dt>负责什么</dt>
<dd>聚合状态机、不变式、版本冲突、授权快照消费规则和状态变化决策。</dd>
<dt>不应负责什么</dt>
<dd>依赖 Controller DTO、Yudao Web DTO 或外部 API DTO。</dd>
<dt>定位证据</dt>
<dd>领域服务、聚合规则、状态机测试、revision / expectedVersion 校验。</dd>
</dl>
</article>
<article class="architecture-layer">
<h3>Query / Assembler</h3>
<dl>
<dt>负责什么</dt>
<dd>读模型查询、DTO / VO 组装、OpenAPI response 对齐。</dd>
<dt>不应负责什么</dt>
<dd>把数据库表行、operation record 或 workflow task 原样暴露给前端。</dd>
<dt>定位证据</dt>
<dd>Query Service、Assembler、OpenAPI schema、响应快照或契约测试。</dd>
</dl>
</article>
<article class="architecture-layer">
<h3>Persistence Mapper</h3>
<dl>
<dt>负责什么</dt>
<dd>MyBatis Mapper、事务内持久化、唯一约束、owner / tenant 条件和查询 SQL。</dd>
<dt>不应负责什么</dt>
<dd>业务状态机决策、外部服务语义或跨 owner 的业务写入。</dd>
<dt>定位证据</dt>
<dd>Mapper、SQL、Flyway、唯一索引、owner 和 tenant 条件。</dd>
</dl>
</article>
<article class="architecture-layer">
<h3>External Adapter</h3>
<dl>
<dt>负责什么</dt>
<dd>New-API、RAGFlow、文件服务、SSE、任务执行器等外部边界。</dd>
<dt>不应负责什么</dt>
<dd>伪造外部成功、吞掉可恢复失败、隐藏超时和重试语义。</dd>
<dt>定位证据</dt>
<dd>adapter client、超时配置、错误映射、重试策略、集成测试。</dd>
</dl>
</article>
<article class="architecture-layer">
<h3>CommonResult</h3>
<dl>
<dt>负责什么</dt>
<dd>对外统一响应形态JSON 字段为 <code>code/data/msg</code></dd>
<dt>不应负责什么</dt>
<dd><code>message</code> 替代 <code>msg</code>,或用通用 JSON 行替代合同 DTO。</dd>
<dt>定位证据</dt>
<dd>OpenAPI base schema、Controller 返回类型、响应断言。</dd>
</dl>
</article>
</div>
<p class="source-note">
来源:<code>content/architecture.md</code>上游P1R real API design section 7。
</p>
</section>
<section
id="openapi"
class="manual-section"
data-section
data-source="content/openapi-paths.md"
data-upstream="docs/api-contracts/**/openapi.yaml"
>
<div class="section-heading">
<p class="eyebrow">OpenAPI</p>
<h2>合同 paths 是完整外部路径</h2>
</div>
<p>
<code>docs/api-contracts/**/openapi.yaml</code><code>paths</code> 键已经是完整外部路径。
讲解、排障和完成矩阵都应直接引用这些键,不应再描述为运行时追加入口前缀。
</p>
<div class="path-proof">
<div>
<span class="step-label">合同文件</span>
<code>docs/api-contracts/content/openapi.yaml</code>
</div>
<div>
<span class="step-label">完整路径</span>
<code>/app-api/muse/works</code>
<button type="button" class="copy-button" data-copy="/app-api/muse/works">复制</button>
</div>
<div>
<span class="step-label">operationId</span>
<code>listWorks</code>
<button type="button" class="copy-button" data-copy="listWorks">复制</button>
</div>
<div>
<span class="step-label">代码入口</span>
<code>AppContentController</code>
<code>ContentAppService</code>
</div>
</div>
<dl class="definition-grid">
<div>
<dt>入口侧</dt>
<dd><code>/app-api/muse/**</code> 是 app 入口,<code>/admin-api/muse/**</code> 是 admin 入口。</dd>
</div>
<div>
<dt>领域归属</dt>
<dd>app/admin 不决定 owner业务事实只能由 Content、Meta、Account 等领域模块拥有。</dd>
</div>
<div>
<dt>完成判断</dt>
<dd>operationId、Controller、Application Service、领域事实、测试和验收证据要一起看。</dd>
</div>
</dl>
<p class="source-note">
来源:<code>content/openapi-paths.md</code>;上游:<code>docs/api-contracts/content/openapi.yaml</code>
</p>
</section>
<section
id="lifecycle"
class="manual-section"
data-section
data-source="content/request-lifecycle.md"
data-upstream="P1R real API design section 5 and 7"
>
<div class="section-heading">
<p class="eyebrow">Lifecycle</p>
<h2>一次请求从入口走到 CommonResult</h2>
</div>
<div class="lifecycle-grid">
<article class="lifecycle-node">
<h3>HTTP Request</h3>
<dl>
<dt>常见问题</dt>
<dd>URL 写错、HTTP method 不匹配、app/admin 入口混用。</dd>
<dt>定位证据</dt>
<dd>OpenAPI path、Controller mapping、网关访问日志。</dd>
<dt>下一步</dt>
<dd>先核对合同完整路径,再看请求是否到达目标 Controller。</dd>
</dl>
</article>
<article class="lifecycle-node">
<h3>Version/Auth</h3>
<dl>
<dt>常见问题</dt>
<dd>缺少 <code>X-API-Version: 1</code>、登录态失效、RBAC 或 owner 拒绝。</dd>
<dt>定位证据</dt>
<dd>请求 header、Security 配置、权限日志、owner / tenant 条件。</dd>
<dt>下一步</dt>
<dd>补齐版本头后复测,再区分 401 登录问题和 403 权限问题。</dd>
</dl>
</article>
<article class="lifecycle-node">
<h3>Controller DTO</h3>
<dl>
<dt>常见问题</dt>
<dd>必填字段、枚举、分页参数或 schema 不符合合同。</dd>
<dt>定位证据</dt>
<dd>Request DTO、Bean Validation、OpenAPI requestBody 和 parameters。</dd>
<dt>下一步</dt>
<dd>用合同样例构造最小请求,确认错误来自 DTO 而不是业务层。</dd>
</dl>
</article>
<article class="lifecycle-node">
<h3>Application</h3>
<dl>
<dt>常见问题</dt>
<dd>事务边界缺失、幂等键重复、跨模块 facade 使用不当。</dd>
<dt>定位证据</dt>
<dd>Application Service 方法、事务注解、commandId 记录、用例测试。</dd>
<dt>下一步</dt>
<dd>确认用例是否进入专用服务,避免落到通用占位处理。</dd>
</dl>
</article>
<article class="lifecycle-node">
<h3>Domain</h3>
<dl>
<dt>常见问题</dt>
<dd>revision、expectedVersion、expectedStatus 或状态机前置条件冲突。</dd>
<dt>定位证据</dt>
<dd>领域规则、聚合状态、冲突错误码、状态机测试。</dd>
<dt>下一步</dt>
<dd>读取当前业务事实和版本,再判断应重试、刷新还是返回 409。</dd>
</dl>
</article>
<article class="lifecycle-node">
<h3>DB/Adapter</h3>
<dl>
<dt>常见问题</dt>
<dd>Mapper 条件漏 owner、外部服务超时、任务没有被执行器消费。</dd>
<dt>定位证据</dt>
<dd>SQL、Flyway、adapter 日志、outbox、workflow task。</dd>
<dt>下一步</dt>
<dd>区分数据库事实不存在、查询条件过滤掉、外部 adapter 失败三类问题。</dd>
</dl>
</article>
<article class="lifecycle-node">
<h3>Assembler</h3>
<dl>
<dt>常见问题</dt>
<dd>DTO 字段缺失、读模型和 OpenAPI response 不一致。</dd>
<dt>定位证据</dt>
<dd>Assembler、Query Service、OpenAPI response schema、契约测试。</dd>
<dt>下一步</dt>
<dd>不要直接改表结构响应,先对齐读模型和合同 DTO。</dd>
</dl>
</article>
<article class="lifecycle-node">
<h3>CommonResult</h3>
<dl>
<dt>常见问题</dt>
<dd>返回 <code>message</code>、遗漏 <code>data</code>、错误码和业务错误混乱。</dd>
<dt>定位证据</dt>
<dd>Controller 返回类型、OpenAPI base schema、响应断言。</dd>
<dt>下一步</dt>
<dd>保持 <code>code/data/msg</code> 外壳稳定,再定位 data 内部 DTO。</dd>
</dl>
</article>
</div>
<p class="source-note">
来源:<code>content/request-lifecycle.md</code>上游P1R real API design section 5 and 7。
</p>
</section>
<section
id="owners"
class="manual-section"
data-section
data-source="content/domain-owners.md"
data-upstream="P1R real API design section 5.3"
>
<div class="section-heading">
<p class="eyebrow">Owner Boundaries</p>
<h2>app/admin 不是领域 owner</h2>
</div>
<p>
入口侧只表示调用场景。业务事实的写入、状态推进和验收证据必须回到所属领域模块。
</p>
<div class="owner-table-wrap" aria-label="领域 owner 表格">
<table class="owner-table">
<thead>
<tr>
<th>领域</th>
<th>负责事实</th>
<th>典型依赖</th>
<th>不应越界</th>
</tr>
</thead>
<tbody>
<tr>
<th>Content</th>
<td>作品、章节、Block、导入导出、Suggestion Merge</td>
<td>File、AI suggestion</td>
<td>不直接拥有市场授权</td>
</tr>
<tr>
<th>Meta</th>
<td>MetaSchema、保护节点、功能链治理</td>
<td>PostgreSQL、审计</td>
<td>不把保护节点降级为用户槽位</td>
</tr>
<tr>
<th>Account</th>
<td>用户资料、权益、配额、用量、New-API 归因</td>
<td>New-API、账本</td>
<td>不允许请求体伪造归因</td>
</tr>
<tr>
<th>AI</th>
<td>Prompt、Agent、Tool Grant、任务、质量治理</td>
<td>New-API、SSE</td>
<td>不伪造 AI 调用成功</td>
</tr>
<tr>
<th>Knowledge</th>
<td>知识库、文档、切片、索引、图谱</td>
<td>RAGFlow、File</td>
<td>不用空列表代替索引结果</td>
</tr>
<tr>
<th>Market</th>
<td>资产、授权、安装、发布、申诉、handoff</td>
<td>Account、授权快照</td>
<td>不写目标领域绑定事实</td>
</tr>
<tr>
<th>Events</th>
<td>SSE、任务事件、跨端事件</td>
<td>Redis、SSE</td>
<td>不返回固定假事件</td>
</tr>
</tbody>
</table>
</div>
<div class="owner-cards" aria-label="移动端领域 owner 摘要">
<article>
<h3>Content</h3>
<p>作品、章节、Block、导入导出、Suggestion Merge不直接拥有市场授权。</p>
</article>
<article>
<h3>Meta</h3>
<p>MetaSchema、保护节点、功能链治理保护节点不能被用户槽位覆盖。</p>
</article>
<article>
<h3>Account</h3>
<p>用户资料、权益、配额、用量、New-API 归因;不信任请求体伪造归因。</p>
</article>
<article>
<h3>AI</h3>
<p>Prompt、Agent、Tool Grant、任务、质量治理不伪造 AI 调用成功。</p>
</article>
<article>
<h3>Knowledge</h3>
<p>知识库、文档、切片、索引、图谱;不用空列表代替索引结果。</p>
</article>
<article>
<h3>Market</h3>
<p>资产、授权、安装、发布、申诉、handoff不写目标领域绑定事实。</p>
</article>
<article>
<h3>Events</h3>
<p>SSE、任务事件、跨端事件不返回固定假事件。</p>
</article>
</div>
<p class="source-note">
来源:<code>content/domain-owners.md</code>上游P1R real API design section 5.3。
</p>
</section>
<section
id="stages"
class="manual-section"
data-section
data-source="content/p1r-stages.md"
data-upstream="P1R real API design section 10"
>
<div class="section-heading">
<p class="eyebrow">P1R Map</p>
<h2>阶段地图按证据推进,不按感觉打勾</h2>
</div>
<div class="stage-grid">
<article class="stage-card">
<h3>P1R-0 Baseline Gate</h3>
<dl>
<dt>负责领域</dt>
<dd>全量 OpenAPI operation 清点和完成矩阵。</dd>
<dt>真实能力</dt>
<dd>标注 owner、side、method、路径、写命令、外部依赖、异步属性和当前实现状态。</dd>
<dt>假完成形态</dt>
<dd>把基线审计结果直接标为 completed。</dd>
<dt>验收证据</dt>
<dd>机器可读矩阵、人类可审报告、可复跑检查命令。</dd>
</dl>
</article>
<article class="stage-card">
<h3>P1R-1 Content Real API</h3>
<dl>
<dt>负责领域</dt>
<dd>作品、章节、Block、导入导出、动态字段、来源归因、Suggestion Merge。</dd>
<dt>真实能力</dt>
<dd>核心内容 API 回到 OpenAPI DTO文件导入和导出产生真实产物。</dd>
<dt>假完成形态</dt>
<dd>空作品列表、固定详情、通用持久化行或未消费的 accepted task。</dd>
<dt>验收证据</dt>
<dd>Controller、ContentAppService、Mapper、文件任务、契约测试和真实环境冒烟。</dd>
</dl>
</article>
<article class="stage-card">
<h3>P1R-2 Meta Real API</h3>
<dl>
<dt>负责领域</dt>
<dd>MetaSchema、保护节点、功能链治理。</dd>
<dt>真实能力</dt>
<dd>版本、草稿、验证、影响预览、发布、激活、回滚、废弃和灰度规则。</dd>
<dt>假完成形态</dt>
<dd>保护节点被当作普通用户槽位,或激活版本没有唯一约束。</dd>
<dt>验收证据</dt>
<dd>expectedVersion、validationResultId、impactPreviewId、审计和状态机测试。</dd>
</dl>
</article>
<article class="stage-card">
<h3>P1R-3 Account Real API</h3>
<dl>
<dt>负责领域</dt>
<dd>用户资料、权益、配额、用量、购买/授权/发布记录聚合和 New-API 归因。</dd>
<dt>真实能力</dt>
<dd>绑定重验、调用归因、用量查询、导出下载和安全事件落到真实事实。</dd>
<dt>假完成形态</dt>
<dd>请求体任意声明归因,或用余额样例替代账本事实。</dd>
<dt>验收证据</dt>
<dd>真实 correlation/call 记录、owner 校验、导出凭证、账户聚合测试。</dd>
</dl>
</article>
<article class="stage-card">
<h3>P1R-4 AI Real API</h3>
<dl>
<dt>负责领域</dt>
<dd>Prompt、Agent、Tool Grant、任务、质量治理、访问日志和审计。</dd>
<dt>真实能力</dt>
<dd>AI task 调用真实 New-API任务支持成功、失败、取消、重试SSE 推送真实事件。</dd>
<dt>假完成形态</dt>
<dd>固定 AI 文本、placeholder SSE、runtime 自授权。</dd>
<dt>验收证据</dt>
<dd>New-API 调用记录、SSE/轮询终态、授权隔离测试、质量治理审计。</dd>
</dl>
</article>
<article class="stage-card">
<h3>P1R-5 Knowledge Real API</h3>
<dl>
<dt>负责领域</dt>
<dd>全局知识库、用户知识库、文档版本、切片、索引、图谱和知识草稿。</dd>
<dt>真实能力</dt>
<dd>文档进入 RAGFlow / 知识引擎,检索结果回到 Knowledge API。</dd>
<dt>假完成形态</dt>
<dd>上传后只存文件名,检索永远空列表,知识草稿不写 Canonical 事实。</dd>
<dt>验收证据</dt>
<dd>入库、切片、索引、检索、草稿确认和授权快照消费记录。</dd>
</dl>
</article>
<article class="stage-card">
<h3>P1R-6 Market Real API</h3>
<dl>
<dt>负责领域</dt>
<dd>资产、分类、推荐、收藏、购买、安装、发布、申诉和 handoff。</dd>
<dt>真实能力</dt>
<dd>购买和安装写授权、安装记录和账户聚合handoff 只交付来源授权摘要和 token。</dd>
<dt>假完成形态</dt>
<dd>Market 直接写目标领域绑定事实,或未完成 ADR 就开放作品资产高阶模式。</dd>
<dt>验收证据</dt>
<dd>授权快照、安装记录、发布审核、申诉审计、目标 owner 消费 precheck。</dd>
</dl>
</article>
<article class="stage-card">
<h3>P1R-7 End-to-End Acceptance</h3>
<dl>
<dt>负责领域</dt>
<dd>跨 Content、AI、Knowledge、Market、Account、Events 的真实环境闭环。</dd>
<dt>真实能力</dt>
<dd>创建作品、AI suggestion、知识索引、市场购买安装、账户用量和治理审计形成链路。</dd>
<dt>假完成形态</dt>
<dd>只跑单元测试或只看接口返回 200没有真实外部依赖和业务终态。</dd>
<dt>验收证据</dt>
<dd>真实 PG/Redis 启动、New-API 调用、RAG 检索、SSE/轮询终态、端到端报告。</dd>
</dl>
</article>
</div>
<p class="source-note">
来源:<code>content/p1r-stages.md</code>上游P1R real API design section 10。
</p>
</section>
<section
id="troubleshooting"
class="manual-section"
data-section
data-source="content/troubleshooting.md"
data-upstream="explainer design section 7.6"
>
<div class="section-heading">
<p class="eyebrow">Troubleshooting</p>
<h2>按症状进入排障,不跳层猜原因</h2>
</div>
<div class="diagnostic-list" data-diagnostic-list>
<article class="diagnostic-row" data-symptom="404">
<h3>404</h3>
<dl>
<dt>症状</dt>
<dd>请求没有命中目标 API或被 catch-all / 网关兜底吞掉。</dd>
<dt>优先定位层</dt>
<dd>OpenAPI 路径 / Controller。</dd>
<dt>检查项</dt>
<dd>合同完整路径、HTTP method、<code>/muse</code>、Controller mapping、路由注册。</dd>
<dt>下一步</dt>
<dd>先用 <code>/app-api/muse/works</code> 这类合同完整路径复测,再查 Controller。</dd>
<dt>证据</dt>
<dd><code>docs/api-contracts/**/openapi.yaml</code>、Controller 类、访问日志。</dd>
</dl>
</article>
<article class="diagnostic-row" data-symptom="400">
<h3>400</h3>
<dl>
<dt>症状</dt>
<dd>参数校验失败、版本头缺失、请求体不符合 schema。</dd>
<dt>优先定位层</dt>
<dd>Header / DTO。</dd>
<dt>检查项</dt>
<dd><code>X-API-Version: 1</code>、必填字段、枚举、分页参数、Bean Validation。</dd>
<dt>下一步</dt>
<dd>构造合同最小请求,确认是入口校验失败还是业务拒绝。</dd>
<dt>证据</dt>
<dd>OpenAPI parameters、requestBody、Request DTO、校验错误日志。</dd>
</dl>
</article>
<article class="diagnostic-row" data-symptom="401-403">
<h3>401/403</h3>
<dl>
<dt>症状</dt>
<dd>未登录、token 失效、权限不足、owner / tenant 不匹配。</dd>
<dt>优先定位层</dt>
<dd>Security。</dd>
<dt>检查项</dt>
<dd>登录态、RBAC、owner、tenant、来源授权、高危动作权限。</dd>
<dt>下一步</dt>
<dd>先区分认证失败和授权失败,再看后端条件是否只靠前端隐藏入口。</dd>
<dt>证据</dt>
<dd>Security 配置、权限日志、SQL owner 条件、审计记录。</dd>
</dl>
</article>
<article class="diagnostic-row" data-symptom="409">
<h3>409</h3>
<dl>
<dt>症状</dt>
<dd>重复命令、版本冲突、状态机前置条件不满足。</dd>
<dt>优先定位层</dt>
<dd>Domain / Idempotency。</dd>
<dt>检查项</dt>
<dd><code>commandId</code>、revision、expectedVersion、expectedStatus、状态机。</dd>
<dt>下一步</dt>
<dd>读取当前业务事实和幂等记录,判断应返回历史结果还是提示刷新。</dd>
<dt>证据</dt>
<dd>领域状态、幂等表、唯一索引、状态机测试。</dd>
</dl>
</article>
<article class="diagnostic-row" data-symptom="empty-list">
<h3>空列表但应有数据</h3>
<dl>
<dt>症状</dt>
<dd>接口返回成功但列表为空,实际应存在业务事实。</dd>
<dt>优先定位层</dt>
<dd>Query / Persistence。</dd>
<dt>检查项</dt>
<dd>owner 条件、tenant 条件、读模型刷新、mapper SQL、分页参数。</dd>
<dt>下一步</dt>
<dd>用同一用户和 tenant 查表,再确认 assembler 是否过滤或映射错误。</dd>
<dt>证据</dt>
<dd>数据库事实、Mapper SQL、Query Service、响应 DTO。</dd>
</dl>
</article>
<article class="diagnostic-row" data-symptom="accepted">
<h3>accepted 但不终态</h3>
<dl>
<dt>症状</dt>
<dd>创建任务返回 accepted但后续查询一直没有成功、失败、取消或超时终态。</dd>
<dt>优先定位层</dt>
<dd>Job / Adapter。</dd>
<dt>检查项</dt>
<dd>workflow task、outbox、执行器、外部服务回调、重试和补偿。</dd>
<dt>下一步</dt>
<dd>跟踪任务状态变化和执行器日志,不把 accepted 当完成。</dd>
<dt>证据</dt>
<dd>workflow task 记录、outbox、adapter 日志、任务状态测试。</dd>
</dl>
</article>
<article class="diagnostic-row" data-symptom="adapter-failure">
<h3>外部服务失败</h3>
<dl>
<dt>症状</dt>
<dd>New-API、RAGFlow、文件服务或 SSE 失败,业务无法形成真实闭环。</dd>
<dt>优先定位层</dt>
<dd>Adapter。</dd>
<dt>检查项</dt>
<dd>超时、认证、错误分类、重试、补偿、外部服务版本和凭据。</dd>
<dt>下一步</dt>
<dd>先诊断 root cause外部服务不可用时相关 API 只能标 blocked。</dd>
<dt>证据</dt>
<dd>adapter client 日志、配置、集成测试、外部调用记录。</dd>
</dl>
</article>
<article class="diagnostic-row" data-symptom="response-shape">
<h3>响应字段不对</h3>
<dl>
<dt>症状</dt>
<dd>返回外壳或 data 字段与 OpenAPI response 不一致。</dd>
<dt>优先定位层</dt>
<dd>DTO / CommonResult。</dd>
<dt>检查项</dt>
<dd><code>code/data/msg</code>、assembler、OpenAPI schema、禁止 <code>message</code> 替代 <code>msg</code></dd>
<dt>下一步</dt>
<dd>先固定 CommonResult 外壳,再逐项对齐 data 内的业务 DTO。</dd>
<dt>证据</dt>
<dd>OpenAPI base schema、Controller 返回类型、契约测试、响应快照。</dd>
</dl>
</article>
</div>
<p class="source-note">
来源:<code>content/troubleshooting.md</code>上游explainer design section 7.6。
</p>
</section>
<section
id="maintenance"
class="manual-section"
data-section
data-source="content/sources.md"
data-upstream="explainer maintenance rules"
>
<div class="section-heading">
<p class="eyebrow">Maintenance</p>
<h2>HTML 是权威阅读面Markdown 是非权威维护备注</h2>
</div>
<p>
后续规格、合同或代码变化时,先核对上游证据,再同步本页。<code>content/*.md</code> 用来提示维护边界,
不能覆盖 OpenAPI、P1R spec 或当前代码事实。
</p>
<div class="source-map">
<div><strong>architecture</strong><span>content/architecture.md</span><span>P1R real API design section 7</span></div>
<div><strong>openapi</strong><span>content/openapi-paths.md</span><span>docs/api-contracts/**/openapi.yaml</span></div>
<div><strong>lifecycle</strong><span>content/request-lifecycle.md</span><span>P1R real API design section 5 and 7</span></div>
<div><strong>owners</strong><span>content/domain-owners.md</span><span>P1R real API design section 5.3</span></div>
<div><strong>stages</strong><span>content/p1r-stages.md</span><span>P1R real API design section 10</span></div>
<div><strong>troubleshooting</strong><span>content/troubleshooting.md</span><span>explainer design section 7.6</span></div>
</div>
<p class="source-note">
来源:<code>content/sources.md</code>上游explainer maintenance rules。
</p>
</section>
</main>
</div>
<script src="assets/app.js" defer></script>
</body>
</html>