222990e587
CI / docs-build (push) Successful in 1m19s
- 13~18 后端纵切六单报告(T2-03~08,测试 95→182) - 14 + openapi-pets-draft.yaml 契约起草档案 - 19 契约冻结报告(v1.2.0,22 项草案修正对照) - 20 契约一致性测试(快照机制 + 1 漂移修复) - 21 第二波收口总表(定型语义汇总,第三波接入依据) - mkdocs build --strict 通过 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1717 lines
48 KiB
YAML
1717 lines
48 KiB
YAML
openapi: 3.0.3
|
||
info:
|
||
title: Patbond API — Pets Domain (M2 Draft)
|
||
version: 1.2.0-draft
|
||
description: |
|
||
M2 宠物健康档案域契约草案(起草态,待 T2-03 权限/错误语义与 T2-08 聚合字段定型后冻结)。
|
||
|
||
本草案扩展既有 1.1.0 契约(6 端点:auth 4 + me 1 + events 1),增加 pets 域全部端点。
|
||
**未冻结,字段可能变更**;冻结后任何变更须显著上报、两端同步。
|
||
|
||
## Pets 域端点概览(本草案范围)
|
||
- 宠物 CRUD:GET/POST /api/v1/pets、GET/PATCH /api/v1/pets/{petId}
|
||
- 品种目录:GET /api/v1/breeds(按 species 过滤)
|
||
- 体重记录:GET/POST /api/v1/pets/{petId}/weights(cursor 分页)
|
||
- 疫苗目录:GET /api/v1/vaccine-catalog(按 species 过滤)
|
||
- 疫苗记录:GET/POST /api/v1/pets/{petId}/vaccinations、PATCH /api/v1/vaccinations/{vaccinationId}
|
||
- 健康事件:GET/POST /api/v1/pets/{petId}/health-events、PATCH /api/v1/health-events/{eventId}
|
||
- 照护提醒:GET/POST /api/v1/pets/{petId}/care-reminders、PATCH /api/v1/care-reminders/{reminderId}
|
||
- 档案聚合:GET /api/v1/pets/{petId}/summary(最新体重、疫苗进度、下次接种、当月花费)
|
||
|
||
## 通用约定(继承既有契约)
|
||
- 公开接口统一前缀 `/api/v1`;JSON 字段一律 `camelCase`;资源 ID 为 UUID 字符串。
|
||
- 所有时间字段为 ISO 8601 且带时区偏移(timestamptz 传输)。
|
||
- 统一响应信封 `{"code": 0, "message": "success", "data": …}`;错误同时携带正确的
|
||
HTTP 状态码与稳定业务码。
|
||
- Pets 域全部端点强制 Bearer 鉴权(`Authorization: Bearer <accessToken>`)。
|
||
|
||
## Pets 域新增错误码(追加进既有表,不改号)
|
||
| 业务码 | HTTP | 场景 |
|
||
| --- | --- | --- |
|
||
| 40300 | 403 | PET_ACCESS_DENIED:对可见宠物无相应操作权限(viewer 尝试写等) |
|
||
| 40401 | 404 | PET_NOT_FOUND:宠物不存在或调用者不可见(防 ID 枚举,不区分) |
|
||
| 40402 | 404 | RECORD_NOT_FOUND:宠物下的记录(体重/疫苗/事件/提醒)不存在 |
|
||
| 40902 | 409 | VERSION_CONFLICT:乐观锁版本冲突(PATCH 操作,version 过期) |
|
||
| 40903 | 409 | DUPLICATE_VACCINATION:同宠物同疫苗同系列同剂次非 cancelled 记录已存在 |
|
||
| 42200 | 422 | BREED_CONSTRAINT_VIOLATION:breed_id 与 custom_breed_name 未互斥 |
|
||
| 42201 | 422 | VACCINATION_STATE_INVALID:疫苗状态机非法迁移或日期约束违反 |
|
||
|
||
## 权限模型(ADR-015:owner/caregiver/viewer 三角色)
|
||
# TODO-FREEZE: 等待 T2-03 权限校验实现定型后,补齐每个端点的权限规则描述与错误响应示例。
|
||
# 草案默认:owner 全权、caregiver 可读写记录不可改宠物档案、viewer 只读;
|
||
# 无权限访问他人宠物返回 404/40401(不可见)或 403/40300(可见但越权)。
|
||
|
||
servers:
|
||
- url: http://127.0.0.1:8082
|
||
description: patbond-pet 模块(本地开发,与 user 同服务或独立端口)
|
||
|
||
tags:
|
||
- name: pets
|
||
description: 宠物档案 CRUD
|
||
- name: dictionaries
|
||
description: 品种与疫苗目录(只读)
|
||
- name: health-records
|
||
description: 体重、疫苗、健康事件、提醒
|
||
|
||
paths:
|
||
/api/v1/pets:
|
||
get:
|
||
tags: [pets]
|
||
summary: 当前用户可见宠物列表
|
||
description: |
|
||
返回当前用户拥有任何权限(owner/caregiver/viewer)的宠物列表。
|
||
# TODO-FREEZE: 列表是否分页待 T2-03 实现时定——量小建议不分页直接返回数组。
|
||
operationId: listPets
|
||
security:
|
||
- bearerAuth: []
|
||
responses:
|
||
'200':
|
||
description: 宠物列表
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/PetListEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
post:
|
||
tags: [pets]
|
||
summary: 创建宠物
|
||
description: |
|
||
创建宠物,创建者自动成为 primary owner(pet_owners 自动写入)。
|
||
品种:breed_id 与 custom_breed_name 必须二选一且互斥(ck_pets_breed 约束)。
|
||
operationId: createPet
|
||
security:
|
||
- bearerAuth: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreatePetRequest'
|
||
responses:
|
||
'201':
|
||
description: 创建成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/PetEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'422':
|
||
description: 业务约束违反(breed_id/custom_breed_name 互斥等,code 42200)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/pets/{petId}:
|
||
get:
|
||
tags: [pets]
|
||
summary: 宠物详情
|
||
description: |
|
||
返回宠物详情及调用者对该宠物的权限角色(role 字段)。
|
||
# TODO-FREEZE: 权限拒绝时 403 vs 404 的语义待 T2-03 定型。
|
||
operationId: getPet
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
'200':
|
||
description: 宠物详情
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/PetDetailEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
patch:
|
||
tags: [pets]
|
||
summary: 更新宠物档案
|
||
description: |
|
||
更新宠物档案(名称、品种、性别、生日等)。
|
||
请求体必须包含 `version` 乐观锁字段;冲突返回 409/40902。
|
||
# TODO-FREEZE: owner/caregiver 权限边界待 T2-03 定型(建议仅 owner 可写档案)。
|
||
operationId: updatePet
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UpdatePetRequest'
|
||
responses:
|
||
'200':
|
||
description: 更新成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/PetEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限更新(code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'409':
|
||
description: 版本冲突(code 40902)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'422':
|
||
description: 业务约束违反(code 42200)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/breeds:
|
||
get:
|
||
tags: [dictionaries]
|
||
summary: 品种目录
|
||
description: |
|
||
品种目录(只读),按 species 过滤。返回 enabled=true 的品种按 sort_order 排序。
|
||
operationId: listBreeds
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: species
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: string
|
||
enum: [dog, cat, other]
|
||
description: 过滤物种;不传则返回全部
|
||
responses:
|
||
'200':
|
||
description: 品种列表
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/BreedListEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
|
||
/api/v1/pets/{petId}/weights:
|
||
get:
|
||
tags: [health-records]
|
||
summary: 体重记录列表
|
||
description: |
|
||
体重记录按 measured_at DESC, id DESC 排序,cursor 分页。
|
||
operationId: listWeights
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 100
|
||
default: 20
|
||
- name: cursor
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: 上一页返回的 nextCursor,首次不传
|
||
responses:
|
||
'200':
|
||
description: 体重记录分页结果
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/WeightListEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
post:
|
||
tags: [health-records]
|
||
summary: 添加体重记录
|
||
description: |
|
||
添加体重记录。支持 Idempotency-Key(可选但推荐,避免重复提交)。
|
||
operationId: createWeight
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
- name: Idempotency-Key
|
||
in: header
|
||
required: false
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
description: 幂等键(可选),相同键重试不产生重复记录
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateWeightRequest'
|
||
responses:
|
||
'201':
|
||
description: 创建成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/WeightEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限添加(viewer 角色,code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/vaccine-catalog:
|
||
get:
|
||
tags: [dictionaries]
|
||
summary: 疫苗目录
|
||
description: |
|
||
疫苗目录(只读),按 species 过滤。返回 enabled=true 的疫苗。
|
||
operationId: listVaccineCatalog
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: species
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: string
|
||
enum: [dog, cat, other]
|
||
responses:
|
||
'200':
|
||
description: 疫苗目录列表
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/VaccineCatalogListEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
|
||
/api/v1/pets/{petId}/vaccinations:
|
||
get:
|
||
tags: [health-records]
|
||
summary: 疫苗记录列表
|
||
description: |
|
||
宠物的疫苗记录。不分页或按 administered_on/planned_on 排序分页(待定)。
|
||
# TODO-FREEZE: 分页策略待 T2-05 实现时定。
|
||
operationId: listVaccinations
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
'200':
|
||
description: 疫苗记录列表
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/VaccinationListEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
post:
|
||
tags: [health-records]
|
||
summary: 创建疫苗记录
|
||
description: |
|
||
创建疫苗记录(计划或已完成)。
|
||
状态机:scheduled 必须带 plannedOn;completed 必须带 administeredOn;
|
||
同宠物同疫苗同系列同剂次非 cancelled 记录唯一(uq_pet_vaccination_dose)。
|
||
# TODO-FREEZE: provider_id/booking_id/certificate_asset_id 按 ADR-010 不开放写入,
|
||
# 待 M5/媒体上传流程补齐后再开放,字段在草案保留但标记只读或不出现在请求体。
|
||
operationId: createVaccination
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
- name: Idempotency-Key
|
||
in: header
|
||
required: false
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateVaccinationRequest'
|
||
responses:
|
||
'201':
|
||
description: 创建成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/VaccinationEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限添加(code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'409':
|
||
description: 同系列同剂次记录已存在(code 40903)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'422':
|
||
description: 状态机或日期约束违反(code 42201)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/vaccinations/{vaccinationId}:
|
||
patch:
|
||
tags: [health-records]
|
||
summary: 更新疫苗记录
|
||
description: |
|
||
更新疫苗记录(状态流转、补充剂次标签、批号等)。
|
||
请求体必须包含 `version` 乐观锁;冲突返回 409/40902。
|
||
operationId: updateVaccination
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: vaccinationId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UpdateVaccinationRequest'
|
||
responses:
|
||
'200':
|
||
description: 更新成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/VaccinationEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限更新(code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 记录不存在(code 40402)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'409':
|
||
description: 版本冲突(code 40902)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'422':
|
||
description: 状态机或日期约束违反(code 42201)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/pets/{petId}/health-events:
|
||
get:
|
||
tags: [health-records]
|
||
summary: 健康事件时间线
|
||
description: |
|
||
健康事件按 occurredAt DESC, id DESC 排序,cursor 分页。
|
||
operationId: listHealthEvents
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 100
|
||
default: 20
|
||
- name: cursor
|
||
in: query
|
||
schema:
|
||
type: string
|
||
responses:
|
||
'200':
|
||
description: 健康事件分页结果
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/HealthEventListEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
post:
|
||
tags: [health-records]
|
||
summary: 添加健康事件
|
||
description: |
|
||
添加健康事件。六类事件类型:medical/feeding/deworming/grooming/measurement/note。
|
||
金额以整数分(amount_cents)传输,非负。
|
||
# TODO-FREEZE: provider_id/booking_id 按 ADR-010 不开放写入。
|
||
operationId: createHealthEvent
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
- name: Idempotency-Key
|
||
in: header
|
||
required: false
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateHealthEventRequest'
|
||
responses:
|
||
'201':
|
||
description: 创建成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/HealthEventEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限添加(code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/health-events/{eventId}:
|
||
patch:
|
||
tags: [health-records]
|
||
summary: 更新健康事件
|
||
description: |
|
||
编辑健康事件(标题、备注、金额)。请求体必须包含 `version` 乐观锁。
|
||
operationId: updateHealthEvent
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: eventId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UpdateHealthEventRequest'
|
||
responses:
|
||
'200':
|
||
description: 更新成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/HealthEventEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限更新(code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 记录不存在(code 40402)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'409':
|
||
description: 版本冲突(code 40902)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/pets/{petId}/care-reminders:
|
||
get:
|
||
tags: [health-records]
|
||
summary: 照护提醒列表
|
||
description: |
|
||
照护提醒列表,按 dueAt 排序。四类提醒类型:deworming/checkup/medication/other。
|
||
# TODO-FREEZE: 是否分页、过滤待办(status=pending)的查询参数待 T2-07 实现时定。
|
||
operationId: listCareReminders
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
'200':
|
||
description: 提醒列表
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CareReminderListEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
post:
|
||
tags: [health-records]
|
||
summary: 创建照护提醒
|
||
description: |
|
||
创建提醒(M2 仅 app 内数据,不做推送,ADR-010 说明)。
|
||
operationId: createCareReminder
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CreateCareReminderRequest'
|
||
responses:
|
||
'201':
|
||
description: 创建成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CareReminderEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限添加(code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/care-reminders/{reminderId}:
|
||
patch:
|
||
tags: [health-records]
|
||
summary: 更新提醒状态
|
||
description: |
|
||
标记提醒完成或忽略(pending → completed/dismissed)。
|
||
completed 状态必须写入 completedAt(ck_care_reminder_completed 约束)。
|
||
operationId: updateCareReminder
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: reminderId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/UpdateCareReminderRequest'
|
||
responses:
|
||
'200':
|
||
description: 更新成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CareReminderEnvelope'
|
||
'400':
|
||
$ref: '#/components/responses/ValidationError'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'403':
|
||
description: 无权限更新(code 40300)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'404':
|
||
description: 记录不存在(code 40402)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
'422':
|
||
description: 状态与 completedAt 一致性违反(code 42201 复用)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
/api/v1/pets/{petId}/summary:
|
||
get:
|
||
tags: [health-records]
|
||
summary: 档案聚合摘要
|
||
description: |
|
||
实时聚合生成档案页摘要:最新体重、疫苗进度、下次接种、当月花费。
|
||
# TODO-FREEZE: 等待 T2-08 聚合字段定型——字段命名、月度边界口径(UTC 或指定时区)、
|
||
# 疫苗进度分母计算规则(总剂次 vs 已登记剂次)、下次接种取值优先级等。
|
||
# 草案字段为占位,冻结前可能变更。
|
||
operationId: getPetSummary
|
||
security:
|
||
- bearerAuth: []
|
||
parameters:
|
||
- name: petId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
'200':
|
||
description: 聚合摘要
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/PetSummaryEnvelope'
|
||
'401':
|
||
$ref: '#/components/responses/AccessTokenInvalid'
|
||
'404':
|
||
description: 宠物不存在或不可见(code 40401)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
|
||
components:
|
||
securitySchemes:
|
||
bearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
bearerFormat: JWT
|
||
description: 'Authorization: Bearer <accessToken>(RS256 JWT)'
|
||
|
||
responses:
|
||
ValidationError:
|
||
description: 参数校验失败(code 40000)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
examples:
|
||
validation:
|
||
value: { code: 40000, message: 参数校验失败, data: null }
|
||
AccessTokenInvalid:
|
||
description: access token 缺失、无效或过期(code 40101)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorEnvelope'
|
||
examples:
|
||
tokenInvalid:
|
||
value: { code: 40101, message: token 无效或过期, data: null }
|
||
|
||
schemas:
|
||
ErrorEnvelope:
|
||
type: object
|
||
required: [code, message]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
description: 稳定业务错误码
|
||
example: 40401
|
||
message:
|
||
type: string
|
||
example: 宠物不存在或不可见
|
||
data:
|
||
nullable: true
|
||
example: null
|
||
|
||
# ========== Pets CRUD ==========
|
||
Pet:
|
||
type: object
|
||
required:
|
||
- petId
|
||
- name
|
||
- species
|
||
- sex
|
||
- status
|
||
- createdAt
|
||
- updatedAt
|
||
- version
|
||
properties:
|
||
petId:
|
||
type: string
|
||
format: uuid
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
species:
|
||
type: string
|
||
enum: [dog, cat, other]
|
||
breedId:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
description: 品种 ID(与 customBreedName 互斥)
|
||
customBreedName:
|
||
type: string
|
||
nullable: true
|
||
minLength: 1
|
||
maxLength: 64
|
||
description: 自定义品种名(与 breedId 互斥)
|
||
sex:
|
||
type: string
|
||
enum: [male, female, unknown]
|
||
birthDate:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
description: 生日(YYYY-MM-DD)
|
||
birthDateEstimated:
|
||
type: boolean
|
||
description: 生日是否为估计值
|
||
personality:
|
||
type: string
|
||
nullable: true
|
||
maxLength: 64
|
||
description: 性格标签
|
||
avatarAssetId:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
description: 头像 asset ID(M2 不开放写入,ADR-010)
|
||
microchipNo:
|
||
type: string
|
||
nullable: true
|
||
description: 芯片号(唯一)
|
||
sterilizedOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
description: 绝育日期
|
||
status:
|
||
type: string
|
||
enum: [active, lost, deceased, archived, deleted]
|
||
description: 状态(deleted 为软删除)
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
version:
|
||
type: integer
|
||
description: 乐观锁版本号(PATCH 时必须提交)
|
||
|
||
PetDetail:
|
||
allOf:
|
||
- $ref: '#/components/schemas/Pet'
|
||
- type: object
|
||
required: [myRole]
|
||
properties:
|
||
myRole:
|
||
type: string
|
||
enum: [owner, caregiver, viewer]
|
||
description: 调用者对该宠物的权限角色
|
||
|
||
CreatePetRequest:
|
||
type: object
|
||
required: [name, species, sex]
|
||
properties:
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
species:
|
||
type: string
|
||
enum: [dog, cat, other]
|
||
breedId:
|
||
type: string
|
||
format: uuid
|
||
description: 品种 ID(与 customBreedName 二选一)
|
||
customBreedName:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
description: 自定义品种名(与 breedId 二选一)
|
||
sex:
|
||
type: string
|
||
enum: [male, female, unknown]
|
||
birthDate:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
birthDateEstimated:
|
||
type: boolean
|
||
default: false
|
||
personality:
|
||
type: string
|
||
maxLength: 64
|
||
microchipNo:
|
||
type: string
|
||
sterilizedOn:
|
||
type: string
|
||
format: date
|
||
|
||
UpdatePetRequest:
|
||
type: object
|
||
required: [version]
|
||
properties:
|
||
version:
|
||
type: integer
|
||
description: 当前持有的版本号(乐观锁)
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
breedId:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
customBreedName:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
nullable: true
|
||
sex:
|
||
type: string
|
||
enum: [male, female, unknown]
|
||
birthDate:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
birthDateEstimated:
|
||
type: boolean
|
||
personality:
|
||
type: string
|
||
maxLength: 64
|
||
nullable: true
|
||
microchipNo:
|
||
type: string
|
||
nullable: true
|
||
sterilizedOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
status:
|
||
type: string
|
||
enum: [active, lost, deceased, archived]
|
||
description: 状态流转(deleted 不开放)
|
||
|
||
PetEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
$ref: '#/components/schemas/Pet'
|
||
|
||
PetDetailEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
$ref: '#/components/schemas/PetDetail'
|
||
|
||
PetListEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Pet'
|
||
|
||
# ========== Breeds ==========
|
||
Breed:
|
||
type: object
|
||
required: [breedId, species, code, displayName]
|
||
properties:
|
||
breedId:
|
||
type: string
|
||
format: uuid
|
||
species:
|
||
type: string
|
||
enum: [dog, cat, other]
|
||
code:
|
||
type: string
|
||
description: 品种代码(唯一标识)
|
||
displayName:
|
||
type: string
|
||
description: 展示名称
|
||
|
||
BreedListEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Breed'
|
||
|
||
# ========== Weights ==========
|
||
WeightRecord:
|
||
type: object
|
||
required: [weightId, petId, weightKg, measuredAt, source, createdAt]
|
||
properties:
|
||
weightId:
|
||
type: string
|
||
format: uuid
|
||
petId:
|
||
type: string
|
||
format: uuid
|
||
weightKg:
|
||
type: number
|
||
format: double
|
||
minimum: 0.01
|
||
maximum: 500
|
||
description: 体重(公斤),保留两位小数
|
||
measuredAt:
|
||
type: string
|
||
format: date-time
|
||
description: 称重时间
|
||
source:
|
||
type: string
|
||
enum: [manual, clinic, device]
|
||
description: 来源
|
||
note:
|
||
type: string
|
||
nullable: true
|
||
maxLength: 500
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
|
||
CreateWeightRequest:
|
||
type: object
|
||
required: [weightKg, measuredAt]
|
||
properties:
|
||
weightKg:
|
||
type: number
|
||
format: double
|
||
minimum: 0.01
|
||
maximum: 500
|
||
measuredAt:
|
||
type: string
|
||
format: date-time
|
||
source:
|
||
type: string
|
||
enum: [manual, clinic, device]
|
||
default: manual
|
||
note:
|
||
type: string
|
||
maxLength: 500
|
||
|
||
WeightEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
$ref: '#/components/schemas/WeightRecord'
|
||
|
||
WeightListEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
type: object
|
||
required: [items, hasMore]
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/WeightRecord'
|
||
nextCursor:
|
||
type: string
|
||
nullable: true
|
||
description: 下一页游标,无更多时为 null
|
||
hasMore:
|
||
type: boolean
|
||
|
||
# ========== Vaccine Catalog ==========
|
||
VaccineCatalogItem:
|
||
type: object
|
||
required: [vaccineId, code, name, species]
|
||
properties:
|
||
vaccineId:
|
||
type: string
|
||
format: uuid
|
||
code:
|
||
type: string
|
||
description: 疫苗代码(唯一标识)
|
||
name:
|
||
type: string
|
||
description: 疫苗名称
|
||
species:
|
||
type: string
|
||
enum: [dog, cat, other]
|
||
description:
|
||
type: string
|
||
nullable: true
|
||
maxLength: 500
|
||
|
||
VaccineCatalogListEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/VaccineCatalogItem'
|
||
|
||
# ========== Vaccinations ==========
|
||
Vaccination:
|
||
type: object
|
||
required:
|
||
- vaccinationId
|
||
- petId
|
||
- vaccineId
|
||
- seriesKey
|
||
- doseNo
|
||
- status
|
||
- createdAt
|
||
- updatedAt
|
||
- version
|
||
properties:
|
||
vaccinationId:
|
||
type: string
|
||
format: uuid
|
||
petId:
|
||
type: string
|
||
format: uuid
|
||
vaccineId:
|
||
type: string
|
||
format: uuid
|
||
seriesKey:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
description: 系列键(区分初次/加强等,与 doseNo 共同唯一)
|
||
doseNo:
|
||
type: integer
|
||
minimum: 1
|
||
description: 剂次号
|
||
doseLabel:
|
||
type: string
|
||
nullable: true
|
||
maxLength: 64
|
||
description: 剂次标签(如"第一针")
|
||
status:
|
||
type: string
|
||
enum: [scheduled, completed, cancelled]
|
||
plannedOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
description: 计划接种日期(scheduled 必填)
|
||
administeredOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
description: 实际接种日期(completed 必填)
|
||
nextDueOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
description: 下次到期日期
|
||
manufacturer:
|
||
type: string
|
||
nullable: true
|
||
maxLength: 128
|
||
batchNo:
|
||
type: string
|
||
nullable: true
|
||
maxLength: 64
|
||
notes:
|
||
type: string
|
||
nullable: true
|
||
maxLength: 1000
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
version:
|
||
type: integer
|
||
|
||
CreateVaccinationRequest:
|
||
type: object
|
||
required: [vaccineId, seriesKey, doseNo, status]
|
||
properties:
|
||
vaccineId:
|
||
type: string
|
||
format: uuid
|
||
seriesKey:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 64
|
||
doseNo:
|
||
type: integer
|
||
minimum: 1
|
||
doseLabel:
|
||
type: string
|
||
maxLength: 64
|
||
status:
|
||
type: string
|
||
enum: [scheduled, completed, cancelled]
|
||
plannedOn:
|
||
type: string
|
||
format: date
|
||
description: scheduled 状态必填
|
||
administeredOn:
|
||
type: string
|
||
format: date
|
||
description: completed 状态必填
|
||
nextDueOn:
|
||
type: string
|
||
format: date
|
||
manufacturer:
|
||
type: string
|
||
maxLength: 128
|
||
batchNo:
|
||
type: string
|
||
maxLength: 64
|
||
notes:
|
||
type: string
|
||
maxLength: 1000
|
||
|
||
UpdateVaccinationRequest:
|
||
type: object
|
||
required: [version]
|
||
properties:
|
||
version:
|
||
type: integer
|
||
status:
|
||
type: string
|
||
enum: [scheduled, completed, cancelled]
|
||
plannedOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
administeredOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
nextDueOn:
|
||
type: string
|
||
format: date
|
||
nullable: true
|
||
doseLabel:
|
||
type: string
|
||
maxLength: 64
|
||
nullable: true
|
||
manufacturer:
|
||
type: string
|
||
maxLength: 128
|
||
nullable: true
|
||
batchNo:
|
||
type: string
|
||
maxLength: 64
|
||
nullable: true
|
||
notes:
|
||
type: string
|
||
maxLength: 1000
|
||
nullable: true
|
||
|
||
VaccinationEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
$ref: '#/components/schemas/Vaccination'
|
||
|
||
VaccinationListEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Vaccination'
|
||
|
||
# ========== Health Events ==========
|
||
HealthEvent:
|
||
type: object
|
||
required:
|
||
- eventId
|
||
- petId
|
||
- eventType
|
||
- occurredAt
|
||
- title
|
||
- createdByUserId
|
||
- createdAt
|
||
- updatedAt
|
||
- version
|
||
properties:
|
||
eventId:
|
||
type: string
|
||
format: uuid
|
||
petId:
|
||
type: string
|
||
format: uuid
|
||
eventType:
|
||
type: string
|
||
enum: [medical, feeding, deworming, grooming, measurement, note]
|
||
occurredAt:
|
||
type: string
|
||
format: date-time
|
||
description: 事件发生时间
|
||
title:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 160
|
||
notes:
|
||
type: string
|
||
nullable: true
|
||
description: 备注(text 长文本)
|
||
amountCents:
|
||
type: integer
|
||
format: int64
|
||
nullable: true
|
||
minimum: 0
|
||
description: 金额(整数分)
|
||
createdByUserId:
|
||
type: string
|
||
format: uuid
|
||
description: 创建者用户 ID
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
version:
|
||
type: integer
|
||
|
||
CreateHealthEventRequest:
|
||
type: object
|
||
required: [eventType, occurredAt, title]
|
||
properties:
|
||
eventType:
|
||
type: string
|
||
enum: [medical, feeding, deworming, grooming, measurement, note]
|
||
occurredAt:
|
||
type: string
|
||
format: date-time
|
||
title:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 160
|
||
notes:
|
||
type: string
|
||
amountCents:
|
||
type: integer
|
||
format: int64
|
||
minimum: 0
|
||
description: 金额(整数分)
|
||
|
||
UpdateHealthEventRequest:
|
||
type: object
|
||
required: [version]
|
||
properties:
|
||
version:
|
||
type: integer
|
||
title:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 160
|
||
notes:
|
||
type: string
|
||
nullable: true
|
||
amountCents:
|
||
type: integer
|
||
format: int64
|
||
minimum: 0
|
||
nullable: true
|
||
|
||
HealthEventEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
$ref: '#/components/schemas/HealthEvent'
|
||
|
||
HealthEventListEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
type: object
|
||
required: [items, hasMore]
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/HealthEvent'
|
||
nextCursor:
|
||
type: string
|
||
nullable: true
|
||
hasMore:
|
||
type: boolean
|
||
|
||
# ========== Care Reminders ==========
|
||
CareReminder:
|
||
type: object
|
||
required:
|
||
- reminderId
|
||
- petId
|
||
- reminderType
|
||
- title
|
||
- dueAt
|
||
- status
|
||
- createdAt
|
||
- updatedAt
|
||
properties:
|
||
reminderId:
|
||
type: string
|
||
format: uuid
|
||
petId:
|
||
type: string
|
||
format: uuid
|
||
reminderType:
|
||
type: string
|
||
enum: [deworming, checkup, medication, other]
|
||
title:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 160
|
||
dueAt:
|
||
type: string
|
||
format: date-time
|
||
description: 到期时间
|
||
status:
|
||
type: string
|
||
enum: [pending, completed, dismissed]
|
||
completedAt:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
description: 完成时间(completed 状态必填)
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
|
||
CreateCareReminderRequest:
|
||
type: object
|
||
required: [reminderType, title, dueAt]
|
||
properties:
|
||
reminderType:
|
||
type: string
|
||
enum: [deworming, checkup, medication, other]
|
||
title:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 160
|
||
dueAt:
|
||
type: string
|
||
format: date-time
|
||
|
||
UpdateCareReminderRequest:
|
||
type: object
|
||
required: [status]
|
||
properties:
|
||
status:
|
||
type: string
|
||
enum: [pending, completed, dismissed]
|
||
completedAt:
|
||
type: string
|
||
format: date-time
|
||
description: 标记 completed 时必填
|
||
|
||
CareReminderEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
$ref: '#/components/schemas/CareReminder'
|
||
|
||
CareReminderListEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/CareReminder'
|
||
|
||
# ========== Pet Summary (Aggregation) ==========
|
||
# TODO-FREEZE: 等待 T2-08 定型,字段为占位草案
|
||
PetSummary:
|
||
type: object
|
||
properties:
|
||
petId:
|
||
type: string
|
||
format: uuid
|
||
latestWeight:
|
||
type: object
|
||
nullable: true
|
||
description: 最新体重
|
||
properties:
|
||
weightKg:
|
||
type: number
|
||
format: double
|
||
measuredAt:
|
||
type: string
|
||
format: date-time
|
||
vaccinationProgress:
|
||
type: object
|
||
nullable: true
|
||
description: 疫苗进度(口径待定:已完成剂次/总预期剂次)
|
||
properties:
|
||
completedDoses:
|
||
type: integer
|
||
description: 已完成剂次
|
||
totalDoses:
|
||
type: integer
|
||
description: 总剂次(口径待定)
|
||
nextVaccination:
|
||
type: object
|
||
nullable: true
|
||
description: 下次接种(scheduled 中最近 plannedOn 或最近 nextDueOn,优先级待定)
|
||
properties:
|
||
vaccineName:
|
||
type: string
|
||
plannedOn:
|
||
type: string
|
||
format: date
|
||
monthlyExpense:
|
||
type: object
|
||
nullable: true
|
||
description: 当月花费(月度边界口径待定:UTC 月或指定时区月)
|
||
properties:
|
||
amountCents:
|
||
type: integer
|
||
format: int64
|
||
description: 金额(整数分)
|
||
month:
|
||
type: string
|
||
description: 月份标识(格式待定,如 2026-09)
|
||
|
||
PetSummaryEnvelope:
|
||
type: object
|
||
required: [code, message, data]
|
||
properties:
|
||
code:
|
||
type: integer
|
||
enum: [0]
|
||
message:
|
||
type: string
|
||
example: success
|
||
data:
|
||
$ref: '#/components/schemas/PetSummary'
|