# 实际端点目录

此表从 `services/api/src/app.ts` 的 HTTP 分发分支整理。`:id` 等为路径参数；同一路径的多个方法分别列出。**必填**仅在路由代码明确强制时标出；如果 body 字段只是被传给领域服务而该处未校验，标为“body 字段（领域校验）”，不得据此客户端省略前端表单校验。响应只列路由直接返回的形状；领域对象内部字段以实际响应为准。通用认证头、错误与分页规则见 [common.md](common.md)。

## 公共与身份

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /health` (`/api/health` 亦可) | 无 | — | 健康状态对象（服务端实现返回） |
| `GET /uploads/:key` | 无；公开资源 | `key` 菜谱图片路径 | 图片字节；公开缓存。仅公开菜单图片，不适用于私有业务附件。 |
| `POST /resident/sessions` | 无 | `code` 必填；可选 `phoneCode`, `name` | 微信居民认证结果（领域 DTO） |
| `GET /resident/sessions/me` | Resident | — | 当前居民会话数据 |
| `DELETE /resident/sessions/me` | Resident | — | `{ success, message }` |
| `POST /resident/sessions/logout` | Resident（若带 token 即撤销） | — | `{ success, message }` |
| `POST /staff/sessions` | 无 | `phone`, `password` | `{ token, clientType:"STAFF", account, jurisdictions, expiresAt }` |
| `GET /staff/sessions/me` | Staff | — | 当前员工会话数据 |
| `POST /staff/sessions/logout` | Staff | — | `{ success, message }` |
| `POST /admin/sessions` | 无 | `username` 和/或 `phone`（由认证服务判断），`password` | `{ token, clientType:"ADMIN", account, permissions, jurisdictions, expiresAt }` |
| `GET /admin/sessions/me` | Admin | — | 当前后台会话数据 |
| `POST /admin/sessions/logout`, `DELETE /admin/sessions` | Admin | — | `{ success, message }` |

## 居民通用与认证审核

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /resident/bindings` | Resident | — | `{ list, total }`；list 为本人历次房屋认证记录，含关系、审核状态、房屋展示字段和时间，按创建时间倒序 |
| `POST /resident/bindings` | Resident | 必填 `relationType`；另需 `houseId`，或 `communityId`/`communityName` + `buildingId`/`buildingNo` + `roomNo` 定位房屋；可选 `unitNo`, `realName`, `proofMaterialId` | 201 房屋认证申请结果 |
| `POST /resident/bindings/:id/unbind` | Resident | 可选 `reason` | `{ success, ...result }` |
| `GET /admin/bindings`, `GET /staff/bindings` | 对应后台/员工 | 可选 `communityId`, `status`, `keyword` | `{ list, total }` |
| `POST /admin/bindings/:id/review`, `POST /staff/bindings/:id/review` | 对应后台/员工审核权限 | `decision` 必填 (`APPROVE`/`REJECT`)，可选 `reason` | `{ success, ...result }` |
| `GET /admin/houses` | Admin | 可选 `communityId` | `{ list, total }` |
| `PATCH /admin/houses/:id`, `PUT /admin/houses/:id` | Admin + 台账授权 | `reason` 必填；可传 `buildingId`, `unitNo`, `roomNo` | `{ success, ...result }` |
| `GET /admin/houses/:id/corrections`, `/correction` | Admin + 台账授权 | — | `{ list, total }` |
| `POST /admin/houses/:id/corrections`, `/correction` | Admin + 台账授权 | `reason` 必填；可传 `buildingId`, `unitNo`, `roomNo` | `{ success, ...result }` |
| `POST /resident/feedback` | Resident | `communityId`, `content` 必填 | 201 `{ success, ...result }` |
| `GET /admin/feedback` | Admin + 小区 VIEW | `communityId` 必填；可选 `status`, `limit`, `offset` | 反馈列表 DTO |
| `GET /resident/inbox` | Resident | 可选 `limit`, `before` | `{ list, total }` |
| `POST /resident/inbox/:id/read` | Resident | — | `{ item }` |
| `GET /resident/inbox/:id/delivery-attempts` | Resident | — | `{ list }` |
| `POST /resident/voice-drafts` | Resident | `clientRequestId`, `intent`, `recognizedText`; 可选 `proposedPayload` | 201 草稿 DTO |
| `POST /resident/voice-drafts/:id/confirm` | Resident | 可选 `confirmedPayload` | 草稿确认结果；标记 `requiresManualSubmission`，不创建业务订单 |

