# OneOS 生产数据库只读审计报告

审计时间：2026-07-14

## 1. 执行边界

- 连接路径：本机 → SSH 加密隧道 → 当前车辆中台 ECS → 阿里云 RDS 内网地址。
- 所有查询会话均执行 `SET SESSION TRANSACTION READ ONLY`。
- 单条查询设置 `MAX_EXECUTION_TIME=10000`（10 秒）。
- 仅执行元数据和聚合查询，未读取密码、客户姓名、手机号、银行账号等明细。
- 未执行任何 INSERT、UPDATE、DELETE、DDL 或权限变更。

## 2. 账号权限核验

当前从 `ln-bi` 部署配置取得的 RDS 账号并不是账号级只读：

- 对 `ln_asset_management`、`ry-cloud` 等多个业务库拥有 `ALL PRIVILEGES`。
- 还拥有 `PROCESS`、`REPLICATION SLAVE`、`REPLICATION CLIENT` 和 `XA_RECOVER_ADMIN` 等全局权限。

本次审计依靠会话只读保护，没有使用这些写权限。但该账号不适合作为车辆数据中台的生产同步账号，也不应继续以“只读账号”管理。

建议另建独立账号，只授予必要表的 `SELECT`；如需最小到列级，优先建立脱敏只读视图并仅授权视图。权限调整属于数据库写操作，需另行审批。

## 3. 数据质量基线

### 车辆档案

| 指标 | 结果 |
| --- | ---: |
| 有效车辆 | 1,209 |
| VIN 缺失 | 0 |
| VIN 重复组 | 0 |
| 车牌缺失 | 0 |

车辆身份基础质量良好，当前 1,209 台有效车辆均有 VIN 和车牌，标准化 VIN 后无重复。

生产库尚未给 `vehicle_info.vin` 建立索引或唯一约束。当前数据满足增加唯一索引的前置条件，但正式 DDL 前仍要确认历史/逻辑删除记录及业务兼容性。

### 客户账号

| 指标 | 结果 |
| --- | ---: |
| 有效客户 | 335 |
| `customer_info.id = sys_user.user_id` 的账号 | 0 |
| `user_type=customer` 的账号 | 0 |
| 客户编码与系统用户名匹配 | 0 |
| 联系手机号与系统账号手机号匹配 | 4 |
| 客户编码缺失 | 7 |

结论：客户账号体系尚未形成，不能通过“补角色”直接开放。4 个手机号匹配仅能作为待人工核验线索，不能自动认定为客户账号或覆盖现有用户。

两个库的字符排序规则不同：

- `customer_info.customer_code/contact_mobile`：`utf8mb4_unicode_ci`
- `sys_user.user_name/phonenumber`：`utf8mb4_0900_ai_ci`

跨库字符串直接等值 JOIN 会报 collation 冲突。正式关联应优先使用稳定 ID；补偿审计若按编码/手机号匹配，需要显式统一 collation。

### 当前客户车辆候选范围（事务事实口径）

候选条件：每车最新有效交车单已完成（`delivery_status IN (2,3)`），且该交车单不存在正式完成的还车任务（`status IN (2,3,5)`）。聚合表仅用于客户归属交叉校验，不使用可能被还车草稿提前写入的 `last_return_time` 判断生命周期。

| 指标 | 结果 |
| --- | ---: |
| 候选记录 | 639 |
| 候选车辆 | 639 |
| 可安全发布记录 | 613 |
| 应隔离记录 | 26 |

隔离原因（可能重叠）：

| 原因 | 数量 |
| --- | ---: |
| 聚合记录或客户 ID 缺失 | 17 |
| 聚合客户与合同有效客户不一致 | 9 |
| 车辆档案不可用 | 0 |
| VIN 缺失 | 0 |

因此第一版客户车辆 Scope 最多只能发布 613 条已校验关系，其余 26 条必须隔离，不能为了数量完整而放宽权限。

与旧聚合时间口径相比，事务事实口径排除 16 台：12 台已有正式还车事实、3 台最新交车尚未完成、1 台没有交车事实；另有 8 台进入事务候选但不在旧聚合候选，其中 4 台缺聚合记录并会继续 fail-closed 隔离。该差异证明 `last_delivery_time/last_return_time` 不适合作为外部授权生命周期真值。

### 租赁聚合与历史一致性

| 指标 | 结果 |
| --- | ---: |
| 有效当前聚合记录 | 831 |
| 无任何交还车时间 | 13 |
| 已交车、无还车时间 | 617 |
| 还车后再次交车 | 30 |
| 已还车 | 171 |
| 聚合表与最新历史关键字段不一致 | 325 |
| 违反“一车一条聚合记录”的车辆组 | 1 |
| 当前候选范围内重复车辆 | 0 |

325 条差异说明 `vehicle_lease_order_record_log` 不能简单取最大 ID 当作当前真值；1 组重复聚合记录也意味着现有 `selectOne(vehicle_id)` 存在运行时异常风险。正式修复前需要对异常组做明细复核，但明细不写入本报告。

## 4. 索引结论

生产库已有车牌、vehicleId 和部分状态索引，但缺少：

- `vehicle_info.vin` 索引/唯一约束；
- `vehicle_lease_order_record.customer_id` 的客户范围查询索引；
- `vehicle_lease_order_record.vehicle_id` 唯一约束；
- `vehicle_status.vehicle_id` 唯一约束；
- 合同有效客户查询所需索引。

当前数据量不大。2026-07-14 事务事实影子查询耗时约 93 ms，主交车表预估扫描 2,320 行，其余关联均使用 `eq_ref/ref`；两分钟一次的单次批量查询压力可控。后续数据增长后仍需监控执行时间，索引 DDL 必须单独审批并用 `EXPLAIN`、影子查询和回滚方案验证。

## 5. 当前可采用的权限口径

在业务确认和异常修复前，外部客户范围必须同时满足：

```text
车辆有效且 VIN 非空
聚合记录有效
最新有效交车单已完成
该交车单不存在正式完成的还车任务
客户档案有效
合同有效
聚合客户 ID 非空
合同有效客户非空
聚合客户 = COALESCE(合同丙方客户, 合同主客户)
同一车辆不存在多客户冲突
```

不满足任一条件的记录进入隔离清单，外部查询失败关闭。

## 6. 下一步

1. 创建真正的最小权限 RDS 只读账号，替换当前高权限账号。
2. 由业务人员复核 26 条隔离关系和 1 组重复聚合记录。
3. 不修改 `ln-asset-management`；将还车草稿提前写聚合字段记录为上游风险，数据中台只读取正式交还车任务状态。
4. 以 613 条可发布关系运行影子 Scope，与合同和交还车样本对账。
5. 完成客户身份入口与所有客户 API 的 Scope 强制校验后，再审批上线外部客户入口。
