Files
fa-agent/docs/gaps-and-testing.html
T
Jayway Liu cd07ba1887
Verify / verify (push) Failing after 1s
AI Review / review (pull_request) Successful in 14s
Verify / verify (pull_request) Failing after 1s
docs: 使用文档与未实现功能/测试指南
- user-guide.html:面向使用者的完整操作说明(含 AI 模型配置)
- gaps-and-testing.html:未实现功能清单、F01-F08 状态、发布门禁与
  分层测试方法、验收矩阵、当前基线
- README 加入口链接
2026-10-11 09:45:22 +08:00

323 lines
22 KiB
HTML
Raw 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.0">
<title>TraceIQ 未实现功能与测试指南</title>
<style>
:root {
--ink: #1a2332;
--muted: #5b6675;
--accent: #1f5fa8;
--accent-soft: #eaf2fb;
--line: #dfe5ec;
--bg: #f6f8fa;
--card: #ffffff;
--p0: #b3261e;
--p0-bg: #fdeceb;
--p1: #9a5b00;
--p1-bg: #fdf3e3;
--p2: #1f5fa8;
--p2-bg: #eaf2fb;
--ok: #1d6b4f;
--ok-bg: #e7f4ee;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
color: var(--ink);
background: var(--bg);
line-height: 1.7;
}
header {
background: linear-gradient(135deg, #16324f, #1f5fa8);
color: #fff;
padding: 48px 24px 40px;
}
header .inner, main { max-width: 960px; margin: 0 auto; }
header h1 { margin: 0 0 8px; font-size: 28px; }
header p { margin: 0; opacity: .85; }
.layout { max-width: 1160px; margin: 0 auto; display: flex; gap: 32px; padding: 32px 24px 64px; }
nav.toc {
flex: 0 0 220px;
position: sticky; top: 24px; align-self: flex-start;
background: var(--card); border: 1px solid var(--line); border-radius: 10px;
padding: 16px 18px; font-size: 14px;
}
nav.toc strong { display: block; margin-bottom: 8px; }
nav.toc a { display: block; color: var(--accent); text-decoration: none; padding: 3px 0; }
nav.toc a:hover { text-decoration: underline; }
main { flex: 1; min-width: 0; }
section {
background: var(--card); border: 1px solid var(--line); border-radius: 10px;
padding: 24px 28px; margin-bottom: 24px;
}
h2 { font-size: 20px; margin: 0 0 12px; padding-bottom: 8px; border-bottom: 2px solid var(--accent-soft); }
h3 { font-size: 16px; margin: 20px 0 8px; }
p { margin: 8px 0; }
ul, ol { margin: 8px 0; padding-left: 22px; }
li { margin: 4px 0; }
code {
background: #eef1f5; border-radius: 4px; padding: 1px 6px;
font-family: "SF Mono", Menlo, Consolas, monospace; font-size: .92em;
}
pre {
background: #16202e; color: #e6edf3; border-radius: 8px;
padding: 14px 16px; overflow-x: auto; font-size: 13px; line-height: 1.6;
}
pre code { background: none; padding: 0; color: inherit; }
table { border-collapse: collapse; width: 100%; margin: 12px 0; font-size: 14px; }
th, td { border: 1px solid var(--line); padding: 8px 12px; text-align: left; vertical-align: top; }
th { background: var(--accent-soft); }
tr:nth-child(even) td { background: #fafcfe; }
.note {
background: var(--accent-soft); border-left: 4px solid var(--accent);
border-radius: 0 8px 8px 0; padding: 10px 16px; margin: 12px 0; font-size: 14px;
}
.warn {
background: var(--p1-bg); border-left: 4px solid var(--p1);
border-radius: 0 8px 8px 0; padding: 10px 16px; margin: 12px 0; font-size: 14px;
}
.tag {
display: inline-block; border-radius: 4px; padding: 0 8px;
font-size: 12px; font-weight: 600; line-height: 20px; white-space: nowrap;
}
.tag.p0 { background: var(--p0-bg); color: var(--p0); }
.tag.p1 { background: var(--p1-bg); color: var(--p1); }
.tag.p2 { background: var(--p2-bg); color: var(--p2); }
.tag.ok { background: var(--ok-bg); color: var(--ok); }
.tag.todo { background: #f1f3f5; color: var(--muted); }
footer { text-align: center; color: var(--muted); font-size: 13px; padding: 24px; }
@media (max-width: 860px) {
.layout { flex-direction: column; }
nav.toc { position: static; flex: none; }
}
</style>
</head>
<body>
<header>
<div class="inner">
<h1>TraceIQ 未实现功能与测试指南</h1>
<p>距离生产商用还差什么 · 每一项怎么测 · 2026-10-08 更新</p>
</div>
</header>
<div class="layout">
<nav class="toc">
<strong>目录</strong>
<a href="#summary">1. 结论摘要</a>
<a href="#codes">2. 代码问题与修复</a>
<a href="#features">3. 未实现功能</a>
<a href="#gates">4. 发布门禁(外部)</a>
<a href="#env">5. 测试环境准备</a>
<a href="#how">6. 分层测试方法</a>
<a href="#matrix">7. 验收矩阵</a>
<a href="#baseline">8. 当前基线</a>
</nav>
<main>
<section id="summary">
<h2>1. 结论摘要</h2>
<p>当前版本<strong>不能认定为生产商用完成</strong>。核心分析链路(导入 → 总览 → 异常 → 下钻 → 证据 → 导出)已经实现并通过自动化回归;仍有<strong>一批 P1/P2 产品功能缺口</strong>,以及<strong>必须由外部环境和业务方关闭的发布门禁</strong>(Excel 实机、财务签字、真实 AI 合规、目标基础设施)。</p>
<div class="note"><strong>2026-10-08 工程整改:</strong>F01–F08 已完成代码修复并补充专项回归;本轮又完成网页自定义列、定义草稿恢复、版本历史、个人/团队共享、公式工作簿输入校验与保护、大文件下载直传。Excel 实机仍是独立门禁。</div>
<div class="note"><strong>2026-10-11 复核:</strong>对当前工作区重新全量验证——ruff/格式/迁移检查通过,SQLite 后端 73 passed(4 skipped),前端构建通过,Playwright 4/4 通过(含原附件验收用例,原附件数据集仍在本机库中)。F01–F08 修复确认有效,无需重复修复;剩余开放项见第 3、4 节。</div>
<p>状态口径:本文区分"源码静态确认"(读代码即可判断、尚无专项复现测试)与"实测通过"(有自动化结果)。清单整合自 <code>docs/acceptance.md</code>、<code>docs/remaining-issues-2026-09-26.html</code> 与 2026-09-27 的修复记录;细节以那两个文档为准,本文是单一入口。</p>
<table>
<tr><th>类别</th><th>数量</th><th>最高优先级</th></tr>
<tr><td>已关闭代码问题(F01–F08)</td><td>8</td><td><span class="tag ok">专项回归通过</span></td></tr>
<tr><td>未实现功能(产品边界)</td><td>约 7 项</td><td><span class="tag p1">P1</span></td></tr>
<tr><td>发布门禁(外部责任)</td><td>5 组</td><td><span class="tag p0">P0 ×3</span></td></tr>
</table>
<div class="note">2026-09-27 已完成、不再属于"未实现"的内容:AI 模型页面配置(云端/本地多模型选择)、证据金额 24 位小数修复、KPI 折行、图表轴标签、表格列遮挡、内部键名暴露等 UI 问题修复。详见第 8 节基线。</div>
</section>
<section id="codes">
<h2>2. 代码问题与修复记录(F01–F08)</h2>
<p>以下是历史问题及其当前修复后的验收方式;详细位置与原始建议见 <a href="remaining-issues-2026-09-26.html">remaining-issues-2026-09-26.html</a>。</p>
<table>
<tr><th>编号</th><th>级别</th><th>问题</th><th>修复后怎么测</th></tr>
<tr>
<td>F01</td><td><span class="tag p0">P0</span></td>
<td>公式导出失败清理可能沿符号链接父目录删除非任务文件(<code>finance/exporting.py</code>)</td>
<td>父目录链接到受保护目录并预置同名文件:执行必须失败、受保护文件字节不变、任务标记 failed;覆盖根目录链接/目标链接/写盘失败/正常重试</td>
</tr>
<tr>
<td>F02</td><td><span class="tag ok">已修复</span></td>
<td>清理失败被静默吞掉,失败任务的孤儿 .xlsx 缺少回收路径</td>
<td>注入 unlink 权限错误:任务仍 failed、有可观察告警;恢复权限后回收成功且不影响其他任务文件</td>
</tr>
<tr>
<td>F03</td><td><span class="tag ok">已修复</span></td>
<td>证据弹窗重复点击当前期间会让列表停在"加载中"(<code>EvidenceDialog.selectSide</code>)</td>
<td>重复点击当前期间、快速本期/基期切换、第二页切期间、空列表、请求失败——均不显示过期数据或永久加载(Playwright E2E)</td>
</tr>
<tr>
<td>F04</td><td><span class="tag ok">已修复</span></td>
<td>载入已保存定义后追问,没有把原定义带给模型,指代修改不可靠</td>
<td>保存定义 A → 重开载入 A → 发送依赖 A 的修改:检查模型请求实际包含 A;未发送补充时禁止生成</td>
</tr>
<tr>
<td>F05</td><td><span class="tag ok">已修复</span></td>
<td>定义库 50 条上限非原子约束;同名更新最后写入覆盖、无 revision 冲突检测;审计不在同一事务</td>
<td>PostgreSQL 下并发保存不得产生第 51 条;两个标签页更新不静默丢失;模拟审计写入失败后定义变更回滚</td>
</tr>
<tr>
<td>F06</td><td><span class="tag ok">已修复</span></td>
<td>工作簿参数页把毛利率标为"可编辑"但实际公式引用每行 MarginRate,修改不联动</td>
<td>每个标为可编辑的输入都对应真实依赖;收入/成本/原价/直接毛利/lookup 毛利率分别改值重算验证</td>
</tr>
<tr>
<td>F07</td><td><span class="tag ok">已修复</span></td>
<td>对账统一用 0.01 阈值,人数/金额/比率混用;自定义列无独立服务器参考值</td>
<td>阈值边界、大数、抵消、极小值、除零、缺失、多层表达式独立黄金样例通过;容差需先经财务确认</td>
</tr>
<tr>
<td>F08</td><td><span class="tag ok">已修复</span></td>
<td>导出任务执行/下载阶段不重新校验角色;撤权后的下载政策未定义;缺超时/崩溃恢复测试</td>
<td>排队后撤权、成功后撤权按签署政策处理;半成品不可下载;worker 崩溃重启不重复发布或卡死在 processing</td>
</tr>
</table>
<p>F01–F08 当前均有代码修复和自动化回归;后续验收重点转为 PostgreSQL 并发、Excel 实机和目标部署环境。</p>
</section>
<section id="features">
<h2>3. 未实现功能(产品边界)</h2>
<table>
<tr><th>级别</th><th>功能</th><th>当前缺口</th></tr>
<tr><td><span class="tag ok">已实现</span></td><td>新列进入网页汇总表</td><td>从定义库选择的列由服务端安全计算并显示在主分析表、汇总和分组行;E2E 覆盖选择后显示</td></tr>
<tr><td><span class="tag ok">已实现</span></td><td>多列编辑与定义生命周期</td><td>网页最多选择 10 列;对话草稿会话恢复,定义支持最近 20 个版本、个人更新与全范围账号共享</td></tr>
<tr><td><span class="tag p1">P1</span></td><td>适用范围与表达式能力</td><td>scope 只是说明文本;不支持任意条件、跨明细新聚合、Excel 函数、维度列、缺失替代策略</td></tr>
<tr><td><span class="tag ok">部分完成</span></td><td>Excel 内编辑防误操作</td><td>结构、证据、人数和公式工作表已保护;计算明细仅收入/成本/毛利输入/毛利率/原价金额解锁并带数值校验。增删明细行仍需重新导出</td></tr>
<tr><td><span class="tag p1">P1</span></td><td>原附件 332,830 行全量导出</td><td>产品上限 100,000 行/200 组,原附件一次导不全;需可审计分卷或正式提高上限后再验收</td></tr>
<tr><td><span class="tag p1">P1</span></td><td>结果缓存与大文件下载</td><td>公式下载已改为浏览器直传,避免前端 Blob 全量驻留;openpyxl/LibreOffice 计算缓存与 /tmp 容量仍需目标环境方案</td></tr>
<tr><td><span class="tag p1">P1</span></td><td>高基数与可访问性</td><td>聚合分组全量返回,无 SSRM/结果窗口;无键盘/屏幕阅读器/平板专项</td></tr>
<tr><td><span class="tag p2">P2</span></td><td>扩展业务能力</td><td>多收入字段口径、消费比率、生效期毛利率、退款策略、结构占比、历史阈值、告警渠道、团队调查分派</td></tr>
<tr><td><span class="tag p2">P2</span></td><td>跨平台与高级网格</td><td>无原生客户端;AG Grid SSRM/Pivot/Tree Data/Master-Detail 未接入(需 Enterprise 许可)</td></tr>
</table>
<div class="note"><strong>本轮 P1 完成:</strong>网页自定义列、多列选择、定义草稿恢复/版本历史/共享、Excel 受保护输入与校验、公式下载直传。<strong>仍开放:</strong>任意条件与跨明细聚合、33 万行分卷/容量、结果缓存、高基数窗口、无障碍专项,以及第 4 节外部发布门禁。</div>
<div class="warn">另外:趋势/贡献图为 ECharts 折线+横条,不是完整瀑布/Pareto/散点套件;异常规则只有变化率+影响额+样本数,无结构占比、历史分位数与告警投递;无团队工单分派。这些属于需求范围决策,开发前先冻结业务定义。</div>
</section>
<section id="gates">
<h2>4. 发布门禁(必须由外部关闭)</h2>
<table>
<tr><th>级别</th><th>门禁</th><th>责任方</th><th>关闭证据</th></tr>
<tr>
<td><span class="tag p0">P0</span></td><td>Microsoft Excel 实机验收</td>
<td>财务、QA、目标终端负责人</td>
<td>可编辑 Windows/Mac Excel 打开受控样例 → 强制重算 → 保存;改值后依赖链正确;覆盖人数、升单率、空集、缺期</td>
</tr>
<tr>
<td><span class="tag p0">P0</span></td><td>财务业务口径签字</td>
<td>财务负责人</td>
<td>签署收入/实收/原价、退款、成本归属、毛利、ROI、自营、升单与容差;原附件成本全缺,ROI 保持不可用</td>
</tr>
<tr>
<td><span class="tag p0">P0</span></td><td>真实 AI 联调与数据合规</td>
<td>合规、数据负责人、AI 服务负责人</td>
<td>数据处理/出境审批、模型版本与留存策略;真实验证超时/拒答/限流/非法输出。批准前保持 AI 关闭</td>
</tr>
<tr>
<td><span class="tag p1">P1</span></td><td>目标基础设施验收</td>
<td>运维、安全</td>
<td>镜像构建、迁移、非 root/卷权限、TLS、代理、数据库认证、队列、备份恢复、日志脱敏、安全扫描、许可证</td>
</tr>
<tr>
<td><span class="tag p1">P1</span></td><td>当前版本 PostgreSQL 与 SLA</td>
<td>工程 + 运维</td>
<td>在独立 PostgreSQL 跑当前全量测试、并发定义保存、worker 恢复、导出压力;记录 P95、资源预算、RPO/RTO</td>
</tr>
</table>
<div class="note">AI 联调现在可以在页面完成配置:管理 → AI 模型,选择 OpenAI 或本地 OpenAI 兼容服务(Ollama / LM Studio / vLLM),"获取可用模型"可多选本地模型。配置入口已实现(见使用文档第 9 节),但"真实模型联调 + 合规审批"这一门禁仍然开放。SQLite 仅用于开发回归,金额验收必须用 PostgreSQL。</div>
</section>
<section id="env">
<h2>5. 测试环境准备</h2>
<h3>5.1 快速启动(SQLite 轻量开发库)</h3>
<pre><code>scripts/dev_up.sh # 迁移 + 管理员 + 前端构建 + API + worker,自动健康检查
scripts/dev_up.sh --stop # 停止</code></pre>
<p>登录凭据在 <code>var/local-access.txt</code>(用户名 <code>admin</code>,随机密码,权限 0600)。</p>
<h3>5.2 PostgreSQL(财务验收必需)</h3>
<pre><code>/opt/homebrew/opt/postgresql@17/bin/pg_ctl -D var/postgres -l var/postgres.log \
-o '-h 127.0.0.1 -p 55432' start
export DATABASE_URL='postgresql://jianwel@127.0.0.1:55432/traceiq'</code></pre>
<div class="warn">SQLite 不保证高精度金额聚合,禁止用于财务验收和生产。对账脚本 <code>scripts/reconcile_reference.py</code> 明确要求 PostgreSQL。</div>
<h3>5.3 Playwright 浏览器</h3>
<pre><code>npx playwright install chromium # 首次执行</code></pre>
</section>
<section id="how">
<h2>6. 分层测试方法</h2>
<h3>6.1 静态检查与后端单测(每次改动都跑)</h3>
<pre><code>uv run ruff check server finance tests scripts
uv run ruff format --check server finance tests scripts
uv run python manage.py makemigrations --check --dry-run
uv run pytest --cov=finance --cov-report=term-missing --cov-fail-under=85</code></pre>
<h3>6.2 前端构建与浏览器 E2E</h3>
<pre><code>npm run build
E2E_PASSWORD='&lt;测试口令&gt;' npm run test:e2e</code></pre>
<p>E2E 需要正在运行的本地 API + worker;会真实导入测试 CSV 数据集,<strong>不可指向生产环境</strong>。覆盖:导入确认、总览 KPI、异常下钻、调查保存、证据分页、设置乐观锁、Copilot、公式工作簿追问与下载、手机布局无横向溢出。</p>
<h3>6.3 原附件验收用例(本机显式启用)</h3>
<pre><code>REFERENCE_DATASET_NAME='分析数据_原稿(1).xlsx' E2E_PASSWORD='&lt;口令&gt;' npm run test:e2e</code></pre>
<p>断言:KPI 精确值(收入 152,419,115.35、毛利 17,868,580.85、人数 38,361)、环比缺 2026-07 禁比、同比 -32.4%、移动端无溢出、无页面脚本错误。附件文件不在仓库中,需本机提供。</p>
<h3>6.4 真实数据对账(PostgreSQL)</h3>
<pre><code>PYTHONPATH=. uv run python scripts/reconcile_reference.py</code></pre>
<p>断言 332,830 行、收入/毛利/人数与历史独立对账一致(误差 0)。原附件 SHA-256:<code>98ef41e898c2…</code>。</p>
<h3>6.5 公式工作簿重算</h3>
<pre><code>uv run pytest tests/test_formula_recalculation.py \
tests/test_formula_recalculation_gross.py # LibreOffice 重算,7 项</code></pre>
<p>LibreOffice 通过 ≠ Excel 通过;Microsoft Excel 实机重算是独立门禁(第 4 节)。</p>
<h3>6.6 安全与部署检查</h3>
<pre><code>uv run pip-audit
npm audit --omit=dev
uv run python manage.py check --deploy # 需完整生产环境变量</code></pre>
<div class="note">依赖审计为 0 漏洞 ≠ 渗透测试通过;<code>check --deploy</code> 无告警 ≠ 基础设施验收通过。</div>
</section>
<section id="matrix">
<h2>7. 验收矩阵:每项怎么算"完成"</h2>
<table>
<tr><th>目标</th><th>通过标准</th><th>手段</th></tr>
<tr><td>F01–F08 修复</td><td>各有"修复前失败、修复后通过"的专项断言;覆盖率 ≥ 85%</td><td>pytest + Playwright(见第 2 节每行)</td></tr>
<tr><td>AI 配置功能</td><td>保存/脱敏回显/权限/模型列表/助手走配置,接口级测试通过</td><td><code>tests/test_assistant_api.py</code>(已实现)</td></tr>
<tr><td>金额精度</td><td>证据与导出无存储尺度尾零;对账 0 误差</td><td><code>test_evidence_amounts_trim_storage_scale</code> + reconcile_reference.py</td></tr>
<tr><td>Excel 引擎门禁</td><td>目标 Excel 改值重算、保存、重开一致</td><td>人工按受控样例执行并记录版本与结果(第 4 节)</td></tr>
<tr><td>财务口径门禁</td><td>财务负责人签字确认口径与容差</td><td>签字文件;不以技术测试替代</td></tr>
<tr><td>AI 合规门禁</td><td>审批完成 + 真实模型故障演练通过</td><td>页面配置真实模型后做超时/拒答/限流演练</td></tr>
<tr><td>基础设施门禁</td><td>镜像构建、TLS、备份恢复演练、RPO/RTO 记录</td><td>docker compose + 恢复演练</td></tr>
<tr><td>性能/SLA</td><td>目标并发下导入/查询 P95 达标;高基数有方案</td><td>压力测试;高基数维度需 SSRM 或服务端窗口</td></tr>
</table>
</section>
<section id="baseline">
<h2>8. 当前基线(最近一次实测)</h2>
<table>
<tr><th>项目</th><th>结果</th><th>日期 / 环境</th></tr>
<tr><td>后端单测(本轮复核)</td><td><span class="tag ok">73 passed</span>,4 skipped</td><td>2026-10-11,SQLite 测试库</td></tr>
<tr><td>Playwright E2E(本轮复核)</td><td><span class="tag ok">4 passed</span>(桌面综合、手机布局、公式导出、原附件验收)</td><td>2026-10-11,本地 API + worker</td></tr>
<tr><td>后端单测</td><td><span class="tag ok">77 passed</span>,finance 覆盖率 88.45%(门槛 85%)</td><td>2026-10-08,SQLite;PostgreSQL 77 passed</td></tr>
<tr><td>Playwright E2E</td><td>3 passed,1 skipped(原附件用例未启用)</td><td>2026-10-08,本地 API + worker</td></tr>
<tr><td>本轮修复</td><td>F01–F08、网页自定义列、多列选择、草稿恢复、版本历史与共享、Excel 输入校验/公式保护、公式下载直传;PostgreSQL 运行与 Excel 实机仍需门禁</td><td>2026-10-08</td></tr>
<tr><td>历史基线(勿直接引用)</td><td>PostgreSQL 67 项、61 项、44/54 项等旧记录,以及 332,830 行旧峰值 RSS 3.31 GB</td><td>历史,见 acceptance.md</td></tr>
</table>
<h3>相关文档</h3>
<ul>
<li><a href="acceptance.md">acceptance.md</a> — 验收状态与上线门禁(最详细)</li>
<li><a href="remaining-issues-2026-09-26.html">remaining-issues-2026-09-26.html</a> — F01–F08 代码问题细节</li>
<li><a href="user-guide.html">user-guide.html</a> — 使用者操作说明(含 AI 模型配置)</li>
<li><a href="improvement-roadmap.html">improvement-roadmap.html</a> / <a href="improvement-plan.html">improvement-plan.html</a> — 改进计划(部分状态已过期,以本文为准)</li>
</ul>
<div class="warn">多个历史文档之间存在状态冲突(如"没有定义库"等旧表述)。后续应统一维护单一验收入口,历史文档标题注明"历史"。本文不是上线授权。</div>
</section>
</main>
</div>
<footer>TraceIQ 未实现功能与测试指南 · 2026-10-11 复核更新 · 状态口径:实测 &gt; 静态确认 &gt; 历史记录</footer>
</body>
</html>