Files
knowledge-governance/docs/USER_FLOWS_ACCEPTANCE.md
T
姚章浩 32b480ce85 docs(acceptance): A1 补钉钉取件走 dws 的实现与复核结论
- 记录开关/路由/平台侧判定保留、凭据共享与续期 runbook 依赖
- 本人复核:worker 内 dws v1.0.63 接线、鉴权(须 HOME=DWS_HOME,否则误报未登录)、
  真实调用 ok、回归测试 18 项 + 19 断言、CI #6/#7/#8 全 success
2026-10-09 14:41:55 +08:00

12 KiB
Raw Blame History

用户操作流程与验收清单

按流程逐项验收用。每条给出:入口 → 用户步骤 → 期望 → 验收证据 → 状态。 状态标记:✅ 已实测(附证据)|⏳ 待验收|⚠️ 已知限制。 深度细节见各自专题文档(P3…/P5…/P6…/P8…/PRODUCTION_BACKUP_RECOVERY.md/WIKI_CO_TRANSPORT…)。

统一入口:http://127.0.0.1:8088/(测试栈;右侧面板可直接操作)。角色:管理员 / 文档工程师 / 只读。


A. 内容进入

A1 取件(钉钉知识库 / PP 清单)

  • 入口:来源与目录 → 内容来源(勾选条目;钉钉扫码会话失效时先刷新会话——注意:走 dws 取件后钉钉这条不再依赖浏览器会话)
  • 步骤:选来源 → 展开目录 → 勾选 → 取件(后台入队)
  • 期望:解析监控出现"处理中";失败进死信,可重排
  • 证据:解析监控 → 死信 队列;重排轮次键 artifact-fetch:<version>:r<n>
  • 状态:✅(死信重排修复 cddc4c9)

A1 补充:钉钉取件改走 dws(f4e1ecc / 6496ee3 / 9155bd3,2026-10-09)

  • 开关:ARTIFACT_DINGTALK_FETCHER=dws|auto|legacy,线上为 auto(先 dws;仅可重试错误回落老路径)。
  • 路由:adoc→doc export docx;axls→sheet 读取转 xlsx;其余→drive 直下;dlink/hlink→missing;amind/appt→unsupported(详见 docs/DINGTALK_DWS_FETCHER.md)。
  • 平台侧判定全部保留:后缀路由、PPT 必须 PDF 双胞胎、magic、大小上限、sha256、spool 原子写、空壳检查 → dws 只负责"取字节"。
  • 本人复核(2026-10-09,在已部署 worker 内):
    • 接线:dws v1.0.63(Edition: open)在 /usr/local/bin/dws;DWS_HOME=/data/home、DWS_CONFIG_DIR=/data/dws、DWS_DISABLE_KEYCHAIN=1;宿主两份 state 已按文档挂载 ✓
    • 鉴权(必须带 HOME=DWS_HOME,直接 docker exec dws 会误报"未登录"):authenticated:true、refresh_token_valid:true、refresh_expires_at 2026-11-08、账号 姚章浩 / 深圳市越疆科技股份有限公司 ✓
    • 真实调用:dws wiki +space-list --limit 1 → ok:true,返回"公司级技术支持知识库" ✓
    • 回归测试:artifact_fetch_test.py 18 项、test_dws_error_map.py 19 断言全绿 ✓
  • 运维依赖(验收时作为背景知识):
    • refresh token 30 天轮换:到期前 7 天按 runbook dws auth login --device 续期(本人浏览器授权);出现 code=credentials 立即停批,不要重试风暴,授权后 --retry-failed 续跑。
    • 在线文档并发建议 ≤4(当前 ingestion_concurrency=2 ✓ 满足);8 路混合时巨型文档曾现 export_failed(已判可重试)。
    • 回退开关:ARTIFACT_DINGTALK_FETCHER=legacy 可完全绕过 dws。
    • CI:Gitea Run #6/#7/#8 全 success(#8 = 含本清单的 b1b4ca5)✓

A2 标注与目录范围(路由到哪个库)

  • 入口:来源与目录 → 勾选 → 标记:对内 / 对外 / 不需要(目录级标记决定整目录)
  • 步骤:标注 → 生成修订
  • 期望:标记按 系统设置 → 测试知识库绑定 分发到对应测试库;不需要 不入库
  • 证据:GET /api/v1/source-catalog/routing-capabilities;绑定未配时标记被拒
  • 状态:✅(本期实测绑定与路由能力)

A3 生成修订 / 新版本(发布准备)

  • 入口:发布管理 → 生成新版本 → 批准 / 驳回
  • 期望:只有批准后的变更集才能进入密封与批次
  • 证据:变更集版本号与审核动作记录
  • 状态:✅(见 P5_REVIEW_AND_SEAL_ACCEPTANCE.md)

B. 入库与监控

