验收管家 - 系统架构设计文档 v1.0

多人协作的需求验收管理系统 — 面向当前生产环境(Cloudflare Pages + D1)的架构说明

目录

  1. 系统概览
  2. 数据模型设计
  3. 前后端交互时序图
  4. API 接口设计
  5. 权限控制逻辑
  6. 前端页面结构

1. 系统概览

验收管家是一个面向业务验收场景的多人协作系统。产品经理(管理员)创建验收需求、维护用例,业务验收人各自独立填写验收结果,云端实时同步,管理员侧一键汇总看板与导出报表。

1.1 业务模型

Project(需求项目) → 包含多个 Test Cases(验收用例) → 每条用例由多个验收人独立填写 Results(验收结果)
数据按验收人隔离存储,多人独立填写互不影响。

1.2 整体架构

graph TB
    subgraph Browser["浏览器(验收人/管理员)"]
        HTML["uat.html
单文件前端(零构建)"] LS["LocalStorage
离线缓存 + 身份持久化"] end subgraph CF["Cloudflare Pages"] PF["Pages Functions
后端 API(14+ 端点)"] D1["D1 (SQLite)
生产数据库"] end HTML -- "fetch /api/*" --> PF PF -- "SQL 查询" --> D1 HTML -- "读写缓存" --> LS LS -. "离线/弱网兜底" .-> HTML

技术栈:Cloudflare Pages + Pages Functions + D1 (SQLite),前端单文件 HTML(零构建),使用 SheetJS 导出 Excel。

2. 数据模型设计

2.1 ER 图

erDiagram
    projects ||--o{ testers : "1:N 按项目隔离"
    projects ||--o{ test_cases : "1:N 用例模板"
    projects ||--o{ shares : "1:N 分享链接"
    testers ||--o{ results : "1:N 验收结果"

    projects {
        TEXT id PK "项目唯一标识"
        TEXT name "项目名称"
        TEXT description "描述"
        TEXT owner "负责人"
        TEXT status "active/archived"
    }
    testers {
        INTEGER id PK "自增主键"
        TEXT project_id FK "所属项目"
        TEXT name "验收人姓名"
        TEXT emp_id "工号"
        TEXT org2 "二级机构"
        TEXT org3 "三级机构"
    }
    results {
        INTEGER id PK "自增主键"
        TEXT project_id "所属项目"
        TEXT tester_name "验收人姓名"
        TEXT case_id "用例标识"
        TEXT status "pass/fail/partial"
        TEXT remark "备注(含截图)"
        TEXT sync_time "同步时间"
    }
    test_cases {
        INTEGER id PK "自增主键"
        TEXT project_id FK "所属项目"
        TEXT module "功能模块"
        TEXT sub_module "二级模块"
        TEXT scenario "验证场景"
        TEXT expected "预期结果"
        INTEGER sort_order "排序"
    }
    shares {
        TEXT id PK "8位短链ID"
        TEXT project_id "所属项目"
        TEXT cases_data "用例JSON"
        TEXT expires_at "过期时间"
    }

2.2 字段定义详解

表名字段类型约束用途
projectsidTEXTPK项目唯一标识(如 conlian-uat-2026)
nameTEXTNOT NULL项目名称
descriptionTEXTDEFAULT ''项目描述
ownerTEXTDEFAULT ''项目负责人
statusTEXTDEFAULT 'active'项目状态
updated_atTEXT自动更新最后更新时间
testersidINTEGERPK AUTO自增主键
project_idTEXTFK, UNIQUE(project,name)所属项目
nameTEXTNOT NULL验收人姓名
emp_idTEXTDEFAULT ''工号
org2TEXTDEFAULT ''二级机构
org3TEXTDEFAULT ''三级机构
updated_atTEXT自动更新信息更新时间
resultsidINTEGERPK AUTO自增主键
project_idTEXTUNIQUE(p,t,c)所属项目
tester_nameTEXTUNIQUE(p,t,c)验收人姓名
case_idTEXTUNIQUE(p,t,c)用例标识(索引号)
statusTEXTDEFAULT ''pass/fail/partial/空
remarkTEXTDEFAULT ''备注内容
sync_timeTEXT自动最近同步时间
test_casesidINTEGERPK AUTO自增主键
project_idTEXTFK所属项目
moduleTEXTDEFAULT ''功能模块
sub_moduleTEXTDEFAULT ''二级模块
scenarioTEXTNOT NULL验证场景描述
expectedTEXTDEFAULT ''预期效果
sort_orderINTEGERDEFAULT 0排序序号
sharesidTEXTPK8位短链ID
project_idTEXTNOT NULL所属项目
cases_dataTEXTNOT NULL用例模板JSON数据
created_atTEXT自动创建时间
expires_atTEXTNOT NULL过期时间(30天)

2.3 索引设计

索引名字段用途
idx_results_project_testerresultsproject_id, tester_name按项目+验收人查询结果
idx_results_caseresultsproject_id, case_id按项目+用例查询
idx_testers_projecttestersproject_id按项目列出验收人
idx_test_cases_projecttest_casesproject_id按项目列出用例
idx_shares_expiressharesexpires_at过期清理

3. 前后端交互时序图

3.1 登录鉴权流程

sequenceDiagram
    participant U as 用户浏览器
    participant API as Pages Functions
    participant D1 as D1 数据库

    U->>API: POST /api/login {name, empId}
    API->>API: 匹配 ADMIN_WHITELIST
(姓名或工号) alt 命中白名单 API->>API: HMAC-SHA256 签发 token
(12h 有效期) API-->>U: {isAdmin: true, token, name} U->>U: 存储 token + testerInfo 到 LocalStorage else 普通验收人 API-->>U: {isAdmin: false, name} U->>U: 仅存储 testerInfo end

3.2 数据同步流程

sequenceDiagram
    participant U as 用户浏览器
    participant LS as LocalStorage
    participant API as Pages Functions
    participant D1 as D1 数据库

    Note over U,D1: 上传(防抖 30s)
    U->>LS: saveResults() 写入本地
    U->>API: POST /api/data {results, testerInfo, testData}
    API->>D1: INSERT OR REPLACE results(批量)
    API-->>U: {success: true}

    Note over U,D1: 加载(页面初始化)
    U->>API: GET /api/data?project=X&tester=Y
    API->>D1: SELECT FROM results
    D1-->>API: rows
    API-->>U: {results, testerInfo, syncTime}
    U->>LS: 缓存到本地

    Note over U,D1: 定时轮询(每 5 分钟)
    U->>API: GET /api/meta?project=X&tester=Y
    API-->>U: {syncTime, resultCount}
    U->>U: 比较 syncTime 判断是否有更新

3.3 管理员查看他人数据

sequenceDiagram
    participant Admin as 管理员
    participant UI as 前端
    participant API as Pages Functions
    participant D1 as D1 数据库

    Admin->>UI: 概览页点击"详情"
    UI->>API: GET /api/data?project=X&tester=张三
    API->>D1: SELECT FROM results WHERE tester_name='张三'
    D1-->>API: rows
    API-->>UI: {results, testerInfo}
    UI->>UI: 保存 _originalResults
    UI->>UI: 设置 _viewingOtherMode=true
    UI->>UI: 替换 results 为张三的数据
    UI->>UI: renderTable()(只读模式)
    Note over UI: 返回列表时 resetViewingOtherMode() 恢复

3.4 分享链接流程

sequenceDiagram
    participant Admin as 管理员
    participant API as Pages Functions
    participant D1 as D1 数据库
    participant User as 被分享人

    Admin->>API: POST /api/share {cases: [...]}
    API->>API: 生成 8 位 shareId
    API->>D1: INSERT INTO shares (id, cases_data, expires_at)
    API-->>Admin: {shareId: "abc12345"}
    Admin->>Admin: 拼接分享 URL

    Note over User,D1: 被分享人访问
    User->>API: GET /api/share/abc12345
    API->>D1: SELECT FROM shares WHERE id='abc12345'
    D1-->>API: row
    API->>API: 检查 expires_at 是否过期
    API-->>User: {cases: [...], createdAt}
    User->>User: 加载用例模板到页面

4. API 接口设计

4.1 接口清单

路径方法鉴权用途
/api/loginPOST公开身份解析,命中白名单签发管理员 token
/api/dataGET公开读取指定验收人的验收数据
/api/dataPOST公开写入验收数据(按 tester 隔离)
/api/metaGET公开项目元信息 / 单验收人状态查询
/api/aggregateGET管理员聚合所有验收人数据 + 用例模板
/api/testersGET管理员获取验收人列表
/api/user/updatePOST管理员更新用户信息
/api/user/deletePOST管理员删除用户及其数据
/api/sharePOST管理员创建用例分享链接(30 天有效)
/api/share/:idGET公开读取分享链接内容
/api/projectsGET管理员项目列表
/api/project/updatePOST管理员创建/更新项目
/api/project/deletePOST管理员删除项目及全部关联数据
/api/ai/generate-casesPOST管理员AI 辅助生成验收用例

4.2 统一响应格式

所有接口返回 JSON 格式,通用结构:

4.3 鉴权机制

HMAC-SHA256 Token

  1. 签发:登录时若命中白名单,服务端用 HMAC-SHA256 对 payload(name, empId, project, role, exp)签名,生成 body.signature 格式的 token
  2. 有效期:12 小时
  3. 传递方式:请求头 X-Admin-Token
  4. 验证:服务端重新计算 HMAC 比对签名,并检查 exp 是否过期

5. 权限控制逻辑

5.1 白名单匹配规则

管理员身份由服务端环境变量 ADMIN_WHITELIST 控制,配置在 wrangler.toml 中:

ADMIN_WHITELIST = "张三,100234,吴美玲,1010001596"
姓名或工号命中白名单即自动成为管理员。建议优先使用工号避免重名。

5.2 权限对照表

功能验收人管理员
提交/查看自己的验收结果OKOK
查看数据汇总看板(概览页)-OK
查看所有验收人明细-OK
新增/删除/导入用例-OK
导出汇总 Excel/JSON-OK
用户管理仅自己全部用户
查看他人验收详情-OK(只读)

5.3 只读模式(查看他人数据)

管理员在概览页点击某验收人的"详情"时,前端进入 _viewingOtherMode

6. 前端页面结构

6.1 页面视图

页面 ID名称URL Hash说明
pageCase验收列表#list需求项目列表,展示所有项目入口
pageDetail验收详情#detail用例表格 + 逐条填写验收结果(主工作区)
pageOverview需求概览#overview验收进度看板 + 用例管理(Tab 切换)
pageCaseManage用例管理#cases用例增删改 + 排序(仅管理员)
pageAccount用户管理#account验收人增删改(管理员管全部,验收人管自己)

6.2 侧边栏导航

左侧固定侧边栏(可折叠),包含两个菜单项:

底部显示当前用户角色(管理员/验收人),点击可切换账号。

6.3 关键全局状态

变量类型用途
resultsObject当前验收人的所有验收结果 {caseId: {status, remark}}
TEST_DATAArray用例模板数据(从 share 链接或云端加载)
_isAdminModeBoolean当前是否为管理员模式
_viewingOtherModeBoolean是否正在查看他人数据
_viewingOtherNameString正在查看的验收人姓名
PROJECT_IDString当前项目 ID(从 URL ?project= 参数获取)
API_BASEStringAPI 基础地址(默认当前域名,可通过 ?api= 覆盖)