Document cockpit I4: seven-scenario browser acceptance and seed hardening #598

Merged
weichen merged 38 commits from feature/document-visualization-cockpit-i4 into main 2026-10-17 06:06:43 +00:00
4 changed files with 367 additions and 2 deletions
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
project: 审计演示项目
docs:
- type: bd_research
title: 验证主体报告
sections:
- title: 概述
content: |
本报告给出验证主体、结论与证据链的总体视图。
- title: 设计说明
content: |
设计说明:两树一网领域事实经驾驶舱只读投影呈现。
- title: 验证结论
+35 -1
View File
@@ -177,6 +177,10 @@ cmd rdm.perm.cap '{"action":"audit.read","allow":true}' >/dev/null
cmd rdm.perm.set "{\"projectId\":\"$PID_MAIN\",\"member\":\"$OWNER\",\"action\":\"audit.read\",\"allow\":true}" >/dev/null
cmd rdm.perm.set "{\"projectId\":\"$PID_ISO\",\"member\":\"$OWNER\",\"action\":\"audit.read\",\"allow\":true}" >/dev/null
log "seed: grant explicit doc.read for the cockpit fixture owner"
cmd rdm.perm.set "{\"projectId\":\"$PID_MAIN\",\"member\":\"$OWNER\",\"action\":\"doc.read\",\"allow\":true}" >/dev/null
cmd rdm.perm.set "{\"projectId\":\"$PID_ISO\",\"member\":\"$OWNER\",\"action\":\"doc.read\",\"allow\":true}" >/dev/null
log "seed: import requirement ledger into $PID_MAIN"
cmd rdm.reqs.import "{\"projectId\":\"$PID_MAIN\",\"items\":$(
python3 - <<'PY'
@@ -199,6 +203,11 @@ log "seed: load doc-tree structure into $PID_MAIN"
"$OUT/agent-system-rdm" -data "$DATA" \
-structure "$RDM_WT/docs/structure/rdm-self.yaml" -project "$PID_MAIN" \
>"$OUT/structure.log" 2>&1 || { tail -5 "$OUT/structure.log"; die "structure load failed"; }
log "seed: load cockpit doc-tree into $PID_MAIN"
"$OUT/agent-system-rdm" -data "$DATA" \
-structure "$DEV_ROOT/docs/structure/cockpit-e2e.yaml" -project "$PID_MAIN" \
>"$OUT/structure-cockpit.log" 2>&1 || { tail -5 "$OUT/structure-cockpit.log"; die "cockpit structure load failed"; }
grep -o '装载(.*)' "$OUT/structure.log" | head -1 || true
# 阶段③:重启服务,切片入库挂载到已装载骨架(API)。
@@ -219,6 +228,31 @@ log "seed: ingest corpus into $PID_MAIN"
cmd rdm.ingest "{\"projectId\":\"$PID_MAIN\",\"source\":\"01-用户需求与系统需求.md\",\"stage\":\"BD\",\"text\":$(python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))' <<<"$SEED_MD")}" >/dev/null
log "seed done"
# ── 驾驶舱 I4 种子:章节探针提案 + 非成员账号(正文经结构 YAML 装载) ──
cmd rdm.perm.set "{\"projectId\":\"$PID_MAIN\",\"member\":\"$OWNER\",\"action\":\"doc.write\",\"allow\":true}" >/dev/null
log "seed: cockpit pending proposal probe (non-danger; scenario 4)"
COCKPIT_OV=$(cmd rdm.cockpit.overview "{\"projectId\":\"$PID_MAIN\"}")
DOC_ID=$(printf '%s' "$COCKPIT_OV" | python3 -c 'import json,sys; d=json.load(sys.stdin); print([i["ref"]["id"] for i in d["documents"] if i["title"]=="验证主体报告"][0])')
SEC_JSON=$(cmd rdm.cockpit.tree "{\"projectId\":\"$PID_MAIN\",\"parent\":\"$DOC_ID\"}")
SEC_DESIGN=$(printf '%s' "$SEC_JSON" | python3 -c 'import json,sys; d=json.load(sys.stdin); print([i["ref"]["id"] for i in d["items"] if i["title"]=="设计说明"][0])')
# 场景 4 驱动用:留一个未采纳提案(浏览器内经 API 采纳后观察投影一致)。
cmd rdm.draft.propose "{\"projectId\":\"$PID_MAIN\",\"sectionId\":\"$SEC_DESIGN\",\"content\":\"一致性探针内容。\"}" >/dev/null
# 场景 2 驱动:验证主体报告设文档级三权(职责判据与正文版本作者无关;
# 结构装载作者为 structure,owner 经文档职责获得正文可读)。
log "seed: duty accounts + doc-level duties (scenario 2)"
DOC_MAIN=$(printf '%s' "$COCKPIT_OV" | python3 -c 'import json,sys; d=json.load(sys.stdin); print([i["ref"]["id"] for i in d["documents"] if i["title"]=="验证主体报告"][0])')
"$OUT/agent-system" user create --data "$DATA" --owner e2e-rev --out-file "$OUT/e2e-rev.bootstrap.key" >/dev/null || die "rev create failed"
"$OUT/agent-system" user create --data "$DATA" --owner e2e-app --out-file "$OUT/e2e-app.bootstrap.key" >/dev/null || die "app create failed"
cmd rdm.project.member.add "{\"projectId\":\"$PID_MAIN\",\"member\":\"e2e-rev\",\"role\":\"member\"}" >/dev/null
cmd rdm.project.member.add "{\"projectId\":\"$PID_MAIN\",\"member\":\"e2e-app\",\"role\":\"member\"}" >/dev/null
cmd rdm.review.assign.doc "{\"projectId\":\"$PID_MAIN\",\"docId\":\"$DOC_MAIN\",\"author\":\"$OWNER\",\"reviewers\":[\"e2e-rev\"],\"approver\":\"e2e-app\"}" >/dev/null
log "seed: second account (non-member negative case)"
"$OUT/agent-system" user create --data "$DATA" --owner e2e-reader --out-file "$OUT/e2e-reader.bootstrap.key" >/dev/null || die "reader create failed"
K2=$(cat "$OUT/e2e-reader.bootstrap.key")
JAR2="$OUT/reader.jar"
curl -sf -c "$JAR2" -X POST "$API_BASE/api/auth/login-key/redeem" -H 'Content-Type: application/json' -d "{\"key\":\"$K2\",\"owner\":\"e2e-reader\"}" >/dev/null || die "reader redeem failed"
curl -sf -b "$JAR2" -c "$JAR2" -X POST "$API_BASE/api/auth/password" -H 'Content-Type: application/json' -d "{\"next\":\"E2eReader#2026\"}" >/dev/null || die "reader password setup failed"
# ── 3. 验收 ─────────────────────────────────────────────
if [ "$SEED_ONLY" = 1 ]; then
log "seed-only mode: api=$API_BASE ui=next;cookie jar=$JAR;数据=$DATA"
@@ -252,7 +286,7 @@ export PLAYWRIGHT_BASE_URL="http://127.0.0.1:$UI_PORT" E2E_OWNER="$OWNER" \
set +e
# 本脚本的种子只覆盖审计工作区。u7 现场验收用例依赖另一套入口,不在这里跑。
# admin-create 场景复用本种子的基座管理员账号(bootstrap-admin)。
npx playwright test e2e/rdm-audit.playwright.ts e2e/admin-user-create.playwright.ts --reporter=list >"$OUT/playwright.log" 2>&1
npx playwright test e2e/rdm-audit.playwright.ts e2e/rdm-cockpit.playwright.ts e2e/admin-user-create.playwright.ts --reporter=list >"$OUT/playwright.log" 2>&1
PW_EXIT=$?
set -e
cat "$OUT/playwright.log"