Files
platforms/docs/11-数据接口与安全.md

118 lines
15 KiB
Markdown
Raw Normal View History

# 数据接口与安全规范
## 1. 核心数据域
### 数据模型强制约定
- 主表命名使用领域模块前缀,具体前缀以 [技术实现规划](10-技术实现规划.md) 的“数据模型与命名强制规范”为准;禁止跨模块使用无前缀的通用表名。
2026-07-27 00:18:42 +08:00
- 同一实体的数据库表、Go/Flutter/Vue 模型文件、模型类型和 OpenAPI/AsyncAPI Schema 必须使用相同的模块前缀与单数实体词根。例如 `org_gas_station``org_gas_station.go``OrgGasStation` 属于同一实体;禁止使用 `org_gas_stations``GasStations` 等复数或不同词根。
- 每个主表必须以 `identity` 字段作为 UUID V7 主键。所有关联字段使用 `<实体名>_identity` 命名,业务编号仅作展示和检索,不作为主键或跨表关联依据。
- 表、字段、索引、约束、枚举及接口模型必须有中文注释;涉及金额、单位、状态、定位、脱敏和留存的数据须在注释中明确口径。
| 数据域 | 核心实体 | 关键约束 |
| --- | --- | --- |
| 身份组织 | `idn_account``idn_role``idn_permission``org_gas_station``org_service_area``org_service_person``org_user_service_relation``org_invitation_qr_code``idn_emergency_contact` | 手机号/账号唯一;角色和数据范围均生效;紧急联系人授权范围、二维码归因和服务关系历史单独记录 |
| 设备 | `dev_device``dev_device_binding``dev_device_group``dev_cylinder``dev_telemetry``dev_command` | 设备序列号唯一;绑定有有效期与历史;命令含幂等键与回执;气瓶信息保留来源和有效期 |
| 安全 | `saf_rule``saf_event``saf_repair_request``saf_inspection``saf_rectification` | 事件编号唯一等级、状态、SLA、证据、操作者完整可追溯报修图片/定位需有采集时间 |
| 商品交易 | `cat_category``cat_product``cat_sku``cat_cart``cat_coupon``ord_order``ord_payment``ord_invoice` | 金额使用最小货币单位整数;库存扣减有事务/预占规则;预约时段、库存快照和开票状态可追溯 |
| 履约 | `ord_service_task``dsp_assignment``ord_delivery_track``dsp_delivery_track_point` | 任务状态转换受限;定位、轨迹和证据均有采集时间 |
| 资金与押金 | `wal_wallet_ledger``wal_deposit``wal_deposit_refund``wal_settlement``wal_withdrawal``wal_reconciliation` | `wal_wallet_ledger` 为唯一钱包事实流水;金额方向、关联对象和余额快照可校验;退押金保留验收、扣减和退款去向 |
| 用气统计 | `dev_usage_stat``dev_usage_report` | 明确统计周期、单位、来源、计算版本和最后更新时间;报表导出留痕 |
| 内容审计 | `cnt_article``cnt_banner``cnt_notice``aud_operation_log` | 发布有版本;审计日志追加写入且设置留存期限 |
## 2. API 约定
- 外部 HTTP 接口采用 `/api/v1` 版本前缀JSON 格式UTC 时间 ISO 8601金额传最小货币单位枚举使用稳定代码。
- 写操作携带 `Idempotency-Key`;响应带 `request_id`;异步动作返回业务任务/命令 ID而非伪造同步成功。
- 分页使用游标优先;敏感字段按角色脱敏;下载使用短效签名 URL 和用途审计。
- 错误码分为认证、权限、参数、状态冲突、限流、外部依赖和系统异常;前端不能依据错误文案判断流程。
### 关键接口族(逻辑级)
| 域 | 示例能力 |
| --- | --- |
| 认证 | 登录、验证码、令牌刷新、注销、协议同意、角色切换 |
| 设备 | 绑定/解绑申请、设备列表/详情、命令创建/查询、遥测历史、群组控制、气瓶信息、自动关闭时间、共享授权 |
| 安全 | 事件列表/详情、确认、派单、检查提交、整改提交、复检、规则管理、一键报修、紧急联系人与紧急通知 |
| 商城 | 商品/分类、购物车、优惠试算、气瓶预约订单、库存查询、支付、合同、售后、电子发票 |
| 履约 | 任务列表、接单、导航、到达、检查表、完成、异常、改派 |
| 配送轨迹 | 轨迹点上报、任务轨迹查询、用户简化轨迹查询、预计到达、轨迹异常和轨迹导出审批 |
| 资金与押金 | 充值、余额支付密码、流水、提现申请、押金汇总、退瓶退押金、审核、对账、结算 |
| 用气统计 | 月度/年度统计、报表明细、导出任务 |
| 邀请注册 | 邀请二维码创建/查询/停用、短链接解析、扫码校验、注册归因、气站/配送点服务关系建立 |
## 3. IoT 协议与可靠性
- 设备厂商 V1.8 二进制帧保持 `0x5E` 起始、`0x5B` 结束、大端序、数据包 AES-128 与 LRC8 规则不变,并作为 MQTT payload 传输Topic 使用 `devices/{deviceId}/{up|down|ack}`QoS 1下行命令禁止 retained。
- `iot-server` 只处理 MQTT 会话和设备协议,`iot-client` 只提供系统侧上下行接口命令、Outbox、原始上行和回执事实由 API 持久化Worker 负责可重试投递。
- 协议封面版本与变更记录冲突时以最新 V1.8 变更记录和绿色标注为兼容实现依据;重复子标识等歧义必须保留原始报文并按设备型号配置解析,不得静默猜测。
- 设备采用 MQTT over TLS设备身份使用每设备证书或短期轮换令牌禁止共享默认密钥。
- 上行消息至少包含设备 ID、协议版本、消息 ID、设备时间、服务端接收时间、指标值、质量标记和固件版本。
- 下行命令包含命令 ID、幂等键、期望状态、过期时间、签名/鉴权信息;设备回传已收到、执行中、成功/失败与错误码。
- 规则计算以服务端接收时间为准并保留设备时间;乱序、重复、缺失遥测应有容错和告警策略。
- 自动关阀须优先在设备本地具备安全兜底逻辑,云端规则作为补充;网络中断不能成为失去基本安全保护的单点原因。
## 3.1 邀请注册二维码安全要求
- 二维码载荷仅为随机、签名且可撤销的邀请码或短链接,不得直接包含组织管理员身份、用户信息、地址、长期访问令牌或 API 密钥。
- 服务端解析后校验二维码状态、归属气站/配送点、有效期、使用次数、服务区域、风险策略和用户登录状态;所有校验均在服务端完成。
- 同一用户多次扫码不重复创建账户;服务关系的首次建立、变更和归因要有幂等键及完整审计。用户已有服务关系时,页面应告知影响并要求确认。
- 对二维码生成、下载、分享链接访问、扫码、注册、失败原因、停用和重新生成记录审计;支持按二维码、组织、人员和活动查询转化漏斗。
- 邀请短链接应具备 HTTPS、频率限制、反爬/风控校验和安全跳转白名单;二维码泄露后可由所属气站、配送点或平台立即停用。
## 3.2 配送轨迹数据与隐私要求
- 轨迹数据至少包括配送任务 ID、订单 ID、配送员 ID、定位时间、服务端接收时间、坐标、定位精度、来源、任务状态和完整性标记。位置点不可用订单创建时间替代。
- 客户端按后台配置的间隔、距离变化和状态节点采集;服务端进行去重、乱序校正、异常速度/精度标记和幂等写入。弱网补传保留原始定位时间和补传标记。
- 用户端只返回本人订单所需的简化轨迹、最近有效位置、预计到达和事件节点;配送点/气站/平台按组织和职责获取更详细数据。精确轨迹回放及导出应审批并记录用途。
- 轨迹属于敏感定位数据,传输与存储加密、最小化留存、访问审计;订单完结后按留存策略降精度展示或限制访问。严禁将配送员非履约时间的位置用于无关用途。
### 3.3 移动端离线、定位与现场证据要求
- 服务端 App 只有在任务执行期间可采集后台定位;定位权限撤销、后台运行受限、精度不足或长时间无位置时必须提示服务人员并向任务记录写入状态,不得伪造实时轨迹。
- 离线队列中的任务材料、定位点、照片/视频元数据、签名、扫描结果和收款确认必须本地加密。补传请求携带原始采集时间、服务端接收时间、`identity`、幂等键、来源和完整性标记;服务端按任务状态和证据哈希进行去重、乱序校正和冲突处置。
- 定位、签名和现场证据的采集开关、保留时长、可见角色、精度降级与导出权限由平台配置;客户端展示或本地删除不能绕过服务端留存、审计和安全事件证据义务。
### 3.4 服务端 App 工单、取证与结算要求
| 场景 | 核心实体 | 必要数据与规则 |
| --- | --- | --- |
| 人员准入与打卡 | `idn_service_person_credential``idn_service_person_vehicle``idn_service_person_check_in``saf_training_attempt` | 角色、证件有效期、车辆、上/下班位置、培训题目版本与结果必须可追溯;未通过准入/培训不可开始任务 |
| 安检与隐患 | `saf_inspection``saf_inspection_item_result``saf_inspection_photo``saf_user_signature``saf_hazard` | 检查项、风险等级、定位/时间水印、签名、隐患状态和整改证据绑定同一任务;高风险事件与关阀/通知动作关联 |
| 维修工单 | `ord_service_task``ord_repair_evidence``ord_repair_material``ord_repair_receipt` | 维修前中后证据、材料、价格快照、应收/实收、签字和支付差异可追溯;不能由服务人员修改订单定价 |
| 安装工单 | `ord_installation_condition``ord_installation_material``ord_installation_step``ord_installation_test``ord_installation_receipt` | 使用条件、备料、安装步骤、测试、前期安检、设备激活和收款按顺序记录;不合格或测试失败不能完成/激活 |
| 配送与回收 | `dsp_delivery_cylinder_scan``dsp_delivery_evidence``dsp_delivery_payment_confirmation``dsp_cylinder_return` | 气瓶/设备编码、蓝牙/扫码来源、随瓶安检照片视频、收款确认、空瓶回收、押金和库存状态均与配送任务关联 |
| 服务收入 | `wal_service_income``wal_withdrawal``wal_bank_card` | 收入由已完成且符合结算规则的任务生成;`wal_withdrawal` 是所有钱包提现的唯一实体,以可提现余额、银行卡验证、审核和打款回执为准 |
- 现场照片、视频、电子签字、蓝牙扫描、定位和收款确认属于取证数据。必须记录原始采集时间、服务端接收时间、任务、操作者、来源、完整性标记和对象存储哈希;客户端离线补传不得覆盖原始采集时间。
- 强制取证项由任务类型、设备型号、风险等级和组织规则确定。服务端在工单完成前校验必填检查项、照片/视频数量、签字、地理围栏、材料和支付状态,前端按钮禁用不能替代服务端校验。
- 收款、押金、退款和服务收入均以不可变流水为准。配送员/安装维修员仅能提交确认材料,不得创建、修改或删除资金事实;出现金额不一致、重复提交或离线补传冲突时进入对账异常。
## 4. 安全、隐私与合规
- 登录令牌短期有效,刷新令牌可撤销;后台高权限账号启用 MFA、IP/设备策略。平台后台管理的平台、气站、配送、员工和业主账号密码按当前实施口径仅要求不少于 6 个字符,不附加复杂度校验。
- 权限校验在服务端执行,前端菜单隐藏不构成权限控制。按角色、站点、区域、对象归属联合鉴权。
- 手机号、地址、身份证明、收款账户、定位、视频为敏感数据:传输 TLS、存储加密/字段加密、显示脱敏、访问留痕、最小化留存。
- 所有支付回调验证签名与金额、订单、商户号一致性;合同文件使用可信第三方原文与哈希存证。渠道回调入口为 `/heqi/payment-return/v1/{alipay|wechat}/notify`,不使用用户 JWT必须完成渠道证书验签、商户/appid、平台支付单号、金额、币种和状态校验后才可在数据库事务中推进业务。重复通知必须幂等原始敏感报文只保存摘要。
- `payment_order` 是统一支付尝试事实;`payment_refund``payment_refund_item` 保存用户退款申请及明细。审批通过与钱包入账必须同事务完成。
- 图片/视频上传做文件类型、大小、病毒/恶意内容检测;访问采用短期授权,不使用公开桶。
- 设备控制、告警等级调整、资金审核、数据导出、账号注销等高风险操作要求二次确认和审计。
## 5. 备份与灾备
- PostgreSQL 至少每日全量、持续 WAL 归档并定期演练恢复;安全事件、订单和资金数据定义更严格 RPO/RTO。
- 对象存储启用版本/生命周期策略,合同和安全证据按合规期限留存;备份不得绕开数据加密和访问控制。
- 关键服务多实例部署MQTT、数据库、消息队列和对象存储须有明确高可用方案和故障演练计划。
## 6. 移动 Client API 安全实施约定
- 用户端和工作人员端分别使用 `user_app``service_app` JWT client claim服务端逐请求校验 client、账户启用状态、岗位、组织和对象归属。
- 验证码由 `/auth/verification-code` 创建Redis 保存五分钟、验证成功即删除,并按手机号及来源 IP 限流;响应只返回请求 `identity` 和有效期。开发 Mock 验证码从 `Global` 配置读取,生产必须关闭。
- 银行卡号、身份证号、预留手机号使用 `Global.FieldEncryptionKey` 经 HKDF 派生独立 AES-GCM 加密键和 HMAC 指纹键;接口列表只返回末四位掩码。开发占位密钥不得用于生产。
- 支付密码独立于登录密码,仅允许六位数字,使用 bcrypt 保存;连续失败达到阈值后在 Redis 短时锁定。绑卡、解绑、余额支付和提现均要求支付密码或限定用途的一次性验证码。
- 公共上传接口 `/upload/file` 必须携带平台、气站、配送点、用户或工作人员任一合法 JWT图片/PDF 最大 10MB视频上限从配置读取。上传只返回资源 URI业务接口负责建立关联并记录操作者、采集与接收时间。
- 充值、支付、提现、工单证据、轨迹点、内容确认等写入均携带幂等号;资金入账在数据库事务内锁定钱包并同时写不可变流水。
- 钱包可提现余额是当前总余额的子集,始终满足 `0 <= 可提现余额 <= 总余额`。普通消费扣减总余额后,必须同步把可提现余额限制在剩余总余额以内。
- 提现申请在同一数据库事务内锁定钱包、同时预扣总余额和可提现余额并写入不可变流水;驳回只返还该申请实际预扣的两类余额,完成打款只确认外部结果,不得再次扣款。