# API Design

当前 API 使用 Next.js Route Handlers 实现，数据通过 Prisma 写入 SQLite。路由形态按未来 Go REST API 设计，后续拆服务时优先保持路径、请求字段和响应字段兼容。

统一约定：

- 列表接口返回 `{ "items": [] }`
- 创建接口成功返回资源对象和 `201`
- 更新接口成功返回更新后的资源对象
- 失败返回 `{ "error": "错误说明" }`
- 频率限制返回 `429` 和 `{ "error": "操作过于频繁，请稍后再试" }`
- 时间字段当前为中文展示字符串，Go 后端落地时建议同时返回 ISO 时间和展示时间
- 生产环境可设置 `REQUIRE_CLIENT_AUTH=true`，要求用户侧敏感写接口必须携带有效 `lawpilot_session`；未登录返回 `401` 和 `{ "error": "login required" }`。未开启时保留匿名演示兼容。

基础限流：

- 全局 API 网关限流：`/api/*` 默认同 IP 每 60 秒 600 次，返回 `X-RateLimit-Limit`、`X-RateLimit-Remaining`，超限返回 `429` 和 `Retry-After`。可通过 `GLOBAL_API_RATE_LIMIT`、`GLOBAL_API_RATE_WINDOW_SECONDS` 调整；当前为进程内基础保护，上线多实例建议换成网关、Redis 或边缘限流。
- `POST /api/orders`：同手机号 10 分钟 5 次
- `POST /api/document-drafts`：同手机号/姓名 10 分钟 5 次
- `POST /api/contract-reviews`：同手机号/姓名 10 分钟 5 次
- `POST /api/questions`：同手机号/姓名 10 分钟 6 次
- `POST /api/business-tickets`：同手机号/企业名 10 分钟 4 次
- `POST /api/payments/session`：同支付来源 5 分钟 12 次
- `POST /api/uploads`：同 IP 10 分钟 20 次

机器可读契约：

- `GET /api/openapi`：返回 OpenAPI 3.0 JSON，供 Android 和 Go 后端生成模型或校验接口。
- `GET /api/health`：返回 API、数据库、OpenAPI 和核心数据表数量，用于部署监控和联调自检。

## Public API

### AI 咨询

- `POST /api/ai/consult`：创建 AI 咨询记录，返回风险识别、摘要、证据建议、知识库参考依据和 `consultationId`
- `POST /api/ai/intake`：根据案情生成追问问题
- `POST /api/ai/case-report`：根据追问答案生成结构化案件报告
- `GET /api/legal-knowledge?area=&sourceType=&q=`：检索法律知识库
- 前台页面 `/knowledge`：按领域、类型、关键词检索知识库，数据来自 `/api/legal-knowledge`

### 法律知识库

- 后台 `GET /api/admin/legal-knowledge?area=&sourceType=&q=`：查询知识条目
- 后台 `POST /api/admin/legal-knowledge`：新增法规、裁判观点、实务指引或常见问答
- 后台 `PATCH /api/admin/legal-knowledge/:id`：启用或停用知识条目
- 当前知识库先服务 AI 咨询参考依据，后续接真实大模型时可作为 RAG 检索数据源

### 客户档案审核

- 后台 `GET /api/admin/client-profiles?status=&q=`：查询客户实名/企业主体档案
- 后台 `PATCH /api/admin/client-profiles/:id`：更新认证状态，支持 `待完善`、`待审核`、`已认证`、`已驳回`
- 后台 `GET /api/admin/enterprise-reports?companyName=&month=YYYY-MM`：生成企业常年顾问月报，聚合企业主体档案、服务包订阅、权益消耗、企业法务工单和合同审查记录
- 审核状态更新会写入审计日志，并给用户侧消息中心发送通知

### 律师

- `GET /api/lawyers/match?area=&city=`：按领域、城市、评分、响应速度匹配律师
- `GET /api/lawyers/availability?area=`：返回律师可预约时段
- `POST /api/lawyers/apply`：律师入驻申请，创建 `待审核` 律师资料，可携带上传后的执业证/资质材料元数据；已登录律师账号会自动写入 `userId/phone` 绑定
- `GET /api/lawyers/:id/credential/download`：统一下载律师资质材料；本地存储跳转 `/uploads`，阿里云 OSS 私有桶生成短期签名 URL 后跳转
- `GET /api/lawyer-reviews?lawyerId=`：查询律师评价
- `POST /api/lawyer-reviews`：对已分配律师的订单提交评价；需后台身份、登录用户或 `q` 查询标识匹配订单归属
- 前台页面 `/lawyer/apply`：律师提交姓名、律所、城市、执业证号、擅长领域、价格、简介和资质附件