B1 待入库 → 开始处理 → 完成

  • 入口:文档工作台(待入库列表)→ 选中 → 开始处理
  • 期望:上传 → 解析 → 索引 → completed;目标库里能看到知识条目与 wiki 页
  • 证据:单文档 E2E tp-3056261d46396a0695497f38421346b3 → processing_state=completed;知识 cf0af40f-7c0c-4526-ad6a-4515b3b2ca00(4 chunks,wiki 9 页)
  • 状态:✅ 2026-10-08 实测

B2 解析监控与补救

  • 入口:解析监控 → 处理中 / 需要你出手 / 需下架 / 死信 / 已完成 / 知识库差异 / 知识库解析进度
  • 步骤:看"需要你出手" → 重排失败项 / 处理需下架项
  • 期望:失败可重排;"需下架"列出仍留在库里的禁止项
  • 证据:死信与重排链路(cddc4c9)
  • 状态:✅ 链路|⚠️ "重排"按钮行为目前只有单测覆盖(页面当时无失败项可点)

C. 发布与回滚

C1 审核 → 密封 → 建批次 → 锁定

  • 入口:发布管理 → 创建草稿批次 → 密封 → 锁定
  • 期望:密封后批次不可改;锁定后才能授权生产发布
  • 证据:批次 rb-9678722c…(1 项);变更集 rcs-832f0cf9… v1(196 项:1 可发布 / 195 阻塞)
  • 状态:✅ 本期实测

C2 授权发布(双闸 + 页面确认语句)

  • 入口:发布管理 → 授权发布 → 逐字输入确认语句 publish-to-production → 确认执行
  • 期望:执行 completed + verified;目标库出现该文档;不出现"一键发布"
  • 证据:执行 rx-dd47920a5b5f5019af4f197fd0c2f92c;目标库 0b217e8a… 文档数 2069→2070;两个闸门 PRODUCTION_RELEASE_REQUESTS_ENABLED / PRODUCTION_BACKUP_RESTORE_VERIFIED 均为 true
  • 状态:✅ 本期实测(页面通道由管理员会话记录操作人;另支持 0600 Bearer 通道)

C3 查看结果 → 回滚

  • 入口:发布管理 → 查看结果 → 需要时 回滚 → 确认语句 rollback-production-release
  • 期望:回滚后目标库该知识停用(不删知识行),wiki 页保持
  • 证据:rx-f1d1d669… → rolled_back,authorized_by=admin,prior_execution_id=rx-dd47920a…;目标库该知识 enable_status=disabled、chunks 4/0 enabled、wiki 9 页完整
  • 状态:✅ 本期实测

C4 重排失败执行

  • 入口:发布管理 → 失败执行 → 重排 → 确认语句 retry-production-release
  • 期望:只重置失败项;verified / rolled_back 项保持完成;重排不改写 AuthorizedBy(历史不可篡改)
  • 证据:internal/httpapi/production_action_test.go 双通道用例
  • 状态:✅ 单测覆盖|⚠️ 当时无失败执行可点

D. 系统设置

D1 服务配置(测试 / 生产端点与 ID)

  • 入口:系统设置 → 服务配置(管理员)
  • 规则:只配四项(测试地址、生产地址、生产 ID、知识库 ID);保存时真探测,无效才拒;凭据只写不读
  • 状态:✅(见 P41/P42 与 ui_settings_* 测试)

D2 测试知识库绑定(对内 / 对外)

  • 入口:系统设置 → 测试知识库绑定 → 选库 → 保存绑定
  • 期望:保存立即生效并重排"还没上传"的待入库项;对内 ≠ 对外
  • 状态:✅ 本期实测

D3 生产知识库绑定(源库 → 目标库)

  • 入口:系统设置 → 生产知识库绑定 → 对内/对外各选一个生产库
  • 期望:发布写入被冻结到该项的 target_knowledge_base_id;未绑定时按同 ID 语义并在契约检查处失败关闭
  • 状态:✅(P8_PRODUCTION_KB_MAPPING_ACCEPTANCE.md;迁移 000044)

D4 存储与备份(整库逻辑备份的定时)★本期新增

  • 入口:系统设置 → 存储与备份(管理员)
  • 步骤:设置 定时时间 + 储存天数(+ 每月归档保留、启用开关)→ 保存并下发到主机;另可 重新下发当前设置 / 立即备份一次
  • 期望:保存即写库并下发到目标主机 cron;页面显示主机上实际生效的计划、cron 条目、最近一次备份与"已一致/待下发"
  • 证据(面板原文):目标主机 weknora-test · 已连接、主机 cron 服务 active、主机 cron 条目:30 03 * * * root /bin/bash /opt/weknora-test/logical-backup.sh >> …、主机上生效的计划 每天 03:30 · 保留 7 天 · 每月 3 份、与设置是否一致 已一致、最近一次备份 20261009T060736Z / 34 秒 · 742.7 MiB / 覆盖 8 库 / 失败 无
  • 实测改动往返:面板改 04:05 / 14 天 → 主机 /etc/cron.d/kb-logical-backup 变 05 04 * * *、参数文件 TIME=04:05 / KEEP_DAYS=14 ✓ → 再改回 03:30 / 7 天 → 主机 30 03 * * * ✓
  • 立即备份:按钮变"备份进行中…"→ 约 50 秒后自动刷出新结果(异步 202 + 在途单飞,重复点击不会跑两次)
  • 状态:✅ 2026-10-09 面板实测(写操作仅管理员:PUT/POST /api/v1/backup-schedule*)

