# 共同约定

## 成功与错误

成功响应通常为 JSON，列表端点按接口分别返回 `{ list, total }` 或 `{ list }`；写入端点可能返回领域对象或包装对象。不要把所有响应统一假定为同一 envelope。

错误响应格式为 `{ "code": "...", "message": "..." }`。源码明确使用的通用码包括：

| HTTP | code | 含义 |
| --- | --- | --- |
| 400 | `BAD_REQUEST` | 参数、格式或业务校验失败 |
| 400 | `VALIDATION_ERROR`, `POINT_DISABLED`, `INVALID_PATH` | 字段/参数校验、门禁点停用、公开图片路径校验等特定错误 |
| 401 | `UNAUTHORIZED` | 缺少或无效会话 |
| 401 | `AUTH_FAILED`, `SESSION_EXPIRED` | 登录失败或会话过期/撤销 |
| 403 | `FORBIDDEN` | 角色/操作/小区权限不足 |
| 404 | `NOT_FOUND` | 路由或可见资源不存在；部分越权资源按不存在处理 |
| 409 | `CONFLICT` 或领域专用冲突码 | 版本、状态、幂等键内容、并发或业务唯一性冲突 |
| 409 | `VERSION_CONFLICT`, `REQUEST_ID_CONFLICT`, `DUPLICATE_PHONE`, `DUPLICATE_USERNAME` | 已在当前 app 错误映射中使用的版本、请求标识或唯一性冲突 |
| 503 | 依适配器配置状态返回 | 外部适配器未配置/不可用；不要推断业务成功 |

支付渠道 callback 失败还可能返回 `FAIL` 或 `INVALID_CALLBACK`；callback 需让支付渠道重试其规定的非成功响应，不应由前端模拟。

领域模块还会返回专用 code（例如重复账号、版本冲突、支付冲突）。前端应优先按 HTTP 状态和 `code` 分支，显示 `message` 仅作用户提示，不依赖中文文案判定状态。未知 5xx 应按失败处理并保留可重试业务请求标识。

## 分页

部分列表支持 `limit` 与 `offset`。通用解析器要求 `limit` 为 1–100，`offset` 为 0–100000；超出范围是 400。不是所有列表都使用该解析器：请只在具体接口已实现参数时传分页参数。部分供应商订单使用 `page`/`pageSize`；收件箱使用 `limit` 与 `before`。响应是否含 `total` 依各端点而异。

## 幂等与并发

只有明确接受请求标识的写接口才保证请求级幂等。涉及流程变更时，客户端应使用新生成且稳定的 `clientRequestId`（具体字段以端点实现为准），超时重试必须复用原请求号及原请求体；同 key 改内容通常冲突。带 `expectedVersion` 的编辑/状态动作需在冲突后重新读取，不应盲目自动重放。支付、完工、配送、活动报名等服务端仍会检查状态/唯一约束，客户端幂等不能代替服务端校验。

## 安全边界

- 不以隐藏按钮作为权限控制；服务端按记录归属和作用端复核。
- 不将私有附件对象 key 或长期可复用 URL 下发客户端；附件经鉴权端点读取。
- callback 是服务端到服务端入口，不使用居民 Bearer token。不可由浏览器/小程序直接调用。
- 登录凭据只在 POST body 发送，不放 query string。不要在文档、日志、提交或截图中放真实凭据/居民数据。
