Files
20260512-skg-tk/RULES.md
2026-05-25 23:51:29 +08:00

163 lines
55 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SKG 营销内容生产平台
## 启动
- 后台启动(不弹 Terminal`./scripts/start-dev-background.sh`(通过 macOS launchd 后台托管;前端 4290 + 后端 4291日志写入 `.logs/`
- 后台停止:`./scripts/stop-dev-background.sh`
- 前端 dev`cd web && npm run dev`Next.js 16端口 4290
- 画布 dev`cd web && npm run dev:canvas`Vue / Vite端口 4292生产构建会作为根域名工作台输出
- 后端 dev`cd api && uvicorn main:app --host 127.0.0.1 --port 4291`FastAPI端口 4291重任务用
- 注意:后端不要带 `--reload` 跑长下载 / 抽帧 / 音频任务reload 会等待后台任务结束,导致 4291 端口占用但新请求卡住。
## 立项决策快索引
- 详见 `CLAUDE.md` 立项决策段 + `.memory/plan.md` 七步管线拆解
- 风格:`04-Dark-Gallery-Ambient`(路径:`~/Projects/research/20260305-网页风格库/04-Dark-Gallery-Ambient.md`
- 第一冲刺:步骤 1-4下载 / 拆轨 / 关键帧 / ASR+翻译)
- 当前产品方向2026-05-25 上游画布能力恢复版):默认入口是多人通用的 SKG 营销内容生产平台,`https://marketing.skg.com` 登录后直接进入个人生成画布,`/canvas/` 只作为旧链接兼容跳转到根域名。终端可见品牌位只放 SKG logo不在主界面展示“生图生视频”“SKG 生成画布”或长系统名。画布本体尽量恢复 `chatfire-AI/huobao-canvas` 的成熟交互不再削成三模式单输入框保留首页推荐词、画布底部推荐词、AI 润色、自动执行、工作流模板、首帧/尾帧/参考图节点、图片/视频/LLM 配置节点、模型配置和批量下载等上游能力多角度分镜、故事板、图转视频、绘本等工作流按上游结构创建节点。API 接入是例外:生成调用继续走本项目后端 `/api` 和当前登录 Cookie不要求员工在浏览器配置个人 API Key图片/视频模型选择只显示后端已经接通的媒体模型不能让浏览器本地自定义或旧缓存模型进入生成下拉。API 设置弹窗只保留模型/端点配置外观,不能出现上游注册链接或外部品牌。用户登录后仍只看到自己的任务、结果和详情页,继续沿用后端 owner 隔离;每个浏览器的画布项目先保存在本地 localStorage图片/视频资产按登录用户写入后端 job。旧 TK 复刻工作台、Agent Cut 一键出片和营销图文方案保留为高级/详情页能力,不再作为默认首页入口或默认理解框架。
## 部署事实
- 平台VPS `76.13.31.179`Ubuntu 24.04 / Docker Compose / Coolify Traefik
- Agent Cut 独立预览服务器:`2.24.28.41`Ubuntu 24.04 / Docker Compose / 裸端口 `4290`),部署目录 `/opt/skg-marketing-studio`Compose 入口 `docker-compose.standalone.yml`,访问地址 `http://2.24.28.41:4290/agent/`。该入口用于“一分钟二创出片终端”预览:用户只提交 TikTok 链接和产品图,后端 `AgentRun` 状态机负责下载、抽帧、规划、生成、自动重跑、审片和合成。
- Agent Cut 独立预览验证2026-05-21已在 `2.24.28.41``/opt/skg-marketing-studio``docker-compose.standalone.yml` 启动 `skg-agent-api` / `skg-agent-web`;独立 compose 通过网络别名兼容 Nginx 的 `skg-marketing-api` upstream。该裸 IP HTTP 入口的服务器 `deploy/.env.production` 需要 `WEB_AUTH_COOKIE_SECURE=false`;本次已补齐 `WEB_AUTH_*` 后重启验证通过:未登录 `/agent/` 返回 302 到 `/login/`,登录后 `/agent/` 返回 200`/api/agent-runs` 返回数组,容器内 `/health` 返回 `ok:true``auth_configured:true`
- 最近部署验证2026-05-25`84d9de6` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,画布图片/视频模型选择收口到当前后端真实可用媒体模型。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525105910.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。补验:外部访问 `https://marketing.skg.com/` 未登录返回 302 到 `/login/?next=/``https://marketing.skg.com/p/test` 未登录返回 302 到 `/login/?next=/p/test`;容器内 `/health` 返回 `image_options=auto,gpt-image-2,gemini-3-pro-image-preview``video_options=seedance:Seedance 2.0 Fast:doubao-seedance-2-0-fast-260128``video_duration_options=5,8,10,12,15`,图片尺寸为 `auto,1024x1536,1024x1024,1536x1024`,视频画幅为 `720x1280,1280x720,1024x1024,960x1280`;生产静态 bundle 命中 `GPT Image 2 / Gemini 图片 / Seedance 2.0 Fast / 1024x1536 / 720x1280`,未命中 `Nano Banana / Seedream / doubao-seedream / doubao-seedance-1 / sora-2 / Kling / Veo 3`
- 生产配置验证2026-05-25 23:49 CST已在服务器 `/opt/skg-marketing-studio/deploy/.env.production` 补齐飞书 OAuth 应用配置,并仅重建 `skg-marketing-api` 使环境变量生效;敏感 App Secret 不入库。验证结果:`https://marketing.skg.com/api/auth/config` 返回 `feishu_enabled=true``password_enabled=true``data_isolation_enabled=true``GET https://marketing.skg.com/api/auth/feishu/start?next=/` 返回 302 跳转到飞书授权页;容器内 `/health` 返回 `auth_modes.feishu=True`
- 最近部署验证2026-05-25`cce9779` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,恢复 `chatfire-AI/huobao-canvas` 上游画布能力但保留 SKG 后端 `/api` 接入。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525102857.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。补验:外部访问 `https://marketing.skg.com/` 未登录返回 302 到 `/login/?next=/``https://marketing.skg.com/canvas/` 返回 308 到 `/``https://marketing.skg.com/p/test` 未登录返回 302 到 `/login/?next=/p/test`;容器内静态 bundle 命中 `AI 润色 / 自动执行 / 推荐: / 首帧 / 尾帧 / 多角度分镜 / 儿童绘本 / 工作流模板 / 批量下载素材`未命中上游注册链接、火宝欢迎文案、GitHub 入口或 `/huobao-canvas`
- 最近部署验证2026-05-25`e767d2b` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,生产根域名改为直接进入个人生成画布,`/canvas/` 仅作为旧链接 308 跳转到 `/`。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525095839.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。补验:容器内 `/usr/share/nginx/html/index.html` 为 Vue 画布产物,引用 `/assets/index-CioZwOvT.js` 且 title 为 `SKG`;静态 bundle 命中 `文生图 / 文生视频 / 图生视频`,未命中 `首帧生视频 / 首尾帧生视频 / 上传首帧 / 上传尾帧 / 推荐:`;外部访问 `https://marketing.skg.com/` 未登录返回 302 到 `/login/?next=/``https://marketing.skg.com/canvas/` 返回 308 到 `/``/p/test` 未登录返回 302 到 `/login/?next=/p/test`
- 最近部署验证2026-05-25`2a1ceee` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,可见品牌位从文字命名收敛为 logo-only首页、登录页和画布首页只显示 SKG logo网页 title 和画布 title 为 `SKG`,首页入口按钮文案为“画布”。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525092749.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。容器内静态产物复验:`index.html` 包含 `<title>SKG</title>``/skg-logo-black.svg`,首页入口包含“画布”,登录页只保留 logo当前 `_next``/canvas` 产物未再命中 `SKG 生图生视频``SKG 生成画布``营销内容生产平台``内容生产画布` 等旧可见文案。
- 发布状态已部署并验证2026-05-20主体元素按套图文件夹分组展示主体生成接口提交后立即返回 queued 占位并后台逐视角生成、逐张回填;工作台外层取消 1800x1000 固定画布和应用层 `zoom` 缩放,改为正常流式桌面容器,最低操作宽度 1280px源视频工作区主体链路为上方竖向参考帧池 + 宽幅对话式转换层、下方主体元素结果栏;转换层通过参考帧 `+` 加入、参考图分析、生图对话,英文 prompt 就绪后由发送区主按钮切换为确认生成,点击后才触发主体套图生成;转换层不再固定 640px 长高,按内容自然高度显示,仅以 560px 最大高度兜底内部滚动;下方主体元素结果栏的套图输出、轮询、文件夹分组、单张重生、删除和 hover 预览逻辑保持不变;胶片双击/拖拽加入参考帧池 + 胶片缓存复用 + 音频解析失败可重试,参考帧缩略图保持小尺寸 9:16 比例 + hover 左侧紧凑预览,旧主体模板区移出主路径 + 逐句时间轴移到原版视频下方并支持双行文案 + 波形同框时间对齐画面胶片 + 胶片密度按钮上移波形顶部 + 去分隔线 + 胶片上下错落 + body 顶层原位大放大 + 隐藏源视频工作区音频解析摘要卡 + 隐藏工作区顶部状态提示条 + 三字段候选生成工作流 + 折叠紧凑候选区);`https://marketing.skg.com` 已启用应用内登录页,未登录 API 返回 401认证后首页 200容器内 `/health` 返回 `ok:true`
- 最近部署验证2026-05-25`2192f15` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,可见命名从“营销内容工作台 / 无限画布”改为“SKG 生图生视频 / 生成画布”。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525091127.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。容器内静态产物复验:首页标题和 header 包含 `SKG 生图生视频`,首页按钮包含 `生成画布``/canvas/index.html` 标题为 `SKG 生成画布`,当前 `_next``/canvas` 产物未再命中旧可见命名。
- 最近部署验证2026-05-25`2d19560` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,新增登录保护下的 SKG 内部生成画布入口 `https://marketing.skg.com/canvas/`,并把首页“生成画布”按钮接到该路径。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525085342.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。补验:未登录访问 `/canvas` 返回 308 到 `/canvas/`,未登录访问 `/canvas/` 返回 302 到 `/login/?next=/canvas/`;容器内确认 `/usr/share/nginx/html/canvas/index.html``canvas/assets` 已存在。
- 最近部署验证2026-05-25`779e9b3` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,视频生成改为个人公平队列:全局默认同时 2 个视频、单用户同时 1 个视频,同一用户连续提交会显示排队且不会占满所有生成通道。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525075706.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。复验静态 bundle 已包含 `queue_message` 和“排队中”文案API 容器确认 `VIDEO_QUEUE_MAX_CONCURRENT=2``VIDEO_QUEUE_MAX_CONCURRENT_PER_USER=1`
- 最近部署验证2026-05-25`b2d84dc` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,修复首页生成视频完成后结果卡点击无反馈的问题:`MediaAssetTile` 新增可选原生视频 controls首页仅在视频 `completed` 后开启播放控件,失败状态展示错误说明。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525071823.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。复验静态 bundle 已包含 `videoControls``controls:`;生产容器内最近完成视频文件存在:`/data/jobs/16b984e804f5/storyboard_videos/ac96d8eba342/video.mp4`,大小 3687229 bytes。
- 最近部署验证2026-05-25`486a682` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,登录页新增飞书客户端 UA 自动发起 `/api/auth/feishu/start`Nginx 未登录跳转改为 `/login/?next=$request_uri` 以保留回跳页面。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525070905.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。复验静态 bundle 已包含 `skg-feishu-auto-login``auth/feishu/start?next`,未登录访问 `/detail/?job=test` 返回 `Location: /login/?next=/detail/?job=test`。该部署当时生产 `auth_config()` 仍显示 `feishu_enabled=false`2026-05-25 23:49 CST 已在服务器环境补齐飞书 OAuth 配置并重建 API当前 `feishu_enabled=true`
- 最近部署验证2026-05-25`a02c5eb` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,修复无首帧文生图 / 文生视频创建空白创作任务时的 `createCreativeImageJob 400 There was an error parsing the body`。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525064659.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。云端容器确认图片 / 视频密钥均已配置:`image_configured=True``video_configured=True``image_base_url=https://ai.skg.com/ezlink/v1``video_base_url=https://ai.skg.com/doubao`;同一个缺 boundary 的空 multipart 探针已从旧版 400 变为认证层 401说明请求体解析问题已消除。
- 最近部署验证2026-05-25`e77e77f` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,生产入口新增图片尺寸、视频画幅和按真实能力返回的视频时长选择。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525062614.tgz`;脚本内首次验证在容器刚启动 3 秒时遇到 `/` 500随后复跑 `./scripts/verify-prod-docker.sh root@76.13.31.179` 通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。容器内能力复验:`image_sizes=auto,1024x1536,1024x1024,1536x1024``video_sizes=720x1280,1280x720,1024x1024,960x1280``video_durations=5,8,10,12,15``video_max=15`;当前 Doubao / Seedance 单条不暴露 30 秒。
- 最近部署验证2026-05-25`dcc8abc` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,生产入口为单对话框四模式生成页,并接入图片 / 视频模型选择。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260525030237.tgz`;首次脚本校验在容器刚启动时遇到 `/` 500经日志确认是 Nginx auth 子请求早于 API 就绪导致的临时连接拒绝,随后复跑 `./scripts/verify-prod-docker.sh root@76.13.31.179` 通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。容器内模型选项复验:`image_options=auto,gpt-image-2,gemini-3-pro-image-preview``video_options=seedance,kling,veo3,veo``video_configured=True`
- 最近部署验证2026-05-24`828b86d` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`,生产入口切换为多人通用营销内容创作平台首页,并保留 `/agent/` 作为高级复刻入口、`/detail/?job=<id>` 作为任务详情页。部署前脚本已备份生产私有环境、任务数据、资源库和 secrets 到 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260523175306.tgz`;生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`、未发现本地 API/dev URL 泄漏)。
- 最近部署验证2026-05-22`6427935` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260522012756.tgz`,生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok``api:ytdlp_cookie_args []`)。部署后已把生产私有 `deploy/.env.production` 明确固定为多语言本地 ASR 路径并重启 API`ASR_LANGUAGE=auto``FASTER_WHISPER_MODEL=base``ASR_REMOTE_ENABLED=false``ASR_LOCAL_FALLBACK_ENABLED=true``ASR_AUDIO_FALLBACK_ENABLED=false`;复验 `./scripts/verify-prod-docker.sh root@76.13.31.179` 通过,容器内 `/health` 确认 `asr_language=auto``faster_whisper=base`
- 最近部署验证2026-05-21`8458dac` 已按“先本地 Docker、再上传部署”流程上线。上线前在本机 Docker 构建 `skg-marketing-studio-web:latest` / `skg-marketing-studio-api:latest`,并用本地 Compose 容器验证通过:`web:/ 302``web:/login/ 200``web:/_next/does-not-exist.js 404``web:/api/health 401``api:health ok``api:ytdlp_cookie_args []`、静态 bundle 包含 `未来健康 · 营销内容工作台``信息流广告复刻生产`,且未发现本地 API/dev URL 泄漏。随后通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260521070327.tgz`,生产 Docker 重建后脚本内验证通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`)。
- 最近部署验证2026-05-20`6597db3` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520151033.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后检查首页静态资源,当前加载 chunk `/_next/static/chunks/c48f07b9aef1cd29.js` 已包含 `min-w-[1280px]``max-w-[1920px]`,未再命中旧的 `h-[1000px]``w-[1800px]``BOARD_SCALE_PRESETS``boardScale`;对应工作台取消固定画布缩放,按浏览器正常流式布局渲染。
- 最近部署验证2026-05-20`2b842fd` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520145223.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后检查首页静态资源,当前加载 chunk `/_next/static/chunks/743b82648dfa9db9.js` 已包含 `h-32``maxHeight:560``提示词就绪``确认生成`,且未再命中旧的 `height:640` / `h-40`;对应转换层取消固定长高,生成要求输入区回到 128px底部仍由发送区主按钮确认生成。
- 最近部署验证2026-05-20`ab31a98` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520144227.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后检查首页静态资源,当前加载 chunk `/_next/static/chunks/5bbecb6cf31316cb.js` 已包含 `h-40``提示词就绪``确认生成`,对应生成要求输入框加高到 160px出图提示词生成后不再自动弹窗底部主按钮直接切换为确认生成。
- 最近部署验证2026-05-20`215987a` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520142849.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后检查首页静态资源,当前加载 chunk `/_next/static/chunks/54e1ee55c5019be8.js` 已包含 `height:640`,对应转换层固定高度从 560px 扩到 640px。
- 最近部署验证2026-05-20`e1e9bf8` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520142145.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后 Playwright 以 2048x1060 复测生成要求 composer文本输入区实际高约 119px张数控件和发送按钮实际高约 42px页面无客户端异常验证截图 `/tmp/skg-generation-composer-expanded.png`
- 最近部署验证2026-05-20`45b25d0` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520140706.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后 Playwright 以 2048x1060 复测转换层:生成要求区不再渲染“当前要求”、“提示词已生成”和“对话记录已收起”摘要,保留元素副本也已移除;该区只保留文本输入、张数控件和发送按钮,页面无客户端异常,验证截图 `/tmp/skg-generation-composer-simplified.png`
- 最近部署验证2026-05-20`54f159b` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520135509.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后 Playwright 以 2048x1060 复测转换层:转换层和参考帧池共用高度从 500px 拉到 560px转换层内部改为 gap 堆叠并让主要板块 `shrink-0`,超出由转换层自身滚动承接;页面无客户端异常,验证截图 `/tmp/skg-conversion-stretched.png`
- 最近部署验证2026-05-20`d1e2b17` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520134529.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后 Playwright 以 2048x1060 复测转换层:内嵌“待确认提示词”卡和黑色“确认并生成 N 张”按钮均不再渲染,页面无客户端异常;有待确认 prompt 时只在“生成要求”标题右侧显示小型“待确认 · N 张”入口,验证截图 `/tmp/skg-conversion-no-inline-confirm.png`
- 最近部署验证2026-05-20`caa7b73` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520132820.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后 Playwright 以 2048x1060 复测:页面无客户端异常,源视频工作区已撤销“布局调节”按钮和 `localStorage["skg-source-workspace-layout:v1"]` 布局读写,固定为左侧原视频列 380px、9:16 视频高 500px、逐句时间轴最大高 270px、参考帧池 140px、转换层 500px 内部滚动、主体空态 78px验证截图 `/tmp/skg-layout-fixed-no-tuning.png`
- 最近部署验证2026-05-20`0db265f` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520131649.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后 Playwright 打开历史任务并展开“布局调节”:面板显示左列宽、视频高、时间轴高、参考池宽、转换层高、主体空态 6 个滑杆,调参值写入 `localStorage["skg-source-workspace-layout:v1"]`,供用户先在线试比例再固化默认值。
- 最近部署验证2026-05-20`5bffd63` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520123949.tgz`,生产 Docker 重建后脚本内验证通过(`web:/login/ 200``web:/api/health 401``api:health ok`)。线上登录后 Playwright 复测 1440x900 与 2048x1060历史任务加载后转换层占据主操作宽度主体元素下移为转换层下方的紧凑结果栏未再出现右侧三栏挤压滚动到主体元素位置后仍能看到下方分镜工作台承接。
- 最近部署验证2026-05-20`f0f567b` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520120958.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 截图复测 1440x900、1728x1117、2048x1060、2560x1440缩放后的工作台在 1440/1728/2560 这类高度有余量的窗口上下居中2048x1060 保持顶部对齐并承接纵向内容,未出现先前的底部黑边失衡。
- 最近部署验证2026-05-20`3e7c165` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520114759.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 复测 1366x768、1440x900、1728x1117、1920x1080、2048x1060、2200x1400、2560x1440缩放档位分别为 0.72、0.8、0.92、1.06、1.06、1.16、1.342048x1060 保留左右 70px 呼吸感且无横向溢出,浏览器 `pageerror` 为空。
- 最近部署验证2026-05-20`e33463e` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520113414.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 复测转换层:页面显示“生成要求”和“对话记录已收起”,不再显示旧标题“生图对话”,也不再渲染“我们将不再强制...”这类模型确认消息;最终英文 prompt 仍保留在“待确认提示词”区域,浏览器 `pageerror` 为空。
- 最近部署验证2026-05-20`f35bfe0` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520111824.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 复测 1440x900、2048x1060、2200x1400 三种窗口,工作台仍按可见宽度优先铺满且外层 wrapper 左右间隙均为 0内层画布已改用 CSS `zoom` 渲染,三个窗口分别为 `zoom=0.8/1.138/1.222``transform` 均为 `none`,避免整屏 transform 小数缩放造成文字发虚,浏览器 `pageerror` 为空。
- 最近部署验证2026-05-20`1d0a77b` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520105846.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 复测 1440x900、2048x1060、2200x1400 三种窗口,工作台按可见宽度优先缩放,外层 wrapper 左右间隙均为 0三个窗口分别缩放到 0.8、1.138、1.2222048x1060 这类高度不足场景通过纵向滚动承接,不再为了完整高度留下左右空白,浏览器 `pageerror` 为空。
- 最近部署验证2026-05-20`54eaac0` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520104155.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 复测 1440x900、2048x1060、2200x1400 三种窗口,工作台以 1800x1000 为基准分别缩放到 0.8、1.06、1.222,主网格列宽、源视频区列宽和三栏主体管线列宽保持一致,浏览器 `pageerror` 为空。
- 最近部署验证2026-05-20`64fef5a` 已通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520102354.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 以 1440x900 与 2200x1400 两种窗口复测,工作台内部画布固定为 1800x1000主网格列宽、源视频区列宽和三栏主体管线列宽一致浏览器 `pageerror` 为空。
- 最近部署验证2026-05-20`40f1f28` 已推送并通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520095941.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 复测首页正常渲染,浏览器 `pageerror` 为空。转换层不再显示固定快捷需求按钮,生图对话空态和输入框改为中性“保留识别元素 / 补充调整要求”,由识别结果 chip 和自然语言对话承接用户意图。
- 最近部署验证2026-05-20`2c0e8a0` 已推送并通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520094923.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过。线上登录后 Playwright 复测首页正常渲染到工作台,浏览器 `pageerror` 为空;本次修复 `selectedAgentTraitsDirty` 残留变量名导致的客户端 `ReferenceError`,恢复转换层页面首屏渲染。
- 最近部署验证2026-05-20`5bdde89` 已推送并通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520092721.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`、无本地 API 地址泄漏)。线上转换层识别结果 chip 改为本地即时切换:点亮表示保留元素、再次点击取消、清空按钮取消全部;点击 chip 不再触发 `/subject-agent/message`,保留元素随下一条“发送消息”一次性提交,避免每点一个特征都等待模型导致卡顿。
- 最近部署验证2026-05-20`10d955c` 已推送并通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520090750.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`、无本地 API 地址泄漏)。线上转换层已移除可见快捷需求 chip复刻/创新/卡通/人物占比作为对话默认意图写入输入提示;生成张数控件移到发送消息旁边,默认 6 张、当前支持 1-10参考输入空态和已选参考图缩略图压小并继续复用 `MediaAssetTile` hover 放大预览。
- 最近部署验证2026-05-20`b9c5511` 已推送并通过 `./scripts/deploy-prod-safe.sh` 部署到 `/opt/skg-marketing-studio`;部署前备份为 `/opt/skg-marketing-studio-backups/skg-marketing-preserve-20260520085513.tgz`,生产 Docker 重建后脚本内 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/` 302、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`、无本地 API 地址泄漏)。线上转换层已更新为参考输入区支持左侧 `+`、参考帧拖拽、胶片拖拽和本地图片拖入,下方为生图对话消息 composer右侧主体元素套图输出逻辑保持不变。
- 最近部署验证2026-05-19`fd794e3` 已推送并部署到 `/opt/skg-marketing-studio`;生产 `/health` 显示 `image=gpt-image-2``subject_image=gpt-image-2``image_request_timeout_seconds=60``image_base_url=https://ai.skg.com/ezlink/v1`。容器内最小文字生图探针在 20 秒限制下返回 `ReadTimeout`,说明当前阻塞点是 `https://ai.skg.com/ezlink/v1``gpt-image-2` 上游通道超时,服务端不会更换图片模型。
- 最近部署验证2026-05-19`3756259` 已推送并部署到 `/opt/skg-marketing-studio`;生产 `/health` 显示 `image=gpt-image-2``image_fallbacks=['gemini-3-pro-image-preview']``subject_image_fallbacks=['gpt-image-2','gemini-3-pro-image-preview']`、短时熔断阈值 2 次 / 600 秒。线上真实探针确认 `gpt-image-2` 读超时后同次调用可自动兜底到 `gemini-3-pro-image-preview` 并返回图片;模拟探针确认连续 2 次主模型失败后第三次直接走 Gemini。
- 最近部署验证2026-05-20`c245bff` 已推送并部署到 `/opt/skg-marketing-studio`;本地 `python3 -m py_compile api/main.py``web/npm run build` 通过,生产 Docker 重建后 `./scripts/verify-prod-docker.sh` 通过web 容器 Up、API 容器 Up、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`)。容器内模型偏好探针确认转换层 `image_model_preference` 路由:`auto -> ['gpt-image-2','gemini-3-pro-image-preview']``gpt-image-2 -> ['gpt-image-2']``gemini-3-pro-image-preview -> ['gemini-3-pro-image-preview']`
- 最近部署验证2026-05-20`2366662` 已推送并部署到 `/opt/skg-marketing-studio`;本地 `python3 -m py_compile api/main.py``web/npm run build` 通过,生产 Docker 重建后 `./scripts/verify-prod-docker.sh` 通过。容器内后处理探针确认白底小主体保存为 `1152x2048` 时有效主体高度占比从约 0.60 可放大到 `0.906`,主体 6 视图 prompt 已注入同一份 pack bible。
- 最近部署验证2026-05-20`7acbfd5` 已推送并部署到 `/opt/skg-marketing-studio`;本地 `python3 -m py_compile api/main.py``web/npm run build` 通过,生产 Docker 重建后 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`)。转换层主体提示词记忆和生图模型偏好改为按 `job.id` 隔离;有参考帧的 `reconstruction_mode=similar` 会先生成 source brief再把参考帧作为 `/images/edits``image[]` 参考提交;自主描述空文本切到 `reconstruction_mode=same` 源形象锁定路径。
- 最近部署验证2026-05-20`e10b1a6` 已推送并部署到 `/opt/skg-marketing-studio`;本地 `python3 -m py_compile api/main.py``web/npm run build` 通过,生产 Docker 重建后 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`)。转换层改为项目内生图对话智能体,新增 `Job.subject_agent``/subject-agent/analyze``/subject-agent/message`GPT / Gemini 改为成套控制分析、对话和生图模型数量与要求修改进入对话状态后再调用主体套图生成Pydantic `model_bundle` protected namespace warning 已消除。
- 最近部署验证2026-05-20`d82175f` 已推送并部署到 `/opt/skg-marketing-studio`;本地 `python3 -m py_compile api/main.py``web/npm run build` 通过,生产 Docker 重建后 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`)。转换层去掉方向卡片、卡通风格下拉和独立数量按钮,保留单一参考区 + 生图对话;后端 `/subject-agent/message` 从对话中识别 `selected_mode``quantity` 后再驱动主体套图生成。
- 最近部署验证2026-05-20`f1c710e` 已推送并部署到 `/opt/skg-marketing-studio`;本地 `web/npm run build` 通过,生产 Docker 重建后 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`)。转换层中间栏先清空为待重构占位,不再接收拖拽或触发 subject-agent / subject-assets右侧主体元素输出逻辑保持不变。
- 最近部署验证2026-05-20`7e763cf` 已推送并部署到 `/opt/skg-marketing-studio`;本地 `web/npm run build` 通过,生产 Docker 重建后 `./scripts/verify-prod-docker.sh` 通过web/API 容器 Up、`/login/` 200、缺失 `_next` 资源 404、未登录 `/api/health` 401、容器内 `api:health ok`)。转换层改为参考帧分析 + 对话生成提示词 + 弹窗确认后再生成主体套图;右侧主体元素输出逻辑保持不变。部署时发现服务器 `WEB_AUTH_*` 环境变量缺失导致 `/auth/check` 503已从 `/root/skg-marketing-studio-login.txt` 和新 session secret 恢复服务器 `deploy/.env.production` 后重启验证通过;后续同步生产代码必须继续排除服务器真实 `deploy/.env.production`
- 主站 / 前端:`https://marketing.skg.com`
- 旧画布路径:`https://marketing.skg.com/canvas/`(仅兼容跳转到根域名)
- API / 后端:`https://marketing.skg.com/api`
- 代码仓库 / Gitea`https://git.kang-kang.com/kangwan/20260512-skg-tk`
- 文档 / 解析:`docs/source-analysis.html`(项目内独立文档,不公开挂主应用路由)
- 管理后台:待定
- 服务器目录:`/opt/skg-marketing-studio`
- 生产部署唯一入口:`./scripts/deploy-prod-safe.sh`(先在服务器备份 `deploy/.env.production``data/jobs`、资源库和 `secrets`,再用受保护 rsync 同步代码,最后 Docker 重建并运行 `verify-prod-docker.sh`
- 生产容器重建命令:`docker compose -f docker-compose.prod.yml --env-file deploy/.env.production up -d --build`;只允许脚本内部或明确只重启容器时使用,不允许再用裸 `rsync --delete` 手动同步。
- 独立预览容器重建命令:服务器 `/opt/skg-marketing-studio` 下执行 `docker compose -f docker-compose.standalone.yml --env-file deploy/.env.production up -d --build`Web 暴露 `0.0.0.0:4290->80`,后端仅在 compose 内部网络暴露,`/api/` 由 Web 容器 Nginx 反代并复用应用内登录校验。
- 生产架构:`web` 容器用 Nginx 承载 Next 静态导出与根域名 Vue / Vite 画布静态应用;构建时先生成画布,再 Next 静态导出,最后用画布产物覆盖 `web/out/index.html``/assets/`,使登录后的 `/` 直接进入画布;`/canvas/` 只做 308 兼容跳转到 `/``/login/``/_next/``/assets/``/skg-logo-black.svg``/oasis-source/` 等登录页必需静态资源公开访问;未登录访问工作台跳转 `/login/``/api/` 通过 Nginx `auth_request` 校验 FastAPI 会话 Cookie 后反代到 `skg-marketing-api:4291`Traefik 通过 `coolify` 外部网络接入 80/443
- Web 验收必须以生产 Docker 形态为准:前端是 `next export` 静态产物 + Nginx不是 `next dev` / `next start`。任何 Web 改动部署后必须运行 `./scripts/verify-prod-docker.sh`,确认 `/login/``/_next/``/api/health`、本地 API 地址泄漏和 API 镜像 `.env` 污染检查通过;不能只用本地 `npm run build` 作为上线依据。
- 当前音频解析:`https://ai.skg.com/azure/v1``gpt-4o-transcribe` 当前返回 `DeploymentNotFound`,且官方 Azure OpenAI transcription 路径探测也未返回可用部署;生产临时复制本地成功策略,直接使用容器内多语言 `faster-whisper` 真实转写,默认语种为 `auto`,支持中文、英文和其他多语言原文识别,关闭 Gemini 多模态音频兜底。拿到真实 Azure ASR deployment 名后再恢复 `ASR_REMOTE_ENABLED=true`,并保持 `ASR_LANGUAGE` 为空或 `auto`,除非明确只想强制单一语种。
- 持久化目录:服务器 `./data/jobs` 挂载到后端 `/data/jobs`;全局资源中心持久化在 `./data/asset_library``./data/prompt_library``./data/_trash`
- TikTok 下载登录态:公开视频默认不带 cookies 直接下载,生产环境变量必须显式保持 `YTDLP_COOKIES_FILE=``YTDLP_COOKIES_FROM_BROWSER=` 为空,防止容器读取不存在的浏览器 cookies。只有 TikTok 明确要求登录态时,才使用服务器私有 cookies 文件 `./secrets/tiktok_cookies.txt` 挂载到 API 容器 `/run/secrets/tiktok_cookies.txt` 并配置 `YTDLP_COOKIES_FILE=/run/secrets/tiktok_cookies.txt``yt-dlp` 会在任务结束时回写 cookies因此不要把该挂载设为只读不要使用云端浏览器读取方案也不要把 cookies 入库。生产容器严禁使用 `YTDLP_COOKIES_FROM_BROWSER=chrome`
- 登录凭证:生产入口以飞书免登录为主;飞书 OAuth 的 `FEISHU_APP_ID` / `FEISHU_APP_SECRET` 只放服务器 `deploy/.env.production`,回调地址固定为 `https://marketing.skg.com/api/auth/feishu/callback` 并需要在飞书开放平台应用安全设置中登记。登录页读取 `/api/auth/config` 后,如果检测到飞书客户端并且 `feishu_enabled=true`,会自动跳转 `/api/auth/feishu/start`,普通浏览器仍保留“飞书免登录”按钮和备用账号。原账号密码登录保留为备用入口,用户名写下方快捷登录,密码明文备份只放服务器 `/root/skg-marketing-studio-login.txt``WEB_AUTH_PASSWORD` / `WEB_AUTH_SESSION_SECRET` 只放服务器 `deploy/.env.production`。开启 `AUTH_DATA_ISOLATION_ENABLED=true` 后,新建任务、素材任务和一键出片记录按登录用户隔离;历史无 owner 的旧任务只对备用账号可见,飞书用户互不可见。
- 禁止手动裸 `rsync --delete` 到服务器;必须使用 `./scripts/deploy-prod-safe.sh`。如遇极端情况必须手动同步,命令必须同时包含 protect/exclude`.git``.memory``.logs``.pids``data``jobs``secrets``api/jobs``api/.env``api/.env.local``api/.env.production``deploy/.env.production``web/node_modules``web/.next``web/out`。不要把本地 `api/.env``deploy/.env.production` 覆盖到 `/opt/skg-marketing-studio`,也不要删除服务器 `data/jobs`,否则会清空案例、登录和模型配置。
## 快捷登录
- 登录地址:`https://marketing.skg.com/login/`
- 主路径:飞书免登录
- 备用用户名:`skg`
- 备用密码:见服务器 `/root/skg-marketing-studio-login.txt`(不入库)
- 说明:当前是生产入口应用内登录页;飞书 App Secret、数据库密码、API Key、服务器 root 密码不要写这里
## 元数据回写清单
- 新增或变更公网地址后,必须同步更新 `.project.json.urls`
- 如果有网页后台登录:
- 可直接入库:写 `.project.json.quick_login`
- 不应入库:写 `.project.json.credentials` 引用
- 部署完成后,`RULES.md``.project.json` 必须同一次任务一起更新
## Git / 开发收口
- 工作看板全局规则适用于本项目:`/Users/kangwan/Projects/code/20260317-rules-dashboard/RULES.md``SCHEMA.md``rules/03-Git约定.md``rules/04-版本发布规则.md`
- 主分支:`main`
- 主远端:`origin``ssh://git@git.kang-kang.com:22222/kangwan/20260512-skg-tk.git`
- Gitea 网页仓库:`https://git.kang-kang.com/kangwan/20260512-skg-tk`
- 每次开发结束前必须执行并汇报 `git status -sb` 和变更范围
- 代码、规则、部署或元数据变更必须形成 `feat:``fix:``docs:``chore:``release:` 等人工语义 commit`auto-save` 只算安全快照
- 能联网和鉴权时必须 `git push origin main`;如果不能推送,最终回复必须写清楚当前分支、领先/落后数量、最新未推送 commit 和失败原因
## 环境变量
- `LLM_BASE_URL` / `LLM_API_KEY`OpenAI 兼容网关,用于翻译、文案改写、音频分析等文本/多模态理解模型调用
- `ASR_BASE_URL` / `ASR_API_KEY`OpenAI Audio Transcriptions 兼容网关,用于上传 `audio.wav` 做真实转写;未配置 `ASR_API_KEY` 时复用 `LLM_API_KEY`,生产默认指向 `https://ai.skg.com/azure/v1`
- `ASR_MODEL`OpenAI Audio Transcriptions 音频转写模型;微软通道使用 Azure OpenAI 部署名 `gpt-4o-transcribe`,如果 Azure 侧实际部署名不同必须同步改这里
- `ASR_LANGUAGE`:远端和本地 ASR 的可选输入语言提示,默认空值/`auto`,由模型自动识别中文、英文和其他多语言;只有明确知道素材固定语种时才填写 ISO-639-1 代码强制识别。
- `ASR_REMOTE_ENABLED`:是否启用远端 OpenAI Audio Transcriptions微软 ASR 验收时必须为 `true`。当前生产因 `https://ai.skg.com/azure/v1``gpt-4o-transcribe` 返回 `DeploymentNotFound`,临时设为 `false`,直接走容器内 `faster-whisper`,等真实 Azure deployment 名补齐后再恢复。
- `ASR_LOCAL_FALLBACK_ENABLED`:是否允许远端 ASR 失败后落到本机 / 容器内 ASR当前生产为 `true`,复制本地成功路径的“本机真实转写”策略,云端用 CPU 版 `faster-whisper` 替代本机 Mac 的 `mlx_whisper`
- `ASR_AUDIO_FALLBACK_ENABLED`:是否允许远端和本机 ASR 失败后落到多模态音频兜底;生产微软 ASR 验收设为 `false`,避免静默使用 Gemini 音频
- `FASTER_WHISPER_MODEL` / `FASTER_WHISPER_DEVICE` / `FASTER_WHISPER_COMPUTE_TYPE`:容器内本地 ASR 兜底,仅在 `ASR_LOCAL_FALLBACK_ENABLED=true` 时启用;默认用多语言 `base`,不要改回 `*.en` 英文专用模型,否则中文和多语言识别会退化。
- `ASR_FALLBACK_MODEL`:多模态音频兜底模型,仅在 `ASR_AUDIO_FALLBACK_ENABLED=true` 时用于兜底或音频画像,默认 `gemini-2.5-flash`;如果模型不能真实听到音频或返回疑似逐秒假字幕,后端必须拒绝写入时间轴
- `ASR_TIMEOUT_SECONDS`:远端 ASR / 翻译 / 音频分析单次请求超时;当前生产本地转写模式设为 45 秒,微软 ASR 重新启用时可按素材长度提高。
- `LOCAL_ASR_BIN` / `LOCAL_ASR_MODEL` / `LOCAL_ASR_TIMEOUT_SECONDS`:本机 ASR 兜底,默认使用 `/opt/homebrew/bin/mlx_whisper` + `mlx-community/whisper-tiny`,用于当前 SKG 网关 `/audio/transcriptions` 不可用时生成真实逐句时间轴
- `TRANSLATE_MODEL`:字幕翻译模型,默认 `gemini-2.5-flash`
- `GPT_TEXT_MODEL`GPT 文本 / 视觉默认模型,默认 `gpt-4o`;用于兜底修正旧 Gemini 覆盖值
- `REWRITE_MODEL`:通用改写/分镜描述模型,默认 `gpt-4o`;如果旧环境仍写 `gemini-*`,后端会自动改用 `GPT_TEXT_MODEL`
- `VISION_MODEL`:关键帧画面理解模型,默认 `gpt-4o`;如果旧环境仍写 `gemini-*`,后端会自动改用 `GPT_TEXT_MODEL`
- `AUDIO_REWRITE_MODEL`:后续音频口播改写模型,默认跟随 `REWRITE_MODEL`;如果旧环境仍写 `gemini-*`,后端会自动改用 `REWRITE_MODEL`
- `AUDIO_PRODUCT_BRIEF`:音频口播改写时注入的 SKG 产品卖点
- `PRODUCT_VIEW_MODEL`:同一产品素材池的视角标注/自动识别模型;当前按项目要求强制使用 `gpt-image-2`
- `IMAGE_BASE_URL` / `IMAGE_API_KEY` / `IMAGE_MODEL`OpenAI 兼容生图网关;当前所有生图入口主模型仍为 `gpt-image-2`
- `IMAGE_REQUEST_TIMEOUT_SECONDS`:单次图片网关请求超时,默认 60 秒;超时会直接把该视图标失败并继续下一张,避免主体 6 视图整包长时间无反馈
- `IMAGE_FALLBACK_ENABLED` / `IMAGE_FALLBACK_MODEL`:图片主模型故障兜底;当前允许在 `gpt-image-2` 超时、429、5xx 或网络错误时临时使用 `gemini-3-pro-image-preview`400/401/403/404 和参数错误不兜底
- `IMAGE_CIRCUIT_FAILURE_THRESHOLD` / `IMAGE_CIRCUIT_COOLDOWN_SECONDS`:短时熔断配置,默认 `gpt-image-2` 连续 2 次上游类失败后 600 秒内直接走 Gemini 兜底;成功恢复后自动清空失败计数
- `GPT_IMAGE_MODEL` / `SUBJECT_ASSET_IMAGE_MODEL` / `SUBJECT_ASSET_IMAGE_MODELS`:保留兼容旧环境变量名;主体 6 视图在转换层默认自动使用 `gpt-image-2`,同一套图内一旦触发 Gemini 兜底,后续视图沿用 Gemini避免一张张等待主模型超时用户显式选择 GPT 或 Gemini 时,`image_model_preference` 会让主体套图只走所选模型
- `AI_HTTP_PROXY` / `IMAGE_HTTP_PROXY`:可选的 AI 网关出站代理;本地 launchd 后台进程不一定继承 shell 的 `http_proxy/https_proxy`,如生图报 DNS / ConnectError可在本地 `api/.env` 配置后重启后端。`/health` 只回传是否配置代理,不回传代理地址。
- `YTDLP_COOKIES_FILE` / `YTDLP_COOKIES_FROM_BROWSER`:可选 TikTok 下载登录态;生产云端固定使用 cookies 文件 `/run/secrets/tiktok_cookies.txt`(宿主机 `./secrets/tiktok_cookies.txt` 挂载进容器),本地开发可临时用浏览器 cookies。cookies 文件属于敏感登录态,只能放本机或服务器私有路径,不允许入库。
- `VOICE_PROVIDER`:配音通道,服务端固定使用 `azure_openai`;旧环境若写 `minimax` 会被忽略
- `AZURE_OPENAI_BASE_URL` / `AZURE_OPENAI_API_KEY`:微软 Azure OpenAI 协议配音网关;本地未单独配置 Key 时回退复用 `LLM_API_KEY`
- `AZURE_TTS_MODEL` / `AZURE_TTS_VOICE_ID` / `AZURE_TTS_VOICE_POOL` / `AZURE_TTS_PATH` / `AZURE_TTS_PATHS`Azure OpenAI TTS 模型、默认音色、音色池和 OpenAI 协议语音路径;后端会按 `AZURE_TTS_PATHS` 依次尝试,便于区分路径不对和整条语音服务不可用
- `POE_API_KEY` / `VIDEO_API_KEY`:视频生成通道 Key只能放本地环境变量
- `WEB_AUTH_USERNAME` / `WEB_AUTH_PASSWORD` / `WEB_AUTH_SESSION_SECRET`:生产备用网页登录和会话签名配置;密码和 session secret 只放服务器环境变量,不入库。即使只开飞书免登录,也必须配置 `WEB_AUTH_SESSION_SECRET` 用于签名会话 Cookie。
- `FEISHU_APP_ID` / `FEISHU_APP_SECRET`:飞书免登录 OAuth 应用凭证;只放服务器 `deploy/.env.production` 或本地 `api/.env`,不入库。
- `FEISHU_REDIRECT_URI`:飞书 OAuth 回调地址,生产固定为 `https://marketing.skg.com/api/auth/feishu/callback`
- `FEISHU_OAUTH_SCOPE`:飞书 OAuth 授权范围;默认空值,按飞书应用后台已开权限执行。
- `FEISHU_ALLOWED_EMAIL_DOMAINS` / `FEISHU_ALLOWED_EMAILS` / `FEISHU_ALLOWED_TENANT_KEYS`:可选飞书账号白名单;留空时由飞书应用可见范围控制。
- `AUTH_DATA_ISOLATION_ENABLED`:多用户数据隔离开关,生产保持 `true`;新建 `Job` / `AgentRun` 会写入当前登录用户 owner列表和详情访问只返回本人数据。
- `VIDEO_QUEUE_MAX_CONCURRENT` / `VIDEO_QUEUE_MAX_CONCURRENT_PER_USER`:视频生成进程内队列并发上限,生产默认全局同时 2 个、单用户同时 1 个;同一用户连续提交会排队,其他用户仍可获得执行机会。当前队列不依赖 RedisAPI 容器重启会把未完成视频标记为失败并提示重新生成。
- `FFMPEG_BIN` / `FFPROBE_BIN`:可选本地媒体二进制路径;本机 Homebrew ffmpeg 动态库损坏时,后端会自动跳过不可用的 PATH 版本并尝试本机静态 ffmpeg 备选,生产仍建议使用系统 ffmpeg/ffprobe
- 生产环境变量:服务器只使用 `deploy/.env.production`,模板为 `deploy/.env.production.example`;真实 Key 不入库
- 同步生产代码时必须排除服务器真实 `deploy/.env.production`,只同步 `deploy/.env.production.example`网页登录密码、session secret、ASR/API Key 只保留在服务器环境文件和 `/root/skg-marketing-studio-login.txt`
## 规则
- 不允许编造不存在的部署域名、账号、密码
- 没有公网地址时,`.project.json.urls` 保持空数组
- 任何部署或域名变化,都要先改元数据,再视为任务完成
- 用户给到源码 / 下载包 / 参考实现时,默认优先按源码实现和复刻,不先自创“类似效果”;如果因安全、依赖、性能或部署限制必须改写,必须先说明差异和原因。
- 媒体素材交互为项目基底规则任何图片、视频、抽帧、产品图、AI 生成图、首尾帧和视频候选缩略图,默认复用 `web/components/media-asset-tile.tsx`;必须支持鼠标停留顶层放大预览,可删除素材必须有删除按钮,预览不能被面板或滚动容器遮挡。
## 注意事项
- 项目内源码解析页:`docs/source-analysis.html`
- 源码解析页是给产品协作和需求描述用的独立 HTML不接入 Next 应用路由
- 后续任何功能、节点职责、接口、数据模型或用户操作路径变更,都要同步更新 `docs/source-analysis.html` 的对应章节和变更记录