Commit Graph

458 Commits

Author SHA1 Message Date
huangzd1997 7a43ed6c43 task-163: 引用中文件不清契约(job/result 引用跳过、引用解除后可清、判定失败保守跳过、批量混合、幂等)+ 8 条测试 2026-09-02 07:30:53 +08:00
huangzd1997 0e4d680aef task-162: 路径穿越输入矩阵(../、..\、绝对路径、%2e 编码、全角点、混合分隔符、空字节全部拒绝)+ 9 条测试 2026-09-02 07:25:49 +08:00
huangzd1997 035ec9ac79 task-161: 巡检任务开关(aiimage.inspection.enabled 默认 disabled、cron 调度、分布式锁双实例去重、单巡检异常隔离、limit 透传)+ 8 条测试 2026-09-02 07:19:56 +08:00
huangzd1997 9712bdf538 task-160: 超保留期仍被引用巡检(超期+引用检出供人工处理、未超期/未引用不报、只读、可重复)+ 8 条测试 2026-09-02 07:14:05 +08:00
huangzd1997 5305d6dbc2 task-159: 已完成任务活跃 Job 巡检(终态任务 RUNNING/PENDING Job 检出、运行中任务正常、只读、可重复)+ 8 条测试 2026-09-02 07:08:53 +08:00
huangzd1997 9998571770 task-158: 结果存在文件缺失巡检(resultFileUrl 对应 OSS 文件缺失检出、空白 URL 不告警、只读、可重复)+ 8 条测试 2026-09-02 07:04:06 +08:00
huangzd1997 9144bce33f task-157: 任务存在结果缺失巡检(终态任务无 file_result 检出、运行中忽略、只读、可重复)+ 8 条测试 2026-09-02 06:57:50 +08:00
huangzd1997 d773748ae9 task-156: 孤立 Job 巡检报表(task/result 缺失孤儿检出、重试耗尽同样报、只读不修改、可重复)+ 8 条测试 2026-09-02 06:53:06 +08:00
huangzd1997 d64ef5284a task-155: 孤立文件巡检报表(只读巡检超保留期且无引用文件,报表含路径/大小/时间,绝不删除,可重复)+ 8 条测试 2026-09-02 06:47:03 +08:00
huangzd1997 87a6d20f88 task-154: 临时目录磁盘容量告警(aiimage.storage.capacity-warn-bytes 阈值、告警含当前容量/阈值、10 分钟频率限制、测量失败容忍不阻塞)+ 8 条测试 2026-09-02 06:40:20 +08:00
huangzd1997 57f75b8bc3 task-153: fileKey 兜底查找契约(保存即登记、重启后目录枚举重建、缺失明确失败、清理后不可找、语义稳定)+ 8 条测试 2026-09-02 06:34:22 +08:00
huangzd1997 3b34ec3bef task-152: 清理失败吞异常记指标(aiimage.temp-cleanup.failed 计数、日志+指标均不阻断主流程、按路径隔离、无重试循环)+ 8 条测试 2026-09-02 06:29:59 +08:00
huangzd1997 f0e12b9b1b task-151: 路径安全校验(PathSafetyGuard 规范化 startsWith 判定、../与绝对路径与符号链接逃逸拒绝、接入清理路径)+ 8 条测试 2026-09-02 06:24:37 +08:00
huangzd1997 ffc3963345 task-150: 清理前引用检查契约(chunk 共享/scope 引用保留、自身行可清、异常保守保留、只读无副作用、批量 IN 反查)+ 8 条测试 2026-09-02 06:19:42 +08:00
huangzd1997 dd569edc66 task-149: 临时文件时间元数据补缺(TempFileMetadata 创建/修改/访问时间与大小读取,mtime 回退不改变清理语义,IO 错误容忍)+ 8 条测试 2026-09-02 06:08:50 +08:00
huangzd1997 383ec544e1 task-148: 临时目录配置盘点(16 配置项/322 清理调用点扫描器 + 9 条测试 + 报告快照,不改生产代码) 2026-09-02 06:02:14 +08:00
huangzd1997 dc90ead263 task-147: downloadUrl 永不过期验证(result/ 走下载域名、无签名参数、bucket 前缀、null/空白安全、输出稳定)+ 8 条测试 2026-09-02 06:00:53 +08:00
huangzd1997 eced873779 task-146: collectdata 自洽行为契约(后端无 file 字段 VO 快照、前端 success+downloadUrl 判定含空白边界)+ 前后端 13 条测试 2026-09-02 05:55:43 +08:00
huangzd1997 5e5056b99d task-143: publish 文件级 file 状态语义契约(ready 由 result.success+url 推导、job 字段独立、多文件混合、无结果 null)+ 8 条测试 2026-09-02 05:46:42 +08:00
huangzd1997 9e58d28a99 task-142: fileReady/fileStatus 语义契约(URL 判定、无 job SUCCESS/null、job 状态与错误映射、空白边界)+ 8 条测试 2026-09-02 05:42:32 +08:00
huangzd1997 89d5eda057 task-141: similarasin file 进度合成单测(LLM/Python 上传/snapshot 三路径、fileReady 恒 100%、除零与状态边界)+ 8 条测试 2026-09-02 05:38:26 +08:00
huangzd1997 b7a403dc22 task-140: 13 模块 file 字段契约快照(fileStatus/fileError/fileReady 类型与白名单冻结、旧字段仍在、collectdata 自洽)+ 8 条守门测试 2026-09-02 05:32:06 +08:00
huangzd1997 4fb33bda1c task-138: 事务时长性能对比基准(prepare/persist 分段测量、200 分片负载上界、文档基线守门不劣化)+ 8 条基准测试 2026-09-02 05:20:54 +08:00
huangzd1997 2493019c27 task-137: 重复提交幂等契约(同 id 幂等接受/不重复落库/终态拒绝/并发撞键不覆盖/多次安全)+ 8 条守门测试 2026-09-02 05:15:18 +08:00
huangzd1997 58cfcfdf35 task-136: 事务外清理异常不阻断契约(响应不受影响/不重试循环/事务已提交/下次可再清理/部分失败继续)+ 8 条守门测试 2026-09-02 05:07:33 +08:00
huangzd1997 a982da0262 task-135: 任务状态成功时机契约(SUCCESS 必在文件生成上传后、无文件不成功、fileReady/downloadUrl 语义不变)+ 8 条守门测试 2026-09-02 05:03:05 +08:00
huangzd1997 c8d14a5b1b task-134: done=true 封口时机契约(分片先落库再强制 finalize、剩余全量行数、result 不重复创建、done=false 只触心跳)+ 8 条守门测试 2026-09-02 04:57:56 +08:00
huangzd1997 44fc43912f task-133: 回滚语义硬约束契约(完整回滚/状态不改写/payload 保留/重试安全/计算幂等/双模块一致)+ 8 条守门测试 2026-09-02 04:51:16 +08:00
huangzd1997 cf83752338 task-132: /result 成功确认时机契约(四模块 200+success=true 必在落库后、失败不成功、重试安全)+ 8 条守门测试 2026-09-02 04:44:21 +08:00
huangzd1997 c60ad48be5 task-131: collectdata 事务收缩契约固化(/result 锁内单条写无长事务 + 响应 DTO 写后组装)+ 8 条守门测试 2026-09-02 04:37:14 +08:00
huangzd1997 29ddf5c780 task-130: publish 事务收缩契约固化(prepare 外置/短事务落库/提交后清理已符合 spec 07)+ 8 条守门测试 2026-09-02 04:25:14 +08:00
huangzd1997 5e71e1bb3d task-129: shopdatacrawl 事务收缩(/result 无长事务契约固化 + deleteTask 纯计算抽静态纯函数)+ 8 条边界测试 2026-09-02 04:15:44 +08:00
huangzd1997 ecc62f095b task-128: appearancepatent 事务收缩(flatten/序列化/存储/哈希纯计算抽 prepareSubmittedChunk 移出事务,双事务路径不变)+ 8 条边界测试 2026-09-02 03:54:29 +08:00
huangzd1997 28f61eb70d task-127: similarasin 临时文件清理时机契约固化(提交后清理/回滚不清理/异常吞掉/可重试/幂等)+ 8 条守门测试 2026-09-02 03:44:38 +08:00
huangzd1997 ef4ea8d24b task-126: similarasin DTO 组装位置契约固化(审计结论:/result 无响应 DTO、可移出组装已在事务外、落库行组装顺序不变)+ 8 条守门测试 2026-09-02 03:39:54 +08:00
huangzd1997 79b3efd365 task-125: similarasin /result 纯计算移出事务(payload 哈希在 prepare 阶段预计算,落库直接引用)+ 9 条事务边界守门测试 2026-09-02 03:34:15 +08:00
huangzd1997 56afee0386 task-124: @Transactional 方法审计清单(147 方法/30 模块扫描器 + 13 条测试 + 报告快照,不改生产代码) 2026-09-02 03:24:23 +08:00
huangzd1997 793bd4f9c8 task-123: 性能基准堆采样前先 GC,消除全量套件下残留垃圾导致的 1GB 边界 flaky 2026-09-02 03:20:44 +08:00
huangzd1997 445b7780c5 task-122: N+1 批量化修复(claim/stuck-reset/stale-check 逐行 selectById 改 selectBatchIds 批量回读 + Map 装配,行为等价) 2026-09-02 03:13:05 +08:00
huangzd1997 29625f703c task-121: N+1 扫描审计(循环内单查扫描器 + 10 条测试 + 报告快照,不改生产代码) 2026-09-02 02:40:16 +08:00
huangzd1997 5f4fcad2ef 修复双实例 owner-scoped 结果文件 job 被非归属实例误杀
Build Backend JAR / build (push) Has been cancelled
线上现象:货源查询任务 26402/26400(归属 server-121)在归属机正常推进,
却被 server-110 判为「结果生成失败」,错误为「该任务已绑定到另一台服务实例处理」。

