-- OneOS 客户账号与当前车辆范围只读审计
-- 仅允许在只读连接执行；不包含任何 INSERT/UPDATE/DELETE/DDL。

SET SESSION TRANSACTION READ ONLY;
SET SESSION MAX_EXECUTION_TIME = 10000;

-- 0. 核验实际授权。只读账号不应出现 ALL PRIVILEGES、PROCESS、REPLICATION 或 DDL/DML 权限。
SHOW GRANTS FOR CURRENT_USER;

-- 1. 核对关键表字段，识别代码、文档与生产结构漂移。
SELECT table_schema, table_name, column_name, data_type, is_nullable, column_key
FROM information_schema.columns
WHERE table_schema IN ('ln_asset_management', 'ry-cloud')
  AND table_name IN (
    'vehicle_info', 'vehicle_lease_order_record', 'vehicle_lease_order_record_log',
    'vehicle_lease_contract_info', 'vehicle_lease_order_detail', 'delivery_vehicle',
    'return_vehicle_task', 'customer_info', 'sys_user', 'sys_user_role'
  )
  AND column_name IN (
    'id', 'user_id', 'vehicle_id', 'plate_number', 'vin', 'customer_id',
    'other_customer_id', 'contract_id', 'contract_code', 'last_delivery_time',
    'last_return_time', 'delivery_time', 'arrival_time', 'user_type', 'status', 'del_flag'
  )
ORDER BY table_schema, table_name, ordinal_position;

-- 2. 车辆基础数据质量。
SELECT
  COUNT(*) AS active_vehicles,
  SUM(vin IS NULL OR TRIM(vin) = '') AS missing_vin,
  COUNT(DISTINCT NULLIF(TRIM(vin), '')) AS distinct_vin,
  COUNT(DISTINCT NULLIF(TRIM(plate_number), '')) AS distinct_plate
FROM ln_asset_management.vehicle_info
WHERE del_flag = '0';

-- 3. 客户档案与客户账号覆盖率，不输出手机号、密码等敏感字段。
SELECT
  COUNT(*) AS active_customers,
  SUM(u.user_id IS NOT NULL) AS customers_with_account,
  SUM(u.status = '0' AND u.del_flag = '0') AS customers_with_enabled_account,
  SUM(u.user_id IS NULL) AS customers_without_account
FROM ln_asset_management.customer_info c
LEFT JOIN `ry-cloud`.sys_user u
  ON u.user_id = c.id
 AND u.user_type = 'customer'
WHERE c.del_flag = '0';

-- 4. 客户账号角色覆盖率。
SELECT
  COUNT(DISTINCT u.user_id) AS customer_accounts,
  COUNT(DISTINCT ur.user_id) AS customer_accounts_with_role
FROM `ry-cloud`.sys_user u
LEFT JOIN `ry-cloud`.sys_user_role ur ON ur.user_id = u.user_id
WHERE u.user_type = 'customer'
  AND u.del_flag = '0';

-- 5. 旧聚合时间口径，仅用于与事务事实口径对比，不能作为授权真值。
SELECT
  COUNT(*) AS scope_rows,
  COUNT(DISTINCT r.vehicle_id) AS scope_vehicles,
  COUNT(DISTINCT r.customer_id) AS scope_customers,
  SUM(r.customer_id IS NULL) AS missing_customer,
  SUM(v.vin IS NULL OR TRIM(v.vin) = '') AS missing_vin,
  SUM(c.id IS NULL AND r.customer_id IS NOT NULL) AS missing_customer_profile
FROM ln_asset_management.vehicle_lease_order_record r
LEFT JOIN ln_asset_management.vehicle_info v
  ON v.id = r.vehicle_id AND v.del_flag = '0'
LEFT JOIN ln_asset_management.customer_info c
  ON c.id = r.customer_id AND c.del_flag = '0'
WHERE r.del_flag = '0'
  AND r.last_delivery_time IS NOT NULL
  AND (r.last_return_time IS NULL OR r.last_return_time < r.last_delivery_time);