排班规则：

- 律师开放时段存储在 `availableSlots`。
- 后台律师管理可新增或删除开放时段。
- `GET /api/lawyers/availability` 会扣减未完成、未取消订单占用的预约时间。
- `GET /api/lawyer-workspace` 已登录律师会按 `userId/phone` 匹配本人律师档案，并返回该律师的 `schedule.slots` 和 `schedule.occupiedSlots`；旧数据兼容姓名匹配，未登录演示场景仍可传 `lawyerId`。
- 后台“排班总览”复用 `GET /api/lawyers/availability`，展示每位律师的可约/已占用状态。

### 用户进度

- `GET /api/me?q=`：按手机号、姓名、订单号、案件号等查询用户进度；已登录用户可不传 `q`，系统会使用 HttpOnly session 对应手机号
- `GET /api/client-profile?q=`：查询客户实名/企业主体档案；企业档案包含行业和员工规模；已登录用户可不传 `q`
- `POST /api/client-profile`：保存客户实名或企业主体档案，个人需姓名和手机号，企业额外要求企业名称，可补充行业和员工规模；已登录用户优先使用当前账号姓名和手机号
- `GET /api/orders/:id/communications`：查询订单服务沟通记录
- `POST /api/orders/:id/communications`：用户记录站内消息、电话、视频或材料沟通；记录会同步进入订单服务日志
- `PATCH /api/notifications/:id`：标记单条通知已读；需后台身份、登录用户或 `q` 查询标识匹配通知归属
- `POST /api/notifications/read-all`：按查询条件批量标记通知已读；已登录用户可不传 `q`，系统会限制为当前账号对应通知
- 后台 `GET /api/admin/notifications?channel=&status=&q=`：查询站内信、短信、邮件发送记录和通知模板；通知模板支持 `{title}`、`{message}`、`{recipientName}`、`{phone}`、`{relatedType}`、`{relatedId}` 变量；短信/邮件未配置时记录为 `待配置`
- 后台 `POST /api/admin/notifications/:id/retry`：重试单条待配置或失败通知，根据当前短信/邮件配置更新状态并写审计日志
- 后台 `POST /api/admin/notifications/retry`：批量重试最近待配置或失败通知
- 用户侧创建订单、服务包订阅、文书草稿、合同审查、企业法务工单、售后工单、免费问答和开票申请时，如果存在登录 session，会优先绑定当前账号姓名和手机号；匿名场景默认继续兼容请求体内的姓名和手机号，生产环境可通过 `REQUIRE_CLIENT_AUTH=true` 强制登录。

`GET /api/me` 会返回：

- `progressItems`：统一进度卡片，供 Web 和 Android 首页进度流使用
- `profile`
- `orders`
- `cases`
- `consultations`
- `documentDrafts`
- `businessTickets`
- `publicQuestions`
- `contractReviews`
- `packageSubscriptions`
- `invoiceRequests`
- `supportTickets`
- `notifications`

### 文书与合同交付