D5 刷新策略

  • 入口:系统设置 → 刷新策略(文档工程师可改)
  • 期望:文档/资源刷新间隔、停滞判定、finalizing 时长;保存先验证再原子启用、旧版本留审计
  • 状态:✅(ui_settings 版本化激活测试)

D6 成员与角色

  • 入口:系统设置 → 成员与角色(管理员)
  • 期望:成员增删、角色(viewer/engineer/admin);管理员初始密码首登强改
  • 状态:✅(users 接口与角色网关)

E. 备份与恢复(运维流程)

E1 发布/导入前留档(PG 行 + ES 文档)

  • 入口:命令行 bash scripts/target_kb_snapshot.sh(默认云内执行)
  • 期望:$KB_BACKUP_ROOT/target-kb-snapshots/<UTC>-<kb8>/ 出现 8 张表 JSONL + es_documents.jsonl.gz + MANIFEST.json(sha256/每库 ES 计数) + export.sql + README.md
  • 证据:实测 2 分 52 秒(PG 8 表 44 秒;两库 ES 131,122 条 / 692 MB);PULL_ES=1 拉回本机 19 分 40 秒
  • 状态:✅ 2026-10-09 实测

E2 发布前硬门禁

  • 期望:写目标库之前必须存在覆盖该库、24h 内、PG 与 ES 两层齐备且哈希可校验的留档;否则 release_target_snapshot_missing(不可重试),目标库一行不碰
  • 证据:go run ./cmd/guardcheck backups/target-kb-snapshots <kb_id> → 两个绑定库 PASS、未绑定库 BLOCK;门禁单测 10 条
  • 状态:✅ 已上线(release-worker 已带此门禁)

E3 回填演练(证明"存了能回去")

  • 入口:python3 scripts/restore_drill.py --snapshot-dir <留档> --target-url <本地测试库>
  • 期望:行数与清单逐一致、抽样页面正文/标题逐字段相同、清理后残留 0
  • 证据:13,539 行全部回填成功;8 张表与清单逐一致、冲突 0、抽样页 388 字符一致、残留 0(实测值)
  • 状态:✅ 2026-10-09 实测

E4 整库逻辑备份(自管,落自己盘上)

  • 入口:主机 bash /opt/weknora-test/logical-backup.sh(手动)或按 D4 的定时
  • 期望:$KB_BACKUP_ROOT/rds-logical/<UTC>/<库>.dir(pg_dump -Fd -j4 -Z6)+ MANIFEST.json(含 failed_databases);按天轮转
  • 证据:33 秒 / 742.6 MiB / 214 文件 / 失败 0,覆盖 8 个库;RDS 管理库 rdsadmin 自动跳过;中断的运行改名 *.incomplete
  • 状态:✅ 2026-10-09 实测

E5 其余三层(现状)

  • ES 快照:仓库 kb_backup(宿主 $KB_BACKUP_ROOT/es-snapshots)+ SLM kb-hourly(3 天)/kb-daily(7 天);首个快照 36 秒 / 4.7 GB / 0 分片失败 ✅
  • OSS 版本控制:桶 dobot-weknora-test 已开启(覆盖/删除可按 VersionId 回滚)✅
  • RDS 托管备份:由控制在控制台自管(按你的决定:本期不做,不阻塞)⏳
  • 备份目录契约:scripts/backup_layout.sh 定义 /srv/kb-backups/{target-kb-snapshots,rds-logical,es-snapshots,logs},换主机(未来的生产云主机)跑同一份 ✅

F. 本期已知限制与边界(验收时不必当缺陷)

  1. ES 留档字节默认留目标主机(PULL_ES=0);异地副本不做(你的决定)。
  2. ES 快照仓与留档同机同盘:整机故障需靠 RDS 托管备份 + OSS 还原。
  3. wiki 通道的真实跨环境发布本期未跑(归属门禁已单测 + 真库集成测试;建议首次在映射库上与 D3 一起验收)。
  4. "重排"在页面上无真实失败项可点(单测覆盖);指标条"失败 1"是旧 artifact.fetch 死信遗留。
  5. 自管逻辑备份不能替代 PITR(RDS 控制台那条本期不做)。

验收建议顺序

  1. D4 存储与备份(本期新增,步骤最短、证据最全)→ 2. E1/E2/E3/E4(留档→门禁→回填→整库)→ 3. C2/C3(授权发布 → 回滚,需闸门开启)→ 4. B1/B2(入库与补救)→ 5. A1–A3、D1–D3、D5、D6(既有流程,按各自专题文档逐条核)。