HTTP 接口规范
Record Kernel v2 固定提供 9 条路由:POST/GET /api/v2/records/:moduleCode、GET/PATCH /api/v2/records/:moduleCode/:recordId、POST /archive、POST /restore、GET /revisions、GET /executions、POST /features/:featureId;共 9 条获批路由,无 DELETE。Identity typed 快照的通用写入失败关闭,typed 读取也必须使用 v2 专用接口;非 typed legacy core 仅保留只读兼容。
Identity 通用 Record Kernel 的 create/update/archive/restore 统一返回 IDENTITY_DEDICATED_ENDPOINT_REQUIRED;typed 记录的通用详情、修订和执行历史读取同样要求 v2 专用接口。旧 v1 Identity 的 POST/PUT/archive/restore/DELETE/features 统一返回 HTTP 410 IDENTITY_LEGACY_WRITE_DISABLED,不会写入或删除 identity_record;GET/list/revisions/export 仅保留只读兼容。
响应合同
成功响应固定为 { data, meta: { requestId } }。普通失败响应固定为 { error: { code, message, requestId, details? } };只有 partial 功能的 HTTP 501 保留 { data: null, error } 联合响应,不能伪造业务成功数据。
@anenreo/contracts 通过 ApiErrorCode 联合类型限制三端错误码。服务端响应缺少合法错误正文时,Web/Mobile 只按 HTTP 状态降级为 PAYLOAD_INVALID、AUTH_REQUIRED、FORBIDDEN、HTTP_404、HTTP_409、HTTP_413、HTTP_429、HTTP_503 或 INTERNAL_ERROR;NETWORK_ERROR 只能由客户端在请求未到达服务端时生成。
Record Kernel 稳定错误矩阵
| HTTP | 稳定错误码 | 合同含义 |
|---|---|---|
| 400 | PAYLOAD_INVALID | DTO、公共字段或领域字段不合法;未声明字段也在此失败。 |
| 400 | RECORD_IDEMPOTENCY_KEY_REQUIRED | 创建记录或执行功能缺少 Idempotency-Key。 |
| 400 | FEATURE_MODULE_MISMATCH | featureId 与 URL moduleCode 不匹配。 |
| 400 | MEMORY_TEXT_DEDICATED_ENDPOINT_REQUIRED | MEM-001 必须使用专用 v2 入口。 |
| 400 | MEMORY_SLICE_DEDICATED_ENDPOINT_REQUIRED | MEM-002 必须使用专用 v2 入口。 |
| 400 | MEMORY_DRAFT_DEDICATED_ENDPOINT_REQUIRED | MEM-003 必须使用专用 v2 入口。 |
| 400 | MEMORY_REVISION_DEDICATED_ENDPOINT_REQUIRED | MEM-004 必须使用专用 v2 入口。 |
| 400 | MEMORY_AI_DRAFT_DEDICATED_ENDPOINT_REQUIRED | MEM-005 必须使用专用 v2 入口。 |
| 400 | MEMORY_TIME_DEDICATED_ENDPOINT_REQUIRED | MEM-006 必须使用专用 v2 入口。 |
| 400 | MEMORY_PRIVACY_DEDICATED_ENDPOINT_REQUIRED | MEM-007 必须使用专用 v2 入口。 |
| 400 | MEMORY_EXPORT_DEDICATED_ENDPOINT_REQUIRED | MEM-008 必须使用专用 v2 入口。 |
| 501 | IDENTITY_DEDICATED_ENDPOINT_REQUIRED | Identity typed 记录必须使用专用 v2 入口;通用入口不产生 JSON 或执行副作用。 |
| 400 | TAXONOMY_TAG_DEDICATED_ENDPOINT_REQUIRED | TAX-001 必须使用专用 v2 入口。 |
| 400 | TAXONOMY_CATEGORY_DEDICATED_ENDPOINT_REQUIRED | TAX-002 必须使用分类树专用 v2 入口。 |
| 400 | TAXONOMY_ALIAS_DEDICATED_ENDPOINT_REQUIRED | TAX-003 必须使用别名检索专用 v2 入口。 |
| 400 | TAXONOMY_GOVERNANCE_DEDICATED_ENDPOINT_REQUIRED | TAX-004 至 TAX-008 必须使用标签治理专用 v2 入口。 |
| 409 | TAXONOMY_TAG_NAME_CONFLICT | 当前 owner 内标签名称或别名规范化后冲突。 |
| 409 | TAXONOMY_CATEGORY_NAME_CONFLICT | 当前 owner 内分类名称或别名规范化后冲突。 |
| 409 | TAXONOMY_CATEGORY_PARENT_INVALID | 分类父节点不属于当前 owner、非 CATEGORY 或已停用。 |
| 409 | TAXONOMY_CATEGORY_DEPTH_EXCEEDED | 分类移动或创建将超过八层。 |
| 409 | TAXONOMY_CATEGORY_CYCLE | 分类父链形成自引用或祖先环。 |
| 401 | AUTH_REQUIRED | Cookie/Bearer 未形成有效 CurrentIdentity。 |
| 403 | FORBIDDEN | 已认证但没有平台操作权限。 |
| 404 | RECORD_MODULE_NOT_FOUND | moduleCode 不在 Catalog 白名单。 |
| 404 | RECORD_NOT_FOUND | 记录不存在、owner 不匹配或 module 不匹配。 |
| 404 | FEATURE_NOT_FOUND | 功能编号不存在。 |
| 410 | IDENTITY_LEGACY_WRITE_DISABLED | 旧版 Identity 写入口已停用,不写入或删除 legacy identity_record。 |
| 409 | REVISION_CONFLICT | 原子乐观锁冲突。 |
| 409 | IDEMPOTENCY_IN_PROGRESS | 相同幂等操作仍在处理。 |
| 501 | FEATURE_NOT_IMPLEMENTED | Catalog 中存在但领域闭环仍为 partial。 |
| 503 | SYSTEM_MAINTENANCE | Record Kernel 收敛迁移已冻结普通写入;读请求仍可继续。 |
| 500 | INTERNAL_ERROR | 未知异常或服务端一致性漂移。 |
DTO、记录 JSON 与 details 安全
recordId 与 cursor 必须是规范 26 位大写 ULID;title 最长 200、summary 最长 1000 个 Unicode code point。更新中的 payload 只覆盖顶层字段,payloadRemove 只删除顶层字段;同名字段不得同时设置和删除。公共 JSON 拒绝循环、类实例、访问器、Symbol、稀疏数组、危险原型键、非有限数字以及超出深度、节点和 UTF-8 字节上限的结构。
生产入口和 E2E 测试入口都启用 whitelist=true 与 forbidNonWhitelisted=true。客户端提交 ownerId 或其他 DTO 未声明字段时返回 HTTP 400 PAYLOAD_INVALID,owner 仍只来自服务端 CurrentIdentity。
错误 details 按错误码顶层字段白名单和递归敏感键/凭据形态清洗,只允许字段名、模块/功能编号、修订号和稳定操作名;不得返回正文、payload、snapshot、input/output、Token、Cookie、连接串或 Provider 响应。未携带公开稳定错误码的通用 HttpException 一律使用固定说明,不回显路由路径、平台内部消息或原始异常文本。历史内部码 IDEMPOTENCY_KEY_REQUIRED 只作为输入兼容,公开输出统一为 RECORD_IDEMPOTENCY_KEY_REQUIRED。持久化记录 module 漂移属于内部一致性错误,公开为 INTERNAL_ERROR。
幂等结果与功能门禁
新幂等结果使用带版本和策略名的 envelope。普通记录只保存 recordId + revision 最小引用,功能结果只额外保存 executionId;同键重放从 owner/module 边界内精确读取首次 revision/execution,不返回后来变化的最新记录,也不把 title、summary、payload、snapshot、input/output 或 MEM-001 原文写入幂等表。
目录状态为 partial 的功能在记录读取、幂等事务和持久化副作用之前返回 HTTP 501 FEATURE_NOT_IMPLEMENTED。功能编号不存在返回 FEATURE_NOT_FOUND;MEM-001 至 MEM-008 与 TAX-001 至 TAX-008 的通用入口分别返回稳定专用地址错误,并要求改用各自的 v2 专用接口。
维护窗口
普通记录、旧兼容模块、MEM-001、Capture、两套 seed 与未来服务端 Outbox replay 在跨实例维护期间返回 HTTP 503 SYSTEM_MAINTENANCE;安全 details 只包含固定 scope 和 entryPoint。读请求保持可用。该错误是业务维护状态,不得进入 Mobile 普通 Outbox,也不得被客户端改写成网络成功。
根 test:e2e 必须显式执行 API E2E、Web 测试以及 platform、feature、legacy-route 三组 Playwright 审计;缺少浏览器门禁时不得声称完成跨端验收。v2 无 DELETE/永久销毁端点。本地 Swagger:http://127.0.0.1:4000/api/docs