baodan/docs/PPT与海报生成全链路详细修复计划书_20260802.md
wsb1224 7a3e2870dc 主要成果:
海报确认、文案生成、海报生成增加服务端失败关闭门禁,绑定文件哈希、解析快照哈希和确认数据哈希,并返回 422 业务错误。[validators.py (line 65)](D:/work/code/python/coding/baodanagent/api/insurance/plan_data/validators.py:65)
缺失金额不再转换为 0;删除错误字段兜底和“年缴×年期=合同总保费”事实推导;里程碑冲突会阻断确认。[normalizer.py (line 14)](D:/work/code/python/coding/baodanagent/api/insurance/ppt/normalizer.py:14)
PPT 渲染器支持可空金额和实际币种,缺失值显示“待确认”,避免 float(None)、空值除法等异常。
模板必须覆盖全部输入保司和产品;自动选择排序确定化,同优先级歧义时阻断。[template_selection.py (line 4)](D:/work/code/python/coding/baodanagent/api/insurance/ppt/template_selection.py:4)
场景判定写入 scenarioOverrideTrace,记录请求、模板、服务端及 Worker 最终判定。[routes.py (line 555)](D:/work/code/python/coding/baodanagent/api/insurance/ppt/routes.py:555)
前端增加哈希提交、人工调整原因、模板歧义提示及真实能力说明。
冻结三份核心 Schema,并建立 Goldens manifest、说明和评估脚本。
验证结果:
后端目标回归:111 passed, 1 skipped
PPT 运行时回归:81 passed
前端生产构建和 vue-tsc:通过
Python compileall:通过
三份 Schema JSON:解析通过
git diff --check:通过,仅有换行符提示
2026-08-02 12:58:41 +08:00

46 KiB
Raw Blame History

PPT 与海报生成全链路详细修复计划书

编制日期2026-08-02
依据文档:docs/PPT与海报生成全链路深度审计报告_20260802.md
适用范围:计划书 PDF 解析、人工复核、PlanData、海报生成、PPT 生成、场景与模板、异步任务、质量门禁、测试、监控与数据留存
文档性质:实施主计划。既有 PPT、海报和 PDF 专项计划继续作为局部设计参考;若与本计划冲突,以“统一事实快照、字段证据链、失败关闭、版本可追溯”四项原则为准。

1. 结论与实施决策

本次整改不能按“海报修一套、PPT 再修一套”的方式推进。审计报告中的 55 项问题共享四个根因:事实来源分裂、字段语义失真、配置运行时失效、任务与输出不可复现。因此,修复主线确定为:

  1. 先止损:阻止空数据、未知值、错误币种、错误字段兜底和不兼容模板继续进入成品;
  2. 再建事实层PDF 先形成保留页码、坐标、表格和 OCR 信息的 Document IR
  3. 再建唯一快照:人工确认后生成不可变 PlanData Snapshot海报与 PPT 只能消费该快照;
  4. 再重构配置:场景负责业务规则,模板负责视觉槽位,生成策略负责兼容、缺失和阻断;
  5. 最后封闭交付任务冻结全部输入输出数值与快照逐项对账P0 不一致时失败关闭。

不得把“有字段”“能打开 PPTX”“测试通过”当作准确性验收。上线以真实脱敏 PDF 金标准集、字段证据完整率和输出数值一致率为准。

2. 目标、边界与工作假设

2.1 核心目标

  • 同一份 PDF 只产生一套经过确认的事实数据;
  • 每个进入海报或 PPT 的关键金额都能定位到 PDF 页码和区域,或有明确的人工录入理由;
  • missingconflictderived 与真实数值 0 在全链路中严格区分;
  • 后台发布的场景、模板和生成策略实际控制生成结果,并可回放;
  • 异步任务提交后不再受会话、模板和配置后续修改影响;
  • 成品中的文本、表格和图表数值与提交时快照 100% 对账;
  • 客户 PDF、解析中间产物、确认快照和成品都有明确留存、鉴权和清理闭环。

2.2 本计划不做的事项

  • 不优先扩充大模型提示词、模板风格或新海报版式;
  • 不把大模型作为密集金额表逐格抄录的唯一方案;
  • 不把现有不可信旧解析结果批量标记为 confirmed
  • 不在首期实现跨币种收益排名或实时汇率换算;
  • 不改 BaoDan/Dify 基座中除现有路由注册约定之外的代码;
  • 不顺带重构与 PPT、海报、文档解析无关的模块。

2.3 工作假设

  • 当前仓库迁移已到 migrate_035,本计划从 migrate_036 起分批增加可回滚的增量迁移;
  • 第一批正式金标准不少于 30 份脱敏计划书,至少覆盖 3 家保险公司、3 类险种及原生/扫描/混合 PDF
  • 业务字段由保险业务人员确认口径,技术团队不自行推断“退保价值等于身故保障”等规则;
  • 旧接口需要在灰度期兼容,但所有新生成任务必须可识别所使用的数据契约版本;
  • 文档审计中的发生比例仍需真实样本测量,因此工期使用区间,不承诺单点日期。

3. 当前代码基线与修复约束

以下事实已结合当前代码核验,作为实施起点:

领域 当前代码事实 修复约束
海报解析 poster/tasks.py 优先执行 extract_for_poster,只有映射结果失败才回退完整解析 过渡期先收紧完整性门,最终删除独立事实解析,只保留 PlanData projection
海报确认 poster/service.py::confirm_case_upload 直接保存 confirmedData,未校验解析状态、必填、冲突、证据和文件哈希 前端校验只能改善体验,最终门禁必须在后端
海报复核 PosterSourcePanel.vue 仅编辑基础字段和 10/20/30 年值,未挂载 PDF 预览和完整利益表 先复用已有 PdfPagePreview.vue,不另造第二套 PDF 查看器
数值语义 normalizer.py 多处把缺失/非法值转为 0,仍存在字段互相兜底和保费乘年期推导 先引入兼容型 nullable 语义,再切换到 FieldValue不可一次修改全部渲染器后才测试
场景 前后端均存在硬编码检测,运行时重新推断场景 场景解析只保留服务端单一入口,返回 matchTrace
模板 scenarioSlides 优先于后台 slidesConfig;模板上传可直接置 clone_ready=True 先明确临时优先级,再建立 pageSpec-slot 契约和发布门禁
任务快照 已有 input_snapshot_jsoninput_revision,但 Worker 仍读取当前 session/template 扩展现有任务模型和创建流程,不另建平行任务系统
留存 清理逻辑覆盖部分海报成品和 PPT 历史,但未覆盖源 PDF、case、Document IR、快照和证据 新数据必须在同一版本同时接入鉴权与清理