两个缺陷叠加:
1. 两台实例共用一个 RocketMQ consumer group,dispatch 消息被轮询投递;
   worker 对"PENDING + owner 不匹配"的 job 选择本地抢跑,模块层
   ensureTaskOwnedByCurrentInstance 直接抛 TaskOwnerMismatchException,
   异常落进通用 catch 被当成生成失败,5 次抢跑即耗尽 retryCount 并终态失败。
2. runPendingJobs 双重 claim:claimRunnableJobsForOwner 已把 job 翻成 RUNNING,
   随后又走 claimRunning(条件 PENDING/FAILED)必然失败 → job 被静默丢弃,
   归属机的定时兜底从未真正生效。

修复:
- worker:非归属实例一律跳过 owner-scoped job;抽出 processClaimed 供已持有
  claim 的调用方使用;processInternal 单独捕获 TaskOwnerMismatchException,
  只 deferRunning 退回 PENDING,不计入重试。
- TaskFileJobLocalDispatcher 新增 dispatchClaimed。
- dispatch 事件带上 owner,coordinator 按归属路由:本机 owner 直接本地派发不发 MQ,
  他机 owner 不发不跑交由归属机轮询接手,owner 为空维持原有 MQ 行为。
- 新增 owner 路由回归测试两组,回滚配合"本地抢跑"的旧断言。

