# API 契约 正式契约见 [openapi.yaml](openapi.yaml)(OpenAPI 3,v1.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/MANAGE(ADR-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 客户端无需改动。