-- 5A. 当前交车/还车事务事实候选及归属质量。
SELECT
  COUNT(*) AS candidate_rows,
  COUNT(DISTINCT d.vehicle_id) AS candidate_vehicles,
  SUM(v.id IS NULL OR v.vin IS NULL OR TRIM(v.vin) = '') AS invalid_vehicle,
  SUM(r.id IS NULL OR r.customer_id IS NULL) AS missing_aggregate_customer,
  SUM(ci.id IS NULL AND r.customer_id IS NOT NULL) AS invalid_customer_profile,
  SUM(co.id IS NULL) AS invalid_contract,
  SUM(co.id IS NOT NULL AND COALESCE(co.other_customer_id, co.customer_id) IS NULL) AS missing_contract_customer,
  SUM(
    r.customer_id IS NOT NULL
    AND COALESCE(co.other_customer_id, co.customer_id) IS NOT NULL
    AND r.customer_id <> COALESCE(co.other_customer_id, co.customer_id)
  ) AS customer_mismatch
FROM ln_asset_management.delivery_vehicle d
LEFT JOIN ln_asset_management.vehicle_info v
  ON v.id = d.vehicle_id AND v.del_flag = '0'
LEFT JOIN ln_asset_management.vehicle_lease_order_record r
  ON r.vehicle_id = d.vehicle_id AND r.del_flag = '0'
LEFT JOIN ln_asset_management.customer_info ci
  ON ci.id = r.customer_id AND ci.del_flag = '0'
LEFT JOIN ln_asset_management.vehicle_lease_contract_info co
  ON co.id = d.contract_id AND co.del_flag = '0'
WHERE d.del_flag = '0'
  AND d.delivery_status IN (2, 3)
  AND d.vehicle_id IS NOT NULL
  AND d.delivery_time IS NOT NULL
  AND NOT EXISTS (
    SELECT 1
    FROM ln_asset_management.delivery_vehicle newer
    WHERE newer.del_flag = '0'
      AND newer.vehicle_id = d.vehicle_id
      AND (
        COALESCE(newer.delivery_time, '1000-01-01') > COALESCE(d.delivery_time, '1000-01-01')
        OR (
          COALESCE(newer.delivery_time, '1000-01-01') = COALESCE(d.delivery_time, '1000-01-01')
          AND newer.id > d.id
        )
      )
  )
  AND NOT EXISTS (
    SELECT 1
    FROM ln_asset_management.return_vehicle_task rt
    WHERE rt.delivery_vehicle_id = d.id
      AND rt.del_flag = '0'
      AND rt.status IN (2, 3, 5)
  );

-- 6. 检查同一车辆是否出现多个当前客户范围记录。
SELECT r.vehicle_id, COUNT(*) AS active_scope_rows, COUNT(DISTINCT r.customer_id) AS customer_count
FROM ln_asset_management.vehicle_lease_order_record r
WHERE r.del_flag = '0'
  AND r.last_delivery_time IS NOT NULL
  AND (r.last_return_time IS NULL OR r.last_return_time < r.last_delivery_time)
GROUP BY r.vehicle_id
HAVING COUNT(*) > 1 OR COUNT(DISTINCT r.customer_id) > 1
ORDER BY active_scope_rows DESC
LIMIT 100;

-- 7. 检查客户 ID 与客户档案不一致的记录。
SELECT COUNT(*) AS unmatched_customer_records
FROM ln_asset_management.vehicle_lease_order_record r
LEFT JOIN ln_asset_management.customer_info c
  ON c.id = r.customer_id AND c.del_flag = '0'
WHERE r.del_flag = '0'
  AND r.customer_id IS NOT NULL
  AND c.id IS NULL;

-- 8. 聚合表客户与合同有效客户是否一致。
SELECT
  COUNT(*) AS records_with_contract,
  SUM(c.id IS NULL) AS missing_contract,
  SUM(c.id IS NOT NULL AND r.customer_id IS NULL) AS missing_record_customer,
  SUM(
    c.id IS NOT NULL
    AND r.customer_id IS NOT NULL
    AND r.customer_id <> COALESCE(c.other_customer_id, c.customer_id)
  ) AS effective_customer_mismatch
FROM ln_asset_management.vehicle_lease_order_record r
LEFT JOIN ln_asset_management.vehicle_lease_contract_info c
  ON c.id = r.contract_id AND c.del_flag = '0'
WHERE r.del_flag = '0'
  AND r.contract_id IS NOT NULL;

-- 9. 已交车但聚合表被清空或缺少客户/合同的可疑记录。
-- delivery_vehicle 的正式完成状态字段需先通过第 1 项结构核对，再按生产枚举追加状态条件。
SELECT
  COUNT(*) AS delivered_rows,
  SUM(r.id IS NULL) AS missing_aggregate_record,
  SUM(r.id IS NOT NULL AND r.customer_id IS NULL) AS aggregate_missing_customer,
  SUM(r.id IS NOT NULL AND r.contract_id IS NULL) AS aggregate_missing_contract,
  SUM(r.id IS NOT NULL AND r.last_delivery_time IS NULL) AS aggregate_missing_delivery_time