## 账号、工作台、公告与活动

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /admin/accounts` | Admin + 账号管理权限 | 可选 `role`, `status`, `keyword` | `{ list, total }` |
| `POST /admin/accounts` | Admin + 账号管理权限 | 账号字段由创建服务校验：`username`, `password`, `name`, `phone`, `role` 等 | 201 创建结果 |
| `GET /admin/accounts/:id` | Admin + 账号管理权限 | — | 账号对象 |
| `PATCH /admin/accounts/:id`, `PUT /admin/accounts/:id` | Admin + 账号管理权限 | `expectedVersion` 必填；可传 `name`, `phone`, `permissions`, `jurisdictions`, `modules` | 更新账号结果 |
| `DELETE /admin/accounts/:id` | Admin + 账号管理权限 | `expectedVersion`, 可选 `reason` | `{ success, ...result }` |
| `POST /admin/accounts/:id/status` | Admin + 账号管理权限 | `targetStatus` 必须为 `ACTIVE`/`DISABLED`/`DELETED`；`expectedVersion`; 可选 `reason` | 状态更新结果 |
| `GET /admin/accounts/:id/community-permissions` | Admin + 账号管理权限 | — | `{ list }` |
| `POST /admin/accounts/:id/community-permissions` | Admin + 账号管理权限 | `communityId`, `permission` 必填 | `{ success:true, communityId, permission }` |
| `DELETE /admin/accounts/:id/community-permissions` | Admin + 账号管理权限 | JSON body: `communityId`, `permission` 必填 | `{ success:true, communityId, permission }` |
| `GET /admin/audit-logs` | Admin + 账号管理权限 | 可选 `targetAccountId`, `action`, `limit` | `{ list, total }` |
| `GET /admin/vendors`, `POST /admin/vendors`, `PUT /admin/vendors/:id`, `POST /admin/vendors/:id/status` | Root Admin | 创建/更新字段由供应商服务校验；状态请求传 `targetStatus`, `expectedVersion` | 列表包装 `{list}`；写入 `{vendor}` |
| `GET /admin/vendor-options` | Admin + 账号管理权限 | — | `{ list }` |
| `GET /staff/workbench`, `GET /admin/workbench` | Staff / Admin | 可选 `communityId` | `{ audience, communities, items, counts, generatedAt }` |
| `GET /admin/notices` | Admin + 公告授权 | 可选 `communityId`, `status`, `category`, `limit`, `offset` | Notice 查询 DTO |
| `POST /admin/notices` | Admin + 公告 HANDLE | 创建字段含 `communityId`, `category`, `title`, `content`；可选发布字段与 `activity` | 201 公告对象 |
| `GET /admin/notices/:id` | Admin + 公告授权 | — | 公告详情 |
| `PATCH /admin/notices/:id`, `PUT /admin/notices/:id` | Admin + 公告 HANDLE | `expectedVersion`；可传标题/正文/分类/图/置顶/时间/活动字段 | 更新公告对象 |
| `POST /admin/notices/:id/publish` | Admin + 公告 HANDLE | `expectedVersion`，可选 `publishAt` | 已发布公告 |
| `POST /admin/notices/:id/revoke` | Admin + 公告 HANDLE | `expectedVersion` | 已撤下公告 |
| `POST /admin/notices/:id/toggle-registration` | Admin + 公告 HANDLE | `registrationOpen` 必须是 boolean | 活动配置 |
| `GET /resident/notices` | Resident | 可选 `communityId`, `category`, `limit`, `offset` | 居民公告查询 DTO |
| `GET /resident/notices/:id` | Resident | — | 公告详情 |
| `PUT /resident/activities/:id/my-registration` | Resident | `status` 必须 `ACTIVE`/`CANCELLED`；报名可传 `houseId`，取消可传 `reason` | 报名记录 |
| `GET /resident/me/activities` | Resident | 可选 `limit`, `offset` | 我的活动 DTO |
| `GET /staff/activities/:id/roster` | Staff + 名单 VIEW | 可选 `status` | 名单 DTO |
| `GET /admin/activities/:id/roster` | Admin + 名单 VIEW | 可选 `status` | 名单 DTO |
| `GET /admin/activities/:id/roster-export` | Admin + EXPORT | 可选 `status`, `format=csv` | 默认 JSON 导出 DTO；`format=csv` 或 Accept `text/csv` 返回 CSV 字节 |

## 门禁与物业账单

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /admin/access-points` | Admin + 社区授权 | `communityId` 必填；可选 `limit`, `offset` | 设备查询 DTO |
| `POST /admin/access-points` | Admin + 管理权限 | body 字段：`communityId`, `buildingId`, `name`, `doorNo`, `deviceIdentifier`, `isEnabled` | 201 点位对象 |
| `PATCH /admin/access-points/:id` | Admin + 管理权限 | 可传 `name`, `doorNo`, `isEnabled`, `buildingId` | 点位对象 |
| `GET /admin/access-history` | Admin + 查询权限 | `communityId`；可选时间/关键词/状态/排序/分页字段 | 历史查询 DTO |
| `GET /admin/access-history/export` | Admin + EXPORT | `communityId`；可选时间/关键词/状态/排序 | CSV 文件 |
| `GET /staff/access-points` | Staff + 小区权限 | `communityId` 必填；可选分页 | 点位 DTO |
| `GET /resident/access-points` | Resident | 可选 `houseId` | `{ list, total }` |
| `POST /resident/access-points/:id/open` | Resident | `houseId` 与 `requestId`（兼容 `clientRequestId`） | 开门尝试结果 DTO |
| `GET /admin/fee-rules` | Admin + 财务权限 | `communityId` 必填 | 费用规则 DTO |
| `PUT /admin/fee-rules` | Admin + 财务权限 | body: `communityId`, `feeType`, `monthlyAmountCents`, `isEnabled` | 更新费用规则 DTO |
| `POST /admin/bill-imports/preview` | Admin + 财务权限 | body: `communityId`, `filename`, `rows` | 导入预览 DTO |
| `POST /admin/bill-imports/:id/confirm` | Admin + 财务权限 | — | 导入确认 DTO |
| `GET /admin/bills` | Admin + 财务 VIEW | `communityId` 必填；可选 `houseId`, `feeType`, `status`, 分页 | 账单查询 DTO |
| `PATCH /admin/bills/batch-price` | Admin + 财务 HANDLE | body: `communityId`, `billIds`, `newAmountCents`, `reason` | 批量更新 DTO |
| `GET /resident/bills` | Resident | 可选 `houseId`, `communityId`, `status` | 本人账单 DTO |
| `POST /resident/payments` | Resident | 必填 `houseId`, `billIds`, `clientRequestId`；可选 `channel`（默认 WECHAT）、`expectedTotalAmountCents`, `communityId` | 201 合并支付单与渠道启动结果 |
| `GET /resident/payments/:id` | Resident | 可选 query `refresh=1` 查渠道 | 支付单；refresh 时附 `reconciliation` |
| `POST /callbacks/payments/:channel` | 渠道回调 | 原始 request body 必须为 bytes；签名头由 adapter 验证 | 微信成功 `204` 空体；其他已支持渠道返回渠道结果。禁止前端调用。 |
| `POST /admin/offline-receipts` | Admin + 财务 HANDLE | body: `communityId`, `houseId`, `billIds`, `amountCents`, `paymentMethod`, `offlineVoucherNo` 等 | 201 收据结果 |
| `GET /admin/receipts` | Admin + 财务 VIEW | 可选 `communityId`, `houseId`, `channel`, `startDate`, `endDate` | 收据查询 DTO |
| `GET /resident/receipts`, `GET /resident/receipts/:id` | Resident | 列表可选 `houseId` | 收据 DTO |
| `POST /admin/reminders` | Admin + 财务 HANDLE | body: `communityId`, `houseId`, `billIds`, `reminderType`, `content` | 201 提醒结果 |
| `GET /admin/reminders` | Admin | 可选社区/房屋/日期范围 | 提醒列表 DTO |
| `GET /staff/reminders` | Staff | 可选 `communityId` | 提醒列表 DTO |
| `GET /admin/reconciliation/report`, `GET /admin/reconciliation/export` | Admin + 财务权限 | `communityId`；report 可选 `period`, `channel`, 日期；export 可选 `period`, `channel` | 报表/导出 DTO（当前路由均 JSON） |

