diff --git a/docs/USER_FLOWS_ACCEPTANCE.md b/docs/USER_FLOWS_ACCEPTANCE.md new file mode 100644 index 0000000..66a0e49 --- /dev/null +++ b/docs/USER_FLOWS_ACCEPTANCE.md @@ -0,0 +1,151 @@ +# 用户操作流程与验收清单 + +按流程逐项验收用。每条给出:**入口 → 用户步骤 → 期望 → 验收证据 → 状态**。 +状态标记:**✅ 已实测**(附证据)|**⏳ 待验收**|**⚠️ 已知限制**。 +深度细节见各自专题文档(`P3…`/`P5…`/`P6…`/`P8…`/`PRODUCTION_BACKUP_RECOVERY.md`/`WIKI_CO_TRANSPORT…`)。 + +统一入口:**http://127.0.0.1:8088/**(测试栈;右侧面板可直接操作)。角色:管理员 / 文档工程师 / 只读。 + +--- + +## A. 内容进入 + +### A1 取件(钉钉知识库 / PP 清单) +- 入口:**来源与目录 → 内容来源**(勾选条目;钉钉扫码会话失效时先刷新会话) +- 步骤:选来源 → 展开目录 → 勾选 → 取件(后台入队) +- 期望:解析监控出现"处理中";失败进**死信**,可重排 +- 证据:`解析监控 → 死信` 队列;重排轮次键 `artifact-fetch::r` +- 状态:✅(死信重排修复 `cddc4c9`) + +### 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/-/` 出现 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 ` → 两个绑定库 `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//<库>.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**(既有流程,按各自专题文档逐条核)。 \ No newline at end of file