同时提交此前工作区内已随 JAR 上线的 backend-java 改动:SimilarAsin 解析载荷
groups 内嵌 items(Python 旧链路兼容)与 chunk 类型不匹配跳过、
PermissionMenuSchemaInitializer 与 V103 两级菜单分组迁移、相关测试。
2026-09-01 21:07:25 +08:00
huangzd1997 55517f996b task-120: 大页数据性能回归 + 恢复 similarasin 测试入库
性能回归(SimilarAsinTaskServicePerf500Test,8/8 绿):
- test_perf_light_200 原以墙钟毫秒比较 light 与 batch(assertTrue
  lightMs < batchMs)。两条路径都跑纯内存 stub,耗时在十几毫秒量级,
  JIT/GC/线程调度抖动远大于真实差值,本机实测 light 14ms / batch 13ms
  直接翻红。改为确定性口径:light 结果明细查询数 == 0(batch ≥ 1)、
  light 总查询数 < batch 总查询数、batch 条目携带任务明细对象而 light
  只有白名单字段;墙钟仅保留单侧上界 1s(N+1 退化会放大到秒级从而失败)。
  连续 3 次独立运行稳定通过。
- 类注释同步移除“已知 flaky,隔离重跑即接受”的说明。

恢复测试入库:
- fa5a59e(task-116) 把 similarasin 测试目录整体从 git 删除,并加了
  .gitignore 规则 *.broken/,磁盘上目录改名 similarasin.broken。
  但包声明仍是 com.nanri.aiimage.modules.similarasin.*,javac 照常编译,
  这 40 个测试文件一直在参与构建、并且是 mvn test 的门禁的一部分——
  等于脱离版本控制却仍在 gate 构建。
- 目录改回 similarasin/(现在与包声明一致),移除 *.broken/ 忽略规则,
  40 个测试文件重新入库。mvn test-compile 退出码 0。