## 订餐与结算

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `POST /admin/meal-menus/upload`, `POST /supplier/meal-menus/upload` | Admin/Supplier + 菜单操作权限 | JSON 的 `data` 必填（base64 图片）；可选 `filename`, `contentType`；也可发送原始图片 bytes | 201 上传结果 |
| `POST /admin/meal-menus`, `POST /supplier/meal-menus` | Admin/Supplier | body: `vendorId`, `communityId`, 周次、供应日、套餐和照片字段（领域校验） | 201 草稿 |
| `GET /admin/meal-menus`, `GET /supplier/meal-menus` | Admin/Supplier | 可选 `vendorId`, `communityId`, `status`, `year` | 菜单列表 DTO |
| `GET /admin/meal-menus/:id`, `GET /supplier/meal-menus/:id` | token 可选；领域服务按有/无 token 返回允许内容 | — | 菜单详情 |
| `PUT /admin/meal-menus/:id`, `PUT /supplier/meal-menus/:id` | Admin/Supplier | 可传 `title`, 日期、供应日、照片、套餐字段 | 更新草稿 |
| `POST /admin/meal-menus/:id/publish`, `/supplier/meal-menus/:id/publish` | Admin/Supplier | — | 已发布菜单 |
| `GET /resident/meal-menus` | 无 Bearer 校验（公开菜单查询） | `communityId`；可选 `startDate`, `limit` | 菜单 DTO |
| `GET /resident/meal-menus/current` | 无 Bearer 校验 | `communityId`；可选 `date` | 当前菜单 DTO |
| `GET /resident/meal-packages/:id` | 无 Bearer 校验 | — | 套餐详情 DTO |
| `POST /resident/meal-orders/quote` | 无 Bearer 校验 | body: `communityId`, `dailyCount`, `weeks` | 报价 DTO |
| `POST /resident/meal-orders` | Resident | body: `clientRequestId`, `communityId`, `houseId`, 联系/配送信息、`dailyCount`, `weeks`, `payMethod`, `expectedTotalAmountCents` | 201 订单 DTO |
| `GET /resident/meal-orders`, `GET /resident/meal-orders/:id` | Resident | 列表可选 `communityId`, `status` | 本人订单 DTO |
| `GET /staff/meal-residents` | Staff | `communityId`；可选 `keyword`, `limit` | 服务对象列表 |
| `POST /staff/meal-orders` | Staff | body: `clientRequestId`, `customerResidentId`, `communityId`, `houseId`, 联系/配送信息、份数周次及支付字段 | 201 代订订单 |
| `GET /admin/vendor-meal-orders` | Supplier session | 可选 `communityId`, `page`, `pageSize` | 供应商最小订单摘要分页 |
| `GET /staff/meal-orders`, `GET /admin/meal-orders`; `GET /staff/meal-orders/:id`, `GET /admin/meal-orders/:id` | Staff/Admin | 列表：`communityId`，可选 `status`, `orderNo` | 订单查询 DTO |
| `POST /admin/meal-collections`, `POST /staff/meal-collections` | Admin/Staff + 收款权限 | body: `orderId`, `receiptNo`, `companyAccount`, `payMethod`, `amountCents`; 可选备注 | 201 实收凭据 |
| `GET /staff/meal-vendors` | Staff | `communityId` | 供应商列表 |
| `POST /staff/meal-handovers` | Staff | body: 小区/供应商/供应日期/批次/应实数量及交接人字段 | 201 交接记录 |
| `GET /staff/meal-handovers` | Staff | `communityId`；可选 `supplyDate`, `vendorId` | 交接列表 |
| `GET /staff/meal-assignments/preview` | Staff | `communityId`, `supplyDate`；可选楼栋/单元 | 派单预览 |
| `POST /staff/meal-assignments` | Staff | body: `communityId`, `supplyDate`, `buildingNo`, `unitNo`, `staffId`, `taskVersions` | 201 派单结果 |
| `GET /staff/meal-assignments` | Staff | `communityId`；可选 `supplyDate`, `staffId` | 派单列表 |
| `POST /staff/meal-assignments/:id/revoke` | Staff | 可选 `reason` | 撤销结果 |
| `POST /staff/meal-deliveries/complete` | Staff | `communityId`, `clientRequestId`, `deliveries` | 送达批量结果 |
| `GET /staff/meal-deliveries` | Staff | `communityId`；可选供应日期、员工、状态、楼栋/单元 | 配送列表 |
| `GET /admin/meal-options`, `GET /supplier/meal-options` | Admin/Supplier | `purpose=menus|settlements`；结算可带 `communityId` | 选项列表 |
| `GET /admin/meal-settlements/preview` | Admin + 结算 VIEW | `communityId`, `vendorId`, `periodValue`；可选 `periodType`, `contractVersion`, sample 参数 | 结算预览 |
| `POST /admin/meal-settlements` | Admin + 结算 HANDLE | body: `clientRequestId`, `communityId`, `vendorId`, `periodType`, `periodValue`, `contractVersion` | 201 结算批次 |
| `GET /admin/meal-settlements`, `GET /supplier/meal-settlements` | Admin/Supplier | 可选 `communityId`, `vendorId`, `periodType`, `periodValue` | 结算批次 DTO |
| `GET /admin/meal-settlements/:id`, `GET /supplier/meal-settlements/:id` | Admin/Supplier | — | 结算批次详情 |
| `GET /admin/meal-settlements/export`, `GET /supplier/meal-settlements/export` | Admin/Supplier + export scope | 可选 `communityId`, `vendorId`, `periodType`, `periodValue`, `batchId`, `format=csv|json` | CSV bytes 或 JSON |

