Files
lixi 5f02909af6
CI / docs-build (push) Failing after 1s
docs(api): M3.5 契约冻结 v1.4.0——用户资料与头像
按 iteration-3.5/03 号报告定型表冻结第一波后端交付,相对 v1.3.0 纯增量
(无字段删改、无类型变更、无必填收紧),v1.3.0 客户端无需改动:

- GET /api/v1/me 响应补 nickname(DB 原值、不做 username 回退)与
  avatarUrl(时效性预签名 GET,会过期、客户端不得持久化),两者键恒在值可空
- 新增 PATCH /api/v1/me:三态部分更新(键缺省=不改 / 显式 null=清空 /
  给值=设置),空 patch 与纯空白昵称 400/40000,无乐观锁无幂等键
- Pet 补 avatarUrl(列表/详情/创建/更新四处统一);PATCH /api/v1/pets/{petId}
  收三态 avatarAssetId,补 404/40405 与 422/42203 两格,权限按本次触及字段
  定档(仅头像 WRITE、触及资料 MANAGE、混合取更严)
- 新增 GET /api/v1/me/community-stats:receivedLikeCount/publishedPostCount
  (int64,空数据 0,永不 404),聚合口径逐条进描述
- 两处均不外露 avatarAssetId(只写不读,"有头像"等价 avatarUrl != null)
- 媒体 purpose 白名单枚举追加 user_avatar/pet_avatar
- 零新增错误码:复用 40000/40101/40300/40400/40401/40405/40902/42203,
  错误码表只补语义(40300/40405/42203 三行)

规模 31→32 路径 / 43→45 操作 / 72→75 schemas(UpdateMeRequest、
CommunityStats、CommunityStatsEnvelope——后者为与全 API「每个 200 响应引一个
XxxEnvelope」的既有形态保持一致,故比 03 号报告预估多一个)。
校验:yaml 解析通过、96 处 $ref 全解析、45 个 operationId 无重复、
零未引用 schema、mkdocs build --strict 通过。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 10:19:19 +08:00

