Files
order_site/apps/backend

order-site-backend

腾讯活动浏览器会话后端。

当前主线只有一条:

  • 后端托管 Playwright 浏览器
  • 前端展示二维码并轮询会话状态
  • 登录完成后,后端直接在活动页填写 CDK、识别验证码、执行兑换
  • 兑换完成后返回状态,并按配置决定是否生成截图/证明产物

快速启动

先安装 Node 依赖:

npm install

首次使用前同步 OCR 子服务依赖:

cd /Users/yml/codes/order-site-workspace/apps/backend/subservices/ocr-worker
uv sync

复制并填写环境变量后启动:

cp /Users/yml/codes/order-site-workspace/.env.mac-docker.example /Users/yml/codes/order-site-workspace/.env
cd /Users/yml/codes/order-site-workspace/apps/backend
npm run dev

Linux 部署:

npm install
npm run build
npm run browser:install:linux
npm run start

后端渐进 TypeScript 迁移已经进入源码和构建双轨模式:

npm run typecheck
npm run build
npm test

当前约定:

  • 开发:npm run dev 使用 tsx watch 直接运行 src,并额外监听 config
  • 数据库迁移:npm run db:migrate 使用 tsx
  • 生产:npm run build 输出 distnpm run start 运行 dist/index.js
  • 新增或迁移后端模块优先使用 .ts

配置

当前后端采用 .env 单一路径做环境配置:

  • 通用默认值:config/default.cjs
  • 本地/部署覆盖:工作区根目录 .env

当前最常改的配置有:

  • 服务端口
  • 日志级别 LOG_LEVEL=debug|info|warn|error
  • 浏览器是否无头、是否预热、是否常驻、slowMo
  • OCR 子服务目录
  • 会话调试开关
  • 兑换证明模式 full | basic | off
  • Agiso 全局配置与后台店铺文件配置

Agiso 多店铺

当前支持同一个 Agiso 应用下配置多个店铺的消息 token。

  • 全局兜底配置仍走 .env
    • AGISO_APP_SECRET
    • AGISO_MESSAGING_ENABLED
  • 默认消息模板与店铺级覆盖配置改为文件:
    • apps/backend/data/agiso-shops.json
  • 后台维护入口:
    • #/admin/platform-shops

消息发送时会按 webhook 识别出的 shop_id 读取 agiso-shops.json 中的店铺配置;模板未命中时,会先回退到文件里的 defaults,再回退到系统内置默认值。店铺的 accessToken 也需要在文件中维护,不再使用全局 .env 兜底。

接口

  • POST /api/v1/tencent/browser/session 创建浏览器会话,返回 sessionId、二维码和初始状态
  • GET /api/v1/tencent/browser/session/:sessionId 返回完整会话状态
  • GET /api/v1/tencent/browser/session/:sessionId/summary 轮询用轻量摘要接口,默认不返回二维码 base64
  • POST /api/v1/tencent/browser/session/:sessionId/refresh 强制刷新后端活动页
  • POST /api/v1/tencent/browser/session/:sessionId/redeem 执行兑换
  • GET /api/v1/tencent/browser/session/:sessionId/screenshot 读取最近一次兑换截图
  • DELETE /api/v1/tencent/browser/session/:sessionId 关闭浏览器会话

目录

  • src/index.js Express 入口
  • src/routes/tencent.js 接口路由
  • src/services/session.js 会话编排与浏览器生命周期
  • src/services/session-*.js 登录、兑换、OCR、凭证产物等模块
  • subservices/ocr-worker 内嵌 OCR 子服务

Docker 开发

当前 docker-compose.dev.yml 已切到源码挂载模式:

  • postgres 容器提供开发库,后端通过 DATABASE_URL 连接
  • 后端容器启动时执行 npm installnpm run dev
  • OCR 子服务会在容器里执行 pip install -e /app/subservices/ocr-worker
  • 所以平时改 src/、改 OCR Python、改 .env,一般都不需要重建镜像
  • 生产镜像会在 build 阶段编译后端并只复制 distconfig 和运行依赖

只有下面几类改动通常还需要 docker compose -f docker-compose.dev.yml up -d --build backend

  • deploy/docker/backend.Dockerfile
  • 系统层依赖
  • Playwright 浏览器基础环境

产物

浏览器会话产物默认保存在:

  • data/browser-sessions/<sessionId>/qq-qr.png
  • data/browser-sessions/<sessionId>/session.json
  • data/browser-sessions/<sessionId>/captcha-attempt-*.png
  • data/browser-sessions/<sessionId>/redeem-result.png
  • data/browser-sessions/<sessionId>/page.html
  • data/browser-sessions/<sessionId>/result.json

这些都是运行时产物,默认不提交 Git。

运行日志默认保存在:

  • data/logs/app-YYYY-MM-DD.log
  • data/logs/webhook-YYYY-MM-DD.log

日志按天切分,默认自动清理 7 天前的旧日志。 成功的 /health/health/live/health/ready 探活请求默认不写 access log。

LOG_LEVEL 默认是 info

  • debug:输出最详细的调试日志
  • info:输出启动、请求、业务成功/失败等常规日志
  • warn:只保留告警和错误
  • error:只保留错误

OCR 子服务已经简化为:

  • 本地源码开发:在 subservices/ocr-worker 里执行一次 uv sync
  • Docker 运行:镜像构建时直接安装 Python 依赖
  • 后端调用:每次识别单独拉起一次 Python 进程,不维护常驻 OCR worker

TENCENT_REDEEM_PROOF_MODE 对应的配置文件项会影响生成强度:

  • full:完整证明
  • basic:只保留最终截图和结果 JSON
  • off:不生成证明文件