## 助浴、维修、陪诊与保洁

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /resident/bathing/packages` | Resident | `communityId`；可选 `targetDate` | `{ list, total }` |
| `GET /resident/bathing/appointments` | Resident | 可选 `communityId`, `status` | `{ list, total }` |
| `POST /resident/bathing/appointments` | Resident | 必填 `clientRequestId`, `communityId`, `houseId`, `packageCode`, `serviceDate`, `timeSlot`, `expectedPackageVersion`, `expectedPriceCents`；代约可传 `isProxyBooking`, `beneficiaryName`, `beneficiaryPhone`, `proxyRelationship`, `elderCondition`, `specialNotes` | 201 预约对象 |
| `GET /resident/bathing/appointments/:id` | Resident | — | 预约详情 |
| `POST /resident/bathing/appointments/:id/confirm` | Resident + 合法确认人 | 可选 `rating`（1–5 星）、`feedbackNotes`, `clientRequestId`；服务端验证确认人和订单状态 | 确认结果 |
| `GET /resident/bathing/appointments/:id/attachments/:attachmentId` | Resident + 附件授权 | — | 私有图片 bytes，`no-store` |
| `GET /staff/bathing/appointments` | Staff | 可选社区/状态/服务日/被派员工 | `{ list, total }` |
| `GET /staff/bathing/appointments/:id` | Staff | — | 预约详情 |
| `POST /staff/bathing/appointments/:id/check-in` | 当前受派 Staff | 必填 `latitude`, `longitude`；可选 `address`, `clientRequestId` | 打卡结果 |
| `POST /staff/bathing/appointments/:id/attachments` | 当前受派 Staff | JSON body 的 `data` 为 base64 图片；可传 `filename`/`fileName`, `contentType`/`mimeType`, `clientRequestId`；也可发送原始图片 bytes | 201 附件引用（不返回对象 URL） |
| `GET /staff/bathing/appointments/:id/attachments/:attachmentId` | Staff + 附件授权 | — | 私有图片 bytes，`no-store` |
| `POST /staff/bathing/appointments/:id/complete` | 当前受派 Staff | 可选 `notes`, `clientRequestId`；照片和居民确认由服务端检查 | 完工结果 |
| `GET /repairs/meta`, `GET /resident/repairs/meta` | 无 | — | 报修元数据 |
| `POST /resident/repairs` | Resident | 必填 `clientRequestId`, `communityId`, `houseId`, `category`, `timeSlot`, `preferredDate`, `description`；可选 `subcategory`, `repairTargetType`, `locationAddress`, `contactName`, `contactPhone`, `urgency`, `photoKeys` | 201 工单 |
| `GET /resident/repairs` | Resident | 可选 `status` | `{ list, total }` |
| `GET /resident/repairs/:id` | Resident + 订单归属 | — | 工单详情/进度 |
| `POST /resident/repairs/upload-photo` | Resident | JSON body 的 `data` 为 base64 图片；可传 `filename`/`fileName`, `contentType`/`mimeType`；也可发送原始图片 bytes | 201 上传引用 |
| `GET /resident/repairs/:id/attachments/:attachmentId` | Resident + 附件授权 | — | 私有图片 bytes，`no-store` |
| `POST /resident/repairs/:id/confirm-completion` | 该单合法业主/代表 | 必填 `expectedVersion`, `photoVersion`, `clientRequestId` | 确认结果 |
| `POST /resident/repairs/:id/rating` | 合法订单居民 | body 由评价服务校验 | 评价结果 |
| `GET /staff/repairs`, `GET /admin/repairs` | Staff/Admin + 工单 VIEW | 可选 `communityId`, `status`, `category`, `urgency` | `{ list, total }` |
| `GET /staff/repairs/:id`, `GET /admin/repairs/:id` | Staff/Admin + 工单范围 | — | 工单详情 |
| `GET /admin/repairs/eligible-public-confirmers` | Admin + 社区权限 | `communityId` | 可选确认人列表 |
| `POST /admin/repairs/:id/public-confirmer` | Admin + 工单 HANDLE | 必填 `residentId`, `expectedVersion`, `clientRequestId`；residentId 必须是本小区当前已认证业主 | 设置结果 |
| `POST /admin/repairs/:id/verify` | Admin + 派工权限 | 必填 `verificationNotes`, `expectedVersion`；可选 `urgency` | 核实结果 |
| `POST /admin/repairs/:id/revoke-dispatch` | Admin + 派工权限 | 必填 `reason`, `expectedVersion` | 撤销派工结果 |
| `GET /admin/repairs/followups`, `/summary`, `/export` | Admin + 对应模块授权 | 查询参数含 `communityId`, 时间范围；export 使用 `requestId` | 列表/汇总/CSV |
| `POST /resident/escort/bookings`, `POST /resident/escort-bookings` | Resident | 预约 body 由服务校验 | 201 预约 |
| `GET /resident/escort/bookings`, `GET /resident/escort-bookings` | Resident | 可选 `status`, `limit`, `offset` | 本人预约列表 |
| `GET /resident/escort/bookings/:id`, `GET /resident/escort-bookings/:id` | Resident | — | 本人预约详情与交接状态 |
| `GET /admin/escort/handovers` | Admin + 社区授权 | `communityId`；可选 `status` | 交接列表 |
| `GET /admin/escort/handovers/:id` | Admin + 社区授权 | — | 交接详情 |
| `POST /admin/escort/handovers/:id/send` | Admin + 交接 HANDLE | `expectedVersion` | 发送尝试结果；不代表对方收单 |
| `POST /admin/escort/handovers/:id/verify` | Admin + 交接 HANDLE | 必填 `expectedVersion`, `clientRequestId`, `decision`, `evidenceRef`；决定为 RECEIVED 时还需 `fuxingReceiptNo` | 人工核对结果 |
| `GET /cleaning/quote` | 无 | query: `communityId`, `serviceType`, `areaSqm`, `serviceDate` | 报价 DTO |
| `GET /cleaning/schedules` | 无 | query: `communityId`, `serviceType`, `serviceDate` | 可预约时段 |
| `GET /resident/cleaning/bookings` | Resident | — | 本人预约列表 |
| `POST /resident/cleaning/bookings` | Resident | 预约 body 由服务校验 | 201 预约 |
| `GET /resident/cleaning/bookings/:id/completion-photo` | Resident + 当前 OWNER | `photoVersion` | 私有图片 bytes，`no-store` |
| `POST /resident/cleaning/bookings/:id/confirm-completion` | Resident + 当前 OWNER | `expectedVersion`, `photoVersion`, `clientRequestId` | 确认结果 |
| `GET /staff/cleaning/work-orders` | Staff | 可选 `communityId`, `status` | 本人工作单 DTO |
| `GET /staff/cleaning/residents` | Staff | `communityId` | 服务对象列表 |
| `GET /staff/cleaning/bookings` | Staff | `communityId`；可选 `status` | 预约列表 |
| `POST /staff/cleaning/bookings/phone` | Staff | 电话预约 body 由服务校验 | 201 预约 |
| `GET /staff/cleaning/bookings/:id/candidates` | Staff | — | 可派人员列表 |
| `POST /staff/cleaning/bookings/:id/verify`, `/assign`, `/check-in`, `/complete` | Staff + 对应流程权限 | 版本与请求字段由各领域服务校验 | 操作结果 |
| `POST /staff/cleaning/bookings/:id/completion-photos` | Staff | `data` (base64) 必填；可传 `expectedVersion`, `clientRequestId`, 文件名/MIME | 201 照片版本/结果 |
| `GET /admin/cleaning/catalog`, `/bookings` | Admin + 清洁业务 VIEW | `communityId`；bookings 可选 status | 目录/预约 DTO |
| `PUT /admin/cleaning/settings`, `POST /admin/cleaning/prices`, `PATCH /admin/cleaning/prices/:id`, `POST /admin/cleaning/schedules` | Admin + HANDLE | body 字段按设置/价格/排期服务校验 | 更新结果/201 新价格规则 |
| `POST /admin/cleaning/bookings/:id/archive` | Admin + HANDLE | 归档 body 由服务校验 | 归档结果 |
| `POST /admin/cleaning/settlements/export` | Admin + EXPORT | body 内社区、日期、request ID 由服务校验 | CSV 下载 |

### 助浴后台管理补充

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /admin/bathing/packages` | Admin + 助浴 VIEW | `communityId`；可选 `packageCode`, `status`, `targetDate` | `{ list, total }` |
| `GET /admin/bathing/packages/:id` | Admin + 助浴 VIEW | — | 套餐对象 |
| `GET /admin/bathing/packages/effective` | Admin + 助浴 VIEW | query `communityId`, `packageCode`, `targetDate` | 有效价格 DTO |
| `POST /admin/bathing/packages` | Admin + 助浴 HANDLE | package body 交由目录服务校验 | 201 套餐对象 |
| `GET /admin/bathing/qualifications` | Admin + 助浴 VIEW | `communityId`；可选 `staffId`, `status`, `validOnDate` | `{ list, total }` |
| `GET /admin/bathing/qualifications/verify` | Admin + 助浴 VIEW | `communityId`, `staffId`, `serviceDate` | 资格校验 DTO |
| `POST /admin/bathing/qualifications` | Admin + 助浴 HANDLE | qualification body 交由目录服务校验 | 201 资质对象 |
| `GET /admin/bathing/schedules` | Admin + 助浴 VIEW | `communityId`；可选员工/日期/时段/状态 | `{ list, total }` |
| `GET /admin/bathing/schedules/check` | Admin + 助浴 VIEW | `communityId`, `staffId`, `scheduleDate`, `timeSlot` | 可用性 DTO |
| `GET /admin/bathing/schedules/available-staff` | Admin + 助浴 VIEW | `communityId`, `scheduleDate`, `timeSlot` | `{ list, total }` |
| `POST /admin/bathing/schedules` | Admin + 助浴 HANDLE | schedule body 交由目录服务校验 | 201 排班对象 |
| `GET /admin/bathing/pilot-readiness` | Admin + 助浴 VIEW | `communityId`；可选 `targetDate` | readiness DTO |
| `GET /admin/bathing/appointments` | Admin + 助浴 VIEW | 可选 `communityId`, `status`, `serviceDate`, `assignedStaffId` | `{ list, total }` |
| `GET /admin/bathing/appointments/overdue-alerts` | Admin + 助浴 VIEW | 可选 `communityId` | `{ list, total }` |
| `GET /admin/bathing/appointments/:id` | Admin + 助浴 VIEW | — | 预约详情 |
| `POST /admin/bathing/appointments/:id/verify-phone`, `/assign`, `/archive` | Admin/对应管家权限 | 动作 body 由业务服务校验 | 操作结果 |
| `GET /admin/bathing/appointments/export` | Admin + EXPORT | `communityId` | CSV（不含原图） |
| `GET /admin/bathing/appointments/:id/attachments/:attachmentId` | Admin + 附件读取授权 | — | 私有图片 bytes，`no-store` |