- `GET /api/document-drafts/:id/download`：下载文书交付文本，并累计 `downloadCount`；需后台身份、登录用户或 `q` 查询标识匹配文书归属；传 `format=doc` 可下载 Word 兼容版，传 `format=pdf` 返回可打印 PDF 版 HTML
- `POST /api/document-drafts/:id/confirm`：用户确认文书交付，写入 `clientConfirmedAt`；需后台身份、登录用户或 `q` 查询标识匹配文书归属
- `GET /api/document-drafts/:id/receipt`：下载文书交付签收回执；仅在用户已确认交付后可用；需后台身份、登录用户或 `q` 查询标识匹配文书归属；传 `format=doc` 可下载 Word 兼容版，传 `format=pdf` 返回可打印 PDF 版 HTML
- `GET /api/contract-reviews/:id/download`：下载合同审查报告，并累计 `downloadCount`；需后台身份、登录用户或 `q` 查询标识匹配合同审查归属；传 `format=doc` 可下载 Word 兼容版，传 `format=pdf` 返回可打印 PDF 版 HTML
- `GET /api/contract-reviews/:id/diff`：获取合同审查版本对比；基于 AI 审查初稿、当前摘要、风险条款、条款定位、替换建议、逐段红线和交付版本留痕生成结构化对比；支持 `format=doc|pdf` 下载对比报告；需后台身份、登录用户或 `q` 查询标识匹配合同审查归属
- `POST /api/contract-reviews/:id/confirm`：用户确认合同审查交付，写入 `clientConfirmedAt`；需后台身份、登录用户或 `q` 查询标识匹配合同审查归属
- `GET /api/contract-reviews/:id/receipt`：下载合同审查交付签收回执；仅在用户已确认交付后可用；需后台身份、登录用户或 `q` 查询标识匹配合同审查归属；传 `format=doc` 可下载 Word 兼容版，传 `format=pdf` 返回可打印 PDF 版 HTML
- 文书和合同审查返回 `deliveryVersions`，记录 AI 草稿、律师修改稿、最终交付和下载记录

### 案件材料

- `POST /api/cases/:id/evidence`：用户补充案件材料；需后台身份、登录用户或 `q` 查询标识匹配案件客户/律师归属；基础版会对材料名称、备注、文件名和链接文本执行规则识别，抽取主体、金额、日期、条款关键词和风险提示
- `POST /api/cases/:id/evidence/:evidenceId/analyze`：重新执行案件材料智能识别，当前为本地规则版，后续可替换为真实 OCR 服务
- `POST /api/uploads`：上传附件，返回 `url` 和 `fileId` 后可写入材料 `fileUrl`；默认本地存储，配置后上传阿里云 OSS，并写入统一上传文件台账。携带 `sourceType/sourceId` 关联业务来源时，需后台身份、登录用户或 `q` 查询标识匹配来源归属
- `POST /api/uploads/presign`：获取阿里云 OSS 直传授权，返回 5 分钟有效的 POST policy、对象 Key、上传地址和完成登记 token；文件内容不经过应用服务器
- `PUT /api/uploads/presign`：客户端直传成功后登记文件台账，继续复用隔离、删除、风险文件下载门禁；携带 `sourceType/sourceId` 关联业务来源时，需后台身份、登录用户或 `q` 查询标识匹配来源归属
- `sourceType=律师评价`、`sourceId=评价ID`：上传文件会作为评价申诉材料展示在后台评价质检区
- 上传接口支持可选 `sourceType`、`sourceId`、`uploaderName`、`uploaderPhone`，前端案件证据和律师资质上传会自动带入来源，便于后台追踪
- 上传接口会拒绝高风险文件类型，包括 `.exe`、`.sh`、`.js`、`.html`、`.php`、`.jar` 等扩展名和对应可执行/脚本 MIME 类型
- 上传接口会计算文件 `SHA-256` 指纹并写入台账；如果同一文件重复上传，会返回并记录 `duplicateOfId`
- `PATCH /api/admin/uploaded-files/:id`：后台文件治理，将上传文件标记为 `可用`、`隔离` 或 `已删除`，并写入审计日志
- `PATCH /api/admin/uploaded-files/:id` 也支持 `scanStatus=扫描通过/风险文件`；标记为 `风险文件` 会自动隔离并阻断下载
- `POST /api/admin/uploaded-files/scan`：批量扫描待复核文件，按扩展名、MIME、大小和重复文件生成扫描结论；风险文件会自动隔离并阻断下载
- `GET /api/admin/uploaded-files/:id/download`：后台从统一上传文件台账直接下载附件；需后台角色身份，复用隔离/删除/风险文件门禁，并写入下载或拒绝下载审计
- `GET /api/cases/:id/evidence/:evidenceId/download`：统一下载案件材料；本地存储跳转 `/uploads`，阿里云 OSS 私有桶生成短期签名 URL 后跳转；需后台身份、登录用户或 `q` 查询标识匹配案件客户/律师归属
- `GET /api/document-drafts/:id/download`、`GET /api/contract-reviews/:id/download`：交付件下载校验客户手机号、客户姓名、交付单 ID、负责律师或后台身份
- `GET /api/document-drafts/:id/receipt`、`GET /api/contract-reviews/:id/receipt`：签收回执下载复用交付件归属校验，且要求已写入 `clientConfirmedAt`
- 下载案件材料、交付件和律师资质前会检查统一上传文件台账；状态为 `隔离`、`已删除` 或 `风险文件` 时拒绝下载并写入审计日志

