85 lines
5.1 KiB
Markdown
85 lines
5.1 KiB
Markdown
# 架构与数据模型
|
||
|
||
## 系统边界
|
||
|
||
Delivery Desk 是 React + Express 单体应用,前后端共享 `shared/types.ts`。开发环境使用 SQLite 和本地上传目录,正式环境使用 PostgreSQL 和腾讯云 COS。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
browser["工作台 / 客户浏览器"] --> app["Express + React"]
|
||
api["外部 API 客户端"] --> app
|
||
app --> db["SQLite / PostgreSQL"]
|
||
app --> storage["本地 uploads / 腾讯云 COS"]
|
||
```
|
||
|
||
## 产品层级
|
||
|
||
```text
|
||
运营组
|
||
└── 项目
|
||
└── 作品
|
||
└── 验收轮次(每轮一个方案)
|
||
```
|
||
|
||
- 客户会话绑定项目,不能跨项目访问。
|
||
- 项目级 API Key 只能访问绑定项目;平台级 Key 可跨组管理项目。
|
||
- 历史作品交付集不再是产品层级。`collections` 表仅作为旧数据和旧 URL 的迁移兼容容器。
|
||
- `work_versions` 继续保存每轮内容快照,但与 `review_rounds` 强制一对一。
|
||
- 升级时如检测到旧的一轮多方案数据,会把额外方案拆成只读的独立历史轮次,保留图片、批注、验收事件和当前活动方案,再建立一轮一方案唯一约束。
|
||
|
||
## 主要数据表
|
||
|
||
| 表 | 用途 |
|
||
|---|---|
|
||
| `operation_groups` | 运营组及状态 |
|
||
| `users` / `sessions` | 工作台账号、角色和会话 |
|
||
| `customer_sessions` | 项目级客户会话 |
|
||
| `projects` | 项目、客户访问配置和自动验收状态 |
|
||
| `collections` | 迁移期内部兼容容器,不属于产品层级 |
|
||
| `notes` | 作品当前状态、活动轮次和项目归属 |
|
||
| `review_rounds` | 验收轮次与完成原因 |
|
||
| `work_versions` | 单轮内容快照;每轮恰好一条 |
|
||
| `images` | 轮次图片、顺序和存储信息 |
|
||
| `annotations` | 图片坐标批注 |
|
||
| `text_annotations` | 标题、正文和 Tag 选区批注与文本上下文 |
|
||
| `work_comments` | 作品总体反馈 |
|
||
| `review_events` | 提交、退修、通过和重新打开记录 |
|
||
| `api_keys` | 平台级/项目级 API Key 哈希 |
|
||
| `storage_configs` | 加密后的 COS 配置 |
|
||
| `audit_logs` | 管理与业务审计 |
|
||
|
||
## 状态计算
|
||
|
||
作品状态为 `draft`、`pending`、`changes_requested`、`approved`。只有活动轮次可新增批注和作出验收决定;新轮次会锁定旧轮次。客户通过活动轮次后作品为已通过,退修后运营通过新轮次提交修改。
|
||
|
||
项目验收状态自动计算:
|
||
|
||
- 没有非草稿作品:`draft`
|
||
- 存在未通过作品:`reviewing`
|
||
- 所有非草稿作品通过:`completed`
|
||
- 人工归档:`archived`
|
||
|
||
完成项目为只读。新增作品、创建新轮次或由管理员重新打开作品时,项目恢复为验收中;已关闭或归档项目始终只读。开放反馈不会阻止通过;通过时仍为开放的反馈会标记为随该轮验收关闭,历史内容保留。
|
||
|
||
## 批注模型
|
||
|
||
- 作品缩略图只展示现有坐标标记,不能新增坐标批注;点击标记会联动打开验收协作面板中的对应反馈。
|
||
- 点击图片打开悬浮图片窗格;只有该窗格可以新增坐标批注,并支持原图查看、缩放和前后切换。点击窗格外会同时关闭图片窗格和验收协作面板。
|
||
- 标题、正文和 Tag 批注保存 `start_offset`、`end_offset`、`selected_text` 及前后文,提交时校验选区仍与轮次快照一致。
|
||
- `GET /api/works/:workId/annotations` 按轮次返回图片批注、文字批注、总体反馈和验收事件。
|
||
- `GET /api/works/:workId/optimization-context?round=N` 聚合指定轮次的内容、图片和可执行反馈,默认排除已关闭或撤回记录,供外部内容优化流程只读使用。
|
||
|
||
## Agent 安全上传
|
||
|
||
内置 Agent Skill 固定连接 `http://192.168.30.90:3010`,采用“发现目标 → 操作者确认运营组和项目 → 生成计划 → 操作者确认内容与确认码 → 单次写入 → 读取核验”的两阶段确认流程。计划文件只保存目标 ID、待写内容和确认摘要,不保存 API Key,并写入已被 Git 忽略的 `tmp/` 目录。
|
||
|
||
新建作品以 `externalId` 保证幂等;新增验收轮次没有幂等键。轮次写入超时或响应不明确时,必须先重新读取作品状态,不能直接重试,以免重复创建轮次。
|
||
|
||
## 存储
|
||
|
||
平台管理员可在管理页保存和测试 COS 配置。SecretId/SecretKey 使用 `COS_CONFIG_ENCRYPTION_KEY` 派生的 AES-256-GCM 密钥加密,读取接口不返回明文。连接测试会上传、读取并删除临时对象。
|
||
|
||
外部 API 图片统一归一到当前活动 COS:所有 URL 会先拒绝本机、私有网段、局域网和保留地址;与配置的 COS 公开域名或 CDN 域名同源时直接保存,其他公开 URL 经 DNS SSRF 防护、图片类型和 20 MB 大小校验后下载,并按内容哈希转存到 COS。没有活动 COS 配置时拒绝 URL 导入;全部图片准备成功后才创建作品或新验收轮次。该规则不自动追溯迁移历史图片内容。
|
||
|
||
外部 Agent 只有本地图片时使用现有 multipart 通道,不使用 Base64。Skill 计划只保存文件路径、大小和 SHA-256,执行时重新校验后流式上传;服务端以 Sharp 验证真实图片内容,再从临时文件写入活动 COS。
|