========================================================================
钱包流水系统备注回填 - 定时任务手工添加清单 (2026-10-08)
========================================================================

说明：以下内容需要管理员在对应环境手工执行（直接执行 SQL）。
SQL 按任务名幂等，风格与 db/20261008_钱包自动创建补漏定时任务.txt 一致。
注意库名：sys_job 在 `pjcloudx_job` 库（与 qrtz_* / sys_job_log 同库）。

一、迁移背景与功能说明：
  wallet_transaction 新增 sys_remark（系统备注，按场景模板自动生成的流水简介，
  如"在食堂线下消费10元"）。新流水由业务代码在写入时直接生成；本任务负责为
  约 150 万行历史流水分批补齐 sys_remark，属于一次性数据回填任务：
  只处理 sys_remark 仍为空的行，天然幂等、可随时暂停/重跑，返回 0 即全部收敛。

  执行链路（daemon-quartz sys_job → Feign → wallet 内部端点）：
    walletSysRemarkBackfillTask.backfillSysRemark
      → POST /wallet/wallet-transaction/inner/backfill-sys-remark（@Inner）
        → 遍历全部有效租户（RemoteTenantService.list + TenantBroker）
        → 每租户按主键游标 500 行/批捞取 sys_remark 为空的历史流水
        → PAYMENT/REFUND 行按 bizId 批量反查硬件订单（RemoteHardOrderService
          getByIds，校验钱包一致防撞号）渲染场景文案，与在线写入同口径
        → 其余业务类型按 WalletSysRemarkTemplate.defaultRemark 兜底
        → 逐行主键 UPDATE 写入 sys_remark（不触碰 update_by/update_time）
  端点仅允许服务间内部调用（@Inner + @NoToken），由定时任务驱动，无需也不应
  手工 curl 触发。

二、部署顺序（硬前提，必须严格按序）：
  1. 执行 db/20261008_add_wallet_transaction_sys_remark.sql（加列，必须先于
     wallet-biz：新代码写入时 sys_remark 恒非空，缺列会导致所有流水 insert 失败）；
  2. 部署包含本次改动的 pjcloud-hardware-biz（订单扣款链路渲染系统备注 +
     getByIds 供回填反查）；
  3. 部署包含本次改动的 pjcloud-wallet-biz（回填端点及实现）；
  4. 部署包含本次改动的 pjcloud-daemon-quartz（新增 spring bean
     walletSysRemarkBackfillTask）；
  5. 执行下方 sys_job INSERT（job_status='2' 运行中）；
  6. daemon-quartz 重启时由 PjcloudInitQuartzJob 自动注册进 Quartz；服务不重启
     可调管理端 POST /sys-job/refresh-jobs（权限 job_sys_job_refresh_job）手动加载。

  空窗期影响：部署顺序颠倒最多造成任务首轮调用失败并记一条失败日志，下一个
  调度周期自动恢复；回填幂等，无数据风险。DDL 未先执行是唯一不可逆序的步骤。

三、行为说明：
  - cron '0 0/30 * * * ?'：每 30 分钟触发一次；每轮每租户最多 200 批 × 500 行
    （约 10 万行），150 万行预计 1~2 天内收敛（白天业务时段批间限速运行，
    对线上写入压力很小；如需更快可在 sys_job 把 method_params_value 调大，
    服务端上限 1000 批/轮）；
  - misfire_policy='3'，@DisallowConcurrentExecution 由统一 PjcloudQuartzFactory
    保证，多实例部署下 Quartz 集群锁兜底，任务不会并发执行；
  - 单个租户失败不影响其余租户，单行渲染失败不影响其余行（回退兜底文案），
    均由下一轮任务自动重试；Feign 超时只影响本轮日志状态，wallet 侧照常执行完，
    下一轮续跑；
  - 返回 0（收敛）后任务变为每轮一次空查询，开销可忽略；建议观察到收敛日志后
    将 job_status 改 '3'（暂停）停用任务；
  - 任务 sys_job 行 tenant_id=1 仅用于 daemon 侧调度上下文，wallet 端点内部自行
    遍历全部有效租户。

------------------------------------------------------------------------
四、sys_job：钱包流水系统备注回填（job_type=2，反射调 daemon 内 spring bean）
------------------------------------------------------------------------

INSERT INTO `pjcloudx_job`.`sys_job`
(`job_id`, `job_name`, `job_group`, `job_order`, `job_type`, `execute_path`, `class_name`, `method_name`,
 `method_params_value`, `cron_expression`, `misfire_policy`, `job_tenant_type`, `job_status`,
 `job_execute_status`, `create_by`, `create_time`, `update_by`, `update_time`, `tenant_id`, `remark`)
SELECT (SELECT GREATEST(COALESCE(MAX(`job_id`), 0), 2026100800000000000) FROM `pjcloudx_job`.`sys_job`) + 1,
       '钱包流水系统备注回填', 'WALLET', '3', '2', NULL, 'walletSysRemarkBackfillTask', 'backfillSysRemark',
       NULL, '0 0/30 * * * ?', '3', '1', '2',
       '0', 'system', NOW(), 'system', NOW(), 1, '分批回填历史钱包流水系统备注(sys_remark)，收敛(日志提示0行)后建议暂停'
FROM DUAL
WHERE NOT EXISTS (
    SELECT 1 FROM `pjcloudx_job`.`sys_job`
    WHERE `job_name` = '钱包流水系统备注回填' AND `job_group` = 'WALLET' AND `tenant_id` = 1
);

------------------------------------------------------------------------
五、内部端点与任务对应关系（@Inner + @NoToken 仅服务间调用，勿对外）
------------------------------------------------------------------------
  POST /wallet/wallet-transaction/inner/backfill-sys-remark
                                                     跨租户分批回填流水系统备注
                                                     （RemoteWalletTransactionService
                                                      backfillSysRemark，仅 daemon 调用）

------------------------------------------------------------------------
六、回滚说明
------------------------------------------------------------------------
  停用任务：将 sys_job 该行 job_status 改为 '4'（删除）或 '3'（暂停）并重启
  daemon-quartz（或调 POST /sys-job/refresh-jobs）；
  代码回滚：回滚 wallet-biz / daemon-quartz 服务即可；已回填的 sys_remark 数据
  无需清理（可空列，旧代码读写均不感知），如确需清理执行
  UPDATE wallet_transaction SET sys_remark = NULL（大表建议分批）。