必填：

- `name`
- `type`

可选：

- `note`
- `fileUrl`
- `storageProvider`
- `objectKey`
- `bucket`
- `fileName`
- `fileSize`
- `contentType`

上传限制：

- 单文件最大 10MB
- `STORAGE_PROVIDER=local`：本地开发存储为 `/uploads/:filename`
- `STORAGE_PROVIDER=aliyun`：上传阿里云 OSS
- 返回字段包含 `provider`、`url`、`filename`、`objectKey`、`bucket`、`size`、`contentType`
- 生产环境建议 Bucket 私有，前端和 Android 不直接拼 OSS 地址，统一调用下载接口
- 大文件或移动端上传建议优先走 `/api/uploads/presign` 获取直传授权，上传完成后再调用完成登记接口写入台账
- OSS 下载签名默认 5 分钟有效，密钥只保存在服务端环境变量中
- 后台 `GET /api/admin/storage-config` 返回当前启用存储、上传大小上限、禁止上传类型、签名下载有效期、直传支持状态、OSS 缺失环境变量、脱敏字段、文件汇总指标和最近上传文件台账；支持 `q`、`provider`、`status`、`scanStatus`、`duplicate` 筛选，台账支持隔离、恢复、标记删除、安全复核和 CSV 导出

阿里云 OSS 环境变量：

- `STORAGE_PROVIDER=aliyun`
- `ALIYUN_OSS_ACCESS_KEY_ID`
- `ALIYUN_OSS_ACCESS_KEY_SECRET`
- `ALIYUN_OSS_BUCKET`
- `ALIYUN_OSS_ENDPOINT`，例如 `oss-cn-shenzhen.aliyuncs.com`
- `ALIYUN_OSS_DIR`，可选，默认 `ai-lawyer/uploads`
- `ALIYUN_OSS_PUBLIC_BASE_URL`，可选，用于自定义 CDN 或公开访问域名

### 法律服务与订单

- `GET /api/legal-services?category=&q=`：法律服务目录
- `POST /api/orders`：创建法律服务订单
- `GET /api/orders/:id`：订单详情；需后台身份、登录用户或 `q` 查询标识匹配订单归属
- `PATCH /api/orders/:id`：用户侧订单操作，支持确认支付、取消订单、确认服务完成；需后台身份、登录用户或 `q` 查询标识匹配订单归属
- `POST /api/payments/session`：为订单或服务包创建微信/支付宝支付会话；需后台身份、登录用户或 `q` 查询标识匹配支付来源归属。会话默认 15 分钟有效，响应返回 `expiresAt/expiresInSeconds`；未配置商户参数时返回 `not_configured`
- `POST /api/payments/confirm`：确认支付成功，开发期可用于沙箱联调；需后台身份、登录用户或 `q` 查询标识匹配支付来源归属。真实接入后由微信/支付宝异步通知验签成功后调用同一业务逻辑
- `POST /api/payments/refund`：发起订单退款；需后台身份、登录用户或 `q` 查询标识匹配订单归属。退款参数未配置时生成 `待配置` 退款流水，配置后可替换为微信/支付宝真实退款 API
- `POST /api/payments/notify/:provider`：支付渠道异步通知入口，`provider` 为 `wechat` 或 `alipay`；当前支持联调字段、金额、交易状态校验，正式接入时在该入口替换官方验签
- `POST /api/payments/refund-notify/:provider`：支付渠道退款异步通知入口，支持根据订单号或退款流水号校验退款金额，成功时同步订单为 `已取消/已退款` 并更新退款流水，失败时标记退款流水为 `失败`
- `POST /api/coupons/validate`：校验优惠码，返回原价、优惠金额和实付金额

创建订单必填：

- `serviceId`
- `clientName`
- `phone`
- `area`
- `requirement`

创建订单可选：

- `assignedLawyerId`
- `appointmentAt`
- `couponCode`

### 服务包