4. 目标链路与责任边界

PDF 上传
  -> Document Ingest哈希、鉴权、页数、文件类型
  -> Document IR页面、bbox、文本块、表格、OCR 候选)
  -> Extraction Candidates正则、profile、表格解析、LLM 语义候选)
  -> Reconciliation字段语义、业务规则、冲突与场景归属
  -> ReviewPDF / 字段 / 表格双向定位)
  -> Confirmed PlanData Snapshot不可变、版本化、可追溯
  -> Poster Projection / PPT DeckContract
  -> ScenarioDefinition + GenerationPolicy + TemplateDefinition
  -> Frozen Generation Input
  -> Render
  -> 数值对账 + 视觉检查
  -> 成品或失败报告

模块职责必须保持清晰:

模块 唯一职责 禁止行为
api/insurance/document/ 保存 PDF 的版面事实和解析过程 直接决定保险字段最终值
api/insurance/plan_data/ 候选合并、业务校验、人工确认、快照、投影 为了适配某个海报模板修改事实
api/insurance/ppt/ 将 PlanData 转为 DeckContract 并渲染 PPT 重新解析 PDF 或静默补造金额
api/insurance/poster/ 将 PlanData 投影为海报内容并渲染 维护独立计划书事实或覆盖里程碑值
api/insurance/generation/ 解析场景、冻结输入、调度、对账、追溯 在 Worker 中读取可变业务状态
管理后台 编辑、验证、发布场景和模板版本 修改已发布版本的内容

5. 数据模型与迁移计划

5.1 migrate_036Document IR 与文档访问

新增表:

  • insurance_documents
    • iduser_idsha256storage_keyoriginal_namemime_typefile_sizepage_count
    • document_typepdf_kindnative/scanned/mixedstatus
    • parser_versionocr_versionprofile_codeprofile_version
    • quality_jsonprocessing_log_jsonexpires_at、时间字段;
    • 唯一约束建议为 (user_id, sha256),不得跨用户复用授权。
  • insurance_document_pages
    • document_idpage_numberwidthheight
    • native_text_qualityocr_qualitypage_class
    • text_blocks_jsonocr_blocks_jsonimages_json
    • 唯一约束 (document_id, page_number)
  • insurance_document_tables
    • document_idtable_idscenario_typeheaders_jsonrows_json
    • source_pages_jsoncontinuation_ofbbox_jsonconflicts_json

取舍说明:文本块和表格首期以 JSON 按页/表存储,避免把每个 PDF 单元格展开成海量数据库记录;需要检索的字段证据单独结构化存储。

5.2 migrate_037PlanData、证据与确认快照

新增表:

  • insurance_plan_snapshots
    • iddocument_idschema_versionsnapshot_versionprevious_snapshot_id
    • statusdraft/review_required/confirmed/superseded/invalid
    • plan_data_jsonvalidation_results_json
    • snapshot_hashdocument_sha256confirmed_byconfirmed_atcreated_atexpires_at
    • 唯一约束 (document_id, snapshot_version)snapshot_hash 索引。
  • insurance_field_evidence
    • snapshot_idfield_pathdocument_idpage_numberbbox_json
    • table_idrow_idcolumn_idraw_texttext_hash
    • extractorextractor_versionconfidenceevidence_status
  • insurance_plan_overrides
    • snapshot_idfield_pathold_value_jsonnew_value_json
    • reasonoperator_idcreated_at

核心约束:

  • confirmed 快照内容不可原地更新;修改必须派生新版本;
  • snapshot_hash 对规范化 JSON 计算,字段排序、数字精度和空值表达必须固定;
  • confirmed 前关键字段的 conflict 数量必须为 0
  • 每个导出关键金额必须存在证据,或存在人工覆盖记录和原因。

5.3 migrate_038:场景、策略与模板版本

保留现有 insurance_ppt_scenariosinsurance_ppt_templates 作为稳定标识与当前指针,新增版本表:

  • insurance_ppt_scenario_versions
    • scenario_codeversionlifecycledraft/validated/published/retired
    • selector_jsonpage_specs_jsonmetric_specs_jsoncomparison_years_json
    • compatibility_rules_jsonfallback_scenariodefinition_hash
    • published_bypublished_at
  • insurance_generation_policy_versions
    • codeversionlifecycle
    • calculation_policy_jsonmissing_value_policy_jsonconclusion_policy_jsonpolicy_hash
  • insurance_ppt_template_versions
    • template_idversionlifecycle
    • asset_idasset_sha256page_slots_jsontheme_jsoncapacity_rules_json
    • supported_scenario_versions_jsonvalidation_report_jsondefinition_hash

已发布版本禁止更新,只能创建新版本。旧的 slides_config_json 在兼容期只读映射为 draft version不自动视为 validated/published。

5.4 migrate_039:任务冻结与输出审计

扩展 insurance_generation_tasks

  • snapshot_idsnapshot_hashscenario_version_idscenario_hash
  • policy_version_idpolicy_hashtemplate_version_idtemplate_hashasset_sha256
  • renderer_versionsubmit_revisionoutput_reconciliation_jsonvisual_check_json
  • heartbeat_atattempt_noresult_statecurrent/stale/failed

扩展 PPT/海报历史记录,保存实际使用的快照、场景、策略、模板和渲染器版本。不得只保存请求中的 template_id

5.5 migrate_040:留存策略与清理审计

  • 为 Document、Page、Table、Snapshot、Evidence、Override、PPT/海报成品增加 expires_at 或可推导的留存策略;
  • 新增不含敏感正文的清理审计记录;
  • 清理逻辑按依赖顺序删除对象文件和数据库数据;
  • 清理任务支持 dry-run、批量上限、失败重试和孤儿文件检查。

