# 提炼配方：特定维度扫码填充

step-03 生成特定维度时，按本配方扫描 `{target-root}`，把真实结果填入对应 skeleton 的 `<!-- SCAN:xxx -->` 占位表。

## 通用流程

1. 按 `detection-matrix.md` 确认维度命中。
2. 按下方配方 Grep/Read/Glob 扫描，得真实清单。
3. 替换 skeleton 中 `<!-- SCAN:xxx -->` 占位与空表为真实数据。
4. **提炼为空兜底**：强信号命中但扫不到实体 → 保留骨架 + 空表 + 顶部标注「⚠ 本服务暂无 XX 实例，以下为团队规范模板」，并在对标报告「需人工补充」记一条。
5. 自检：表中不得残留 `<!-- SCAN -->` 或 pj-incentive 专有类名（如 `DataUpgradeJobHandler`、`ExportApplication`）——若残留说明未真正扫码。

---

## xxl-job

**扫描**
- `Grep "@XxlJob" {target-root}/src -l` → Handler 文件集；逐文件 Read。
- 每个 Handler 抽取：类名、`@XxlJob("注解值")`、**方法返回类型**、类注释 Cron、锁 key 常量（`LOCK:xxx`）、注入的 Application/Service、用途（类注释首句）。

**风格判定（关键）**
- 方法签名 `ReturnT<String> execute(String)` + `return ReturnT.SUCCESS` → **ReturnT 风格**。
- 方法 `void` + `XxlJobHelper.handleSuccess()/handleFail()` → **XxlJobHelper 风格**。
- **hybrid**：签名 `ReturnT<String>` 但方法体用 `XxlJobHelper.log()/getJobParam()` 记日志/取参（如 pj-incentive）→ 以**签名**为准归为 ReturnT 风格，但代码模板需体现 `XxlJobHelper.log()` 日志调用。
- 统计全部 Handler：取多数风格。skeleton 内含「风格 A=ReturnT」「风格 B=XxlJobHelper」两段模板，step-03 **保留匹配的一段、删除另一段**，并在基础设施小节注明「本项目统一 XX 风格」。

**填表**「已有定时任务清单」：`| Handler | 注解值 | 频率(Cron) | 锁超时 | 用途 |`

**基础设施小节**：用真实 `XxlJobConfig` 路径、`zqyl-xx-job` 坐标、`application-job.properties` 配置项替换。

> 靶子预期：3 行（`DailyMinPriceJobHandler`/`InquiryExpireJobHandler`/`QuoteExpireJobHandler`），XxlJobHelper 风格。

---

## feign

**扫描**
- `Grep "@FeignClient" {target-root}/src -l`；逐文件 Read 抽取：接口名、`@FeignClient` 的 `name`/`path`/`value`、**返回壳类型（逐个读方法签名实测，不要预设）**。
- ⚠ **返回壳必须实测**：可能是 `ResultData<T>`、`ResponseInfo<T>`、或裸类型（`String`/`feign.Response`）。中企云链本服务 Controller 统一 `ResultData`，但 Feign 反序列化**外部服务**的返回壳取决于被调服务——`Grep "ResultData|ResponseInfo" {target-root}/**/feign` 看哪种实际占多数，逐个客户端据真实签名填，**禁止照搬骨架示例**。
- 解包判成功方式随壳而定：`ResultData` 多用 `isSuccess()`/`getCode()`、`ResponseInfo` 用 `"M0200".equals(getStatus())`——读一个 Gateway 防腐类确认本服务实际写法。
- 对应 Gateway 防腐层：`Glob {target-root}/**/gateway/*Gateway.java`，配对（通常同前缀，如 `FileFeignClient`↔`FileGateway`）。

**填表**「已有 Feign 客户端清单」：`| Feign 接口 | 目标服务(name) | path | 返回壳(实测) | 对应 Gateway | 用途 |`
**附**「已有 Gateway 防腐层」：`| Gateway | 封装的 Feign | 职责 |`

> 靶子预期：6 个 FeignClient（Data/File/Pjs/Report/UserAuth/UserCenter）+ 6 个对应 Gateway。

---

## file-import-export

**扫描**
- 文件基础设施类：`Grep "FileGateway|FileUrlHelper|FileDownLoadFeign|FileUrlConfig|MockMultipartFile|InMemoryMultipartFile" {target-root}/src -l`。
- 上传/下载地址：Read `application*.properties`，找 `file.manager.*.url` / `file.*.upload`。
- 导入实体与校验：`Glob {target-root}/**/*Import*.java`、`**/*ImportError*.java`、`Grep "@ExcelProperty"`。
- 导入上限常量：`Grep "MAX.*IMPORT|IMPORT.*LIMIT|\\b(300|500|1000)\\b" {target-root}/src`（弱信号，需人工确认）。

**填表**「已有文件基础设施清单」：`| 组件 | 位置 | 职责 |`

**兜底**：上限未找到 → 写默认 300/1000 + 报告「需人工确认导入上限」。

> 靶子预期：`FileGateway`/`FileUrlHelper`/`FileUrlConfig`/`MockMultipartFile` + `PriceImportDTO`/`PriceImportErrorDTO`/`AcceptorLevelImportErrorDTO`。

---

## async-export

**扫描**
- `Grep "createManageReserveTask|reserveUploadFile|exportThreadPool|ThreadPoolConfig" {target-root}/src -l`。
- 导出方法：`Grep "export[A-Z]\\w*|doExport" {target-root}/src`。
- 线程池 bean 名与参数：Read `ThreadPoolConfig`。
- Redis 锁前缀：`Grep "export:.*:|EXPORT_LOCK" {target-root}/src`。

**填表**「已有导出基础设施」：`| 组件 | 位置 | 说明 |`

**跳过条件**：无 `createManageReserveTask`/`exportThreadPool` 强信号 → **不生成本维度**（async-export 是可选高级特性，靶子预期跳过）。

---

## mq

**扫描**
- `Grep "@RocketMQMessageListener|MessageListener|MQProducer|DefaultMQProducer|@RabbitListener|@KafkaListener" {target-root}/src -l`。
- topic/tag 常量：`Grep "TOPIC|TAG\\b" {target-root}/src`。

**填表**「已有 MQ 生产/消费者」：`| 类 | 角色(生产/消费) | topic/tag | 用途 |`

> 靶子预期：跳过（无 MQ）。

---

## redis

**扫描**
- `Grep "RedissonClient|StringRedisTemplate|RedisTemplate" {target-root}/src -l`。
- 锁/缓存 key 前缀常量：`Grep "LOCK:|:lock:|CACHE_KEY|_KEY_PREFIX" {target-root}/src`。

**填表**「已有分布式锁 / 缓存 key 约定」：`| key 前缀 | 类型(锁/缓存) | 用途 | 过期 |`

**阈值**：仅普通缓存无自定义 key 约定 → 不单列，并入 security（见 `dimension-catalog.md`）。