- `GET /api/service-packages?audience=&q=`：服务包目录
- `POST /api/package-subscriptions`：创建服务包订阅
- `POST /api/package-subscriptions/:id/use`：使用服务包权益并生成权益消耗流水和履约工单；需后台身份、登录用户或 `q` 查询标识匹配服务包归属。文书权益会自动生成文书草稿，合同审查权益会自动生成合同审查单，咨询和律师小时会自动生成零元已支付订单。`benefitType` 支持 `consultation`、`document`、`contractReview`、`lawyerHour`，可传 `requirement` 记录本次服务需求，建议传 `clientRequestId` 做幂等，避免重复点击导致重复扣减

创建服务包可选：

- `couponCode`

### 优惠活动

- 默认活动：`NEW50` 新用户满199减50；`BUSINESS10` 企业服务包满1000享9折，最高抵1000
- 创建订单或服务包时传入 `couponCode` 会真实核销优惠券，并按优惠后的金额进入支付
- 后台 `GET /api/admin/coupons` 返回活动列表和核销明细
- 后台 `POST /api/admin/coupons` 创建优惠活动，`PATCH /api/admin/coupons/:id` 可启用、停用、调整名额和截止日期

支付环境变量：

- 微信支付：`WECHAT_PAY_APP_ID`、`WECHAT_PAY_MCH_ID`、`WECHAT_PAY_API_KEY`、`WECHAT_PAY_NOTIFY_URL`
- 支付宝：`ALIPAY_APP_ID`、`ALIPAY_SELLER_ID`、`ALIPAY_PRIVATE_KEY`、`ALIPAY_NOTIFY_URL`
- 微信退款：`WECHAT_PAY_REFUND_NOTIFY_URL`、`WECHAT_PAY_CERT_SERIAL_NO`、`WECHAT_PAY_PRIVATE_KEY`、`WECHAT_PAY_API_V3_KEY`
- 支付宝退款：`ALIPAY_REFUND_NOTIFY_URL`、`ALIPAY_PUBLIC_KEY`，并复用 `ALIPAY_APP_ID`、`ALIPAY_PRIVATE_KEY`
- 后台 `GET /api/admin/payment-config` 返回每个渠道的收款 `configured/missingKeys/fields/setupHint` 和退款 `refundConfigured/refundMissingKeys/refundFields/refundSetupHint`
- 后台 `GET /api/admin/metrics?from=&to=` 返回运营指标；`from/to` 为 `YYYY-MM-DD` 时，线索转化、支付转化、交付完成、律师响应、近 7 日趋势和分渠道漏斗按日期范围计算，待办类指标保持全量
- 后台 `POST /api/admin/payments/close-overdue` 可扫描并关闭超时未支付订单，默认关闭超过 30 分钟仍为 `待支付/未支付` 的订单，并取消对应 `应收` 流水
- 支付会话未配置时，`POST /api/payments/session` 返回 `status=not_configured`、`missingConfigKeys` 和配置提示，前端收银台会直接展示缺失项

收银台页面：

- `/pay/wechat/:sourceId`：微信支付收银台
- `/pay/alipay/:sourceId`：支付宝收银台
- `sourceId` 支持订单号 `order-` 和服务包订阅号 `sub-`
- 收银台会轮询 `/api/payments/session`，支付回调或沙箱确认后自动显示已支付状态并停止轮询

支付通知联调字段：

- `sourceType`：`订单` 或 `服务包`，可选；不传时根据 `order-`、`sub-` 前缀推断
- `sourceId` 或 `outTradeNo`：订单号或服务包订阅号
- `tradeStatus`：微信可传 `SUCCESS`，支付宝可传 `TRADE_SUCCESS`
- `transactionId`：渠道交易号
- `amountCny` 或 `totalFeeFen`：通知金额，必须和订单/服务包金额一致

退款通知联调字段：

- `orderId` 或 `outTradeNo`：订单号
- `refundTransactionId` 或 `outRefundNo`：平台退款流水号，和订单号至少传一个
- `refundStatus`：微信可传 `SUCCESS`，支付宝可传 `REFUND_SUCCESS`；失败可传 `FAIL`、`REFUND_FAIL`
- `channelRefundId`：渠道退款号，可选
- `amountCny` 或 `refundFeeFen`：退款金额，必须和订单金额、退款流水金额一致

### 法律文书