所有迁移必须满足:可重复执行、启动失败即停止、先加后切、旧字段灰度期可读、不在迁移中执行耗时 PDF 重解析。

6. 分阶段实施计划

Phase 0止损、基线与开关P046 人日)

目标

在统一事实层完成前,先阻止已知错误继续进入海报和 PPT并建立可以量化修复效果的基线。

任务包

P0-A海报确认与生成后端门禁

关联问题P0-05、P0-06、P0-07、P1-08、P1-16、P2-01。

修改:

  • confirm_case_upload 增加服务端 schema
  • 只允许 parse_status in ('parsed', 'partial') 进入确认,partial 必须补齐必填并解决冲突;
  • 验证 file_hash、解析快照哈希和当前 case 一致;
  • 按险种校验年龄、性别、币种、保费、缴费期、保额和关键利益字段;
  • 检查所选产品与 PDF 提取产品;不一致时必须提交 overrideReason 并写审计记录;
  • 空对象、非法数字、未解决冲突、无证据关键金额一律返回 4xx 业务错误;
  • 生成接口再次执行同一门禁,不能信任 confirmed_data is not None
  • parsed 只表示“可复核”,只有 confirmed 快照可用于生成。

主要文件:

  • api/insurance/poster/service.py
  • api/insurance/poster/routes.py
  • api/insurance/poster/tasks.py
  • api/insurance/models/poster_case_upload.py
  • 新增 api/insurance/plan_data/validators.py 的兼容入口

验收:

  • {}、错误状态、缺必填、未解决冲突均无法确认;
  • 绕过前端直接请求同样被阻断;
  • 已确认数据修改后必须重新确认;
  • 错产品不会被后台选择静默覆盖。

P0-B修正未知值、错误兜底和币种

关联问题P0-11、P0-12、P0-13、P1-12、P1-13、P1-14、P1-15。

修改:

  • 新增 nullable 数值转换函数,明确区分 None、非法、0
  • 停止以 deathBenefit 写入 totalSurrenderValue
  • 停止 sumAssured -> deathBenefit、现金价值字段互相兜底;
  • 停止把 annualPremium * payYears 当合同总保费;需要展示时标记 derived_estimate,默认不参与对账、排名和结论;
  • 海报字段取值从 Python or 改为显式 is not None
  • 显式里程碑与利益表同年值不一致时产生冲突,不覆盖;
  • 渲染器统一使用 currencycurrency_symbol,删除所有硬编码 US$
  • 兼容期渲染器对未知值显示 或“待确认”,不得显示 0

主要文件:

  • api/insurance/ppt/normalizer.py
  • api/insurance/ppt/comparison.py
  • api/insurance/ppt/validator.py
  • api/insurance/ppt/scripts/fast_pptx_renderer.py
  • api/insurance/poster/tasks.py
  • api/insurance/poster/content_builder.py

验收:

  • 真实 0 保留为 0缺失和非法值均不变成 0
  • 退保价值与身故保障不再互相替代;
  • HKD、CNY、SGD、USD 样本的所有页面币种一致;
  • 缺失金额不会进入排名、IRR 或“更优”结论。

P0-C模板适用性、排序与后台诚实提示

关联问题P0-08、P0-09、P1-18、P1-20、P2-03。

修改:

  • 前后端多产品模板适用条件统一为“所有输入产品均满足”;
  • 自动模板查询增加稳定排序精确场景、产品覆盖、优先级、版本、ID同优先级多个匹配时阻断
  • 在场景系统完成前,后台明确标注现有 slidesConfig 仅影响视觉页框/元数据,不能承诺控制业务页面;
  • 记录临时 scenario_override_trace,把硬编码检测、用户选择、模板标签和最终场景全部写入任务日志;
  • 生成页文案与真实能力一致,暂不展示不存在的“手动选择场景”。

验收:

  • 任一产品不适用时模板不可选且后端拒绝;
  • 同一输入重复自动选模板结果稳定;
  • 管理员能看到当前配置是否只作为视觉配置使用。

P0-D金标准与回归基线

关联问题P0-17、P2-08。

修改:

  • 建立脱敏样本登记表、标注规范和双人复核流程;
  • 首批 10 份用于开发探针Phase 2 前扩充到不少于 30 份;
  • 标注标量、完整利益表、场景、页码、bbox、币种、单位和允许的空值
  • 将当前解析结果、耗时、人工修改率和 PPT/海报输出保存为基线,不把当前值当正确值;
  • 新增批量评测命令,输出 JSON 和 Markdown 差异报告。

