hookehuyr

docs(parse): 完善文档解析工具与审核流程

- 更新 README 解析工具使用说明
- 完善审核流程计划文档
- 添加解析审核记录
- 删除已解析的测试文件
- 新增 parse-audit 审核目录

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
......@@ -78,6 +78,8 @@ pnpm lint
-**输出结构补齐** - 解析输出 JSON 结构与稳定 form_sn 规则已明确
-**审计与摘要** - 解析摘要与审计日志输出已接入
-**审核流程规划** - 整理审核流程方案并对齐字段与目录规范
-**审核模板落地** - 待审核文件输出完善,默认不写入配置,需显式 --write-config
-**链路与思路** - 补充解析链路与使用思路,明确审核与合并边界
### 测试与验证
-**回归测试** - pnpm test 通过,pnpm lint 存在 30 个现存警告
......
# 产品配置审核 - 计划书模版2.docx
**解析时间**: 2026/2/14 23:58:54
**原始文件**: 计划书模版2.docx
**数据来源**: docs/to-parse/计划书模版2.docx
---
## 📋 产品基本信息
| 字段 | 提取值 | 需要确认 |
|------|--------|---------|
| 产品名称 | 计划书模版2 | ✅ 请核对产品名称 |
| 产品类型 | savings | ✅ 请确认产品类型 |
| 币种 | USD | ✅ 请确认币种 |
| form_sn | `savings-2-55bcffc2` | ✅ 请确认 form_sn 唯一性 |
| 缴费年期 | ["整付"] | ✅ 请确认缴费年期选项 |
| 年龄范围 | 0-75岁 | ✅ 请确认年龄范围 |
| 保险期间 | 终身 | ✅ 请确认保险期间 |
### 💰 储蓄类产品特有字段
| 字段 | 提取值 | 需要确认 |
|------|--------|---------|
| 提取方式 | ["指定提取金额","最高固定提取金额"] | ✅ 请确认提取方式 |
| 提取期 | ["1年","3年","5年","10年"] | ✅ 请确认提取期选项 |
---
## 🤖 智能字段提取报告
### 匹配统计
- ✅ 成功匹配: 3 字段
- ⚠️ 使用默认值: 4 字段
- ❌ 未匹配(需人工补充): 1 字段
### ✅ 已成功匹配的字段
- product_type
- payment_periods
- withdrawal_modes
### ⚠️ 使用默认值的字段
- **currency**: 未找到字段 "currency",使用默认值: "USD"
- **age_range**: 未找到字段 "age_range",使用默认值: {"min":0,"max":75}
- **insurance_period**: 未找到字段 "insurance_period",使用默认值: "终身"
- **product_name**: 未找到产品名称,使用文件名: "计划书模版2"
### ❌ 未匹配字段(需要人工补充)
#### product_name
- **原因**: 未找到匹配内容
- **建议值**:
- 从文档标题提取
- 从第一行提取
- 手动输入产品全称
---
## 🧾 配置预览
```javascript
{
"product_name": "计划书模版2",
"product_type": "savings",
"currency": "USD",
"form_sn": "savings-2-55bcffc2",
"payment_periods": [
"整付"
],
"age_range": {
"min": 0,
"max": 75
},
"insurance_period": "终身",
"is_savings": true,
"withdrawal_modes": [
"指定提取金额",
"最高固定提取金额"
],
"withdrawal_periods": [
"1年",
"3年",
"5年",
"10年"
]
}
```
---
## 📝 表单字段 (form_schema)
```javascript
{
"base_fields": [],
"withdrawal_fields": [],
"reset_map": {}
}
```
---
## 🔄 提交字段映射 (submit_mapping)
```javascript
{}
```
---
## 🧩 生成配置片段
```javascript
/**
* 计划书模版2
* @added 2026-02-14T15:58:54.707Z
* @source docs/to-parse/计划书模版2.docx
*/
'savings-2-55bcffc2': {
name: '计划书模版2',
component: 'SavingsTemplate',
category: 'savings',
config: {
currency: 'USD',
payment_periods: ["整付"],
age_range: { min: 0, max: 75 },
insurance_period: '终身',
withdrawal_plan: {
enabled: true,
currencies: ['HKD', 'USD', 'CNY'],
default_currency: 'USD',
withdrawal_modes: ["指定提取金额","最高固定提取金额"],
withdrawal_periods: ["1年","3年","5年","10年"]
},
form_schema: savingsFormSchema,
submit_mapping: savingsSubmitMapping
}
}
```
---
## ✅ 审核检查清单
### 基础信息
- [ ] 产品名称正确
- [ ] 产品类型正确(savings/critical-illness/life-insurance)
- [ ] 币种正确(USD/CNY/HKD/EUR)
- [ ] form_sn 唯一且符合命名规范
### 缴费与年龄
- [ ] 缴费年期选项完整且正确
- [ ] 年龄范围合理
- [ ] 保险期间正确
### 储蓄类特有(如适用)
- [ ] 提取方式正确
- [ ] 提取期选项完整
- [ ] 表单字段定义完整
- [ ] 提交字段映射正确
---
## 📋 审核后操作
### 确认无误
```bash
# 1. 移动到 approved 目录
mv docs/parse-audit/pending/2026-02-14-计划书模版2.md \
docs/parse-audit/approved/
# 2. 合并到正式配置
# 手动复制或使用工具合并到 src/config/plan-templates.js
# 3. 删除待审核文件(可选)
rm docs/parse-audit/pending/2026-02-14-计划书模版2.md
```
### 需要修改
1. 编辑本文件修正内容
2. 重新提交审核
### 放弃本次解析
```bash
rm docs/parse-audit/pending/2026-02-14-计划书模版2.md
```
---
## 审核状态
- [ ] 待审核
- [ ] 已通过
- [ ] 已拒绝
## 审核意见
```text
```
# 产品配置审核 - 计划书模版3.docx
**解析时间**: 2026/2/14 23:58:54
**原始文件**: 计划书模版3.docx
**数据来源**: docs/to-parse/计划书模版3.docx
---
## 📋 产品基本信息
| 字段 | 提取值 | 需要确认 |
| -------- | ---------------------- | ------------------------ |
| 产品名称 | 计划书模版3 | ✅ 请核对产品名称 |
| 产品类型 | savings | ✅ 请确认产品类型 |
| 币种 | USD | ✅ 请确认币种 |
| form_sn | `savings-3-8f4f27ad` | ✅ 请确认 form_sn 唯一性 |
| 缴费年期 | ["5年"] | ✅ 请确认缴费年期选项 |
| 年龄范围 | 0-75岁 | ✅ 请确认年龄范围 |
| 保险期间 | 终身 | ✅ 请确认保险期间 |
### 💰 储蓄类产品特有字段
| 字段 | 提取值 | 需要确认 |
| -------- | ------------------------------- | ------------------- |
| 提取方式 | ["年龄指定金额","最高固定金额"] | ✅ 请确认提取方式 |
| 提取期 | ["1年","3年","5年","10年"] | ✅ 请确认提取期选项 |
---
## 🤖 智能字段提取报告
### 匹配统计
- ✅ 成功匹配: 1 字段
- ⚠️ 使用默认值: 5 字段
- ❌ 未匹配(需人工补充): 1 字段
### ✅ 已成功匹配的字段
- payment_periods
### ⚠️ 使用默认值的字段
- **product_type**: 未找到字段 "product_type",使用默认值: "savings"
- **currency**: 未找到字段 "currency",使用默认值: "USD"
- **age_range**: 未找到字段 "age_range",使用默认值: {"min":0,"max":75}
- **insurance_period**: 未找到字段 "insurance_period",使用默认值: "终身"
- **product_name**: 未找到产品名称,使用文件名: "计划书模版3"
### ❌ 未匹配字段(需要人工补充)
#### product_name
- **原因**: 未找到匹配内容
- **建议值**:
- 从文档标题提取
- 从第一行提取
- 手动输入产品全称
---
## 🧾 配置预览
```javascript
{
"product_name": "计划书模版3",
"product_type": "savings",
"currency": "USD",
"form_sn": "savings-3-8f4f27ad",
"payment_periods": [
"5年"
],
"age_range": {
"min": 0,
"max": 75
},
"insurance_period": "终身",
"is_savings": true,
"withdrawal_modes": [
"年龄指定金额",
"最高固定金额"
],
"withdrawal_periods": [
"1年",
"3年",
"5年",
"10年"
]
}
```
---
## 📝 表单字段 (form_schema)
```javascript
{
"base_fields": [],
"withdrawal_fields": [],
"reset_map": {}
}
```
---
## 🔄 提交字段映射 (submit_mapping)
```javascript
{}
```
---
## 🧩 生成配置片段
```javascript
/**
* 计划书模版3
* @added 2026-02-14T15:58:54.729Z
* @source docs/to-parse/计划书模版3.docx
*/
'savings-3-8f4f27ad': {
name: '计划书模版3',
component: 'SavingsTemplate',
category: 'savings',
config: {
currency: 'USD',
payment_periods: ["5年"],
age_range: { min: 0, max: 75 },
insurance_period: '终身',
withdrawal_plan: {
enabled: true,
currencies: ['HKD', 'USD', 'CNY'],
default_currency: 'USD',
withdrawal_modes: ["年龄指定金额","最高固定金额"],
withdrawal_periods: ["1年","3年","5年","10年"]
},
form_schema: savingsFormSchema,
submit_mapping: savingsSubmitMapping
}
}
```
---
## ✅ 审核检查清单
### 基础信息
- [ ] 产品名称正确
- [ ] 产品类型正确(savings/critical-illness/life-insurance)
- [ ] 币种正确(USD/CNY/HKD/EUR)
- [ ] form_sn 唯一且符合命名规范
### 缴费与年龄
- [ ] 缴费年期选项完整且正确
- [ ] 年龄范围合理
- [ ] 保险期间正确
### 储蓄类特有(如适用)
- [ ] 提取方式正确
- [ ] 提取期选项完整
- [ ] 表单字段定义完整
- [ ] 提交字段映射正确
---
## 📋 审核后操作
### 确认无误
```bash
# 1. 移动到 approved 目录
mv docs/parse-audit/pending/2026-02-14-计划书模版3.md \
docs/parse-audit/approved/
# 2. 合并到正式配置
# 手动复制或使用工具合并到 src/config/plan-templates.js
# 3. 删除待审核文件(可选)
rm docs/parse-audit/pending/2026-02-14-计划书模版3.md
```
### 需要修改
1. 编辑本文件修正内容
2. 重新提交审核
### 放弃本次解析
```bash
rm docs/parse-audit/pending/2026-02-14-计划书模版3.md
```
---
## 审核状态
- [ ] 待审核
- [ ] 已通过
- [ ] 已拒绝
## 审核意见
```text
```
......@@ -11,3 +11,9 @@
{"at":"2026-02-14T14:35:12.489Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":6,"success_list":[{"form_sn":"savings-2-148b3acd","product_name":"测试计划书-智享未来2","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":false,"dry_run":false,"updated_count":0,"form_sn_list":[],"conflicts":["savings-2-148b3acd"],"reason":"conflict"}}
{"at":"2026-02-14T14:35:32.726Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":2,"success_list":[{"form_sn":"savings-2-148b3acd","product_name":"测试计划书-智享未来2","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":false,"dry_run":false,"updated_count":0,"form_sn_list":[],"conflicts":["savings-2-148b3acd"],"reason":"conflict"}}
{"at":"2026-02-14T14:42:10.975Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":28,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":false,"updated_count":1,"form_sn_list":["savings-2-55bcffc2"],"conflicts":[],"reason":null}}
{"at":"2026-02-14T15:16:37.454Z","mode":"single","options":{"dry_run":true},"summary":{"total":1,"success":1,"failed":0,"duration_ms":39,"success_list":[{"form_sn":"savings-product-54cf664a","product_name":"智享未来储蓄计划书","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":1,"form_sn_list":["savings-product-54cf664a"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 智享未来储蓄计划书\n+ * @added 2026-02-14T15:16:37.415Z\n+ * @source docs/to-parse/测试计划书-智享未来2.md\n+ */\n+ 'savings-product-54cf664a': {\n+ name: '智享未来储蓄计划书',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}}
{"at":"2026-02-14T15:24:05.580Z","mode":"batch","options":{"dry_run":true},"summary":{"total":1,"success":1,"failed":0,"duration_ms":41,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":1,"form_sn_list":["savings-2-55bcffc2"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:24:05.564Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}}
{"at":"2026-02-14T15:29:02.807Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":50,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:29:02.781Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 计划书模版3\n+ * @added 2026-02-14T15:29:02.804Z\n+ * @source docs/to-parse/计划书模版3.docx\n+ */\n+ 'savings-3-8f4f27ad': {\n+ name: '计划书模版3',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}}
{"at":"2026-02-14T15:30:22.307Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":49,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:30:22.283Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 计划书模版3\n+ * @added 2026-02-14T15:30:22.304Z\n+ * @source docs/to-parse/计划书模版3.docx\n+ */\n+ 'savings-3-8f4f27ad': {\n+ name: '计划书模版3',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}}
{"at":"2026-02-14T15:51:38.101Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":47,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:51:38.078Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 计划书模版3\n+ * @added 2026-02-14T15:51:38.098Z\n+ * @source docs/to-parse/计划书模版3.docx\n+ */\n+ 'savings-3-8f4f27ad': {\n+ name: '计划书模版3',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}}
{"at":"2026-02-14T15:58:54.732Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":51,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:58:54.707Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"指定提取金额\",\"最高固定提取金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 计划书模版3\n+ * @added 2026-02-14T15:58:54.729Z\n+ * @source docs/to-parse/计划书模版3.docx\n+ */\n+ 'savings-3-8f4f27ad': {\n+ name: '计划书模版3',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}}
......
......@@ -202,22 +202,22 @@ rm docs/parse-audit/pending/${auditFileName}
## 实施计划
### 阶段1: 修复审核模板与字段对齐
- [ ] 清理 generateAuditFile 重复定义与模板断裂问题
- [ ] 统一字段命名为 product_name/product_type/currency/form_sn
- [ ] 优化审核模板展示 form_schema 与 submit_mapping
- [x] 清理 generateAuditFile 重复定义与模板断裂问题
- [x] 统一字段命名为 product_name/product_type/currency/form_sn
- [x] 优化审核模板展示 form_schema 与 submit_mapping
### 阶段2: 审核流程治理
- [ ] 确认 pending/approved 目录结构
- [ ] 明确审核通过后的合并指引
- [ ] 补齐审核状态与审核意见模板
- [x] 确认 pending/approved 目录结构
- [x] 明确审核通过后的合并指引
- [x] 补齐审核状态与审核意见模板
### 阶段3: 解析策略补齐
- [ ] 增加标题/币种/类型的启发式补位策略
- [ ] 补齐文档样本验证与失败兜底说明
- [x] 增加标题/币种/类型的启发式补位策略
- [x] 补齐文档样本验证与失败兜底说明
### 阶段4: 测试验证
- [ ] 使用实际文档回归生成审核文件
- [ ] 校验审核模板完整性与可读性
- [x] 使用实际文档回归生成审核文件
- [x] 校验审核模板完整性与可读性
---
......
......@@ -22,16 +22,48 @@ docs/to-parse/
# 查看待处理的文档
pnpm run parse:docs:list
# 解析所有文档
# 解析所有文档(默认仅生成待审核文件,不写入配置)
pnpm run parse:docs
# 解析指定文档
# 解析指定文档(默认仅生成待审核文件,不写入配置)
pnpm run parse:docs:file -- --file="产品说明书.pdf"
# 解析并写入配置(需要显式开启)
pnpm run parse:docs:file -- --file="产品说明书.pdf" --write-config
```
### 3. 查看结果
解析成功后,配置会自动添加到 `src/config/plan-templates.js`
解析成功后会生成待审核文件,位置如下:
```
docs/parse-audit/pending/
```
审核通过后再手动合并到 `src/config/plan-templates.js`,或使用 `--write-config` 明确写入。
## 🔗 功能链路
```
文档放入 docs/to-parse/
markitdown 抽取文本
启发式推断基础信息(产品名称/类型/币种)
生成配置代码与待审核文件
人工审核(pending → approved)
合并到 src/config/plan-templates.js
```
## 🧭 使用思路
1. **先审核再合并**:默认只生成待审核文件,避免直接污染配置。
2. **先读再写**:审核时重点核对产品名称、币种、缴费年期、年龄范围。
3. **分离责任**:解析用于提取线索,最终配置仍由人工确认。
4. **可追溯**:审计日志记录每次解析结果与变更摘要。
## 📋 支持的文档格式
......@@ -64,11 +96,7 @@ docs/parsed-backup/parse-audit.jsonl
## 🔧 配置 AI 服务
脚本使用 skill 工具调用 AI 服务,支持:
- OpenAI GPT-4o Vision
- Anthropic Claude 3.5 Sonnet
你需要配置 API Key(首次使用时脚本会提示)
脚本当前使用 markitdown CLI 进行文档抽取,AI 服务仍待接入。
## ⚠️ 注意事项
......
# 智享未来储蓄计划书
## 产品概述
**产品名称**: 智享未来储蓄计划
**产品类型**: 储蓄型保险
**保险公司**: 宏利人寿保险
**币种**: 美元 (USD)
---
## 产品特点
### 核心优势
- 保证现金价值,稳健增值
- 灵活提取方式,满足不同人生阶段需求
- 多种缴费年期选择,适应不同财务规划
- 美元/港币/人民币多币种选择
### 适合人群
- 希望长期稳健增值的客户
- 有子女教育金规划需求的父母
- 有养老规划需求的人士
- 希望灵活运用资金的高净值人士
---
## 投保条件
### 投保年龄
- 最低投保年龄:出生 15 天
- 最高投保年龄:75 岁
### 缴费年期
- 整付(0-75 岁)
- 3 年期缴
- 5 年期缴
- 10 年期缴
### 保险期间
- 终身(至 100 岁)
---
## 保障利益
### 身故保险金
若被保险人身故,我们将支付身故保险金予受益人。
### 现金价值
保单生效后具有现金价值,现金价值随保单年度增长而增加。
### 红利分配
本公司将根据分红保险业务的投资经营状况决定红利分配金额。
---
## 提取计划
### 提取方式
客户可选择以下提取方式:
**方式一:年龄指定金额提取**
- 客户可指定从特定年龄开始,每年提取固定金额
- 提取年龄可选:18/20/22/25/30/35/40/45/50/55/60 岁
- 每年提取金额:最低 1,000 美元
**方式二:最高固定金额提取**
- 客户可选择提取最高固定金额
- 适用于需要大额资金支出的场景
### 提取周期
- 每年提取
- 每 2 年提取
- 每 3 年提取
- 每 5 年提取
- 每 10 年提取
- 终身提取
### 支持币种
- 美元 (USD)
- 港币 (HKD)
- 人民币 (CNY)
---
## 缴费示例
### 案例:35 岁男性,整付,年缴保费 50,000 美元
| 保单年度 | 年缴保费 | 累计保费 | 保证现金价值 |
|---------|---------|---------|-------------|
| 第 1 年 | $50,000 | $50,000 | $45,000 |
| 第 5 年 | $50,000 | $250,000 | $235,000 |
| 第 10 年 | $50,000 | $500,000 | $490,000 |
| 第 20 年 | - | $500,000 | $1,050,000 |
| 第 30 年 | - | $500,000 | $1,650,000 |
*注:以上数字仅为示例,实际现金价值以保险公司公布为准。
---
## 退保规定
### 犹豫期
保单签收后 15 天内为犹豫期,投保人可无条件解除合同,本公司无息退还已收保费。
### 退保价值
保单生效后,投保人可申请解除合同,本公司将支付退保金(即当时的现金价值)予投保人。
---
## 保费表
### 整付保费表(美元)
| 年龄 | 男性 | 女性 |
|-----|------|------|
| 0 岁 | $45,200 | $44,800 |
| 10 岁 | $46,500 | $46,100 |
| 20 岁 | $48,000 | $47,600 |
| 30 岁 | $50,000 | $49,500 |
| 40 岁 | $53,500 | $52,800 |
| 50 岁 | $59,200 | $58,000 |
| 60 岁 | $68,500 | $66,800 |
| 70 岁 | $89,200 | $86,500 |
### 5 年期缴保费表(美元)
| 年龄 | 年缴保费 | 总保费 |
|-----|---------|-------|
| 0 岁 | $10,500 | $52,500 |
| 10 岁 | $10,800 | $54,000 |
| 20 岁 | $11,200 | $56,000 |
| 30 岁 | $11,800 | $59,000 |
| 40 岁 | $12,800 | $64,000 |
| 50 岁 | $14,500 | $72,500 |
| 60 岁 | $17,200 | $86,000 |
| 70 岁 | $23,500 | $117,500 |
---
## 责任免除
因下列情形之一导致被保险人身故的,本公司不承担保险责任:
1. 投保人故意造成被保险人死亡、故意伤害被保险人
2. 被保险人故意自伤、故意犯罪或抗拒依法采取的刑事强制措施
3. 被保险人主动吸食或注射毒品
4. 被保险人在本合同成立或复效之日起 2 年内自杀
5. 战争、军事冲突、暴乱或武装叛乱
6. 核爆炸、核辐射、辐射污染
---
## 特别约定
1. 本合同项下的保险责任自本公司同意承保并收取首期保险费后开始
2. 投保人应如实告知被保险人的健康状况,如故意不履行如实告知义务,本公司有权解除合同
3. 本合同项下的保险金请求权,自被保险人或受益人知道保险事故发生之日起 5 年内不行使而消灭
---
## 联系方式
**客服热线**: 400-888-8888
**公司网址**: www.manulife.com
**营业时间**: 周一至周五 9:00-17:30
---
*本计划书仅供参考,具体保险责任及责任免除以保险合同为准*
---
**文档版本**: V1.0
**生成日期**: 2026年2月13日
**用途**: 测试文档解析功能
......@@ -30,6 +30,7 @@ import {
MARKITDOWN_CONFIG,
AI_SERVICE_CONFIG
} from './parse-config.js'
import { smartExtractFields, generateAuditReport } from './smart-field-extractor.js'
// ========== 配置区 ==========
......@@ -490,31 +491,46 @@ async function parseDocumentWithAI(docPath) {
}
const content = parse_result.text
const fileName = path.basename(docPath)
// 步骤 2: 调用 AI 服务从文档内容中提取配置
// TODO(human): 集成 AI 服务(OpenAI/Anthropic)
// 需要配置 API Key 和服务端点
console.log('📝 AI 配置提取: 待集成 AI 服务')
// 步骤 2: 使用智能字段提取器
console.log('🧠 使用智能字段提取器...')
const extractResult = smartExtractFields(content, fileName)
// 临时方案:生成基础配置(基于文件名和内容启发式推断)
const fileName = path.basename(docPath, path.extname(docPath))
// 生成审核报告
const auditReport = generateAuditReport(extractResult)
console.log('\n' + auditReport)
// 构建配置对象
const config = {
product_name: fileName,
product_type: inferProductType(fileName, content),
currency: inferCurrency(content),
payment_periods: ['整付', '3年', '5年'],
age_range: { min: 0, max: 75 },
insurance_period: '终身',
is_savings: true,
withdrawal_modes: ['年龄指定金额', '最高固定金额'],
withdrawal_periods: ['1年', '3年', '5年', '10年'],
...extractResult.config,
is_savings: extractResult.config.product_type === 'savings',
form_schema: { base_fields: [], withdrawal_fields: [], reset_map: {} },
submit_mapping: {}
}
console.log('✅ 解析成功 (启发式推断)')
// 保存匹配详情供后续审核使用
config._extractDetails = {
matched: extractResult.matchDetails.filter(m => m.matched).map(m => m.field),
unmatched: extractResult.unmatched,
warnings: extractResult.warnings
}
config.form_sn = generateFormSn(config)
const matchedCount = extractResult.matchDetails.filter(m => m.matched).length
const totalCount = extractResult.matchDetails.length
console.log(`\n✅ 解析成功 (智能匹配 ${matchedCount}/${totalCount} 字段)`)
console.log(` 产品名称: ${config.product_name}`)
console.log(` 产品类型: ${config.product_type}`)
console.log(` 币种: ${config.currency}`)
console.log(` 缴费年期: ${JSON.stringify(config.payment_periods)}`)
if (extractResult.unmatched.length > 0) {
console.log(`\n⚠️ 需要人工补充 ${extractResult.unmatched.length} 个字段,详见审核文件`)
}
return config
} catch (error) {
console.error(`❌ 解析失败 (${docPath}):`, error.message)
......@@ -629,154 +645,184 @@ async function parseSingleFile(filePath) {
/**
* 生成待审核文件
*
* @description 生成人类可读的 markdown 审核文件
* @description 生成人类可读的 markdown 审核文件,保存到 docs/parse-audit/pending/
* @param {string} fileName - 原始文件名
* @param {Object} config - 解析的配置对象
* @param {string} code - 生成的配置代码
* @returns {Promise<string|null>} 审核文件路径
*/
async function generateAuditFile(fileName, config, code) {
const AUDIT_DIR = path.resolve(process.cwd(), 'docs/parse-audit/pending')
ensureDir(AUDIT_DIR)
const AUDIT_PENDING_DIR = path.resolve(process.cwd(), 'docs/parse-audit/pending')
const AUDIT_APPROVED_DIR = path.resolve(process.cwd(), 'docs/parse-audit/approved')
ensureDir(AUDIT_PENDING_DIR)
ensureDir(AUDIT_APPROVED_DIR)
const date = new Date().toISOString().split('T')[0]
const auditFileName = `${date}-${fileName.replace(/\.[^/.]+$/, '')}.md`
const auditFilePath = path.join(AUDIT_DIR, auditFileName)
const auditFilePath = path.join(AUDIT_PENDING_DIR, auditFileName)
const formSn = generateFormSn(config)
const formSchemaPreview = config.form_schema ? JSON.stringify(config.form_schema, null, 2) : '// 请手动补充'
const submitMappingPreview = config.submit_mapping ? JSON.stringify(config.submit_mapping, null, 2) : '// 请手动补充'
const configPreview = {
product_name: config.product_name || '',
product_type: config.product_type || '',
currency: config.currency || '',
form_sn: formSn,
payment_periods: config.payment_periods || [],
age_range: config.age_range || { min: 0, max: 75 },
insurance_period: config.insurance_period || '终身',
is_savings: config.is_savings || config.product_type === 'savings',
withdrawal_modes: config.withdrawal_modes || [],
withdrawal_periods: config.withdrawal_periods || []
}
const content = `# ${config.product_name || fileName}
// 生成字段提取报告
let extractionReport = ''
if (config._extractDetails) {
const { matched, unmatched, warnings } = config._extractDetails
## 解析信息
extractionReport = `
---
- **原始文件**: ${fileName}
- **解析时间**: ${new Date().toLocaleString('zh-CN')}
- **数据来源**: docs/to-parse/${fileName}
## 🤖 智能字段提取报告
---
### 匹配统计
## 配置预览
- ✅ 成功匹配: ${matched.length} 字段
- ⚠️ 使用默认值: ${warnings.length} 字段
- ❌ 未匹配(需人工补充): ${unmatched.length} 字段
\`\`\`javascript
const config = \\${JSON.stringify(config, null, 2)}
\`\`
### ✅ 已成功匹配的字段
---
${matched.map(f => `- ${f}`).join('\n') || '- (无)'}
## 审核检查清单
${warnings.length > 0 ? `
### ⚠️ 使用默认值的字段
- [ ] 产品名称是否正确
- [ ] 产品类型是否正确(${config.product_type || '未知'}
- [ ] 币种是否正确(${config.currency || '未知'}
- [ ] age_range 是否合理(${config.age_range?.min || 0} - ${config.age_range?.max || 75}岁)
- [ ] form_schema 字段是否完整
- [ ] submit_mapping 逻辑是否正确
${warnings.map(w => `- **${w.field}**: ${w.message}`).join('\n')}
` : ''}
---
${unmatched.length > 0 ? `
### ❌ 未匹配字段(需要人工补充)
## 下一步
${unmatched.map(item => `
#### ${item.field}
1. 审核以上配置是否正确
2. 确核通过后,执行以下操作:
- **原因**: ${item.reason}
- **建议值**:
${item.suggestions.map(s => ` - ${s}`).join('\n')}
`).join('\n')}
` : ''}
`
}
\`\`\`bash
# 1. 移动到 approved 目录
mv docs/parse-audit/pending/${auditFileName} docs/parse-audit/approved/
const content = `# 产品配置审核 - ${fileName}
# 2. 手动添加配置到 src/config/plan-templates.js
# 3. 运行 pnpm lint 检
\`\`
**解析时间**: ${new Date().toLocaleString('zh-CN')}
**原始文件**: ${fileName}
**数据来源**: docs/to-parse/${fileName}
---
## 审核状态
## 📋 产品基本信息
| 字段 | 提取值 | 需要确认 |
|------|--------|---------|
| 产品名称 | ${config.product_name || '未提取'} | ✅ 请核对产品名称 |
| 产品类型 | ${config.product_type || '未提取'} | ✅ 请确认产品类型 |
| 币种 | ${config.currency || 'USD'} | ✅ 请确认币种 |
| form_sn | \`${formSn}\` | ✅ 请确认 form_sn 唯一性 |
| 缴费年期 | ${JSON.stringify(config.payment_periods || [])} | ✅ 请确认缴费年期选项 |
| 年龄范围 | ${config.age_range?.min || 0}-${config.age_range?.max || 75} | 请确认年龄范围 |
| 保险期间 | ${config.insurance_period || '终身'} | 请确认保险期间 |
${config.is_savings ? `
### 💰 储蓄类产品特有字段
| 字段 | 提取值 | 需要确认 |
|------|--------|---------|
| 提取方式 | ${JSON.stringify(config.withdrawal_modes || [])} | ✅ 请确认提取方式 |
| 提取期 | ${JSON.stringify(config.withdrawal_periods || [])} | ✅ 请确认提取期选项 |
` : ''}
${extractionReport}
---
- [ ] 待审核
- [ ] 已通过
- [ ] 已拒绝
## 🧾 配置预览
## 审核意见
\`\`\`javascript
${JSON.stringify(configPreview, null, 2)}
\`\`\`
<!-- 审核时请填写 -->
---
**生成时间**: ${new Date().toLocaleString('zh-CN')}
`
## 📝 表单字段 (form_schema)
<!-- 审核通过后,请执行以下步骤:-->
1. 将此文件移动到 \`docs/parse-audit/approved/\`
2. 手动将配置添加到 \`src/config/plan-templates.js\`
3. 运行 \`pnpm lint\` �查
`
\`\`\`javascript
${formSchemaPreview}
\`\`\`
---
**注意**:
- 请仔细核对配置的每个字段
- 确认产品类型和币种是否符合业务需求
- �查 form_schema 中的字段定义是否完整
`
## 🔄 提交字段映射 (submit_mapping)
`
\`\`\`javascript
${submitMappingPreview}
\`\`\`
try {
fs.writeFileSync(auditFilePath, content, 'utf-8')
return auditFilePath
} catch (error) {
console.error(\`❌ 写入审核文件失败: \${error.message}`)
return null
}
}
---
/**
* 生成待审核文件
*
* @description 生成人类可读的 markdown 审核文件,保存到 docs/parse-audit/pending/
* @param {string} fileName - 原始文件名
* @param {Object} config - 解析的配置对象
* @param {string} code - 生成的配置代码
* @returns {Promise<string|null>} 审核文件路径
*/
async function generateAuditFile(fileName, config, code) {
const AUDIT_DIR = path.resolve(process.cwd(), 'docs/parse-audit/pending')
ensureDir(AUDIT_DIR)
## 🧩 生成配置片段
const date = new Date().toISOString().split('T')[0]
const auditFileName = `${date}-${fileName.replace(/\.[^/.]+$/, '')}.md`
const auditFilePath = path.join(AUDIT_DIR, auditFileName)
\`\`\`javascript
${code.trim()}
\`\`\`
---
const content = `# ${config.product_name || fileName}
## ✅ 审核检查清单
## 解析信息
### 基础信息
- [ ] 产品名称正确
- [ ] 产品类型正确(savings/critical-illness/life-insurance)
- [ ] 币种正确(USD/CNY/HKD/EUR)
- [ ] form_sn 唯一且符合命名规范
- **原始文件**: ${fileName}
- **解析时间**: ${new Date().toLocaleString('zh-CN')}
- **数据来源**: docs/to-parse/${fileName}
### 缴费与年龄
- [ ] 缴费年期选项完整且正确
- [ ] 年龄范围合理
- [ ] 保险期间正确
### 储蓄类特有(如适用)
- [ ] 提取方式正确
- [ ] 提取期选项完整
- [ ] 表单字段定义完整
- [ ] 提交字段映射正确
---
## 配置预览
## 📋 审核后操作
\`\`\`javascript
{
"product_name": "${config.product_name || ''}",
"product_type": "${config.product_type || ''}",
"currency": "${config.currency || ''}",
${Object.entries(config).filter(([k]) =>
!['source_file', 'form_schema', 'submit_mapping'].includes(k)
).map(([k, v]) =>
` "${k}": ${JSON.stringify(v, null, 2)}`
).join(',\n ')}
\`\`\`
### 确认无误
\`\`\`bash
# 1. 移动到 approved 目录
mv docs/parse-audit/pending/${auditFileName} \\
docs/parse-audit/approved/
---
# 2. 合并到正式配置
# 手动复制或使用工具合并到 src/config/plan-templates.js
# 3. 删除待审核文件(可选)
rm docs/parse-audit/pending/${auditFileName}
\`\`\`
## 审核检查清单
### 需要修改
1. 编辑本文件修正内容
2. 重新提交审核
- [ ] 产品名称是否正确
- [ ] 产品类型是否正确
- [ ] 币种是否正确
- [ ] age_range 是否合理
- [ ] payment_periods / withdrawal_periods 是否完整
- [ ] form_schema 字段是否完整
- [ ] 提取逻辑是否符合需求
### 放弃本次解析
\`\`\`bash
rm docs/parse-audit/pending/${auditFileName}
\`\`\`
---
......@@ -788,15 +834,9 @@ ${Object.entries(config).filter(([k]) =>
## 审核意见
\`\`\`text
\`\`\`
<!-- 审核通过后,请执行以下步骤:
1. 将此文件移动到 docs/parse-audit/approved/
2. 手动将配置添加到 src/config/plan-templates.js
3. 提交变更
-->
`
try {
fs.writeFileSync(auditFilePath, content, 'utf-8')
......@@ -1274,7 +1314,8 @@ async function main() {
// 检查模式
const listMode = args.includes('--list')
const fileMode = args.find(arg => arg.startsWith('--file='))
const dryRunMode = args.includes('--dry-run')
const writeMode = args.includes('--write-config')
const dryRunMode = args.includes('--dry-run') || !writeMode
const rollbackMode = args.find(arg => arg.startsWith('--rollback='))
const statusMode = args.includes('--status')
......