### 维修后台流程补充

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /admin/repairs/schedules`, `POST /admin/repairs/schedules` | Admin + 派工权限 | 列表可选小区/员工/日期/时段；写入 schedule body | `{list,total}` / 201 排班 |
| `POST /admin/repairs/dispatch/suggestions` | Admin + 派工权限 | `orderIds` 数组 | `{ suggestions, total }` |
| `POST /admin/repairs/dispatch/confirm` | Admin + 派工权限 | `items` 数组 | `{ results, total }` |
| `POST /staff/repairs/:id/check-in` | 当前受派 Staff | 必填 `expectedVersion`, `clientRequestId`, `latitude`, `longitude`；可选 `address` | 到场打卡结果 |
| `POST /staff/repairs/:id/complete` | 当前受派 Staff | 必填 `expectedVersion`, `photoVersion`, `clientRequestId`；须已有合法业主/代表确认 | 完工结单结果 |
| `POST /staff/repairs/:id/completion-photos` | 当前受派 Staff | `data` base64 必填；文件名/MIME、版本和 request ID 由领域服务处理 | 201 照片关联结果 |
| `GET /staff/repairs/my-tasks` | Staff | 可选 `status` | `{ list, total }` |
| `POST /admin/repairs/:id/followup` | Admin/管家授权 | 回访 body 由服务校验 | 回访/归档结果 |
| `POST /admin/repairs/notifications/dispatch` | Admin + 派单权限 | 可选 `limit` | 通知投递处理结果 |

## 商店、大屏、其他格式

| 方法与路径 | 身份 | 请求（关键字段） | 成功响应 |
| --- | --- | --- | --- |
| `GET /shop/catalog` | Resident | 当前小区上下文由认证绑定解析 | 商品目录 |
| `GET /shop/placements/:id/destination` | Resident | — | 允许跳转的 destination DTO（外部交易状态不在响应中保证） |
| `GET /admin/shop/catalog` | Admin + 小区 VIEW | 查询小区参数 | 后台目录 |
| `PUT /admin/shop/catalog/:communityId` | Admin + HANDLE | 目录更新 body（版本字段由领域服务校验） | 更新目录 |
| `POST /admin/shop/placements`, `PUT /admin/shop/placements/:id` | Admin + HANDLE | 投放字段由领域服务校验 | 201/更新投放 |
| `GET /dashboard/communities` | Admin/授权 Staff | — | `{ list: [{id,name}] }` |
| `GET /dashboard/summary` | Admin/授权 Staff | query 必填 `communityId`, `from`, `to` | `{ communityId, from, to, generatedAt, timeZone, blocks }` |

### 私有附件边界

以下业务路径在授权会话、订单关系及读取权限复核后返回图片 bytes，不是 JSON，也不返回可复用对象 URL：

- 助浴：`GET /resident|staff/bathing/appointments/:id/attachments/:attachmentId`
- 报修：`GET /resident/repairs/:id/attachments/:attachmentId`
- 保洁：`GET /resident/cleaning/bookings/:id/completion-photo?photoVersion=N`

另有上传：`POST /staff/bathing/appointments/:id/attachments`、`POST /resident/repairs/upload-photo`、`POST /staff/cleaning/bookings/:id/completion-photos`、`POST /staff/repairs/:id/completion-photos`。`GET /uploads/:key`（也接受 `/api/uploads/:key`）只读取公开菜谱图片资源，不能拿来访问上述私有附件。
