# LTJT 生产控制平面 这是围绕现有 LTJT 浏览器适配器增加的生产级控制层。它不新增 ERP 业务路线,也不替换 LTJT;它负责把现有任务、解析结果、确认、插件接管、执行回查和审计变成可持久化、可恢复的服务端状态。 ## 服务边界 - PostgreSQL 是任务、事件、幂等、审计和回查状态的唯一事实源。 - 管理员使用原生账号登录;服务端会话使用 HttpOnly/Secure/SameSite Cookie。 - 业务页面通过 REST 创建/确认任务,通过 SSE 或轮询读取服务端状态。 - Chrome 插件仍在管理员已登录的浏览器/ERP 会话中工作;`chrome.storage.local` 只是临时缓存。 - ERP 写入继续遵循预检、管理员确认、单次提交、ERP 回查;不确定结果禁止自动重试。 - 由于插件不使用独立凭据,执行期间必须保持管理员业务页面和已登录 ERP 浏览器会话可用;页面断开不会触发自动补偿或重复提交。 - 服务端先创建唯一 ERP execution,再允许页面向插件下发;同一任务只有一个 `erp` attempt。刷新、重连、超时和迟到回执都不能创建第二次执行。 - 插件回执必须携带服务端 `execution_id` 和领取连接;完成、阻断及待回查状态不可被后续 `running` 回执覆盖。执行租约过期会进入待回查,不会重新入队。 - Chrome 插件最低兼容版本为 `0.3.1`。该版本在 `chrome.storage.local` 保存执行闸门,并在真实提交前持久化 `write_started`;扩展后台重启后也不会重跑同一任务。 ## 本地命令 本地命令会自动读取项目根目录 `.env`,不需要先手动 `export` 环境变量。首次部署或换环境时,只需替换该文件;生产 Docker Compose 使用 `.env.production`。 ```bash npm install npm run check npm run build npm run db:migrate ADMIN_USERNAME=admin ADMIN_PASSWORD='replace-with-12-plus-chars' npm run admin -- bootstrap npm run data:retention npm run dev ``` `db:migrate` 和管理员初始化需要可连接的 PostgreSQL。开发机没有数据库时,可以运行 `npm run test:control-plane` 完成无数据库静态/健康烟测。 ## 生产部署 1. 复制 `.env.production.example` 为部署机受保护的 `.env.production`,填入 PostgreSQL URL、字段加密密钥和外部解析 Key。 2. 在正式数据库上线前执行并验证备份:`infra/backup-postgres.sh`。 3. 使用 `docker compose --env-file .env.production up -d --build` 启动;Compose 会先执行数据库迁移,再启动控制平面。 4. 首次启动后在容器内通过 `docker compose exec -e ADMIN_USERNAME=admin -e ADMIN_PASSWORD='replace-with-12-plus-chars' control-plane node dist/control-plane/src/admin-cli.js bootstrap` 创建管理员;不要把密码写入镜像或 Git。 5. 配置 `infra/Caddyfile` 中的正式域名和 HTTPS,然后在 Chrome 插件中加载对应生产业务页面。 正式环境没有独立 staging。上线前必须完成离线测试、迁移预检查和迁移前备份;恢复检查使用 `infra/restore-check.sh` 指向一次性恢复数据库。 生产容器中的定期清理命令为:`docker compose exec control-plane node dist/control-plane/src/retention.js`。本地开发则使用上面的 `npm run data:retention`。