- `GET /api/document-templates?docType=&area=&q=`：文书模板库
- `POST /api/document-drafts`：创建文书草稿

### 合同审查

- `POST /api/contract-reviews`：提交合同审查，返回评分、风险条款、条款定位、替换建议和报告目录
- `GET /api/contract-reviews/:id/download`：下载增强版合同审查报告，包含风险条款、定位、替换建议和报告目录
- `GET /api/contract-reviews/:id/diff`：查看 AI 初稿到当前交付版本的摘要、条款定位、替换建议、风险项变化和逐段红线对比；支持 `format=doc|pdf`

### 企业法务

- `POST /api/business-tickets`：创建企业法务工单，并按紧急度生成首次响应 SLA 截止时间
- 企业工单返回 `responseDueAt`、`firstRespondedAt`、`completedAt`、`slaStatus`、`slaRemainingMinutes`、`serviceTeam`、`escalationLevel`、`escalationReason` 和 `escalatedAt`
- 后台更新企业工单到 `方案制定`、`服务中` 或 `已完成` 时自动记录首次响应时间；更新到 `已完成` 时记录完成时间
- `POST /api/admin/business-tickets/sla-scan`：后台扫描临近超时和已超时企业工单，生成通知和审计日志；已超时工单会按紧急度自动升级到主管关注或管理层升级
- `GET|POST /api/cron/business-ticket-sla-scan`：部署平台定时任务入口，复用企业工单 SLA 扫描逻辑；生产环境需配置 `CRON_SECRET`，调用时使用 `Authorization: Bearer <CRON_SECRET>` 或 `?secret=`
- `GET /api/admin/enterprise-reports?companyName=&month=YYYY-MM`：后台生成企业常年顾问月报，返回主体认证状态、行业/员工规模、套餐余额、当月权益消耗、企业工单 SLA、合同库摘要、合同审查摘要和下月动作
- `GET /api/enterprise-reports/download?companyName=&month=YYYY-MM&format=doc|pdf&q=`：客户侧下载企业常年顾问月报，支持文本、Word 兼容版和可打印 PDF 版

### 免费问答

- `GET /api/questions?area=&status=&q=&sort=&limit=`：公开问答列表，支持最新/热门排序
- `GET /api/questions/favorites?q=`：我的收藏问答列表，优先按登录用户或访客标识查询收藏关系，并兼容历史收藏计数数据
- `GET /api/questions/topics`：按法律领域聚合公开问答专题，返回浏览、点赞、收藏和热门问题
- `/questions/topics/:area`：按法律领域生成服务端渲染专题页，包含热门问题、最新答复、CollectionPage/FAQPage 结构化数据和 canonical
- `/questions/search/:keyword`：按长尾关键词生成服务端渲染搜索落地页，复用公开问答搜索结果，包含相关领域、匹配问答、搜索转化入口、SearchResultsPage/FAQPage 结构化数据和 canonical
- `/questions?keyword=&area=`、`/consult?keyword=&area=`：搜索转化入口可带入关键词和法律领域，前台表单自动预填问题描述和领域
- `GET /api/questions/:id`：公开问答详情，累加浏览量并返回同领域相似问题
- `POST /api/questions/:id/engagement`：公开问答点赞或收藏；点赞写入 `likeCount`，收藏写入用户/访客收藏关系并幂等更新 `favoriteCount`
- `POST /api/questions`：提交免费问答；已登录用户优先绑定当前账号姓名和手机号

### 发票与售后

- `POST /api/invoices`：提交开票申请；已登录用户优先绑定当前账号姓名和手机号，并校验开票来源属于当前用户
- `POST /api/support-tickets`：提交售后工单；未关联客服工单可直接提交，关联订单、服务包、案件、文书、合同审查或企业法务时，需后台身份、登录用户或 `q` 查询标识匹配来源归属

退款规则：

- 用户侧对已支付且未完成/未取消的订单可提交 `category=退款` 的售后工单。
- 后台客服审核通过后，将该退款工单状态改为 `已解决`。
- 系统会自动把关联订单更新为 `已取消/已退款`，生成退款流水、通知和审计日志。
- 财务流水可对成功收款发起退款；未配置退款参数时保留待配置退款流水，不假装渠道退款成功。
- 如果客服驳回退款，只更新处理结果，不要把工单状态改为 `已解决`。