FROM ln_asset_management.delivery_vehicle d
LEFT JOIN ln_asset_management.vehicle_lease_order_record r
  ON r.vehicle_id = d.vehicle_id AND r.del_flag = '0'
WHERE d.del_flag = '0'
  AND d.delivery_time IS NOT NULL;

-- 10. 当前聚合表与最新历史记录的关键字段差异。
SELECT COUNT(*) AS aggregate_log_mismatch
FROM ln_asset_management.vehicle_lease_order_record r
JOIN ln_asset_management.vehicle_lease_order_record_log l
  ON l.vehicle_id = r.vehicle_id
 AND l.del_flag = '0'
 AND l.id = (
   SELECT MAX(l2.id)
   FROM ln_asset_management.vehicle_lease_order_record_log l2
   WHERE l2.vehicle_id = r.vehicle_id AND l2.del_flag = '0'
 )
WHERE r.del_flag = '0'
  AND NOT (
    r.customer_id <=> l.customer_id
    AND r.contract_id <=> l.contract_id
    AND r.last_delivery_time <=> l.last_delivery_time
    AND r.last_return_time <=> l.last_return_time
  );

-- 11. 检查支撑客户车辆范围查询的索引。这里只读索引元数据，不执行 DDL。
SELECT table_name, index_name, non_unique,
       GROUP_CONCAT(column_name ORDER BY seq_in_index) AS indexed_columns
FROM information_schema.statistics
WHERE table_schema = 'ln_asset_management'
  AND table_name IN (
    'vehicle_info', 'vehicle_lease_order_record', 'vehicle_lease_order_record_log',
    'vehicle_lease_contract_info', 'delivery_vehicle', 'return_vehicle_task'
  )
GROUP BY table_name, index_name, non_unique
ORDER BY table_name, index_name;

-- 12. 客户编码与系统用户名的冲突、错类型和错租户情况。
-- tenant_id 的目标值应由生产配置确认，这里先按客户 ID 关联并报告实际分布。
SELECT
  COUNT(*) AS customer_profiles,
  SUM(u.user_id IS NULL) AS no_same_id_account,
  SUM(u.user_id IS NOT NULL AND u.user_type <> 'customer') AS same_id_wrong_type,
  SUM(
    u.user_id IS NOT NULL
    AND (CONVERT(u.user_name USING utf8mb4) COLLATE utf8mb4_unicode_ci)
      <> (CONVERT(c.customer_code USING utf8mb4) COLLATE utf8mb4_unicode_ci)
  ) AS username_code_mismatch,
  COUNT(DISTINCT CASE WHEN u.user_id IS NOT NULL THEN u.tenant_id END) AS account_tenant_count
FROM ln_asset_management.customer_info c
LEFT JOIN `ry-cloud`.sys_user u ON u.user_id = c.id AND u.del_flag = '0'
WHERE c.del_flag = '0';

-- 13. 同一租户、用户名是否存在多账号或跨 user_type 冲突。
SELECT tenant_id, user_name,
       COUNT(*) AS account_count,
       COUNT(DISTINCT user_type) AS user_type_count
FROM `ry-cloud`.sys_user
WHERE del_flag = '0'
  AND user_name IS NOT NULL
  AND TRIM(user_name) <> ''
GROUP BY tenant_id, user_name
HAVING COUNT(*) > 1 OR COUNT(DISTINCT user_type) > 1
ORDER BY account_count DESC
LIMIT 100;

-- 14. 业务库整体体积与最大表。table_rows 为 InnoDB 估算值，不用于财务或业务计数。
SELECT
  COUNT(*) AS base_tables,
  SUM(data_length) AS data_bytes,
  SUM(index_length) AS index_bytes
FROM information_schema.tables
WHERE table_schema = 'ln_asset_management'
  AND table_type = 'BASE TABLE';

SELECT table_name, table_rows, data_length, index_length
FROM information_schema.tables
WHERE table_schema = 'ln_asset_management'
  AND table_type = 'BASE TABLE'
ORDER BY data_length + index_length DESC
LIMIT 20;

-- 15. API 月日志体积，用于核对保留策略；不读取任何日志内容。
SELECT table_name, table_rows, data_length, index_length
FROM information_schema.tables
WHERE table_schema = 'ln_asset_management'
  AND table_name LIKE 'api_request_log\\_%'
ORDER BY table_name;
