Tangent-90C/aix-collab-workbench

★ 0Forks 0HTMLGitHub ↗Compare

README

AI+X 话题海报协作工作台

这是从原单文件海报编辑器改造出的多人协作版本。海报版式、字段编辑、JSON 导入导出、单张 PNG 和批量 ZIP 导出保持不变;PocketBase 新增了共享数据、实时更新、编辑租约、在线成员、修改记录、回收站和团队素材库。

协作规则

  • 团队共用一个账号和密码,每台浏览器另外保存昵称与设备 ID。
  • 同一话题只有一台设备持有编辑权;其他人实时只读查看,可以确认后接管。
  • 编辑租约每 15 秒续期,60 秒未续期自动失效。
  • 输入停止约 420 毫秒后保存;旧版本保存返回 409,其他设备占用时返回 423。
  • 昵称归属用于可信团队协作,不属于不可伪造的审计身份。
  • 离线时显示上次缓存并禁止编辑,恢复连接后重新同步。

本地运行

要求 Node.js 22、npm、curl、unzip。

./scripts/download-pocketbase.sh
npm install
export WORKBENCH_USER=workbench
export WORKBENCH_PASSWORD='请替换为团队长密码'
./.runtime/pocketbase serve \
  --http=127.0.0.1:8090 \
  --dir=./pb_data \
  --migrationsDir=./pb_migrations \
  --hooksDir=./pb_hooks

另开终端运行:

npm run dev

打开 http://127.0.0.1:4173。登录框中的 workbench 会自动映射为 PocketBase 内部账号 [email protected]。

首次启动必须设置至少 12 位的 WORKBENCH_PASSWORD,否则迁移会终止,不会生成公开可猜的默认账号。PocketBase 只在第一次迁移时创建团队账号;之后修改环境变量不会重置密码,应由服务器管理员在 PocketBase 管理后台修改。

旧数据迁移

  1. 打开原来的 话题回顾总结-海报工作台.html。
  2. 点击“导出全部 JSON”。
  3. 登录协作版,点击“导入全部 JSON”并选择导出的文件。
  4. 数组、{meta, topics} 和单话题 JSON 均继续兼容;新导入话题会获得 PocketBase 合法 ID。

原 JSON 中已有的 Base64 Logo、二维码和头像会在首次保存时自动上传到共享素材库,并按 SHA-256 去重,再替换为素材引用。以后需要重复使用的图片可直接从“共享素材库”选择,不再在每个话题中重复写入 Base64。

Docker Compose 发布(推荐)

要求 Docker Engine 与 Docker Compose v2。镜像采用多阶段构建:Node.js 只负责构建前端,最终镜像只包含 PocketBase、静态页面、迁移和 Hooks;支持 amd64 与 arm64。

cp .env.example .env
openssl rand -base64 24   # 填入 WORKBENCH_PASSWORD,至少 12 位
openssl rand -hex 16      # 填入 PB_ENCRYPTION_KEY,必须恰好 32 字符
docker compose config
docker compose up -d --build
docker compose ps

默认仅发布到宿主机 127.0.0.1:8090,数据保存在 Compose 命名卷 workbench-data,不会随容器重建而删除。打开 http://127.0.0.1:8090/api/workbench/health 应返回健康状态。

.env.example 默认使用 DaoCloud 的 Docker Hub 国内镜像地址,适合中国大陆服务器;如果服务器能直接访问 Docker Hub,可将 NODE_BASE_IMAGE 和 ALPINE_BASE_IMAGE 改回 node:22.14.0-alpine、alpine:3.21。

常用运维命令:

docker compose logs -f workbench
docker compose restart workbench
docker compose up -d --build
docker compose down                 # 保留数据卷
docker compose down --volumes       # 会删除全部业务数据,请勿日常使用
  • 参考 deploy/nginx.conf.example 将现有 HTTPS 子域名反向代理到 127.0.0.1:8090;配置已关闭代理缓冲,避免影响 PocketBase 的实时 SSE。
  • 公网防火墙只开放 80/443,不直接开放 8090。
  • 管理后台 /_/ 应限制到运维 IP 或额外加一层认证。
  • 页面和 Nginx 已设置 noindex,但登录页本身仍可能被扫描发现。
  • 容器以 UID/GID 10001 的非 root 用户运行,根文件系统只读、移除 Linux capabilities,并启用健康检查和日志轮转。
  • PocketBase 固定为 0.39.8。升级前先备份并在副本上执行迁移测试,不使用浮动 latest。

如果之前已用原生方式运行并存在 ./pb_data,先停止旧服务,然后把数据复制进 Compose 卷:

docker compose build
docker compose run --rm --no-deps --user 0:0 \
  --entrypoint sh -v "$PWD/pb_data:/source:ro" workbench \
  -c 'cp -a /source/. /app/pb_data/'
docker compose up -d

Docker 数据备份

备份脚本会短暂停止服务,确保 SQLite 数据库与素材文件处于一致状态;备份完成后自动恢复服务,默认保留 14 天:

./scripts/docker-backup.sh

备份文件写入 ./backups/pb_data-时间.tar.gz。可通过 WORKBENCH_BACKUP_DIR 和 WORKBENCH_BACKUP_RETENTION_DAYS 修改目录与保留天数。建议用 systemd timer 或 cron 每天运行,并把备份同步到另一台服务器或对象存储。

原生 Linux 发布(可选)

npm ci
npm run build:release
./scripts/download-pocketbase.sh

build:release 会把完整静态站点复制到 pb_public/,随后由同一个 PocketBase 进程提供网页、API、实时 SSE 和素材文件。若采用 Docker Compose,无需执行本节命令。

  • 参考 deploy/ai-x-poster-workbench.service 创建 systemd 服务。
  • 参考 deploy/nginx.conf.example 将现有 HTTPS 子域名反向代理到 127.0.0.1:8090。
  • 公网防火墙只开放 80/443,不直接开放 8090。
  • 管理后台 /_/ 应限制到运维 IP 或额外加一层认证。
  • 设置 PocketBase 内置限流;页面和 Nginx 已设置 noindex,但登录页本身仍可能被扫描发现。
  • PocketBase 固定为 0.39.8。升级前先备份并在副本上执行迁移测试,不使用浮动 latest。

原生方式备份

scripts/backup.sh 使用 SQLite 在线备份并复制本地素材,默认保留 14 天:

sudo WORKBENCH_DIR=/opt/ai-x-poster-workbench \
  WORKBENCH_BACKUP_DIR=/var/backups/ai-x-poster-workbench \
  ./scripts/backup.sh

建议通过 systemd timer 每天执行,并每周把备份目录同步到另一台服务器或对象存储。恢复前停止 PocketBase,将备份的 data.db 和 storage/ 放回 pb_data/。

验证

npm test
WORKBENCH_PASSWORD='测试密码' npm run test:api
PLAYWRIGHT_CHROMIUM_EXECUTABLE=/path/to/chrome \
  WORKBENCH_PASSWORD='测试密码' npm run test:e2e
npm run build

test:api 和 test:e2e 需要本地 PocketBase 与 Vite 服务已启动。端到端测试会创建测试话题、上传一个 1×1 PNG 素材,并验证双浏览器实时同步,因此应在测试数据库运行。

Contributors

Tangent-90C

Issues