订单履约推进规则：

- 未支付订单不能进入 `待分配`、`服务中`、`已完成`。
- 支付确认后，订单从 `待支付` 自动进入 `待分配`。
- 后台可将已支付待分配订单推进到 `服务中`。
- 订单必须先处于 `服务中`，才能标记为 `已完成`。
- 已支付订单取消会自动生成退款流水并更新为 `已退款`。
- 律师工作台发起 `reschedule` 时会生成待客户确认的改约申请，不直接覆盖预约时间；用户在我的进度里确认后才写入新的 `appointmentAt`，也可拒绝。
- `POST /api/admin/orders/reschedule-scan`：后台扫描待客户确认的改约申请，超过指定小时后生成客户和律师提醒并写审计。
- `GET|POST /api/cron/order-reschedule-scan?olderThanHours=`：部署平台定时扫描改约提醒入口，生产环境需 `CRON_SECRET`。

## Lawyer Workspace API

- `GET /api/lawyer-workspace?lawyerId=`：律师工作台数据，包括订单、案件、文书、企业法务和合同审查；已登录律师优先使用 `userId/phone` 绑定身份
- `PATCH /api/lawyer-workspace/orders/:id`：律师处理订单，`action` 支持 `accept`、`reject`、`reschedule`、`service_log`、`complete`；`reschedule` 会进入待客户确认，其他动作写入订单服务记录；已登录律师优先使用 `userId/phone` 绑定身份，未登录演示场景可传 `lawyerId`
- `POST /api/lawyer-workspace/orders/:id/communications`：律师归档订单服务沟通，支持站内消息、电话、视频、材料和服务计时，并同步写入订单服务日志

## Admin API

### 指标

- `GET /api/admin/metrics`：后台统计指标，包含分渠道漏斗 `channelFunnels`
- `GET /api/admin/audit-logs?resourceType=&q=`：后台操作审计日志
- `GET /api/admin/approvals?status=&q=`：后台高风险操作审批队列
- `POST /api/admin/approvals`：提交高风险操作审批申请
- `PATCH /api/admin/approvals/:id`：管理员审批通过或拒绝申请

### 案件

- `GET /api/admin/cases?status=&area=&urgency=&q=`
- `POST /api/admin/cases`
- `GET /api/admin/cases/:id`
- `PATCH /api/admin/cases/:id`
- `PATCH /api/admin/cases/:id/evidence/:evidenceId`

### 律师

- `GET /api/admin/lawyers?status=&area=&city=&q=`
- `GET /api/admin/lawyers/:id`
- `PATCH /api/admin/lawyers/:id`
- `GET /api/admin/lawyer-reviews?lawyerId=&q=`
- `PATCH /api/admin/lawyer-reviews/:id`：评价质检，支持抽检状态、申诉状态、调整评分和质检备注；调整后刷新律师评分
- `POST /api/admin/lawyer-reviews/quality-scan`：按低分、投诉关键词和申诉材料执行质检抽样，自动标记需复核并写审计
- 售后工单责任判定为 `律师` 且质检结果为 `需整改` 或 `升级处理` 时，会按规则联动律师结算扣罚：质检结论给基础比例，叠加高优先级、投诉/退款类别、严重关键词和关联低分评价，上限 30%；待结算单会扣减金额，已结算单只写入扣罚备注和审计

### 咨询质检

- `GET /api/admin/consultations`
- `POST /api/admin/consultations/:id/convert`

### 订单与支付

- `GET /api/admin/orders?status=&area=&q=`
- `GET /api/admin/orders/:id`
- `PATCH /api/admin/orders/:id`
- `POST /api/admin/orders/:id/convert`
- `GET /api/admin/payments?q=&type=&status=`

### 服务包、发票、售后

