Files
fa-agent/docs/excel-formula-export-plan.html
2026-09-26 01:12:10 +08:00

46 lines
30 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>财务 Agent · Excel 公式导出实施计划</title>
<style>
:root{color-scheme:light;--ink:#202725;--muted:#58645f;--line:#d8dfdc;--green:#17664f;--red:#ac3440;--bg:#f5f7f6}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.8 system-ui,-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;letter-spacing:0}header{background:#fff;border-bottom:3px solid var(--green);padding:40px 24px 28px}main,header>div,footer{max-width:1120px;margin:auto}h1{font-size:32px;line-height:1.35;margin:8px 0 16px}h2{font-size:24px;margin:0 0 18px}h3{font-size:18px;margin:24px 0 8px}p{margin:10px 0}small,.muted{color:var(--muted)}main{padding:0 24px}section{padding:32px 0;border-bottom:1px solid var(--line);scroll-margin-top:16px}nav{padding:22px 0;border-bottom:1px solid var(--line);display:flex;gap:12px 24px;flex-wrap:wrap}a{color:var(--green);text-underline-offset:4px}ul,ol{padding-left:24px}li{margin:8px 0}.notice{border-left:4px solid var(--red);padding:10px 18px;background:#fff}.recommend{border-left:4px solid var(--green);padding:10px 18px;background:#fff}.table-wrap{overflow:auto;max-width:100%;border:1px solid var(--line)}table{border-collapse:collapse;width:100%;min-width:720px;background:#fff;font-size:14px}th,td{text-align:left;vertical-align:top;padding:13px 15px;border-bottom:1px solid var(--line)}th{background:#eaf0ed}tr:last-child td{border-bottom:0}code{font:13px/1.7 ui-monospace,SFMono-Regular,Consolas,monospace;overflow-wrap:anywhere}pre{padding:16px;background:#eaf0ed;overflow:auto;max-width:100%;line-height:1.7}pre code{white-space:pre;overflow-wrap:normal}.tag{font-size:13px;font-weight:700;color:var(--red)}.grid{display:grid;grid-template-columns:1fr 1fr;gap:24px}.grid>div{min-width:0}footer{padding:28px 24px 48px;color:var(--muted);font-size:14px}strong{font-weight:650}@media(max-width:650px){header{padding:26px 18px}main{padding:0 18px}h1{font-size:26px}h2{font-size:21px}.grid{grid-template-columns:1fr;gap:0}section{padding:25px 0}}@media print{body{background:white;font-size:11pt}header{padding:0 0 16px}main{padding:0}nav{display:none}section{break-inside:auto;padding:18px 0}h2,h3{break-after:avoid}tr{break-inside:avoid}.table-wrap{overflow:visible}table{min-width:0;font-size:9pt}pre{white-space:pre-wrap}pre code{white-space:pre-wrap}footer{padding:16px 0}}
</style>
</head>
<body>
<aside style="max-width:1120px;margin:16px auto;padding:16px 24px;background:#fff4e5;border-left:4px solid #a95712"><strong>当前状态复核 · 2026-09-24:</strong>本页下方保留 2026-09-23 的历史实施方案,不能再据此判断当前功能状态。方案中的公式工作簿、说明页、异步导出和对话新增列已经实现;LibreOfficeDev 小样本重算已验证,Microsoft Excel Windows/Mac 尚未验收。当前限制为 100,000 行/200 组,332,830 行原附件公式工作簿、真实 AI 合规、财务签字和商业部署仍未通过。详情见 <a href="acceptance.md">验收状态与剩余门禁</a>。</aside>
<aside style="max-width:1120px;margin:16px auto;padding:16px 24px;background:#fff4e5;border-left:4px solid #a95712"><strong>状态更新 · 2026-09-24:</strong>本计划中的公式工作簿、说明页、异步导出及对话新增公式列已实现。新增列追问/导出专项、workspace 桌面和手机测试及后端测试通过。下方内容是实施前方案记录;目前仍未通过 Microsoft Excel 动态数组重算验收,LibreOffice 人数公式存在兼容错误;公式导出限制 100,000 行/200 组,无法一次覆盖 332,830 行附件;真实 AI 联调、财务口径签字及商业部署安全门禁未完成。因此公式版尚不具备生产发布资格。详见 <a href="acceptance.md">验收状态与剩余门禁</a>。</aside>
<header><div><small>TRACEIQ / 财务 Agent / 工程实施与验收方案</small><h1>Excel 公式导出实施计划</h1><p>从只读证据快照,升级到可解释、可重算、可对账的财务工作簿。</p><p class="tag">状态:待实施 · 本文不是功能已完成或生产验收通过的证明</p><small>核查日期:2026-09-23 | 交付范围:计划文档,不修改现有导出逻辑</small></div></header>
<main>
<nav aria-label="目录"><a href="#current">现状证据</a><a href="#decisions">设计选择</a><a href="#workbook">工作簿结构</a><a href="#formulas">公式与口径</a><a href="#precision">精度策略</a><a href="#editing">可重算边界</a><a href="#security">安全与性能</a><a href="#implementation">实施步骤</a><a href="#tests">测试与门禁</a><a href="#questions">待确认事项</a></nav>
<section id="current"><h2>01 / 核查结论:目前不含公式</h2><div class="notice"><strong>当前 XLSX 导出不满足本次需求。</strong><p>现有实现将每个单元格转换为字符串,并明确设置为文本类型。导出的收入、成本和毛利贡献是结果快照,没有可重算公式,也没有完整的行列字典和操作说明。</p></div><div class="table-wrap"><table><thead><tr><th>核查对象</th><th>已存在的行为</th><th>与目标的差距</th></tr></thead><tbody><tr><td><code>finance/views.py · export()</code></td><td>一张“证据明细”;前四行含版本 SHA、筛选上下文、ROI 口径、导出时间;所有值写为文本。</td><td>没有公式计算层、汇总报表或说明页。</td></tr><tr><td><code>tests/test_finance.py · test_excel_export_precision_and_formula_safety</code></td><td>明确断言所有单元格都不是公式,验证高精度金额及注入保护。</td><td>只能证明证据快照行为正确,不能证明公式导出正确。</td></tr><tr><td><code>frontend/src/dialogs.tsx · EvidenceDialog</code></td><td>选择 XLSX 下载证据明细。</td><td>没有公式版选择、兼容性说明、精度提示或异步状态。</td></tr><tr><td>规模与参考附件</td><td>现有单次导出上限 100,000 行;附件共有 332,830 行。</td><td>不能通过现有接口一次导出原附件全部明细。</td></tr></tbody></table></div><p>已运行的两项针对性测试:<code>test_excel_export_precision_and_formula_safety</code>、<code>test_xlsx_double_header_and_lookup</code>,结果 <strong>2 passed(1.59 秒)</strong>。后者验证导入双表头与毛利率匹配,不是 Excel 公式重算测试。</p><p>保留金额文本并非无意义限制:系统使用高精度 Decimal,而 Excel 普通数值只有约 15 位有效数字。新方案必须保留证据精度,不能直接把所有字符串改成浮点数。</p></section>
<section id="decisions"><h2>02 / 设计选择与推荐</h2><div class="table-wrap"><table><thead><tr><th>决策</th><th>选项与代价</th><th>推荐</th></tr></thead><tbody><tr><td>导出模式</td><td>A. 替换现有证据导出,破坏旧语义。<br>B. 保留证据快照,新增公式工作簿。</td><td><strong>B</strong>。界面清楚区分“证据快照”和“公式分析工作簿”;CSV 始终是快照,不承诺公式。</td></tr><tr><td>精度</td><td>A. 全部按 Excel 浮点数,丢失高精度证据。<br>B. 精确文本证据 + 数值计算层 + Decimal 对账。<br>C. 宏或自定义高精度插件,兼容、部署及安全成本高。</td><td><strong>B</strong>。明确公式值遵守批准后的精度政策,不声称原生公式保持 24 位小数精确运算。</td></tr><tr><td>公式兼容性</td><td>A. Microsoft 365,支持动态数组去重。<br>B. 旧版 Excel / WPS / LibreOffice,需另做兼容实现及验证。</td><td>先以 <strong>Microsoft 365 桌面 Windows / Mac</strong> 为明确验收目标;网页版另测。其他引擎通过验证后再声明支持,不能以应用跨平台替代工作簿兼容性。</td></tr><tr><td>人数计算</td><td>A. UNIQUE/FILTER 真正按范围去重。<br>B. 服务端预制去重辅助表,修改客户或分组后可能失效。<br>C. 每行 COUNTIFS 扫全表,规模大时开销很高。</td><td>公式版选 <strong>A</strong>,限定报表分组数量并压测;B 仅作明确只读的兼容快照,不能冒充完全可重算。避免 C。</td></tr><tr><td>生成与重算</td><td>A. 现有 openpyxl 写公式,打开 Excel 时重算。<br>B. 导出后由经验证的受控引擎重算并保存缓存。<br>C. 添加写缓存库,但缓存仍是服务器结果。</td><td>第一阶段 <strong>A + 真实 Excel 验收</strong>;首次打开前预览可能空白,必须告知。若业务要求下载即带可信缓存,则 B 是上线前置条件;不把 C 当作重算证明。</td></tr><tr><td>编辑能力</td><td>A. 任意插行、改维度和期间并自动重建全部报表。<br>B. 固定导出范围,允许指定输入修改,结构性变化重新导出。</td><td>首版 <strong>B</strong>,边界容易验证;完整可变结构作为后续独立需求,不暗示已经支持。</td></tr><tr><td>大文件</td><td>A. 同步放宽现有上限。<br>B. 数据库任务 + 独立 worker + 私有文件下载。</td><td>全量附件采用 <strong>B</strong>;复用项目已有任务处理模式,不预先引入新的消息队列。</td></tr></tbody></table></div></section>
<section id="workbook"><h2>03 / 工作簿结构与行列说明</h2><p>输出放在前面,输入和证据放在后面。仅创建实际需要的页,不按每个指标拆页。所有名称均为规划,尚未实现。</p><div class="table-wrap"><table><thead><tr><th>工作表</th><th>行与列的含义</th><th>内容与用途</th></tr></thead><tbody><tr><td>分析汇总</td><td>每行一个指标或已选维度分组;列为本期、基期、差额、变化率、单位、可用状态。</td><td>汇总金额、去重人数、比率由明细或计算结果引用产生;非加法指标不合计子组值。页首注明范围、期间、版本及模拟状态。</td></tr><tr><td>使用说明</td><td>按主题分行:范围、粒度、字段、公式、操作、限制。</td><td>字典列包括名称、业务含义、数据类型、单位、来源字段、可否修改、空值含义、公式与示例;另附版本、时区和支持的 Excel 版本。</td></tr><tr><td>参数与口径</td><td>每行一个参数或产品毛利率;列为当前值、含义、来源、是否可改。</td><td>收入映射、ROI 分支、自营产品集合、毛利率、精度政策;首版期间及筛选锁定。允许的模拟参数必须明确标识。</td></tr><tr><td>计算明细</td><td>一行对应一个导入后的 Fact,保留来源定位键;不是一位客户或一次就诊。</td><td>期间、维度、去标识客户 token、基础数值、原价、毛利来源、适用毛利率、毛利公式、缺失标志等;Excel Table 管理引用范围。</td></tr><tr><td>原始证据</td><td>与计算明细一一对应;金额和标识保留精确文本。</td><td>授权范围内的来源行、字段映射及原值;不可把完整患者原始信息无差别复制出去。工作表保护只防误操作,不是加密或权限控制。</td></tr><tr><td>对账检查</td><td>每行一个指标及范围;列为服务器精确文本、批准精度的参考数值、公式结果、差异、阈值和检查状态。</td><td>包含行数、缺失数、总分一致性、公式覆盖与精度警告;此页仅观察结果,不反向驱动业务公式。</td></tr></tbody></table></div><h3>说明页必须回答的问题</h3><ul><li>本文件覆盖哪个数据版本、期间、组织及筛选?这是授权范围快照,不代表整院所有数据。</li><li>金额单位是什么?百分比以小数储存;升单率变化“百分点”与相对变化率分列,不混用。</li><li>收入、实收、原价、毛利贡献分别指什么?毛利贡献不是净利润,ROI 成本的定义必须写明。</li><li>哪些单元格可改?颜色之外同时提供文字标签、批注和数据验证;公式格保护防止误覆盖。</li><li>如何启用自动计算、重新计算和查看公式?不需要启用宏,不连接外部数据,不回写业务系统。</li><li>空值、0、不可用、缺期和超精度分别是什么意思?遇到不支持函数时不要把错误当成 0。</li><li>修改后如何核对?本地修改是模拟结果,服务器原始快照及其 SHA 不因此变成修改后内容的认证。</li></ul></section>
<section id="formulas"><h2>04 / 公式契约:每个衍生结果可追溯</h2><p>基础事实可以是输入常量;新增衍生金额、计数、比率和差异必须来自真正的公式依赖。禁止用 <code>=12345</code> 或引用隐藏的静态答案来伪装计算。建立“指标 → 输入 → 公式 → 单位 → 缺失策略 → 测试”的显式清单。</p><div class="table-wrap"><table><thead><tr><th>指标</th><th>计算定义</th><th>边界与验收重点</th></tr></thead><tbody><tr><td>收入 / 成本 / 原价</td><td>在指定范围汇总对应基础字段。</td><td>有数据但全为 0 与无数据不同;成本或原价部分缺失时依赖指标不可用,不能只合计非空项。</td></tr><tr><td>毛利贡献</td><td>原始毛利有值时使用该输入;否则收入 × 已匹配产品毛利率;汇总逐行结果。</td><td>必须恢复并记录 direct / lookup / missing 来源。Fact.gross 已是结果,不能直接把它当作原始毛利来伪造推导。必要时从保留的 raw 与映射提取,先做一致性测试。</td></tr><tr><td>ROI</td><td>profit_over_cost:(收入 − 成本) / 成本;gross_less_cost_over_cost:(毛利贡献 − 成本) / 成本。</td><td>遵从数据版本映射;成本 ≤ 0 或任何必要字段缺失时不可用。</td></tr><tr><td>消费人数 / 客单价</td><td>范围内客户 token 去重计数;收入 / 消费人数。</td><td>跨月、跨产品、跨科室重复客户只计一次;有任一缺失客户时与现有后端口径一致地不可用。</td></tr><tr><td>毛利率 / 产品扣率</td><td>毛利贡献 / 收入;收入 / 原价金额。</td><td>先汇总再相除,不能平均行级比率;分母必须大于 0;不把扣率解释为“1 − 比值”。</td></tr><tr><td>自营收入 / 升单率</td><td>配置自营产品范围内收入;该范围客户去重数 / 全部客户去重数。</td><td>产品集合未配置时不可用;不能以自营收入占比替代升单率。</td></tr><tr><td>原价客单价</td><td>原价金额 / 去重人数。</td><td>原价或客户缺失时不可用。</td></tr><tr><td>差额 / 变化率</td><td>本期 − 基期;差额 / ABS(基期)。</td><td>基期 0 不计算变化率;缺期不比较;比率指标同时注明差额单位。</td></tr><tr><td>贡献率</td><td>子组金额差额 / 父组金额差额。</td><td>仅收入、成本、毛利、自营收入等可加指标;父级差额 0 不计算,不为人数或比率伪造加法贡献。</td></tr></tbody></table></div><h3>公式示例与生成规则</h3><p>下列为设计样例。<code>Data</code> 表名、英文列名和命名范围须由模板定义,不能让用户字符串直接拼入公式;状态判断在拥有该指标的计算层生成。公式使用英文函数名和 OOXML 语法,实际写入动态数组需要验证序列化及兼容前缀。</p><pre><code>收入(已确认该期间有记录):
=SUMIFS(Data[Revenue],Data[Period],CurrentPeriod)
成本完整性检查后计算 ROI:
=IF(CostStatus&lt;&gt;"OK",NA(),IF(Cost&lt;=0,NA(),(Revenue-Cost)/Cost))
变化率(先确认本期与基期可比较):
=IF(Comparable=0,NA(),IF(BaselineValue=0,NA(),
(CurrentValue-BaselineValue)/ABS(BaselineValue)))
365 去重人数(先确认范围有记录,且该范围客户字段完整):
=IF(CustomerStatus&lt;&gt;"OK",NA(),
ROWS(UNIQUE(FILTER(Data[CustomerToken],Data[Period]=CurrentPeriod))))
毛利计算分支:
=IF([@GrossSource]="direct",[@GrossInput],
IF([@RateStatus]="OK",[@Revenue]*[@MarginRate],NA()))</code></pre><p>多月、多维度条件需生成对应掩码;上述单月例子不能直接替代完整上下文。全量、大量分组不允许每个明细行扫描全表。公式构建须限制报告维度及单元格数量。</p><p><strong>缺失表达推荐:</strong>计算层用预期的 <code>NA()</code> 阻止错误结果传播;输出页用配套状态显示“不可用:缺成本”等原因。只对已知状态做展示转换,不用 <code>IFERROR(...,0)</code> 吞掉真实公式错误。</p></section>
<section id="precision"><h2>05 / 精度与财务对账</h2><div class="recommend"><strong>推荐:原始精确文本不可变,计算数值有明确精度契约。</strong><p>“显示两位小数”不是“计算只用两位小数”。原附件有 11,990 行收入超过四位小数,不能在导出时静默按行截断。</p></div><ol><li><strong>证据层:</strong>保留 Decimal 原始字符串及来源映射;不经 JavaScript Number 中转。完整金额不可因导出而发生舍入。</li><li><strong>计算层:</strong>先检测有效数字、数量级和累计误差风险,再转换 Excel 数值。把转换策略、舍入位数、舍入模式和发生时点写入文件。</li><li><strong>推荐默认:</strong>分析公式不逐行强制 ROUND;展示金额两位,最终财务比较按批准的规则舍入。若业务要求“每行先舍入再汇总”,另设明确版本口径,不能混用。</li><li><strong>两套参照:</strong>Decimal 对原始业务口径的精确结果用于证据核验;按相同批准数值政策得到的参考结果用于 Excel 计算对账。区别“政策导致的差异”与“实现错误”。</li><li><strong>误差门槛:</strong>逐项规定金额绝对误差、比率误差及人数严格相等。建议金额以最终批准币种最小单位一致为目标;具体阈值必须经真实样本和财务确认,不能先放宽到让测试通过。</li><li><strong>边界处理:</strong>超过可接受数值范围、舍入临界点或差异超阈值时阻止宣称“精确一致”,给出可定位的警告或拒绝公式版,证据版仍保留。</li></ol><p>不推荐启用 Excel“以显示精度为准”,因为它会改变存储值。原生数值公式不能承诺任意 24 位小数精确运算;若确有此硬要求,应保留服务端 Decimal 为权威计算引擎,并另行评估高精度插件,不在首版隐式引入宏。</p></section>
<section id="editing"><h2>06 / 修改后究竟会重算什么</h2><div class="table-wrap"><table><thead><tr><th>操作</th><th>首版承诺</th><th>限制</th></tr></thead><tbody><tr><td>修改允许编辑的收入、成本、原价、直接毛利</td><td>行级毛利、汇总、比率、差额及对账随公式重算。</td><td>原始证据不变;明确标记为本地模拟,不回写服务器。</td></tr><tr><td>修改已有产品的毛利率</td><td>仅 lookup 来源行重算;direct 来源行不受影响。</td><td>不自动新增产品,不静默替换原始毛利。</td></tr><tr><td>筛选或隐藏明细行</td><td>默认仅改变可见行,不改变汇总范围。</td><td>明确 SUMIFS 不随 AutoFilter 改变;若未来要“仅可见行汇总”,作为独立模式实现及测试。</td></tr><tr><td>改变期间、维度、客户、产品集合,追加或删除行</td><td>首版不承诺;从系统重新选择范围并导出。</td><td>Table 能扩展不等于分组报表、去重及状态范围全部正确扩展;锁定结构以防误解。</td></tr><tr><td>修改公式</td><td>默认保护防误操作;允许授权副本解除保护后自行分析。</td><td>解除保护后的结果不属于系统验证范围;工作表保护不是安全边界。</td></tr></tbody></table></div><p>源事实 ID 或稳定行键只用于追溯;本地模拟状态可通过可编辑输入与导出初值比较生成。任何数据版本 SHA 都只标识服务器来源,不能认证已被本地修改的文件。</p></section>
<section id="security"><h2>07 / 安全、权限与 33 万行性能</h2><h3>可信公式与不可信内容严格分离</h3><ul><li>公式只由受控模板生成;原始文本、列名、维度标签保持文本类型。保留并扩展当前 =、+、-、@、制表符及换行注入测试。</li><li>无 VBA、DDE、外部工作簿链接或未经允许的 HYPERLINK;扫描 OOXML 关系和公式,不只检查文件扩展名。</li><li>客户去重使用工作簿内稳定的去标识 token。推荐每次导出独立密钥 HMAC,在所有页统一使用,密钥不写入文件;仍按敏感数据管理,不能称为不可逆匿名化。</li><li>申请、执行、下载三个阶段复核组织和科室权限;执行快照只包含授权行,下载前权限被撤销必须拒绝。原始证据页也不能绕过字段权限。</li><li>下载文件私有存储、短期保留、自动清理;审计记录版本、范围、模式、公式版本、结果及文件哈希,不记录患者原值。</li></ul><h3>任务化导出</h3><p>保留旧同步证据入口的行为;新增公式版任务状态:queued → running → succeeded / failed / expired。请求校验后冻结数据版本、映射、筛选、权限范围、参数和公式版本。worker 用分块迭代处理,临时文件原子完成后才发布;支持超时、失败重试、去重请求、崩溃恢复和过期清理。</p><p>真实附件 332,830 行未超过 Excel 单表 1,048,576 行的限制,但当前接口的 100,000 行限制仍然存在。完整公式版必须另做容量评估,超过支持范围应显式拒绝或提示缩小范围,不能悄悄截断。</p><p>性能基准至少覆盖 1,000 / 100,000 / 332,830 行,测导出耗时、峰值内存、文件大小、首次打开、改值重算、并发排队。记录设备、Excel 版本和数据分组基数;本轮不虚构 SLA。高基数分组达到预算时提示缩小报表范围,不降级为静态结果却仍标“公式版”。</p></section>
<section id="implementation"><h2>08 / 文件级实施步骤</h2><div class="table-wrap"><table><thead><tr><th>阶段</th><th>工作与目标文件</th><th>完成条件 / 依赖</th></tr></thead><tbody><tr><td>P0 · 口径冻结<br>估计 1–2 人日</td><td>复核 <code>finance/analysis.py</code>、<code>finance/importing.py</code> 与原附件;定义精度政策、公式清单、编辑边界及兼容矩阵;确认毛利来源恢复。</td><td>财务确认收入 N / 实收 I、原价、退款、自营产品、成本与 ROI;否则不可冻结黄金结果。</td></tr><tr><td>P1 · 最小公式工作簿<br>估计 2–4 人日</td><td>新增 <code>finance/exporting.py</code> 集中生成模板、状态和公式;复用现有分析口径,不引入通用公式 DSL。先实现小样本汇总、明细、参数、说明和对账。</td><td>每个衍生单元格可追溯;输入/公式/文本写入类型分离;小样本真实 Excel 重算通过。</td></tr><tr><td>P2 · 精度与隐私<br>估计 1–2 人日</td><td>同模块实现精确文本、数值转换预检、毛利来源、客户 token、来源定位和注入防护;增加针对性单元测试。</td><td>Decimal 对账、去重、缺失、恶意文本及越权用例通过;不破坏证据版。</td></tr><tr><td>P3 · 任务与 API<br>估计 2–3 人日</td><td>在 <code>finance/models.py</code> 增加必要的导出任务与迁移;在 <code>finance/views.py</code> 及现有 URL 配置增加提交/查询/下载入口;新增导出 worker 命令,复用导入 worker 的部署模式。</td><td>完整附件能异步生成;崩溃恢复、重试、权限撤销、留存清理可验证。schema_version、mode、context、compatibility 等字段由服务端白名单校验。</td></tr><tr><td>P4 · 网页交互<br>估计 1–2 人日</td><td><code>frontend/src/dialogs.tsx</code>、<code>types.ts</code>、<code>api.ts</code> 按需调整:模式选择、兼容性与精度说明、任务状态、错误反馈、下载和重试。</td><td>桌面/手机可用;不显示无依据百分比;错误不丢失筛选上下文;CSV 与旧 XLSX 行为清晰保留。</td></tr><tr><td>P5 · 引擎与全量验收<br>估计 3–5 人日</td><td>新增 <code>tests/test_exporting.py</code>、扩展 <code>tests/e2e/workspace.spec.ts</code>;编写受控重算与差异报告脚本;更新 <code>docs/acceptance.md</code>。</td><td>下节所有适用门禁有可复现记录;33 万行性能验证及财务签字完成。</td></tr></tbody></table></div><p>合计粗估 <strong>10–18 人日</strong>,用于排期,不是承诺。受控 Excel 测试环境、财务确认和超预算性能优化可能增加日历时间。P1 小样本原型通过后再投入大文件任务流程;各阶段保持可单独审查和回滚。</p><p>兼容 API:旧 <code>format=xlsx</code> 默认仍为证据快照;新公式模式显式申请任务并返回任务 ID。服务端返回实际导出模式与版本,前端不凭文件后缀推断。</p></section>
<section id="tests"><h2>09 / 严格测试与上线门禁</h2><div class="notice"><strong>写入公式不等于公式算对。</strong><p>openpyxl 不执行计算;设置自动重算或 fullCalcOnLoad 也不是测试结果。必须在目标 Excel 引擎执行、保存,再同时读取公式和结果缓存验证。</p></div><div class="table-wrap"><table><thead><tr><th>测试层</th><th>必须覆盖的场景</th><th>通过标准</th></tr></thead><tbody><tr><td>结构与公式覆盖</td><td>每页、命名范围、Table、单元格类型、公式依赖、说明及数据验证;空数据导出。</td><td>衍生区域全覆盖真实公式,基础输入无意外公式;无循环引用、损坏修复提示或外部链接。</td></tr><tr><td>财务黄金样例</td><td>两种 ROI、direct/lookup 毛利、退款、负数、0、缺成本、部分缺字段、缺期、基期0、新增/消失分组。</td><td>与独立 Decimal 预期一致到批准精度;人数完全相等;缺失不能变0。</td></tr><tr><td>客户去重</td><td>同人跨科室/产品/月,重复明细、自营与非自营交集、空客户字段。</td><td>总体不相加子组人数;升单率分子去重正确;缺客户状态与系统一致。</td></tr><tr><td>真实引擎重算</td><td>Excel Windows / Mac;打开重算保存;分别读取 formula 与 data_only;修改收入、成本、原价及毛利率后再次计算。</td><td>受影响链路变化符合独立预期,非依赖指标不误变。扫描 #REF!、#DIV/0!、#VALUE!、#NAME?、#SPILL!;仅允许明确缺失状态对应的 #N/A。</td></tr><tr><td>精度极限</td><td>15位边界、24位小数、极大金额、正负抵消、舍入临界值、33万行累计差异。</td><td>精确文本不变;超出政策明确报警或拒绝;不通过放宽误差掩盖错误。</td></tr><tr><td>注入与越权</td><td>恶意标签/原始公式、工作表名特殊字符、跨组织/科室、任务 ID 猜测、下载前撤权。</td><td>无执行不可信公式、外链或敏感原值泄露;未授权下载拒绝并审计。</td></tr><tr><td>任务可靠性</td><td>重复提交、worker中断、磁盘不足、超时、并发、到期清理。</td><td>无半成品下载、孤儿文件和静默截断;失败可解释,恢复无重复发布。</td></tr><tr><td>前端与兼容回归</td><td>两模式选择、状态、错误重试、下载、移动端;现有 CSV/XLSX。</td><td>浏览器端到端通过;旧证据版仍保持精度与公式注入防护。新公式版测试只允许白名单公式,不删除旧安全断言。</td></tr><tr><td>真实附件全量</td><td>332,830行;2025-08/2026-08及原映射;全量与分组对账。</td><td>行数不缺失,金额满足政策,人数为33,147 / 38,361;缺成本 ROI 不可用,未配置自营范围不擅自补值。</td></tr></tbody></table></div><h3>发布清单(全部待实施验证)</h3><ul><li>□ 口径、精度、编辑范围、支持引擎由财务及产品负责人确认。</li><li>□ 所有指标有公式覆盖与独立数值断言,修改输入后的重算链通过。</li><li>□ 真实 Excel 重算证据包含引擎版本、脚本或步骤、输入哈希、结果与误差报告;LibreOffice 只能证明其自身兼容性。</li><li>□ 原附件全量导出、权限、安全和资源预算通过;大文件首开及改值重算满足商定目标。</li><li>□ 使用说明、列字典、异常状态与原始证据齐全,无患者原始标识泄露。</li><li>□ 灰度开关、失败回退、审计、清理、任务运行监控与运维说明就绪。</li></ul><p>上线先小范围授权用户试用公式模式,旧证据导出保留作为回退。只有 Excel 导出门禁通过,不意味着整个财务系统所有商业上线门禁自动满足。</p></section>
<section id="questions"><h2>10 / 需确认的业务决策</h2><div class="grid"><div><h3>可直接采用的工程默认</h3><ul><li>双模式并存,公式版 XLSX 不含宏和外链。</li><li>精确证据 + 数值计算 + 对账,不牺牲原始精度。</li><li>Microsoft 365 为首版公式验收目标。</li><li>固定范围、指定输入可改,结构变化重新导出。</li><li>大文件异步、授权下载、客户去标识。</li></ul></div><div><h3>上线前必须由财务确认</h3><ul><li>收入继续使用 N 列,还是另需 I 列实收口径?</li><li>舍入在每行还是最终汇总发生?使用哪种舍入规则与容差?</li><li>毛利率允许本地模拟吗?直接毛利是否允许修改?</li><li>自营产品集合、退款计人、成本归属及 ROI 口径是什么?</li><li>是否必须支持旧版 Excel/WPS,以及首次打开前就有结果缓存?</li></ul></div></div><p class="recommend"><strong>建议实施顺序:</strong>先确认口径与 Excel 版本 → 小样本真正公式与重算验证 → 33 万行任务化及性能测试 → 前端完整交互与财务签字。不要先把导出值改成数值、加几条 SUM,就标记需求完成。</p></section>
</main><footer>本文件是实施计划。现有 XLSX 导出仍为文本证据快照;本轮没有新增公式导出功能,也没有执行尚未实现功能的验收。</footer>
</body>
</html>