2026-09-01 13:45:34 +08:00
huangzd1997 fa5a59e5cd task-116: 后台管理新增/导入表单弹窗化 + 分组管理独立菜单与UI优化 + 轻量进度端点
Build Backend JAR / build (push) Has been cancelled
- 后台管理页(admin)所有面板的新增/导入表单改为弹窗操作,原有字段 ID 全部保留、提交逻辑不变;导入删除入口不再触发二次确认拦截
- 分组管理升级为独立菜单(V102 + schema initializer),移除 5 个面板内的管理分组按钮;分组列表改为蓝白主题、增加权限分组横幅
- Python 侧 group-manage 权限守卫(_ensure_backend_menu_access 补充 group-manage)
- 引入 V101(biz_task_file_job 复合索引)+ 新增 TaskProgressLight/TaskFileJob 轻量端点与进度聚合作
- 前端 progress-light / page-separated-loads / dispatch-guard 共享模块及单元测试
2026-09-01 12:54:13 +08:00
huangzd1997 e2607ab723 task-98: 移除 similar-asin/appearance-patent 模块 Coze,状态机与共享组件改名 LLM
Build Backend JAR / build (push) Has been cancelled
- similarasin/appearancepatent 模块全部 Coze 工作流调用改走 direct-LLM(已确认唯一运行路径)
- 共享组件改名:CozeTaskQueueGate→TaskQueueGate、CozeGroupResultPropagator→GroupResultPropagator
- 状态机改名:biz_task_scope_state 的 coze_* 列→llm_*、stateJson coze 键→llm(V100 迁移已应用生产)
- 删除 biz_coze_credential 表、CozeCredential* 类、SimilarAsinCozeClient、AppearancePatentCozeClient→LlmClient
- 前端 brand 页 Coze 文案→LLM;Python 后端删除 cozepy 依赖与死配置
- 修复 TaskResultFileJobWorker 启动失败:TaskFileJobConfig 注册 ResultFileJobHandlerRegistry 与 13 个 handler bean(含 validateCoverage 启动校验)
2026-09-01 02:20:50 +08:00
huangzd1997 c8cd851b2f feat: 外观专利改直连 LLM(DeepSeek/Gemini)、无效ASIN菜单更名 BRAND_DB、紫鸟店铺索引场景化
Build Backend JAR / build (push) Has been cancelled
- AppearancePatent:Coze 工作流切换为 llm-host 直连模型(title/appearance 双模型、行并发、重试),配置键迁移并保留旧环境变量兜底
- InvalidAsinDataMapper 补充按值+品牌唯一键查询
- ZiniaoShopIndexService 新增店铺分类/索引场景
- V98:无效ASIN菜单 rename 补充 BRAND_DB;docs 架构优化规划
- 配套单测更新
2026-08-31 17:04:59 +08:00
huangzd1997 14a41e64f1 feat: SimilarASIN 直连 LLM 通道(Gemini/DeepSeek 多模型)替代 Coze 工作流
- SimilarAsinLlmClient/Service:分类、符合性、图片比对三阶段直连 LLM
- PuzzleImageMerger:拼图合并用于图片比对
- direct-llm-enabled 开关 + llm-host/api-key/模型/超时/并发配置(默认开)
- LlmGatewayTlsProbe、SimilarAsinLlmLocalVerify 为本地验证工具
2026-08-31 17:02:53 +08:00
huangzd1997 7f4737c800 feat: 店铺密码检测任务(后台发起→客户端领取→紫鸟真实登录判定→回传结果)
- 新增 biz_shop_credential_check 表(V99)与 ShopCredentialCheck 全链路
- Controller /api/admin/shop-credential-checks(create/poll/report/latest,X-Internal-Token 鉴权)
- ShopManageService 列表附带 latestCheck(每店铺最近一次检测结果)
- 客户端通过 poll 领取(60s 轮询、原子置 RUNNING),报告 SUCCESS/FAILED/OTP_REQUIRED/NO_NEED_LOGIN/ERROR
2026-08-31 17:02:49 +08:00
huangzd1997 26f4bb3f25 后台菜单重构:菜单类型分组排序(软件在前/后台在后)、新增同类型末尾排序;任务中心分组移除,视频任务记录归入记录与版本、店铺数据记录归入店铺管理;界面名词优化(菜单权限配置/去重数据汇总/无效ASIN数据/视频任务记录/店铺数据记录/生成记录)
Build Backend JAR / build (push) Has been cancelled
2026-08-31 01:48:05 +08:00
huangzd1997 0408c9752e fix: 菜单排序 app 分组优先于 admin,sort_order 按 menuType 作用域解析
Build Backend JAR / build (push) Has been cancelled
- menuComparator 增加 menuType 排序维度(app → admin → 其他)
- resolveSortOrder 查询限定同 menuType,避免跨类型尾部误判
- 抽出 loadRawMenus 保持原始 SQL 与比较器语义一致
2026-08-31 01:21:45 +08:00
huangzd1997 483374744a fix: Spring 多构造器类显式 @Autowired 标注 + V95 迁移兼容 MySQL 8.4
Build Backend JAR / build (push) Has been cancelled
- CapacityPlanService / ExternalCallMetricsRecorder / ZiniaoClientImpl:
  双构造器(生产 + 测试入口)导致 Spring 6 不自动推断构造器注入,
  启动报 'No default constructor found';生产构造器显式加 @Autowired
- V95:shop_key 列 V85 建表时已有,原 ADD COLUMN shop_key 会报
  duplicate column;MySQL 8.4 不支持 ADD COLUMN IF NOT EXISTS,改
  information_schema 动态 SQL;shop_key 缩到 VARCHAR(255) 以容纳
  (shop_key, business_date) 唯一键(1000 在 utf8mb4 下超 3072 字节
  索引上限);删除多余行改为单表 DELETE
2026-08-31 01:09:19 +08:00