- `GET /api/admin/package-subscriptions?q=&status=`
- `PATCH /api/admin/package-subscriptions/:id`
- `GET /api/admin/package-benefit-usages?q=`：查询服务包权益消耗流水
- `GET /api/admin/service-packages?q=&audience=`：后台查询全部服务包套餐，包含已下架套餐
- `POST /api/admin/service-packages`：新增服务包套餐
- `PATCH /api/admin/service-packages/:id`：更新服务包套餐、上下架、排序和权益额度
- `GET /api/admin/invoices?q=&status=`
- `PATCH /api/admin/invoices/:id`
- `GET /api/admin/lawyer-settlements?q=&status=&lawyerId=`：律师结算列表
- `GET /api/admin/lawyer-settlements/monthly-bill?month=&lawyerId=`：按月份生成律师结算月度账单，汇总金额、状态拆分和扣罚记录
- `POST /api/admin/lawyer-settlements`：从已支付且已分配律师的订单生成待结算记录
- `POST /api/lawyer-workspace/settlements/:id/withdrawal`：律师对已结算记录提交提现账户并发起提现申请
- `POST /api/lawyer-workspace/settlements/:id/invoice`：律师对已结算记录提交结算发票抬头、税号和可选文件链接
- `PATCH /api/admin/lawyer-settlements/:id`：更新结算状态、提现状态或律师发票状态；标记 `已结算` 时记录结算时间并通知律师，提现或发票标记最终状态时通知律师
- `GET /api/admin/support-tickets?q=&status=&category=`
- `PATCH /api/admin/support-tickets/:id`：售后处理，支持责任方、质检结论和质检备注

### 运营配置

- `GET /api/operation-configs?slot=&q=&visitorKey=&limit=`：前台读取已启用且在有效期内的运营配置；`visitorKey` 用于稳定 A/B 分流
- `POST /api/operation-configs/events`：前台记录运营位曝光或点击事件，支持 `impression` / `click`
- `GET /api/admin/operation-configs?slot=&q=`：后台查询首页推荐、服务频道、热门问答和律师排序配置
- `GET /api/admin/operation-configs/events?slot=&from=&to=`：后台查询运营配置曝光、点击和 CTR 汇总
- `POST /api/admin/operation-configs`：新增运营配置
- `PATCH /api/admin/operation-configs/:id`：更新标题、描述、目标、链接、排序、上下架和有效期
- `slot=seoMetadata`：配置主要页面 SEO 元数据；`targetId` 或 `href` 填页面路径（如 `/`、`/services`、`/consult`、`/lawyers`、`/questions`），`title` 为页面标题，`subtitle` 为页面描述
- `slot=questionKeyword`：配置问答长尾搜索词；`title` 或 `targetId` 填关键词，前台问答页展示高频搜索入口，sitemap 会生成 `/questions/search/:keyword`
- `slot=priceCampaign`：配置限时活动价；`targetType` 填 `service` 或 `package`，`targetId` 填服务/服务包 ID，`title` 为活动名，`subtitle` 填活动价数字；服务列表、服务包列表、下单和优惠码校验使用活动价
- `/sitemap.xml`：包含首页、核心服务入口、公开问答领域专题页、公开问答长尾搜索页和最多 200 条已公开问答详情页；生产环境建议配置 `NEXT_PUBLIC_SITE_URL`
- `/robots.txt`：允许公开页面抓取，屏蔽后台、API、我的进度、登录和支付路径

### 企业法务、文书、问答、合同

- `GET /api/admin/business-tickets?q=&status=&scenario=`
- `PATCH /api/admin/business-tickets/:id`
- `POST /api/admin/business-tickets/sla-scan`
- `GET|POST /api/cron/business-ticket-sla-scan`
- `GET /api/admin/document-drafts?q=&status=&area=`
- `PATCH /api/admin/document-drafts/:id`
- `GET /api/admin/document-templates?q=&docType=&area=`
- `GET /api/admin/questions?q=&status=&area=`
- `PATCH /api/admin/questions/:id`
- `POST /api/admin/questions/:id/convert`
- `GET /api/admin/contract-reviews?q=&status=&contractType=`
- `PATCH /api/admin/contract-reviews/:id`

### 基础配置

- `GET /api/admin/legal-areas?q=`：后台法律领域配置

## Go Migration Notes

Go 后端拆分时建议以这个 API 文档作为第一版 OpenAPI 蓝本：

- 保持 URL 和 JSON 字段兼容
- 数据库切换为 PostgreSQL 或 MySQL
- 使用 Redis 承载通知、AI任务和异步审查队列
- 文件类能力统一走对象存储，API 只返回签名上传/下载地址
- 给后台接口增加 JWT + RBAC
- 给所有状态变更增加审计日志
- Web 和 Android 只依赖 OpenAPI，不依赖 Next.js 内部实现
