hookehuyr

feat(docs): 优化文档解析工具并添加单元测试

- 重构 generateConfigCode 函数,简化代码生成逻辑
- 导出核心函数以支持单元测试
- 为储蓄产品添加顶层 category 属性
- 添加 parse-docs.test.js 单元测试(3个测试用例全部通过)
- 优化 commit-msg hook 校验逻辑
- 更新 CHANGELOG.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
......@@ -21,10 +21,12 @@ echo ""
ALLOWED_TYPES="feat|fix|docs|style|refactor|perf|test|chore|revert"
# 允许的范围(常见模块)
ALLOWED_SCOPES="material|product|plan|user|auth|api|ui|config|build|ci|release|husky|chore"
ALLOWED_SCOPES="material|product|plan|user|auth|api|ui|config|build|ci|release|husky|chore|to-parse"
# 检查格式 - 使用简单的正则
PATTERN="^([a-z]+)\\(([a-z]+\\))?: .{1,50}"
# 支持: type(scope): subject,subject 允许中文、英文、数字、标点
# 范围支持连字符: to-parse, test-tabs 等
PATTERN="^([a-z]+)\(([a-z-]+)\): .{1,50}"
# 检查格式
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
......
......@@ -52,6 +52,9 @@ pnpm lint
-**回跳路径统一** - 统一保存登录回跳路径,确保权限拦截后可恢复
-**搜索页测试** - 搜索页测试对齐当前实现并补充接口 Mock
### 文档解析
-**配置生成修复** - 修复文档解析生成配置的 form_sn 前缀、category 位置与插入稳定性
## 🆕 最新更新(2026-02-12)
### 计划书功能优化
......@@ -305,6 +308,11 @@ export default {
3. **微信支付**`src/utils/wechatPay.js`
4. **时间选择器**`src/components/time-picker-data/`
## ✅ 优化建议
- 建议将文档解析脚本接入真实 AI 解析服务以替代 mock 配置
- 建议为 parse:docs 增加一键校验配置合法性的脚本输出
## 📚 相关文档
- **[经验教训总结](docs/lessons-learned.md)** - Taro 项目开发经验、最佳实践和常见陷阱
......
## [2026-02-13] - 文档解析配置生成修复
### 修复
- 修复文档解析生成的 form_sn 前缀不匹配模板映射问题
- 修复储蓄型产品 category 写入位置错误导致模板识别异常
- 修复配置插入位置不稳定导致写入结构损坏的问题
- 修复测试时脚本自动执行导致进程退出的问题
### 新增
- 增加文档解析脚本的生成逻辑测试覆盖
---
**详细信息**
- **影响文件**: scripts/parse-docs.js, scripts/parse-docs.test.js
- **技术栈**: Node.js, Vitest
- **测试状态**: 已通过(pnpm test scripts/parse-docs.test.js)
- **备注**: lint 存在历史 warning 未处理
---
## [2026-02-13] - 消息详情页布局与状态优化
### 优化
......
# 保险知识库
> 本文档提供保险产品解析所需的行业知识,AI 解析器可以引用此内容来正确识别和提取产品信息。
## 📚 保险产品分类
### 1. 储蓄型保险(Savings Insurance)
**特点**
- 具有储蓄功能,保单有现金价值
- 通常支持灵活提取现金
- 保险期间较长(终身或至指定年龄如 100 岁)
**常见产品名关键词**
- 储蓄计划
- 传承计划
- 累积计划
- 增值计划
- 万能险
- 投连险
**关键提取字段**
| 字段 | 说明 | 示例 |
|------|------|------|
| 产品名称 | 保险产品全称 | 宏挚传承保障计划 |
| 币种 | 支持的货币 | HKD, USD, CNY |
| 缴费年期 | 可选择的缴费年限 | 整交、5年、10年 |
| 保险期间 | 保障期限 | 终身、至 100 岁 |
| 最低/最高投保年龄 | 年龄限制 | 15 日 - 75 岁 |
| 提取方式 | 现金提取方式 | 灵活提取、固定提取 |
| 提取周期 | 提取频率 | 每年、每半年、每季、每月 |
---
### 2. 人寿保险(Life Insurance)
**特点**
- 提供身故保障
- 保费相对较低
- 保障期间固定
**常见产品名关键词**
- 人寿保险
- 定期寿险
- 终身寿险
- 保障计划
**关键提取字段**
| 字段 | 说明 | 示例 |
|------|------|------|
| 身故保险金 | 被人身故赔付金额 | 基本保额 × 倍数 |
| 保费形式 | 缴费方式 | 年缴、季缴、月缴 |
---
### 3. 重疾保险(Critical Illness Insurance)
**特点**
- 保障重大疾病
- 确诊即赔付
- 可选保费豁免
**常见产品名关键词**
- 重疾险
- 危疾保障
- 重大疾病保险
- 健康保障
**关键提取字段**
| 字段 | 说明 | 示例 |
|------|------|------|
| 保障疾病数量 | 覆盖病种数量 | 100+ 种 |
| 赔付次数 | 可赔付次数 | 单次、多次 |
| 等待期 | 观察期 | 90 天、180 天 |
---
## 📋 保险专业术语对照表
| 中文术语 | 英文术语 | 说明 |
|---------|---------|------|
| 投保人 | Applicant | 购买保险的人 |
| 被保险人 | Insured | 受保障的人 |
| 受益人 | Beneficiary | 接受保险金的人 |
| 保额 | Sum Assured | 保险公司承担的最高赔偿额 |
| 保费 | Premium | 投保人支付的费用 |
| 缴费年期 | Payment Period | 保费缴纳的年限 |
| 保险期间 | Policy Term | 保险合同的有效期 |
| 现金价值 | Cash Value | 退保时可获得的价值 |
| 保单年度 | Policy Year | 保单生效的年数 |
| 宽限期 | Grace Period | 逾期未缴保费但保障仍有效的期间 |
| 观察期/等待期 | Waiting Period | 保险生效后需等待的一段时间 |
| 免责期 | Exclusion Period | 保险公司不承担责任的时间 |
---
## 🏦 币种识别
| 币种代码 | 币种名称 | 符号 |
|---------|---------|------|
| HKD | 港元 | $, HK$ |
| USD | 美元 | US$, $ |
| CNY | 人民币 | ¥, RMB |
| MOP | 澳门元 | MOP$ |
---
## 📊 缴费年期识别规则
| 文案表述 | 标准化值 |
|---------|---------|
| 整交、趸交 | lump_sum |
| 5年、5年缴 | 5 |
| 10年、10年缴 | 10 |
| 15年、15年缴 | 15 |
| 20年、20年缴 | 20 |
| 25年、25年缴 | 25 |
| 30年、30年缴 | 30 |
| 终身缴费、至终身 | to_age_100 |
---
## 📅 保险期间识别规则
| 文案表述 | 标准化值 |
|---------|---------|
| 终身、100岁 |终身 |
| 至 85 岁 | to_85 |
| 至 88 岁 | to_88 |
| 至 100 岁 | to_100 |
| 1 年、1 年期 | 1_year |
| 20 年、20 年期 | 20_years |
---
## 🎯 年龄范围识别
| 文案表述 | 最低年龄 | 最高年龄 |
|---------|---------|---------|
| 出生 15 天起 | 0 | - |
| 15 日 - 75 岁 | 0 | 75 |
| 18 岁 - 65 岁 | 18 | 65 |
| 30 日 - 70 岁 | 0 | 70 |
**注意**:年龄通常按周岁计算。
---
## 💰 提取功能识别
### 提取方式(Withdrawal Modes)
| 文案表述 | 标准化值 |
|---------|---------|
| 灵活提取 | flexible |
| 固定提取 | fixed |
| 定期提取 | regular |
| 终身年金 | lifetime_annuity |
### 提取周期(Withdrawal Periods)
| 文案表述 | 标准化值 |
|---------|---------|
| 每年 | yearly |
| 每半年 | half_yearly |
| 每季 | quarterly |
| 每月 | monthly |
| 终身 | lifetime |
---
## 🔍 产品名称关键词识别
### 储蓄型关键词
- 传承、累积、增值、储蓄、分红
- 宏挚、迈达、创富、丰誉
- 5G、6G、世代
### 人寿保险关键词
- 人寿、寿险、身故保障
- 定期、终身、保额
### 重疾保险关键词
- 重疾、危疾、重大疾病
- 疾病保障、健康保障
- 守护、守护
---
## 📐 配置生成规则
### form_sn 生成规则
```
{产品类型}-{产品代号}-{币种}
```
**示例**
- `savings-hc77-hkd` - 宏挚 77(储蓄型,港币)
- `life-term-20-usd` - 定期寿险 20 年期(人寿,美元)
- `ci-essential-cny` - 基础重疾险(重疾,人民币)
### 组件选择规则
| 产品类型 | 对应组件 |
|---------|----------|
| 储蓄型 | SavingsTemplate |
| 人寿保险 | LifeInsuranceTemplate |
| 重疾保险 | CriticalIllnessTemplate |
---
## ⚠️ 常见解析错误及修正
### 错误 1:币种识别错误
- **问题**:将 "USD$" 识别为港币
- **修正**:检查符号,$ 后面跟 USD 才是美元
### 错误 2:年龄范围解析错误
- **问题**:将 "15 日 - 75 岁" 的最低年龄识别为 15
- **修正**:15 日应转换为 0 岁
### 错误 3:缴费年期单位错误
- **问题**:将 "20 年期" 识别为 20 年缴费
- **修正**:"年期"通常指保险期间,"缴费"才是缴费年期
### 错误 4:提取方式缺失
- **问题**:储蓄型产品未识别到提取功能
- **修正**:查找"现金价值"、"提取"、"红利"等关键词
---
## 📖 参考规范
### 产品说明书标准结构
1. **产品概述** - 产品定位和特点
2. **投保条件** - 年龄、职业限制
3. **保障内容** - 具体保障项目
4. **缴费方式** - 缴费年期和币种
5. **红利分配**(如有)- 红利政策和领取方式
6. **提取功能**(如有)- 现金价值提取规则
7. **费用说明** - 各项费用标准
8. **案例演示** - 实际投保示例
### 文档解析优先级
1. **表格数据** > 文本描述
2. **明确的数字** > 模糊的表达(如"左右"、"约")
3. **章节标题** > 正文内容
4. **示例数据** > 说明文字
---
## 🔄 更新记录
| 日期 | 更新内容 | 更新人 |
|------|---------|--------|
| 2026-02-13 | 创建初始版本,添加保险产品分类和术语表 | Claude Code |
This diff is collapsed. Click to expand it.
import { describe, it, expect } from 'vitest'
import { generateFormSn, generateConfigCode, updateConfigContent } from './parse-docs'
describe('parse-docs 生成逻辑', () => {
it('generateFormSn 使用产品类型前缀', () => {
const form_sn = generateFormSn({
product_name: 'WIOP3E 盈传创富保障计划 3 - 优选版',
product_type: 'life-insurance'
})
expect(form_sn.startsWith('life-insurance-')).toBe(true)
})
it('generateConfigCode 储蓄配置包含顶层 category', () => {
const result = generateConfigCode({
product_name: '宏挚传承保障计划',
product_type: 'savings',
currency: 'USD',
payment_periods: ['整付'],
age_range: { min: 0, max: 75 },
insurance_period: '终身',
is_savings: true,
withdrawal_modes: ['年龄指定金额'],
withdrawal_periods: ['1年']
})
expect(result.code.includes("component: 'SavingsTemplate'")).toBe(true)
expect(result.code.includes("category: 'savings'")).toBe(true)
expect(result.code.includes("config: {\n category")).toBe(false)
})
it('updateConfigContent 插入到 PLAN_TEMPLATES 末尾', () => {
const base_content = `export const PLAN_TEMPLATES = {
'a': {
name: 'A',
component: 'LifeInsuranceTemplate',
config: {
currency: 'USD',
payment_periods: [],
age_range: { min: 0, max: 1 },
insurance_period: '终身'
}
}
}
export const FEATURE_FLAGS = {}`
const result = updateConfigContent(base_content, [
{
code: " 'b': {\n name: 'B',\n component: 'SavingsTemplate',\n category: 'savings',\n config: {\n currency: 'USD',\n payment_periods: [],\n age_range: { min: 0, max: 1 },\n insurance_period: '终身',\n withdrawal_plan: {\n enabled: true,\n currencies: ['HKD', 'USD', 'CNY'],\n default_currency: 'USD',\n withdrawal_modes: [],\n withdrawal_periods: []\n }\n }\n }"
}
])
expect(result).toMatch(/'a'[\s\S]*},\n\s+'b'/)
expect(result).toMatch(/'b'[\s\S]*}\n\nexport const FEATURE_FLAGS/)
})
})