37 lines
5.1 KiB
Markdown
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.
# API 契约
正式契约见 [openapi.yaml](openapi.yaml)OpenAPI 3v1.4.0),当前 32 路径 / 45 操作:
- 认证域(第一迭代冻结):注册、登录、刷新、退出、当前用户 5 个端点,统一错误信封 `{code, message, data}` 与错误码表,以及会话轮换与登录锁定策略说明。
- 埋点域(M2 第一波补录):`POST /api/v1/events` 批量上报产品事件——单批 1–50 条、202 逐条结果(accepted/duplicate/rejected)、`eventId` 幂等去重、唯一允许匿名的写端点(携带 Bearer 则完整校验)。
- 宠物健康档案域(M2 第二波冻结,12 路径;冻结报告为 iteration-2 的 19 号报告,波末入档):
- 宠物 CRUD`GET/POST /api/v1/pets``GET/PATCH /api/v1/pets/{petId}`(乐观锁、防枚举 404/40401、MANAGE 仅 owner
- 只读字典:`GET /api/v1/breeds``GET /api/v1/vaccine-catalog``?species=` 过滤)
- 体重记录:`GET/POST /api/v1/pets/{petId}/weights`cursor 分页正典 `{items, nextCursor, hasMore}`
- 疫苗记录:`GET/POST /api/v1/pets/{petId}/vaccinations``PATCH /api/v1/vaccinations/{vaccinationId}`(状态机 422/42201、剂次唯一 409/40904
- 健康事件:`GET/POST /api/v1/pets/{petId}/health-events``PATCH /api/v1/health-events/{eventId}`cursor 分页、金额整数分)
- 照护提醒:`GET/POST /api/v1/pets/{petId}/care-reminders``PATCH /api/v1/care-reminders/{reminderId}``?status=` 过滤、流转 422/42202
- 档案聚合:`GET /api/v1/pets/{petId}/summary`(最新体重、疫苗进度、下次接种、当月花费;`?tz=` 缺省 UTC
权限三档 READ/WRITE/MANAGEADR-015 三角色)、创建返回 201、PATCH 不支持清空回 null、四个记录类 POST 支持可选 `Idempotency-Key`;错误码新增 40300/40401/40402/40902/40903/40904/42201/42202。
- 社区与媒体域(M3 第二波冻结,13 路径;冻结报告为 iteration-3 的 18 号报告,波末入档):
- 媒体两步上传:`POST /api/v1/media/uploads``POST /api/v1/media/uploads/{assetId}/complete`(预签名 PUT 直传 + HEAD 校验确认;私有桶,一切读取 URL 为时效性预签名 GET)
- 帖子生命周期:`POST /api/v1/posts``GET/PATCH/DELETE /api/v1/posts/{postId}``GET /api/v1/me/posts`(草稿/编辑/发布/软删;发布 = `PATCH {status: published}`,乐观锁 409/40902,防枚举 404/40403
- 公共 Feed`GET /api/v1/feed``(published_at, id)` keyset 游标;FeedCard = 200 码点摘要 + 唯一封面行 + 计数)
- 单层评论:`GET/POST /api/v1/posts/{postId}/comments``DELETE /api/v1/comments/{commentId}`@ 回复 `replyToUserId`;仅评论作者可删,帖主不可删他人评论)
- 点赞/收藏:`PUT/DELETE /api/v1/posts/{postId}/like|bookmark``GET /api/v1/me/bookmarks`PUT/DELETE 语义幂等,响应回 `{liked, likeCount}` 族权威终态;收藏列表失效帖静默剔除)
- 关注最小接口:`PUT/DELETE /api/v1/users/{userId}/follow``GET /api/v1/users/{userId}/follow-stats`(自关注 422/42204,自取关 200 幂等 no-op
创建型写入(发帖/评论)`Idempotency-Key` **必带**1~128,比对规范化 request_hash,与 pets 域可选键刻意不同);互动面 = 帖子公开面(作者本人草稿在互动路径同样 404);错误码新增 40301/40403/40404/40405/40406/40905/42203/42204/42205。
- 用户资料与头像(M3.5 第一波冻结,1 新路径 / 2 新操作;冻结报告为 iteration-3.5 的 04 号报告,波末入档):
- 本人资料读写:`GET/PATCH /api/v1/me``nickname` + `avatarUrl` 读,昵称与头像写;**三态部分更新**:键缺省 = 不改 / 显式 `null` = 清空 / 给值 = 设置;空 patch 400/40000;无乐观锁、无幂等键)
- 宠物头像:`Pet.avatarUrl`(列表/详情/创建/更新四处统一)+ `PATCH /api/v1/pets/{petId}``avatarAssetId`(三态;权限**按本次触及字段定档**——仅头像 WRITE、触及资料字段 MANAGE、混合取更严)
- 我的社区数字:`GET /api/v1/me/community-stats``receivedLikeCount`/`publishedPostCount`,读侧实时聚合,空数据 0,**永不 404**)
- 媒体 `purpose` 白名单追加 `user_avatar`/`pet_avatar`(枚举纯追加)
头像读取一律为**时效性预签名 GET**(会过期、客户端不得持久化);`avatarAssetId` **只写不读**,「有头像」等价 `avatarUrl != null`;三种用途互不通用(不符 404/40405,未就绪 422/42203)。**零新增错误码**(复用 40000/40101/40300/40400/40401/40405/40902/42203),故本次错误码表只补语义不加号。
约定:契约变更须先改本文件目录下的 OpenAPI,再改实现(契约先行);错误码只增不改义;**pets 域已冻结(1.2.0)、community/media 域已冻结(1.3.0)、用户资料与头像已冻结(1.4.0)——冻结后任何字段变更须显著上报、两端同步**。v1.4.0 相对 v1.3.0 **纯增量**(新增操作/响应字段/可选请求字段/响应格/枚举追加),v1.3.0 客户端无需改动。