建议文件:

  • tests/fixtures/plan_goldens/manifest.json
  • tests/fixtures/plan_goldens/labels/*.json
  • tests/plan_data_golden_test.py
  • scripts/tools/evaluate_plan_goldens.py

Phase 0 出口门禁所有止损测试通过10 份样本可批量运行;确认和生成接口无法绕过门禁;不开启新架构开关时现有已确认记录仍可查看。

Phase 1Document IR 与字段证据基础P0710 人日)

目标

解决“字符可读但页、表、行、列归属错误”的根因,保留后续对账所需的几何和来源信息。

任务包

P1-A统一文档摄取

关联问题P0-02、P1-01、P1-02、P1-03、P1-11。

  • 新建 api/insurance/document/ingest.py,统一计算 SHA-256、文件类型、页数、存储键和权限
  • 新建 pdf_classifier.py 判断 native/scanned/mixed不再只依赖全文乱码率
  • 按页保存文本块、读取顺序、bbox 和质量,不再使用 120000 字符全局硬截断;
  • OCR 由“最多 40 页”改为按页质量和任务预算调度,超过预算时明确 partial/blocked
  • 缓存键包含文档哈希、parser/OCR/profile/规则/model/prompt 版本;
  • 文档读取失败、加密、超限和低质量返回结构化错误。

P1-B表格恢复与跨页关系

关联问题P0-03、P0-04、P1-04、P1-05。

  • 新建 layout.pytables.py;保留线条、坐标聚类、表头层级、合并单元格和单位;
  • 续页识别使用表格边界、列坐标、表头指纹和页间连续性,不只依赖关键词;
  • 行主键改为 (table_id, scenario_type, policy_year, row_variant),禁止只按 policy_year 去重;
  • source_page 由解析器根据真实块坐标产生,不接受模型孤立给出的页码作为唯一证据;
  • 同一值存在多个候选时全部保留并标为 conflict。

P1-CEvidenceRef 服务

关联问题P1-10、P1-27。

  • 新建 evidence.py 提供字段到 PDF 区域、表格单元格到字段的双向索引;
  • 原文保存必要的最小片段和 hash避免在日志中复制全文
  • 提供受鉴权的页面预览接口和证据定位接口;
  • 证据状态包含 auto/confirmed/rejected/superseded

建议 API

  • GET /api/insurance/documents/{id}
  • GET /api/insurance/documents/{id}/pages/{page}
  • GET /api/insurance/documents/{id}/pages/{page}/preview
  • GET /api/insurance/plan-snapshots/{id}/evidence?fieldPath=...

Phase 1 出口门禁:每个关键金额具有真实页码和 bbox同年份多场景不合并跨页表在金标准中的行召回达到阶段阈值服务端路径不出现在 API 响应。

Phase 2候选合并、人工复核与金标准达标P0812 人日)

目标

让“正确性”取代“完整度”成为确认依据,并让用户真正具备核对能力。

任务包

P2-AExtraction Candidate 与 Reconciliation

关联问题P1-06、P1-07、P1-08、P1-09、P1-10、P1-14、P1-15。

  • 正则、profile 表格提取、OCR、LLM 语义识别均输出候选,不直接覆盖最终值;
  • 候选包含 raw_valuenormalized_valueunitcurrencystatusevidence[]
  • 文件名和所选产品只写入 context_hint;与 PDF 证据不一致时生成 conflict
  • 正则不再因为“有标签”自动压过 LLM/表格结果由证据质量、profile 和业务校验统一评分;
  • LLM 仅负责页面/表头语义、同义词和段落摘要,密集金额优先由表格解析产生;
  • completeness 与 correctness 分开计算,存在关键冲突时最高只能 review_required

P2-B业务校验规则

关联问题P0-02、P0-11、P0-12、P1-13、P1-26。

最少实现:

  • 币种/单位一致;
  • 保单年度与受保人年龄关系;
  • 保证、非保证、总额公式(只在产品规则明确时启用);
  • 场景、提取前后和红利实现率隔离;
  • 身故利益、退保价值、账户价值不可互代;
  • 比较输入的年龄、性别、吸烟、保费、缴费期、保额、币种、附加险和提取方案兼容性;
  • 口径不可比时允许并列展示,但禁止生成排名和“更优”结论。

P2-C复核工作台

关联问题P0-07、P1-27、P1-29。

  • PdfPagePreview.vue 抽成 PPT/海报共享证据预览组件;
  • 宽屏使用 PDF、字段、完整利益表三栏窄屏使用标签页不隐藏关键校验状态
  • 点击字段定位 PDF 页和 bbox点击 PDF 区域反向高亮候选字段;
  • 完整利益表按 scenario_type 分组,支持逐行编辑、冲突比较和证据查看;
  • 人工修改必须填写原因;modificationLog 通过后端持久化为 override不再只存前端内存
  • 所有阻断项集中展示,确认按钮展示具体不可用原因。

Phase 2 出口门禁30 份双人标注样本完成;关键标量精确率不低于 99.5%;金额单元格精确率和目标行召回率不低于 99.0%;同年多场景污染为 0所有导出候选金额证据覆盖率 100%。未达门槛不得进入默认解析路径。

Phase 3统一 PlanData Snapshot 与海报/PPT 投影P069 人日)

目标

消除海报和 PPT 两套计划书事实,使任何修改、生成和历史记录都指向唯一快照。

任务包

P3-APlanData Schema 和不可变快照

关联问题P0-01、P0-14、P0-15、P1-28、P1-29。

  • 定义版本化 PlanData JSON Schema
  • 身份、保单、受保人、分场景利益、提领、附加险、假设、校验结果分区;
  • 所有字段使用 FieldValue 或等价结构;
  • 通过 document_id/snapshot_id 更新,不再按 pdfName 匹配;
  • 确认、修改、撤销确认都创建新版本并保留 previous link
  • 快照 hash 使用规范化 JSON写入历史和生成任务。

P3-B海报 Projection

关联问题P0-01、P0-05、P1-12、P1-14、P1-15。

  • 删除海报独立紧凑解析在新链路中的事实职责;
  • extract_for_poster 仅在兼容开关下保留,标记 deprecated
  • 新建 plan_data/projections.py::to_poster_projection,里程碑值只从已确认完整表投影;
  • 文案事实、产品手册规则和计划书事实分开传递,禁止互相覆盖;
  • 海报渲染后抽取文本并与 projection 对账。

P3-CPPT DeckContract Projection

  • Normalizer 改为纯 PlanData -> DeckContract 转换,不做业务猜测;
  • DeckContract 保留字段状态、币种、单位和 evidence id
  • 图表只接收可比较且已确认的 series
  • 不允许渲染器自行推导缺失值。

P3-D旧数据策略

  • 旧记录只读展示;
  • 需要重新生成时提示“需使用当前解析器重新解析并确认”;
  • 不自动把旧 confirmed_data 转为可信快照;
  • 可将旧数据导入 draft candidate但状态必须是 review_required

Phase 3 出口门禁:同一 snapshot 的海报和 PPT 基础字段、币种、10/20/30 年值一致率 100%;任何修改生成新版本;成品可追溯到唯一 snapshot hash。

Phase 4PPT 场景、策略与模板可执行化P0/P1812 人日)

目标

让后台配置真实、确定地控制 PPT 的业务页面、比较规则和视觉承载。

任务包

P4-AScenarioDefinition 与服务端解析器

关联问题P0-08、P0-09、P0-10、P1-19、P1-25、P2-02、P2-03。

  • 实现场景 selector文件数量、险种/产品/公司组合和客户条件;
  • 实现 pageSpecs、metricSpecs、comparisonYears、fallback
  • 前端删除硬编码场景检测,只展示服务端 /resolve-scenario 结果;
  • 用户明确选择已发布场景时优先;不兼容则阻断,不静默改为硬编码场景;
  • 多个同优先级命中或无匹配时阻断并返回 matchTrace
  • 后台补齐编辑、复制版本、校验、发布、停用和规则试跑。

P4-BGenerationPolicy

关联问题P1-26。

  • 明确兼容性、计算、缺失、排名、结论、阻断和降级策略;
  • 不同口径只能并列展示时,在 pageSpec 中使用 nonComparableReason
  • IRR、倍数和排名所用公式、输入字段和精度必须版本化
  • 不允许策略写回或修改 PlanData。

P4-CTemplateDefinition 与发布门禁

关联问题P1-22、P1-23、P1-24、P2-04、P2-08。

  • 每种 page_type 定义语义槽位、容量、溢出规则和样本;
  • 上传 PPT 后校验必需 page_type、slot、唯一映射、字体、图表和页容量
  • 取消页面匹配失败时静默取第一张未使用页面;
  • clone_ready 改为校验结果,不得仅因文件能打开就设为 true
  • 不再无差别清除模板文本/图表/表格;只替换已声明的业务 slot
  • 风格选项要么提供真实独立主题,要么合并重复选项,避免后台虚假差异。

P4-D唯一合并规则

运行时顺序固定为:

  1. 解析并冻结 ScenarioDefinition
  2. 使用 pageSpecs 形成业务页面清单;
  3. 验证 GenerationPolicy
  4. 将 page_type 映射到 TemplateDefinition slot
  5. 无槽位或容量超限则阻断;
  6. 生成 DeckContract
  7. 渲染器严格按合并结果执行。

不得再以 scenarioSlides or slidesConfig 这种隐式优先级决定业务逻辑。

Phase 4 出口门禁:修改场景比较年份和 pageSpecs 后样本输出按新版本变化;修改模板映射后页面顺序变化;不兼容输入可解释地阻断;同输入同版本结构确定;发布配置应用测试 100% 通过。

Phase 5冻结任务输入、输出对账与任务可靠性P069 人日)

目标

保证提交时预览、Worker 实际输入和最终成品一致,并让错误成品无法显示为成功。

任务包

P5-A完整输入冻结

关联问题P0-14、P0-15、P1-20、P1-21。

任务创建时冻结:

  • PlanData 内容、ID、版本、hash
  • 源 PDF hash
  • ScenarioDefinition 内容、版本、hash
  • GenerationPolicy 内容、版本、hash
  • TemplateDefinition 内容、版本、hash 和源资产 hash
  • renderer version
  • 用户选择、人工覆盖记录、brand policy
  • 提交时 draft_revision

Worker 只读 input_snapshot_json 或不可变版本记录,不查询当前 session.extractions_json、当前模板配置或当前场景。完成时使用 submit_revision:若会话已变化,则标记 stale,不得把 generated_revision 写成当前草稿版本。

P5-BPPTX 数值对账

关联问题P0-16。

  • 生成后解析 PPTX XML
  • 校验所有可见金额文本、表格单元格和图表 series
  • 对账键至少包含 field_path/page_type/series/category/currency/value
  • 区分格式化差异与数值差异;
  • P0 数值缺失、多余、币种错误或冲突直接失败;
  • 失败任务保留诊断报告,不提供成功下载入口。

P5-C海报数值对账

  • 对 render document 和最终 DOM/导出文本做字段清单对账;
  • AI 背景不得包含业务文字;
  • 导出尺寸、裁切、文本溢出和空模块纳入门禁。

P5-D任务心跳、幂等与重试

关联问题P2-05、P2-06。

  • Worker 定期更新 heartbeat_at;超时判断使用心跳而非创建时间;
  • 幂等键包含 artifact type、snapshot hash、scenario/template/renderer hash
  • 重试复用同一冻结输入,禁止重试时重新解析或重新选模板;
  • parse_worker.py 明确标记 deprecated确认无引用后单独删除不与主修复混改。

Phase 5 出口门禁排队期间修改会话或后台配置不改变已提交任务PPT/海报所有输出金额对账 100%;任何 P0 对账失败都不会产生可下载成功成品;任务可按冻结输入重放。

Phase 6监控、隐私、灰度与正式切换P1/P257 人日)

目标

让准确率、异常和数据生命周期持续可管理,并安全替换旧链路。

任务包

P6-A质量看板与结构化日志

关联问题P2-07。

解析指标:

  • 文档 hash、PDF 类型、页数、profile 和版本;
  • 原生/OCR 页数、耗时、字段候选数、冲突数;
  • 表格数、跨页表数、未识别列数;
  • 自动通过、人工修改、阻断数量和按字段修改率。

生成指标:

  • snapshot/scenario/policy/template/renderer 版本与 hash
  • matchTrace、页面类型、降级、对账和视觉检查;
  • 队列时间、执行时间、心跳、重试和最终状态。

指标需可按保险公司、产品、版式、PDF 类型和解析版本聚合。

P6-B隐私、访问与清理

关联问题P1-17、P1-30。

  • PosterCaseUpload.to_dict() 不再返回服务器绝对路径;
  • PDF 仅通过鉴权预览/下载接口访问;
  • 日志禁止写原始全文、完整客户身份和大段解析内容;
  • 为源 PDF、IR、候选、快照、证据、海报、PPT 和日志分别配置留存期;
  • 到期清理同时覆盖数据库和对象文件,并留下脱敏审计;
  • 金标准集仅使用获批脱敏样本。

P6-C双轨灰度与切换

  • 功能开关建议:DOCUMENT_IR_V1PLAN_SNAPSHOT_V1SCENARIO_ENGINE_V2OUTPUT_RECONCILIATION_V1
  • 先影子解析,不影响用户输出;比较新旧字段并记录差异;
  • 达到金标准门槛后按保司/profile 灰度到 10% -> 30% -> 100%
  • 新链路稳定后关闭紧凑解析和旧场景检测的默认入口;
  • 旧链路仅作为短期只读回放,不允许产生新成品。

Phase 6 出口门禁指标、报警、权限和清理任务可验证100% 流量切换后连续观察期无 P0 对账错误;旧写路径关闭;应急回滚可在不丢失新快照的情况下执行。

7. API 改造清单

7.1 文档与证据

方法 路径 用途 关键约束
POST /api/insurance/documents 统一上传并创建 Document 返回 documentId不返回绝对路径
GET /api/insurance/documents/{id} 文档状态和质量 仅所有者/授权角色可见
GET /api/insurance/documents/{id}/pages/{page}/preview PDF 页预览 鉴权、限时、可审计
GET /api/insurance/documents/{id}/tables 表格和跨页关系 支持 scenario/page 过滤
POST /api/insurance/documents/{id}/extract 创建解析任务 接收 profile hint不允许覆盖文档事实

7.2 PlanData 与复核

方法 路径 用途 关键约束
GET /api/insurance/plan-snapshots/{id} 获取快照与校验结果 返回 schemaVersion、hash、status
GET /api/insurance/plan-snapshots/{id}/evidence 查询字段证据 fieldPath 必填或分页
PATCH /api/insurance/plan-snapshots/{id}/draft 编辑草稿 乐观锁 + overrideReason
POST /api/insurance/plan-snapshots/{id}/validate 执行业务校验 不改变 confirmed 版本
POST /api/insurance/plan-snapshots/{id}/confirm 生成确认版本 冲突为零、关键证据齐全
GET /api/insurance/plan-snapshots/{id}/poster-projection 海报只读投影 不允许调用端覆盖事实
GET /api/insurance/plan-snapshots/{id}/deck-contract PPT 只读投影 返回可比较性和缺失状态

7.3 场景与模板

方法 路径 用途
POST /api/insurance/ppt/scenarios/resolve 基于 snapshot 列表返回唯一场景和 matchTrace
POST /api/insurance/admin/ppt/scenarios/{code}/versions 创建 draft 版本
POST /api/insurance/admin/ppt/scenario-versions/{id}/validate 使用样本试跑
POST /api/insurance/admin/ppt/scenario-versions/{id}/publish 发布不可变版本
POST /api/insurance/admin/ppt/template-versions/{id}/validate 校验 page_type、slot、容量和样本渲染
POST /api/insurance/admin/ppt/template-versions/{id}/publish 发布模板版本

7.4 生成

现有 PPT/海报生成入口保留,但请求改为携带 snapshotId、可选的已发布 scenarioVersionIdtemplateVersionId。响应和任务详情新增:

  • submitRevisionsnapshotHash
  • scenarioVersionpolicyVersiontemplateVersionrendererVersion
  • matchTracereconciliationStatusvisualCheckStatus
  • resultState=current|stale|failed

错误码至少区分:数据未确认、证据不足、存在冲突、场景多匹配、场景不匹配、模板槽位缺失、输入不兼容、输出对账失败、视觉门禁失败。

8. 前端实施计划

8.1 复核工作台

  • PPT 与海报共用一个证据复核核心组件,业务外壳可分别保留;
  • 显示字段状态:自动提取、人工确认、冲突、缺失、推导;
  • 未知值显示 ,不预填 0
  • 金额编辑同步选择币种/单位,避免只改数字;
  • 完整利益表按场景标签分组;
  • 提交确认前展示阻断项数量、警告项数量和人工覆盖数量;
  • 后端返回错误使用字段路径定位到具体控件。

8.2 PPT 生成页

  • 删除本地场景计算,调用服务端 resolver
  • 展示最终场景、版本、命中规则和不可比较原因;
  • 模板列表只显示服务端返回的兼容模板;
  • 管理员/用户明确选择场景时,显示“已选择”而不是被后台替换;
  • 历史成品展示数据、场景、模板版本以及 current/stale 状态。

8.3 管理后台

  • 场景:选择规则、比较条件、指标、年份、页面、缺失/结论策略;
  • 模板page_type、semantic slot、容量、溢出规则、预览和校验报告
  • 发布前必须选样本集试跑;
  • 已发布版本只读;编辑操作自动创建新 draft
  • 明确展示“验证失败不可发布”的原因。

8.4 可访问性和响应式

  • 键盘可完成字段跳转、冲突选择、表格编辑和确认;
  • 状态不能只依赖颜色;
  • PDF bbox 高亮有文本说明;
  • 小屏不强行三栏,使用固定操作栏和标签切换;
  • 长表使用虚拟滚动或分页,但不得只加载里程碑行。

9. 测试与质量门禁

9.1 测试分层

层级 重点 必须覆盖
单元测试 数值语义、候选合并、业务规则、hash 0/None/非法值、场景隔离、币种/单位、公式
Schema 测试 Document IR、FieldValue、PlanData、配置版本 向后兼容、未知字段、版本拒绝
API 测试 上传、确认、覆盖、发布、生成 越权、绕过前端、乐观锁、错误码
金标准测试 真实 PDF 精确值和证据 标量、每个表格单元格、页码、bbox、场景
集成测试 PDF -> confirmed snapshot -> 海报/PPT 同快照一致、任务冻结、重放
输出对账 PPTX XML、海报 DOM/导出文本 文本、表格、图表 series、币种
视觉回归 页面图片差异和布局探针 溢出、遮挡、裁切、空图、字体
稳定性 队列、重试、并发、清理 心跳、幂等、旧版本、孤儿文件

9.2 金标准样本矩阵

  • 原生文本、全扫描、混合 PDF
  • 单栏、多栏、横向页;
  • 有线框/无线框表、合并表头;
  • 单页表、跨页表、续页无表头;
  • 中文、英文、中英混合;
  • 储蓄、重疾、IUL
  • 同一年多场景、提取前后、不同演示利率;
  • 正确文件名、错误文件名、无意义文件名;
  • 加密、损坏、超长、OCR 模糊/倾斜/低对比度。

9.3 强制验收指标

指标 门槛 阻断级别
关键标量精确率 >= 99.5% 未达不得默认开启新解析
金额表格单元格精确率 >= 99.0% 未达不得默认开启新解析
目标利益行召回率 >= 99.0% 未达不得默认开启新解析
导出金额正确证据覆盖率 100% 单次任务失败
同年份不同场景污染 0 发布阻断
未解决冲突自动确认 0 确认阻断
未知值静默变 0 0 测试/发布阻断
海报与 PPT 同快照一致率 100% 发布阻断
PPT 与 DeckContract 数值一致率 100% 单次任务失败
已发布场景/模板应用测试 100% 配置发布阻断
生成物版本追溯率 100% 发布阻断

9.4 建议回归命令

pytest -q tests/ppt_poster_optimization_test.py \
  tests/ppt_template_asset_test.py \
  tests/ppt_task_lifecycle_test.py \
  tests/ppt_parse_route_test.py \
  tests/poster_render_document_test.py \
  tests/poster_render_validation_test.py \
  tests/user_product_material_test.py

pytest -q tests/plan_data_*_test.py tests/document_ir_*_test.py tests/output_reconciliation_*_test.py

cd frontend
npm run lint
npm run build

部署环境另行执行 LibreOffice/Office/WPS 打开验证和页面渲染对比;本地缺少 python-pptx 时不得把相应跳过项当作通过。

10. 发布、灰度与回滚

10.1 发布顺序

  1. 上线 Phase 0 门禁和兼容代码;
  2. 上线 migrate_036~037 与只写不读的 Document/Snapshot 基础设施;
  3. 开启影子解析,旧链路继续服务,收集差异;
  4. 达到金标准门槛后按 profile 小流量读取新快照;
  5. 上线版本化场景/模板,但先只发布内置样本验证通过的版本;
  6. 上线任务冻结和输出对账,先 warning 模式观察,再切 failure 模式;
  7. 关闭旧紧凑解析、旧场景检测和旧任务可变读取;
  8. 观察稳定后清理 deprecated 写路径。

10.2 回滚原则

  • 数据迁移只增表/增列,业务回滚不删除新数据;
  • 功能开关按 profile 或租户回退,不回写旧确认状态;
  • 已生成的新快照和审计记录保留,可在修复后重放;
  • 对账 failure 模式可临时回退到“阻断下载、允许内部预览”,不得回退为对外成功交付;
  • 已发布配置不修改,通过切换当前版本指针回滚;
  • 任何回滚都记录操作者、原因、版本和影响范围。

10.3 灰度停止条件

  • 任一错误金额进入成品;
  • 同一快照海报/PPT 值不一致;
  • 新解析人工修改率显著高于基线;
  • 场景多匹配、模板错配或任务输入漂移;
  • 鉴权绕过、绝对路径泄露或清理误删;
  • P95 解析/生成时延超过约定容量且无法通过限流缓解。

11. 工作量、人员与里程碑

11.1 粗略工作量

阶段 预计人日 主要角色
Phase 0 止损与基线 46 后端、前端、QA、业务 SME
Phase 1 Document IR 710 后端/PDF、QA
Phase 2 合并与复核 812 后端/PDF、前端、QA、业务 SME
Phase 3 统一快照与投影 69 后端、前端、QA
Phase 4 场景与模板 812 后端、前端、PPT、QA
Phase 5 冻结与输出门禁 69 后端、PPT/前端、QA
Phase 6 运营与切换 57 后端、运维、安全、QA
合计 4465 人日 不含业务样本收集等待时间

建议配置2 名后端(其中 1 名熟悉 PDF/PPTX、1 名前端、1 名 QA、1 名兼职保险业务 SME、1 名兼职运维/安全。该配置下预计 710 个自然周;如果仅 1 名开发串行推进,应按阶段门禁排期,不压缩金标准标注和灰度观察。

11.2 里程碑

  • M1Phase 0 完成,已知高危错误停止扩散;
  • M2Document IR 和证据定位可用30 份金标准建立;
  • M3海报/PPT 统一消费 confirmed snapshot
  • M4后台场景和模板版本真实控制生成
  • M5任务可重放输出对账失败关闭
  • M6全量切换、留存闭环、旧写路径关闭。

每个里程碑必须单独评审,不以“代码已合并”代替完成。

12. 风险、依赖与需要确认的业务决策

风险/决策 影响 处理方式
缺少获批真实 PDF 无法量化准确率 Phase 0 即启动脱敏和双人标注;样本不到位不发布新解析
不同保司版式差异大 通用解析准确率波动 profile + 通用回退;按 profile 灰度
bbox/表格 IR 数据量大 存储和查询成本 按页 JSON、压缩、分层留存、避免逐字符入库
OCR 成本与时延 队列拥塞 按页质量调度、预算和并发限制、心跳
业务公式口径不明确 校验误报或错误推导 所有公式进入版本化 GenerationPolicy由 SME 签字
模板缺少语义槽位 无法自动适配旧资产 旧模板作为 draft逐个补 slot 并样本验证
旧记录无法可靠迁移 历史再生成受限 旧记录只读;再生成前重新解析确认
失败关闭降低短期成功率 用户感知任务变“更容易失败” 明确错误原因,提供修复入口;不以错误成品换成功率
多版本系统增加管理成本 管理员操作复杂 只提供 draft/validate/publish 三步,不引入无需求的审批流

开发前需业务明确:

  1. 各险种关键必填字段及合理范围;
  2. 哪些公式可用于校验,哪些仅可作为提示;
  3. 同类比较与跨类并列展示的兼容条件;
  4. 非保证利益的情景命名、演示利率和提取前后口径;
  5. 源 PDF、快照、成品和日志的留存天数
  6. 金标准样本的授权、脱敏和双人复核负责人。

13. 问题覆盖矩阵

审计编号 计划任务 解决方式 验收位置
P0-01 P3-B/P3-C 海报/PPT 共用 confirmed snapshot Phase 3
P0-02 P1-A/P1-B/P2-B 版面 IR、表格和业务校验 Phase 2
P0-03 P1-B 复合行键保留场景 Phase 1
P0-04 P1-B 跨页表连续性识别 Phase 1
P0-05 P0-A/P3-B 收紧回退并删除独立事实解析 Phase 3
P0-06 P0-A 后端确认 schema 和冲突门禁 Phase 0
P0-07 P2-C PDF、字段、完整表并排复核 Phase 2
P0-08 P0-C/P4-D 临时诚实提示 + 唯一合并规则 Phase 4
P0-09 P0-C/P4-A 服务端场景解析与 matchTrace Phase 4
P0-10 P4-A/P4-B 可执行场景和生成策略 Phase 4
P0-11 P0-B/P2-B nullable/FieldValue 语义 Phase 2
P0-12 P0-B 删除错误字段兜底 Phase 0
P0-13 P0-B 统一币种格式化 Phase 0
P0-14 P3-A/P5-A 快照与完整任务冻结 Phase 5
P0-15 P5-A 使用 submit_revision 标记结果 Phase 5
P0-16 P5-B/P5-C 输出数值对账失败关闭 Phase 5
P0-17 P0-D/P2 真实 PDF 金标准 Phase 2
P1-01 P1-A 按页处理,取消全文硬截断 Phase 1
P1-02 P1-A OCR 按页质量和预算调度 Phase 1
P1-03 P1-A 版面质量触发 OCR Phase 1
P1-04 P1-B/P2-A 强 schema + 表格优先 Phase 2
P1-05 P1-C 真实 bbox 证据 Phase 1
P1-06 P2-A 候选合并,不静默覆盖 Phase 2
P1-07 P2-A 文件名仅作为 context hint Phase 2
P1-08 P0-A/P2-A 产品选择只参与冲突检测 Phase 2
P1-09 P2-A/P2-B correctness 与 completeness 分离 Phase 2
P1-10 P1-C 字段级 EvidenceRef Phase 1
P1-11 P1-A 完整版本化缓存键 Phase 1
P1-12 P0-B 显式 None 判断 Phase 0
P1-13 P0-B/P2-B 禁止推导值冒充合同值 Phase 2
P1-14 P0-B/P3-B 字段语义统一 Phase 3
P1-15 P0-B/P2-A 冲突替代覆盖 Phase 2
P1-16 P0-A PDF 产品一致性门禁 Phase 0
P1-17 P6-B 鉴权接口替代绝对路径 Phase 6
P1-18 P0-C 全产品满足模板条件 Phase 0
P1-19 P4-A 删除前端硬编码场景 Phase 4
P1-20 P0-C/P5-A 稳定排序并冻结实际模板 Phase 5
P1-21 P5-A 保存实际模板版本 Phase 5
P1-22 P4-C 仅替换语义槽位 Phase 4
P1-23 P4-C 页面无法匹配即阻断 Phase 4
P1-24 P4-C validate/publish 门禁 Phase 4
P1-25 P4-A comparisonYears 可配置 Phase 4
P1-26 P2-B/P4-B 完整兼容策略 Phase 4
P1-27 P1-C/P2-C PDF 双向定位 Phase 2
P1-28 P3-A document/snapshot ID 更新 Phase 3
P1-29 P2-C/P3-A 后端持久化 override Phase 3
P1-30 P6-B 全链路留存和清理 Phase 6
P2-01 P0-A parsed 与 confirmed 状态分离 Phase 0
P2-02 P4-A 完整场景版本编辑 Phase 4
P2-03 P0-C/P4-A 前端能力与文案一致 Phase 4
P2-04 P4-C 真实主题或合并重复风格 Phase 4
P2-05 P5-D 旧 Worker 退役 Phase 5
P2-06 P5-D 心跳超时 Phase 5
P2-07 P6-A 解析质量看板 Phase 6
P2-08 P0-D/P4-C/P5 视觉回归和输出门禁 Phase 5

14. Definition of Done

只有同时满足以下条件,本次全链路修复才算完成:

  • 55 项审计问题均有关闭证据或经批准的延期记录;
  • 30 份以上真实脱敏样本金标准通过,关键指标达到第 9.3 节门槛;
  • 海报和 PPT 不再独立解析同一计划书事实;
  • 所有新生成任务只接受 confirmed snapshot
  • 未知、冲突和推导值不会静默作为真实 0 或合同值输出;
  • 后台场景、策略和模板均经过版本化发布与样本验证;
  • Worker 不读取提交后的可变会话、场景和模板状态;
  • PPT/海报成品数值对账 100%P0 差异失败关闭;
  • API 不暴露服务器绝对路径,源文件访问有鉴权;
  • 源 PDF、IR、快照、证据、成品和日志留存清理经过 dry-run 与实删验证;
  • 前端 lint/build、后端单元/集成/金标准/输出对账/视觉回归全部通过;
  • 灰度、回滚、监控和运维手册已完成并演练;
  • 相关 API、数据字典、测试用例和用户操作文档同步更新。

15. 建议立即启动的首个迭代

首个迭代只做以下内容,避免同时开太多架构分支:

  1. 完成 P0-A海报后端确认/生成门禁及绕过前端测试;
  2. 完成 P0-BNone/0、错误字段兜底、币种的止损修复;
  3. 完成 P0-C模板全量适用条件、稳定排序和后台提示
  4. 建立 10 份开发金标准、标注规范和批量评测脚本;
  5. 评审并冻结 Document IR、FieldValue、PlanData Snapshot 三份 schema再开始 migrate_036~037

首个迭代结束时必须提供变更清单、测试证据、10 份样本基线、未解决冲突清单、下阶段 schema 评审记录。没有这些产出,不进入 Document IR 开发。

16. 与既有文档的关系

  • PDF计划书解析后续演进详细计划_20260802.md:作为 parser profile、金标准和未知保司接入的详细参考本计划补充统一快照及海报/PPT 消费边界。
  • 海报生成工作台完整重构修复计划.md:作为海报画布、资产、导出和工作台交互参考;事实模型统一改用本计划 PlanData Snapshot。
  • 保险智能客服系统_PPT与海报优化修复计划书_20260731.md:作为已完成/历史专项修复记录;新发现的配置覆盖和可复现性问题以本计划为准。
  • PPT与海报编辑体验及解析问题专项优化修复计划书_20260731.md:继续作为局部 UI 与编辑体验参考;确认门禁、证据和版本规则以本计划为准。
  • PPT多文件上传比对功能_详细修复计划书.md:继续作为上传和多文件交互参考;比较兼容性和场景解析迁移到 ScenarioDefinition/GenerationPolicy。

本计划不删除或覆盖既有文档,通过统一的阶段门禁和问题覆盖矩阵把它们纳入同一实施路线。