{"allowContribute":false,"item":{"artifactHtml":"\u003cstyle\u003e\n  :root { --paper:#FFFBF5; --ink:#1C1E1E; --ink-2:#5E6A6B; --accent:#C2410C; --accent-2:#9A3412; --soft:#FFF1E6; --soft-2:#FFF7ED; --hair:#E8DDD0; --ok:#0F766E; --muted:#F1EDE8; }\n  :root[data-theme=\"dark\"] { --paper:#141412; --ink:#EDE9E3; --ink-2:#A8B0B1; --accent:#FB7135; --accent-2:#F97316; --soft:#2A1E14; --soft-2:#231A12; --hair:#2D2A26; --ok:#2DD4BF; --muted:#1E1E1C; }\n  .doc { background:var(--paper); color:var(--ink); padding:28px 30px; font:16px/1.72 -apple-system,\"PingFang TC\",\"Noto Sans TC\",sans-serif; max-width:860px; margin:0 auto; }\n  .eyebrow { font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.16em; color:var(--accent); text-transform:uppercase; }\n  h1 { font-size:27px; line-height:1.25; letter-spacing:-.02em; margin:10px 0 0; }\n  .lede { color:var(--ink-2); font-size:14px; margin:10px 0 0; line-height:1.6; }\n  .meta { display:flex; flex-wrap:wrap; gap:8px; margin:14px 0 0; }\n  .meta span { font:600 11px ui-monospace,Menlo,monospace; letter-spacing:.04em; padding:5px 9px; border-radius:999px; border:1px solid var(--hair); background:var(--muted); color:var(--ink-2); }\n  .meta span.bad { background:var(--soft); color:var(--accent-2); border-color:#FDBA74; }\n  :root[data-theme=\"dark\"] .meta span.bad { border-color:#7C2D12; }\n  .stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; margin:20px 0; }\n  .stat { background:var(--soft-2); border:1px solid var(--hair); border-radius:10px; padding:13px 14px; }\n  .stat.bad { background:var(--soft); border-color:#FDBA74; }\n  :root[data-theme=\"dark\"] .stat.bad { border-color:#7C2D12; }\n  .stat .k { font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.08em; color:var(--accent); }\n  .stat .v { font-size:22px; font-weight:800; margin-top:4px; letter-spacing:-.02em; }\n  .stat .n { font-size:12px; color:var(--ink-2); margin-top:2px; line-height:1.5; }\n  .callout { display:flex; gap:13px; padding:14px 16px; background:var(--soft); border:1px solid #FDBA74; border-radius:10px; margin:18px 0; }\n  :root[data-theme=\"dark\"] .callout { border-color:#7C2D12; }\n  .callout .tag { flex:none; font:800 11px ui-monospace,Menlo,monospace; letter-spacing:.08em; color:var(--accent); padding-top:2px; }\n  .callout div { font-size:14px; line-height:1.7; color:var(--ink); }\n  h2 { font-size:18px; margin:28px 0 10px; letter-spacing:-.01em; padding-bottom:8px; border-bottom:1px solid var(--hair); }\n  h3 { font-size:14px; margin:18px 0 8px; color:var(--accent-2); letter-spacing:.04em; }\n  p { color:var(--ink-2); margin:0 0 10px; font-size:14.5px; line-height:1.78; }\n  ul,ol { margin:0 0 14px 18px; padding:0; color:var(--ink-2); font-size:14.5px; line-height:1.78; }\n  li { margin:4px 0; }\n  li strong { color:var(--ink); }\n  code { font:600 13px ui-monospace,Menlo,monospace; background:var(--muted); padding:1px 6px; border-radius:4px; border:1px solid var(--hair); }\n  .tableWrap { overflow-x:auto; margin:12px 0 16px; border:1px solid var(--hair); border-radius:10px; }\n  table { border-collapse:collapse; width:100%; font-size:13.5px; min-width:520px; }\n  th,td { text-align:left; padding:10px 12px; border-bottom:1px solid var(--hair); vertical-align:top; }\n  th { font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.06em; color:var(--ink-2); background:var(--muted); white-space:nowrap; }\n  td { color:var(--ink-2); }\n  td:first-child { font-weight:700; color:var(--ink); white-space:nowrap; }\n  .steps { list-style:none; margin:10px 0 14px; padding:0; counter-reset:step; }\n  .steps li { counter-increment:step; display:flex; gap:12px; padding:12px 14px; background:var(--muted); border:1px solid var(--hair); border-radius:10px; margin:8px 0; }\n  .steps li::before { content:counter(step); flex:none; width:28px; height:28px; display:grid; place-items:center; background:var(--accent); color:#fff; border-radius:999px; font:800 12px ui-monospace,Menlo,monospace; margin-top:1px; }\n  .steps li.bad::before { background:var(--accent); }\n  .steps .t { font-weight:700; color:var(--ink); font-size:14px; }\n  .steps .d { font-size:13px; color:var(--ink-2); margin-top:2px; }\n  .grid2 { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin:12px 0; }\n  .card { border:1px solid var(--hair); border-radius:10px; padding:14px; background:var(--muted); }\n  .card .num { font:800 11px ui-monospace,Menlo,monospace; color:var(--accent); }\n  .card .title { font-weight:800; font-size:14px; margin:4px 0 6px; }\n  .card p { font-size:13px; margin:0; }\n  .pill { display:inline-block; font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.06em; padding:3px 8px; border-radius:999px; border:1px solid var(--hair); background:var(--paper); color:var(--ink-2); margin-right:6px; }\n  .pill.bad { background:var(--soft); color:var(--accent-2); border-color:#FDBA74; }\n  :root[data-theme=\"dark\"] .pill.bad { border-color:#7C2D12; }\n  .foot { margin-top:24px; padding:14px 16px; background:var(--muted); border:1px dashed var(--hair); border-radius:10px; font-size:12.5px; color:var(--ink-2); line-height:1.7; }\n  @media (max-width:640px) { .doc { padding:20px 16px; } h1 { font-size:22px; } .grid2 { grid-template-columns:1fr; } }\n\u003c/style\u003e\u003cdiv class=\"doc\"\u003e\n  \u003cheader\u003e\n    \u003cdiv class=\"eyebrow\"\u003eCubeLV 平台 Bug 回報 · 市集上架\u003c/div\u003e\n    \u003ch1\u003eCubeLV 平台 Bug 回報：上架組合包打包超時觸發 HTTP 504 未進入 AI 審核\u003c/h1\u003e\n    \u003cp class=\"lede\"\u003e上架組合包時，打包階段耗時過長 → Gateway / LB 超時中斷 → 回應 \u003ccode\u003eHTTP 504 Gateway Timeout\u003c/code\u003e，請求未抵達 AI 審核，無法上架且無審核紀錄可追。\u003c/p\u003e\n    \u003cdiv class=\"meta\"\u003e\n      \u003cspan\u003e回報日 2026-08-29\u003c/span\u003e\n      \u003cspan class=\"bad\"\u003eHTTP 504 Gateway Timeout\u003c/span\u003e\n      \u003cspan\u003e階段：打包 → 審核前\u003c/span\u003e\n      \u003cspan\u003e嚴重度 🔴 高 · 阻斷發布\u003c/span\u003e\n    \u003c/div\u003e\n  \u003c/header\u003e\n\n  \u003csection class=\"stats\" data-cube=\"stats\"\u003e\n    \u003cdiv class=\"stat bad\"\u003e\u003cdiv class=\"k\"\u003e錯誤代碼\u003c/div\u003e\u003cdiv class=\"v\"\u003e504\u003c/div\u003e\u003cdiv class=\"n\"\u003eGateway Timeout\u003cbr\u003e超時中斷\u003c/div\u003e\u003c/div\u003e\n    \u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e發生時機\u003c/div\u003e\u003cdiv class=\"v\"\u003e打包中\u003c/div\u003e\u003cdiv class=\"n\"\u003e點擊上架後\u003cbr\u003e等待期間\u003c/div\u003e\u003c/div\u003e\n    \u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003eAI 審核\u003c/div\u003e\u003cdiv class=\"v\"\u003e未進入\u003c/div\u003e\u003cdiv class=\"n\"\u003e無任務、無紀錄\u003cbr\u003e無退回原因\u003c/div\u003e\u003c/div\u003e\n    \u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e影響\u003c/div\u003e\u003cdiv class=\"v\"\u003e阻斷\u003c/div\u003e\u003cdiv class=\"n\"\u003e大包必現\u003cbr\u003e重試同樣失敗\u003c/div\u003e\u003c/div\u003e\n  \u003c/section\u003e\n\n  \u003cdiv class=\"callout\"\u003e\u003cspan class=\"tag\"\u003e核心判斷\u003c/span\u003e\u003cdiv\u003e\u003cstrong\u003e這不是 AI 審核被拒，是連審核都沒排進去。\u003c/strong\u003e504 發生在 Gateway 層，打包請求在單一 HTTP 連線內同步執行、超過 upstream timeout（常見 30s / 60s）就被切斷，後端審核服務根本沒收到任務。\u003c/div\u003e\u003c/div\u003e\n\n  \u003ch2\u003e一、現象\u003c/h2\u003e\n  \u003cp\u003e於市集執行「上架組合包」後，前端長時間轉圈、無進度提示，最終彈出 \u003ccode\u003e504 Gateway Timeout\u003c/code\u003e。檢查後台：無 AI 審核任務、無審核結果、無可重送審的入口，狀態回到未送審。\u003c/p\u003e\n  \u003cul\u003e\n    \u003cli\u003e\u003cspan class=\"pill bad\"\u003e504\u003c/span\u003e錯誤發生在打包階段，非審核階段\u003c/li\u003e\n    \u003cli\u003e組合包內容越多 / 檔案越大，越容易復現（打包耗時與體積正相關）\u003c/li\u003e\n    \u003cli\u003e重試相同組合包 → 同樣 504，無法靠重試自癒\u003c/li\u003e\n    \u003cli\u003e使用者無法區分是網路問題、打包失敗還是審核失敗\u003c/li\u003e\n  \u003c/ul\u003e\n\n  \u003ch2\u003e二、重現步驟（推估）\u003c/h2\u003e\n  \u003col class=\"steps\"\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e準備較大的組合包\u003c/div\u003e\u003cdiv class=\"d\"\u003e含多個插件 / 檔案，或單檔體積較大，觸發較長的打包/壓縮/校驗時間\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e執行上架\u003c/div\u003e\u003cdiv class=\"d\"\u003e市集 → 組合包 → 上架，觀察請求開始後長時間無回應\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e等待至 Gateway 超時門檻\u003c/div\u003e\u003cdiv class=\"d\"\u003e數十秒後（依 LB/Nginx 設定常見 30s / 60s / 120s）回應 \u003ccode\u003e504\u003c/code\u003e\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e檢查後台\u003c/div\u003e\u003cdiv class=\"d\"\u003e審核中心 / 任務清單：無對應 AI 審核紀錄，視為從未送審\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\n  \u003ch2\u003e三、實際 vs 預期\u003c/h2\u003e\n  \u003cdiv class=\"tableWrap\"\u003e\n  \u003ctable\u003e\n    \u003cthead\u003e\u003ctr\u003e\u003cth\u003e項目\u003c/th\u003e\u003cth\u003e實際行為\u003c/th\u003e\u003cth\u003e預期行為\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\n    \u003ctbody\u003e\n      \u003ctr\u003e\u003ctd\u003e打包\u003c/td\u003e\u003ctd\u003e同步阻塞在單一 HTTP 請求內，超時即全中斷\u003c/td\u003e\u003ctd\u003e非同步背景任務，前端輪詢或訂閱進度\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003e超時處理\u003c/td\u003e\u003ctd\u003e直接拋 504 給前端，無 taskId、無續查入口\u003c/td\u003e\u003ctd\u003e超時前回 \u003ccode\u003e{ taskId }\u003c/code\u003e，背景續跑；或提供明確錯誤文案\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e完全未觸發\u003c/td\u003e\u003ctd\u003e打包完成後自動進入 AI 審核佇列\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003e使用者回饋\u003c/td\u003e\u003ctd\u003e只有 504，看不出是打包慢還是審核問題\u003c/td\u003e\u003ctd\u003e明確狀態機：打包中 → 已送審 → 審核結果\u003c/td\u003e\u003c/tr\u003e\n    \u003c/tbody\u003e\n  \u003c/table\u003e\n  \u003c/div\u003e\n\n  \u003ch2\u003e四、可能原因推測\u003c/h2\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003cstrong\u003e同步打包架構：\u003c/strong\u003e壓縮、校驗、產物生成都在 API 請求執行緒內同步執行，耗時隨組合包大小線性增長\u003c/li\u003e\n    \u003cli\u003e\u003cstrong\u003eUpstream timeout \u0026lt; 打包耗時：\u003c/strong\u003eGateway / Nginx / LB 的超時門檻小於實際打包時間，必觸 504\u003c/li\u003e\n    \u003cli\u003e\u003cstrong\u003e未非同步化：\u003c/strong\u003e缺少 \u003ccode\u003e建立任務 → 背景執行 → 查詢狀態 → 完成後入審核\u003c/code\u003e 的四段式流程\u003c/li\u003e\n    \u003cli\u003e\u003cstrong\u003e無進度回饋與續查機制：\u003c/strong\u003e前端無法顯示進度、無法以 taskId 續查，只能乾等至超時\u003c/li\u003e\n  \u003c/ol\u003e\n\n  \u003ch2\u003e五、影響範圍\u003c/h2\u003e\n  \u003cdiv class=\"tableWrap\"\u003e\n  \u003ctable\u003e\n    \u003cthead\u003e\u003ctr\u003e\u003cth\u003e功能\u003c/th\u003e\u003cth\u003e影響\u003c/th\u003e\u003cth\u003e說明\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\n    \u003ctbody\u003e\n      \u003ctr\u003e\u003ctd\u003e組合包上架\u003c/td\u003e\u003ctd\u003e🔴 阻斷\u003c/td\u003e\u003ctd\u003e體積/數量大的包必定失敗，無法發布\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e🔴 未觸發\u003c/td\u003e\u003ctd\u003e無任務可追、無日誌可查\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003e創作者體驗\u003c/td\u003e\u003ctd\u003e🟡 困惑\u003c/td\u003e\u003ctd\u003e重試無效、無指引，誤以為是審核被拒\u003c/td\u003e\u003c/tr\u003e\n    \u003c/tbody\u003e\n  \u003c/table\u003e\n  \u003c/div\u003e\n\n  \u003ch2\u003e六、建議修復方向\u003c/h2\u003e\n  \u003cdiv class=\"grid2\"\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 01\u003c/div\u003e\u003cdiv class=\"title\"\u003e改為非同步打包\u003c/div\u003e\u003cp\u003e\u003ccode\u003ePOST /bundle/publish\u003c/code\u003e 僅建立任務回 \u003ccode\u003etaskId\u003c/code\u003e，打包在 worker / queue 背景執行，前端輪詢 \u003ccode\u003eGET /bundle/tasks/:id\u003c/code\u003e 或 WebSocket 訂閱進度。\u003c/p\u003e\u003c/div\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 02\u003c/div\u003e\u003cdiv class=\"title\"\u003e分層 timeout + 友好錯誤\u003c/div\u003e\u003cp\u003e短期無法非同步時，調大打包 API 的 upstream timeout（如 300s），並對 504 回專屬文案：「打包逾時，請拆小組合包或稍後重試」。\u003c/p\u003e\u003c/div\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 03\u003c/div\u003e\u003cdiv class=\"title\"\u003e任務狀態機與日誌\u003c/div\u003e\u003cp\u003e提供 \u003ccode\u003equeued / packing / packed / reviewing / done / failed\u003c/code\u003e 狀態 API，失敗時回原因與可操作建議。\u003c/p\u003e\u003c/div\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 04\u003c/div\u003e\u003cdiv class=\"title\"\u003e打包效能優化\u003c/div\u003e\u003cp\u003e增量打包、並行壓縮、快取已打包產物，減少重複計算；大檔分片處理。\u003c/p\u003e\u003c/div\u003e\n  \u003c/div\u003e\n  \u003cp\u003e前端同步配合：打包期間顯示進度條與取消按鈕；收到 504 時自動以 \u003ccode\u003etaskId\u003c/code\u003e 續查，而非直接報錯終止。\u003c/p\u003e\n\n  \u003ch2\u003e七、暫時規避（給創作者）\u003c/h2\u003e\n  \u003cul\u003e\n    \u003cli\u003e嘗試\u003cstrong\u003e拆小組合包\u003c/strong\u003e分批上架，降低單次打包耗時\u003c/li\u003e\n    \u003cli\u003e避開尖峰時段重試\u003c/li\u003e\n    \u003cli\u003e記錄\u003cstrong\u003e組合包名稱 / 大小 / 操作時間\u003c/strong\u003e，提供給工程團隊對照 Gateway log 定位超時門檻\u003c/li\u003e\n    \u003cli\u003e若需保留原包體積，請先回報此 Bug 筆記連結，請後端協助以背景任務手動觸發打包與送審\u003c/li\u003e\n  \u003c/ul\u003e\n\n  \u003cdiv class=\"foot\"\u003e\n    \u003cstrong\u003e備註：\u003c/strong\u003e此為使用者回報之推測性 Bug（操作端僅可見 504，無後端 log）。實際打包耗時、Gateway 超時數值與是否已進入審核佇列，需由後端 APM / Gateway access log / 審核服務日誌進一步確認。建議工程側補上 \u003ccode\u003erequest_id\u003c/code\u003e 與打包任務關聯，以便下次復現時直接定位。\u003cbr\u003e\n    \u003cspan style=\"color:var(--ink-2)\"\u003e分類：市集 · 上架流程 · 打包/審核 \u0026nbsp;|\u0026nbsp; 關鍵字：504 / timeout / async task / AI review\u003c/span\u003e\n  \u003c/div\u003e\n\u003c/div\u003e","content":"\u003cdiv class=\"doc\"\u003e  \u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e錯誤代碼\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e504\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003eGateway Timeout超時中斷\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e發生時機\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e打包中\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e點擊上架後等待期間\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003eAI 審核\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e未進入\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e無任務、無紀錄無退回原因\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e影響\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e阻斷\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e大包必現重試同樣失敗\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e \u003cdiv class=\"callout\"\u003e\u003cspan class=\"tag\"\u003e核心判斷\u003c/span\u003e\u003cdiv\u003e\u003cstrong\u003e這不是 AI 審核被拒，是連審核都沒排進去。\u003c/strong\u003e504 發生在 Gateway 層，打包請求在單一 HTTP 連線內同步執行、超過 upstream timeout（常見 30s / 60s）就被切斷，後端審核服務根本沒收到任務。\u003c/div\u003e\u003c/div\u003e \u003ch2\u003e一、現象\u003c/h2\u003e \u003cp\u003e於市集執行「上架組合包」後，前端長時間轉圈、無進度提示，最終彈出 \u003ccode\u003e504 Gateway Timeout\u003c/code\u003e。檢查後台：無 AI 審核任務、無審核結果、無可重送審的入口，狀態回到未送審。\u003c/p\u003e \u003cul\u003e \u003cli\u003e\u003cspan class=\"pill bad\"\u003e504\u003c/span\u003e錯誤發生在打包階段，非審核階段\u003c/li\u003e \u003cli\u003e組合包內容越多 / 檔案越大，越容易復現（打包耗時與體積正相關）\u003c/li\u003e \u003cli\u003e重試相同組合包 → 同樣 504，無法靠重試自癒\u003c/li\u003e \u003cli\u003e使用者無法區分是網路問題、打包失敗還是審核失敗\u003c/li\u003e \u003c/ul\u003e \u003ch2\u003e二、重現步驟（推估）\u003c/h2\u003e \u003col class=\"steps\"\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e準備較大的組合包\u003c/div\u003e\u003cdiv class=\"d\"\u003e含多個插件 / 檔案，或單檔體積較大，觸發較長的打包/壓縮/校驗時間\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e執行上架\u003c/div\u003e\u003cdiv class=\"d\"\u003e市集 → 組合包 → 上架，觀察請求開始後長時間無回應\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e等待至 Gateway 超時門檻\u003c/div\u003e\u003cdiv class=\"d\"\u003e數十秒後（依 LB/Nginx 設定常見 30s / 60s / 120s）回應 \u003ccode\u003e504\u003c/code\u003e\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e檢查後台\u003c/div\u003e\u003cdiv class=\"d\"\u003e審核中心 / 任務清單：無對應 AI 審核紀錄，視為從未送審\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003c/ol\u003e \u003ch2\u003e三、實際 vs 預期\u003c/h2\u003e \u003cdiv class=\"tableWrap\"\u003e \u003ctable\u003e \u003cthead\u003e\u003ctr\u003e\u003cth\u003e項目\u003c/th\u003e\u003cth\u003e實際行為\u003c/th\u003e\u003cth\u003e預期行為\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e \u003ctbody\u003e \u003ctr\u003e\u003ctd\u003e打包\u003c/td\u003e\u003ctd\u003e同步阻塞在單一 HTTP 請求內，超時即全中斷\u003c/td\u003e\u003ctd\u003e非同步背景任務，前端輪詢或訂閱進度\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003e超時處理\u003c/td\u003e\u003ctd\u003e直接拋 504 給前端，無 taskId、無續查入口\u003c/td\u003e\u003ctd\u003e超時前回 \u003ccode\u003e{ taskId }\u003c/code\u003e，背景續跑；或提供明確錯誤文案\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e完全未觸發\u003c/td\u003e\u003ctd\u003e打包完成後自動進入 AI 審核佇列\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003e使用者回饋\u003c/td\u003e\u003ctd\u003e只有 504，看不出是打包慢還是審核問題\u003c/td\u003e\u003ctd\u003e明確狀態機：打包中 → 已送審 → 審核結果\u003c/td\u003e\u003c/tr\u003e \u003c/tbody\u003e \u003c/table\u003e \u003c/div\u003e \u003ch2\u003e四、可能原因推測\u003c/h2\u003e \u003col\u003e \u003cli\u003e\u003cstrong\u003e同步打包架構：\u003c/strong\u003e壓縮、校驗、產物生成都在 API 請求執行緒內同步執行，耗時隨組合包大小線性增長\u003c/li\u003e \u003cli\u003e\u003cstrong\u003eUpstream timeout \u0026lt; 打包耗時：\u003c/strong\u003eGateway / Nginx / LB 的超時門檻小於實際打包時間，必觸 504\u003c/li\u003e \u003cli\u003e\u003cstrong\u003e未非同步化：\u003c/strong\u003e缺少 \u003ccode\u003e建立任務 → 背景執行 → 查詢狀態 → 完成後入審核\u003c/code\u003e 的四段式流程\u003c/li\u003e \u003cli\u003e\u003cstrong\u003e無進度回饋與續查機制：\u003c/strong\u003e前端無法顯示進度、無法以 taskId 續查，只能乾等至超時\u003c/li\u003e \u003c/ol\u003e \u003ch2\u003e五、影響範圍\u003c/h2\u003e \u003cdiv class=\"tableWrap\"\u003e \u003ctable\u003e \u003cthead\u003e\u003ctr\u003e\u003cth\u003e功能\u003c/th\u003e\u003cth\u003e影響\u003c/th\u003e\u003cth\u003e說明\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e \u003ctbody\u003e \u003ctr\u003e\u003ctd\u003e組合包上架\u003c/td\u003e\u003ctd\u003e🔴 阻斷\u003c/td\u003e\u003ctd\u003e體積/數量大的包必定失敗，無法發布\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e🔴 未觸發\u003c/td\u003e\u003ctd\u003e無任務可追、無日誌可查\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003e創作者體驗\u003c/td\u003e\u003ctd\u003e🟡 困惑\u003c/td\u003e\u003ctd\u003e重試無效、無指引，誤以為是審核被拒\u003c/td\u003e\u003c/tr\u003e \u003c/tbody\u003e \u003c/table\u003e \u003c/div\u003e \u003ch2\u003e六、建議修復方向\u003c/h2\u003e \u003cdiv class=\"grid2\"\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 01\u003c/div\u003e\u003cdiv class=\"title\"\u003e改為非同步打包\u003c/div\u003e\u003cp\u003e\u003ccode\u003ePOST /bundle/publish\u003c/code\u003e 僅建立任務回 \u003ccode\u003etaskId\u003c/code\u003e，打包在 worker / queue 背景執行，前端輪詢 \u003ccode\u003eGET /bundle/tasks/:id\u003c/code\u003e 或 WebSocket 訂閱進度。\u003c/p\u003e\u003c/div\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 02\u003c/div\u003e\u003cdiv class=\"title\"\u003e分層 timeout + 友好錯誤\u003c/div\u003e\u003cp\u003e短期無法非同步時，調大打包 API 的 upstream timeout（如 300s），並對 504 回專屬文案：「打包逾時，請拆小組合包或稍後重試」。\u003c/p\u003e\u003c/div\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 03\u003c/div\u003e\u003cdiv class=\"title\"\u003e任務狀態機與日誌\u003c/div\u003e\u003cp\u003e提供 \u003ccode\u003equeued / packing / packed / reviewing / done / failed\u003c/code\u003e 狀態 API，失敗時回原因與可操作建議。\u003c/p\u003e\u003c/div\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 04\u003c/div\u003e\u003cdiv class=\"title\"\u003e打包效能優化\u003c/div\u003e\u003cp\u003e增量打包、並行壓縮、快取已打包產物，減少重複計算；大檔分片處理。\u003c/p\u003e\u003c/div\u003e \u003c/div\u003e \u003cp\u003e前端同步配合：打包期間顯示進度條與取消按鈕；收到 504 時自動以 \u003ccode\u003etaskId\u003c/code\u003e 續查，而非直接報錯終止。\u003c/p\u003e \u003ch2\u003e七、暫時規避（給創作者）\u003c/h2\u003e \u003cul\u003e \u003cli\u003e嘗試\u003cstrong\u003e拆小組合包\u003c/strong\u003e分批上架，降低單次打包耗時\u003c/li\u003e \u003cli\u003e避開尖峰時段重試\u003c/li\u003e \u003cli\u003e記錄\u003cstrong\u003e組合包名稱 / 大小 / 操作時間\u003c/strong\u003e，提供給工程團隊對照 Gateway log 定位超時門檻\u003c/li\u003e \u003cli\u003e若需保留原包體積，請先回報此 Bug 筆記連結，請後端協助以背景任務手動觸發打包與送審\u003c/li\u003e \u003c/ul\u003e \u003cdiv class=\"foot\"\u003e \u003cstrong\u003e備註：\u003c/strong\u003e此為使用者回報之推測性 Bug（操作端僅可見 504，無後端 log）。實際打包耗時、Gateway 超時數值與是否已進入審核佇列，需由後端 APM / Gateway access log / 審核服務日誌進一步確認。建議工程側補上 \u003ccode\u003erequest_id\u003c/code\u003e 與打包任務關聯，以便下次復現時直接定位。\u003cbr\u003e \u003cspan style=\"color:var(--ink-2)\"\u003e分類：市集 · 上架流程 · 打包/審核 \u0026nbsp;|\u0026nbsp; 關鍵字：504 / timeout / async task / AI review\u003c/span\u003e \u003c/div\u003e \u003c/div\u003e","createdAt":1788014761384,"deletedAt":null,"displayMode":"artifact","embedRenders":{},"id":"9021496d162c3018b0251e13","isNew":false,"isPublic":true,"itemType":"NOTE","name":"CubeLV 平台 Bug 回報：上架組合包打包超時觸發 HTTP 504 未進入 AI 審核","parents":{"4465d0a863da5d1b345d888c":1788014761384},"preParentID":null,"updatedAt":1788094272928,"updatedBy":{"userId":"6a3dcfc700e9b9fd06d5ef","userName":"蔡其樺"},"version":17},"ownerName":"蔡其樺","subtree":[{"artifactHtml":"\u003cstyle\u003e\n  :root { --paper:#FFFBF5; --ink:#1C1E1E; --ink-2:#5E6A6B; --accent:#C2410C; --accent-2:#9A3412; --soft:#FFF1E6; --soft-2:#FFF7ED; --hair:#E8DDD0; --ok:#0F766E; --muted:#F1EDE8; }\n  :root[data-theme=\"dark\"] { --paper:#141412; --ink:#EDE9E3; --ink-2:#A8B0B1; --accent:#FB7135; --accent-2:#F97316; --soft:#2A1E14; --soft-2:#231A12; --hair:#2D2A26; --ok:#2DD4BF; --muted:#1E1E1C; }\n  .doc { background:var(--paper); color:var(--ink); padding:28px 30px; font:16px/1.72 -apple-system,\"PingFang TC\",\"Noto Sans TC\",sans-serif; max-width:860px; margin:0 auto; }\n  .eyebrow { font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.16em; color:var(--accent); text-transform:uppercase; }\n  h1 { font-size:27px; line-height:1.25; letter-spacing:-.02em; margin:10px 0 0; }\n  .lede { color:var(--ink-2); font-size:14px; margin:10px 0 0; line-height:1.6; }\n  .meta { display:flex; flex-wrap:wrap; gap:8px; margin:14px 0 0; }\n  .meta span { font:600 11px ui-monospace,Menlo,monospace; letter-spacing:.04em; padding:5px 9px; border-radius:999px; border:1px solid var(--hair); background:var(--muted); color:var(--ink-2); }\n  .meta span.bad { background:var(--soft); color:var(--accent-2); border-color:#FDBA74; }\n  :root[data-theme=\"dark\"] .meta span.bad { border-color:#7C2D12; }\n  .stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; margin:20px 0; }\n  .stat { background:var(--soft-2); border:1px solid var(--hair); border-radius:10px; padding:13px 14px; }\n  .stat.bad { background:var(--soft); border-color:#FDBA74; }\n  :root[data-theme=\"dark\"] .stat.bad { border-color:#7C2D12; }\n  .stat .k { font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.08em; color:var(--accent); }\n  .stat .v { font-size:22px; font-weight:800; margin-top:4px; letter-spacing:-.02em; }\n  .stat .n { font-size:12px; color:var(--ink-2); margin-top:2px; line-height:1.5; }\n  .callout { display:flex; gap:13px; padding:14px 16px; background:var(--soft); border:1px solid #FDBA74; border-radius:10px; margin:18px 0; }\n  :root[data-theme=\"dark\"] .callout { border-color:#7C2D12; }\n  .callout .tag { flex:none; font:800 11px ui-monospace,Menlo,monospace; letter-spacing:.08em; color:var(--accent); padding-top:2px; }\n  .callout div { font-size:14px; line-height:1.7; color:var(--ink); }\n  h2 { font-size:18px; margin:28px 0 10px; letter-spacing:-.01em; padding-bottom:8px; border-bottom:1px solid var(--hair); }\n  h3 { font-size:14px; margin:18px 0 8px; color:var(--accent-2); letter-spacing:.04em; }\n  p { color:var(--ink-2); margin:0 0 10px; font-size:14.5px; line-height:1.78; }\n  ul,ol { margin:0 0 14px 18px; padding:0; color:var(--ink-2); font-size:14.5px; line-height:1.78; }\n  li { margin:4px 0; }\n  li strong { color:var(--ink); }\n  code { font:600 13px ui-monospace,Menlo,monospace; background:var(--muted); padding:1px 6px; border-radius:4px; border:1px solid var(--hair); }\n  .tableWrap { overflow-x:auto; margin:12px 0 16px; border:1px solid var(--hair); border-radius:10px; }\n  table { border-collapse:collapse; width:100%; font-size:13.5px; min-width:520px; }\n  th,td { text-align:left; padding:10px 12px; border-bottom:1px solid var(--hair); vertical-align:top; }\n  th { font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.06em; color:var(--ink-2); background:var(--muted); white-space:nowrap; }\n  td { color:var(--ink-2); }\n  td:first-child { font-weight:700; color:var(--ink); white-space:nowrap; }\n  .steps { list-style:none; margin:10px 0 14px; padding:0; counter-reset:step; }\n  .steps li { counter-increment:step; display:flex; gap:12px; padding:12px 14px; background:var(--muted); border:1px solid var(--hair); border-radius:10px; margin:8px 0; }\n  .steps li::before { content:counter(step); flex:none; width:28px; height:28px; display:grid; place-items:center; background:var(--accent); color:#fff; border-radius:999px; font:800 12px ui-monospace,Menlo,monospace; margin-top:1px; }\n  .steps li.bad::before { background:var(--accent); }\n  .steps .t { font-weight:700; color:var(--ink); font-size:14px; }\n  .steps .d { font-size:13px; color:var(--ink-2); margin-top:2px; }\n  .grid2 { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin:12px 0; }\n  .card { border:1px solid var(--hair); border-radius:10px; padding:14px; background:var(--muted); }\n  .card .num { font:800 11px ui-monospace,Menlo,monospace; color:var(--accent); }\n  .card .title { font-weight:800; font-size:14px; margin:4px 0 6px; }\n  .card p { font-size:13px; margin:0; }\n  .pill { display:inline-block; font:700 11px ui-monospace,Menlo,monospace; letter-spacing:.06em; padding:3px 8px; border-radius:999px; border:1px solid var(--hair); background:var(--paper); color:var(--ink-2); margin-right:6px; }\n  .pill.bad { background:var(--soft); color:var(--accent-2); border-color:#FDBA74; }\n  :root[data-theme=\"dark\"] .pill.bad { border-color:#7C2D12; }\n  .foot { margin-top:24px; padding:14px 16px; background:var(--muted); border:1px dashed var(--hair); border-radius:10px; font-size:12.5px; color:var(--ink-2); line-height:1.7; }\n  @media (max-width:640px) { .doc { padding:20px 16px; } h1 { font-size:22px; } .grid2 { grid-template-columns:1fr; } }\n\u003c/style\u003e\u003cdiv class=\"doc\"\u003e\n  \u003cheader\u003e\n    \u003cdiv class=\"eyebrow\"\u003eCubeLV 平台 Bug 回報 · 市集上架\u003c/div\u003e\n    \u003ch1\u003eCubeLV 平台 Bug 回報：上架組合包打包超時觸發 HTTP 504 未進入 AI 審核\u003c/h1\u003e\n    \u003cp class=\"lede\"\u003e上架組合包時，打包階段耗時過長 → Gateway / LB 超時中斷 → 回應 \u003ccode\u003eHTTP 504 Gateway Timeout\u003c/code\u003e，請求未抵達 AI 審核，無法上架且無審核紀錄可追。\u003c/p\u003e\n    \u003cdiv class=\"meta\"\u003e\n      \u003cspan\u003e回報日 2026-08-29\u003c/span\u003e\n      \u003cspan class=\"bad\"\u003eHTTP 504 Gateway Timeout\u003c/span\u003e\n      \u003cspan\u003e階段：打包 → 審核前\u003c/span\u003e\n      \u003cspan\u003e嚴重度 🔴 高 · 阻斷發布\u003c/span\u003e\n    \u003c/div\u003e\n  \u003c/header\u003e\n\n  \u003csection class=\"stats\" data-cube=\"stats\"\u003e\n    \u003cdiv class=\"stat bad\"\u003e\u003cdiv class=\"k\"\u003e錯誤代碼\u003c/div\u003e\u003cdiv class=\"v\"\u003e504\u003c/div\u003e\u003cdiv class=\"n\"\u003eGateway Timeout\u003cbr\u003e超時中斷\u003c/div\u003e\u003c/div\u003e\n    \u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e發生時機\u003c/div\u003e\u003cdiv class=\"v\"\u003e打包中\u003c/div\u003e\u003cdiv class=\"n\"\u003e點擊上架後\u003cbr\u003e等待期間\u003c/div\u003e\u003c/div\u003e\n    \u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003eAI 審核\u003c/div\u003e\u003cdiv class=\"v\"\u003e未進入\u003c/div\u003e\u003cdiv class=\"n\"\u003e無任務、無紀錄\u003cbr\u003e無退回原因\u003c/div\u003e\u003c/div\u003e\n    \u003cdiv class=\"stat\"\u003e\u003cdiv class=\"k\"\u003e影響\u003c/div\u003e\u003cdiv class=\"v\"\u003e阻斷\u003c/div\u003e\u003cdiv class=\"n\"\u003e大包必現\u003cbr\u003e重試同樣失敗\u003c/div\u003e\u003c/div\u003e\n  \u003c/section\u003e\n\n  \u003cdiv class=\"callout\"\u003e\u003cspan class=\"tag\"\u003e核心判斷\u003c/span\u003e\u003cdiv\u003e\u003cstrong\u003e這不是 AI 審核被拒，是連審核都沒排進去。\u003c/strong\u003e504 發生在 Gateway 層，打包請求在單一 HTTP 連線內同步執行、超過 upstream timeout（常見 30s / 60s）就被切斷，後端審核服務根本沒收到任務。\u003c/div\u003e\u003c/div\u003e\n\n  \u003ch2\u003e一、現象\u003c/h2\u003e\n  \u003cp\u003e於市集執行「上架組合包」後，前端長時間轉圈、無進度提示，最終彈出 \u003ccode\u003e504 Gateway Timeout\u003c/code\u003e。檢查後台：無 AI 審核任務、無審核結果、無可重送審的入口，狀態回到未送審。\u003c/p\u003e\n  \u003cul\u003e\n    \u003cli\u003e\u003cspan class=\"pill bad\"\u003e504\u003c/span\u003e錯誤發生在打包階段，非審核階段\u003c/li\u003e\n    \u003cli\u003e組合包內容越多 / 檔案越大，越容易復現（打包耗時與體積正相關）\u003c/li\u003e\n    \u003cli\u003e重試相同組合包 → 同樣 504，無法靠重試自癒\u003c/li\u003e\n    \u003cli\u003e使用者無法區分是網路問題、打包失敗還是審核失敗\u003c/li\u003e\n  \u003c/ul\u003e\n\n  \u003ch2\u003e二、重現步驟（推估）\u003c/h2\u003e\n  \u003col class=\"steps\"\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e準備較大的組合包\u003c/div\u003e\u003cdiv class=\"d\"\u003e含多個插件 / 檔案，或單檔體積較大，觸發較長的打包/壓縮/校驗時間\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e執行上架\u003c/div\u003e\u003cdiv class=\"d\"\u003e市集 → 組合包 → 上架，觀察請求開始後長時間無回應\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e等待至 Gateway 超時門檻\u003c/div\u003e\u003cdiv class=\"d\"\u003e數十秒後（依 LB/Nginx 設定常見 30s / 60s / 120s）回應 \u003ccode\u003e504\u003c/code\u003e\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e檢查後台\u003c/div\u003e\u003cdiv class=\"d\"\u003e審核中心 / 任務清單：無對應 AI 審核紀錄，視為從未送審\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\n  \u003ch2\u003e三、實際 vs 預期\u003c/h2\u003e\n  \u003cdiv class=\"tableWrap\"\u003e\n  \u003ctable\u003e\n    \u003cthead\u003e\u003ctr\u003e\u003cth\u003e項目\u003c/th\u003e\u003cth\u003e實際行為\u003c/th\u003e\u003cth\u003e預期行為\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\n    \u003ctbody\u003e\n      \u003ctr\u003e\u003ctd\u003e打包\u003c/td\u003e\u003ctd\u003e同步阻塞在單一 HTTP 請求內，超時即全中斷\u003c/td\u003e\u003ctd\u003e非同步背景任務，前端輪詢或訂閱進度\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003e超時處理\u003c/td\u003e\u003ctd\u003e直接拋 504 給前端，無 taskId、無續查入口\u003c/td\u003e\u003ctd\u003e超時前回 \u003ccode\u003e{ taskId }\u003c/code\u003e，背景續跑；或提供明確錯誤文案\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e完全未觸發\u003c/td\u003e\u003ctd\u003e打包完成後自動進入 AI 審核佇列\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003e使用者回饋\u003c/td\u003e\u003ctd\u003e只有 504，看不出是打包慢還是審核問題\u003c/td\u003e\u003ctd\u003e明確狀態機：打包中 → 已送審 → 審核結果\u003c/td\u003e\u003c/tr\u003e\n    \u003c/tbody\u003e\n  \u003c/table\u003e\n  \u003c/div\u003e\n\n  \u003ch2\u003e四、可能原因推測\u003c/h2\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003cstrong\u003e同步打包架構：\u003c/strong\u003e壓縮、校驗、產物生成都在 API 請求執行緒內同步執行，耗時隨組合包大小線性增長\u003c/li\u003e\n    \u003cli\u003e\u003cstrong\u003eUpstream timeout \u0026lt; 打包耗時：\u003c/strong\u003eGateway / Nginx / LB 的超時門檻小於實際打包時間，必觸 504\u003c/li\u003e\n    \u003cli\u003e\u003cstrong\u003e未非同步化：\u003c/strong\u003e缺少 \u003ccode\u003e建立任務 → 背景執行 → 查詢狀態 → 完成後入審核\u003c/code\u003e 的四段式流程\u003c/li\u003e\n    \u003cli\u003e\u003cstrong\u003e無進度回饋與續查機制：\u003c/strong\u003e前端無法顯示進度、無法以 taskId 續查，只能乾等至超時\u003c/li\u003e\n  \u003c/ol\u003e\n\n  \u003ch2\u003e五、影響範圍\u003c/h2\u003e\n  \u003cdiv class=\"tableWrap\"\u003e\n  \u003ctable\u003e\n    \u003cthead\u003e\u003ctr\u003e\u003cth\u003e功能\u003c/th\u003e\u003cth\u003e影響\u003c/th\u003e\u003cth\u003e說明\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\n    \u003ctbody\u003e\n      \u003ctr\u003e\u003ctd\u003e組合包上架\u003c/td\u003e\u003ctd\u003e🔴 阻斷\u003c/td\u003e\u003ctd\u003e體積/數量大的包必定失敗，無法發布\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e🔴 未觸發\u003c/td\u003e\u003ctd\u003e無任務可追、無日誌可查\u003c/td\u003e\u003c/tr\u003e\n      \u003ctr\u003e\u003ctd\u003e創作者體驗\u003c/td\u003e\u003ctd\u003e🟡 困惑\u003c/td\u003e\u003ctd\u003e重試無效、無指引，誤以為是審核被拒\u003c/td\u003e\u003c/tr\u003e\n    \u003c/tbody\u003e\n  \u003c/table\u003e\n  \u003c/div\u003e\n\n  \u003ch2\u003e六、建議修復方向\u003c/h2\u003e\n  \u003cdiv class=\"grid2\"\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 01\u003c/div\u003e\u003cdiv class=\"title\"\u003e改為非同步打包\u003c/div\u003e\u003cp\u003e\u003ccode\u003ePOST /bundle/publish\u003c/code\u003e 僅建立任務回 \u003ccode\u003etaskId\u003c/code\u003e，打包在 worker / queue 背景執行，前端輪詢 \u003ccode\u003eGET /bundle/tasks/:id\u003c/code\u003e 或 WebSocket 訂閱進度。\u003c/p\u003e\u003c/div\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 02\u003c/div\u003e\u003cdiv class=\"title\"\u003e分層 timeout + 友好錯誤\u003c/div\u003e\u003cp\u003e短期無法非同步時，調大打包 API 的 upstream timeout（如 300s），並對 504 回專屬文案：「打包逾時，請拆小組合包或稍後重試」。\u003c/p\u003e\u003c/div\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 03\u003c/div\u003e\u003cdiv class=\"title\"\u003e任務狀態機與日誌\u003c/div\u003e\u003cp\u003e提供 \u003ccode\u003equeued / packing / packed / reviewing / done / failed\u003c/code\u003e 狀態 API，失敗時回原因與可操作建議。\u003c/p\u003e\u003c/div\u003e\n    \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 04\u003c/div\u003e\u003cdiv class=\"title\"\u003e打包效能優化\u003c/div\u003e\u003cp\u003e增量打包、並行壓縮、快取已打包產物，減少重複計算；大檔分片處理。\u003c/p\u003e\u003c/div\u003e\n  \u003c/div\u003e\n  \u003cp\u003e前端同步配合：打包期間顯示進度條與取消按鈕；收到 504 時自動以 \u003ccode\u003etaskId\u003c/code\u003e 續查，而非直接報錯終止。\u003c/p\u003e\n\n  \u003ch2\u003e七、暫時規避（給創作者）\u003c/h2\u003e\n  \u003cul\u003e\n    \u003cli\u003e嘗試\u003cstrong\u003e拆小組合包\u003c/strong\u003e分批上架，降低單次打包耗時\u003c/li\u003e\n    \u003cli\u003e避開尖峰時段重試\u003c/li\u003e\n    \u003cli\u003e記錄\u003cstrong\u003e組合包名稱 / 大小 / 操作時間\u003c/strong\u003e，提供給工程團隊對照 Gateway log 定位超時門檻\u003c/li\u003e\n    \u003cli\u003e若需保留原包體積，請先回報此 Bug 筆記連結，請後端協助以背景任務手動觸發打包與送審\u003c/li\u003e\n  \u003c/ul\u003e\n\n  \u003cdiv class=\"foot\"\u003e\n    \u003cstrong\u003e備註：\u003c/strong\u003e此為使用者回報之推測性 Bug（操作端僅可見 504，無後端 log）。實際打包耗時、Gateway 超時數值與是否已進入審核佇列，需由後端 APM / Gateway access log / 審核服務日誌進一步確認。建議工程側補上 \u003ccode\u003erequest_id\u003c/code\u003e 與打包任務關聯，以便下次復現時直接定位。\u003cbr\u003e\n    \u003cspan style=\"color:var(--ink-2)\"\u003e分類：市集 · 上架流程 · 打包/審核 \u0026nbsp;|\u0026nbsp; 關鍵字：504 / timeout / async task / AI review\u003c/span\u003e\n  \u003c/div\u003e\n\u003c/div\u003e","content":"\u003cdiv class=\"doc\"\u003e  \u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e錯誤代碼\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e504\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003eGateway Timeout超時中斷\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e發生時機\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e打包中\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e點擊上架後等待期間\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003eAI 審核\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e未進入\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e無任務、無紀錄無退回原因\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cp\u003e影響\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e阻斷\u003c/p\u003e\u003c/td\u003e\u003ctd\u003e\u003cp\u003e大包必現重試同樣失敗\u003c/p\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e \u003cdiv class=\"callout\"\u003e\u003cspan class=\"tag\"\u003e核心判斷\u003c/span\u003e\u003cdiv\u003e\u003cstrong\u003e這不是 AI 審核被拒，是連審核都沒排進去。\u003c/strong\u003e504 發生在 Gateway 層，打包請求在單一 HTTP 連線內同步執行、超過 upstream timeout（常見 30s / 60s）就被切斷，後端審核服務根本沒收到任務。\u003c/div\u003e\u003c/div\u003e \u003ch2\u003e一、現象\u003c/h2\u003e \u003cp\u003e於市集執行「上架組合包」後，前端長時間轉圈、無進度提示，最終彈出 \u003ccode\u003e504 Gateway Timeout\u003c/code\u003e。檢查後台：無 AI 審核任務、無審核結果、無可重送審的入口，狀態回到未送審。\u003c/p\u003e \u003cul\u003e \u003cli\u003e\u003cspan class=\"pill bad\"\u003e504\u003c/span\u003e錯誤發生在打包階段，非審核階段\u003c/li\u003e \u003cli\u003e組合包內容越多 / 檔案越大，越容易復現（打包耗時與體積正相關）\u003c/li\u003e \u003cli\u003e重試相同組合包 → 同樣 504，無法靠重試自癒\u003c/li\u003e \u003cli\u003e使用者無法區分是網路問題、打包失敗還是審核失敗\u003c/li\u003e \u003c/ul\u003e \u003ch2\u003e二、重現步驟（推估）\u003c/h2\u003e \u003col class=\"steps\"\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e準備較大的組合包\u003c/div\u003e\u003cdiv class=\"d\"\u003e含多個插件 / 檔案，或單檔體積較大，觸發較長的打包/壓縮/校驗時間\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e執行上架\u003c/div\u003e\u003cdiv class=\"d\"\u003e市集 → 組合包 → 上架，觀察請求開始後長時間無回應\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e等待至 Gateway 超時門檻\u003c/div\u003e\u003cdiv class=\"d\"\u003e數十秒後（依 LB/Nginx 設定常見 30s / 60s / 120s）回應 \u003ccode\u003e504\u003c/code\u003e\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003cli\u003e\u003cdiv\u003e\u003cdiv class=\"t\"\u003e檢查後台\u003c/div\u003e\u003cdiv class=\"d\"\u003e審核中心 / 任務清單：無對應 AI 審核紀錄，視為從未送審\u003c/div\u003e\u003c/div\u003e\u003c/li\u003e \u003c/ol\u003e \u003ch2\u003e三、實際 vs 預期\u003c/h2\u003e \u003cdiv class=\"tableWrap\"\u003e \u003ctable\u003e \u003cthead\u003e\u003ctr\u003e\u003cth\u003e項目\u003c/th\u003e\u003cth\u003e實際行為\u003c/th\u003e\u003cth\u003e預期行為\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e \u003ctbody\u003e \u003ctr\u003e\u003ctd\u003e打包\u003c/td\u003e\u003ctd\u003e同步阻塞在單一 HTTP 請求內，超時即全中斷\u003c/td\u003e\u003ctd\u003e非同步背景任務，前端輪詢或訂閱進度\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003e超時處理\u003c/td\u003e\u003ctd\u003e直接拋 504 給前端，無 taskId、無續查入口\u003c/td\u003e\u003ctd\u003e超時前回 \u003ccode\u003e{ taskId }\u003c/code\u003e，背景續跑；或提供明確錯誤文案\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e完全未觸發\u003c/td\u003e\u003ctd\u003e打包完成後自動進入 AI 審核佇列\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003e使用者回饋\u003c/td\u003e\u003ctd\u003e只有 504，看不出是打包慢還是審核問題\u003c/td\u003e\u003ctd\u003e明確狀態機：打包中 → 已送審 → 審核結果\u003c/td\u003e\u003c/tr\u003e \u003c/tbody\u003e \u003c/table\u003e \u003c/div\u003e \u003ch2\u003e四、可能原因推測\u003c/h2\u003e \u003col\u003e \u003cli\u003e\u003cstrong\u003e同步打包架構：\u003c/strong\u003e壓縮、校驗、產物生成都在 API 請求執行緒內同步執行，耗時隨組合包大小線性增長\u003c/li\u003e \u003cli\u003e\u003cstrong\u003eUpstream timeout \u0026lt; 打包耗時：\u003c/strong\u003eGateway / Nginx / LB 的超時門檻小於實際打包時間，必觸 504\u003c/li\u003e \u003cli\u003e\u003cstrong\u003e未非同步化：\u003c/strong\u003e缺少 \u003ccode\u003e建立任務 → 背景執行 → 查詢狀態 → 完成後入審核\u003c/code\u003e 的四段式流程\u003c/li\u003e \u003cli\u003e\u003cstrong\u003e無進度回饋與續查機制：\u003c/strong\u003e前端無法顯示進度、無法以 taskId 續查，只能乾等至超時\u003c/li\u003e \u003c/ol\u003e \u003ch2\u003e五、影響範圍\u003c/h2\u003e \u003cdiv class=\"tableWrap\"\u003e \u003ctable\u003e \u003cthead\u003e\u003ctr\u003e\u003cth\u003e功能\u003c/th\u003e\u003cth\u003e影響\u003c/th\u003e\u003cth\u003e說明\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e \u003ctbody\u003e \u003ctr\u003e\u003ctd\u003e組合包上架\u003c/td\u003e\u003ctd\u003e🔴 阻斷\u003c/td\u003e\u003ctd\u003e體積/數量大的包必定失敗，無法發布\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003eAI 審核\u003c/td\u003e\u003ctd\u003e🔴 未觸發\u003c/td\u003e\u003ctd\u003e無任務可追、無日誌可查\u003c/td\u003e\u003c/tr\u003e \u003ctr\u003e\u003ctd\u003e創作者體驗\u003c/td\u003e\u003ctd\u003e🟡 困惑\u003c/td\u003e\u003ctd\u003e重試無效、無指引，誤以為是審核被拒\u003c/td\u003e\u003c/tr\u003e \u003c/tbody\u003e \u003c/table\u003e \u003c/div\u003e \u003ch2\u003e六、建議修復方向\u003c/h2\u003e \u003cdiv class=\"grid2\"\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 01\u003c/div\u003e\u003cdiv class=\"title\"\u003e改為非同步打包\u003c/div\u003e\u003cp\u003e\u003ccode\u003ePOST /bundle/publish\u003c/code\u003e 僅建立任務回 \u003ccode\u003etaskId\u003c/code\u003e，打包在 worker / queue 背景執行，前端輪詢 \u003ccode\u003eGET /bundle/tasks/:id\u003c/code\u003e 或 WebSocket 訂閱進度。\u003c/p\u003e\u003c/div\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 02\u003c/div\u003e\u003cdiv class=\"title\"\u003e分層 timeout + 友好錯誤\u003c/div\u003e\u003cp\u003e短期無法非同步時，調大打包 API 的 upstream timeout（如 300s），並對 504 回專屬文案：「打包逾時，請拆小組合包或稍後重試」。\u003c/p\u003e\u003c/div\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 03\u003c/div\u003e\u003cdiv class=\"title\"\u003e任務狀態機與日誌\u003c/div\u003e\u003cp\u003e提供 \u003ccode\u003equeued / packing / packed / reviewing / done / failed\u003c/code\u003e 狀態 API，失敗時回原因與可操作建議。\u003c/p\u003e\u003c/div\u003e \u003cdiv class=\"card\"\u003e\u003cdiv class=\"num\"\u003eFIX 04\u003c/div\u003e\u003cdiv class=\"title\"\u003e打包效能優化\u003c/div\u003e\u003cp\u003e增量打包、並行壓縮、快取已打包產物，減少重複計算；大檔分片處理。\u003c/p\u003e\u003c/div\u003e \u003c/div\u003e \u003cp\u003e前端同步配合：打包期間顯示進度條與取消按鈕；收到 504 時自動以 \u003ccode\u003etaskId\u003c/code\u003e 續查，而非直接報錯終止。\u003c/p\u003e \u003ch2\u003e七、暫時規避（給創作者）\u003c/h2\u003e \u003cul\u003e \u003cli\u003e嘗試\u003cstrong\u003e拆小組合包\u003c/strong\u003e分批上架，降低單次打包耗時\u003c/li\u003e \u003cli\u003e避開尖峰時段重試\u003c/li\u003e \u003cli\u003e記錄\u003cstrong\u003e組合包名稱 / 大小 / 操作時間\u003c/strong\u003e，提供給工程團隊對照 Gateway log 定位超時門檻\u003c/li\u003e \u003cli\u003e若需保留原包體積，請先回報此 Bug 筆記連結，請後端協助以背景任務手動觸發打包與送審\u003c/li\u003e \u003c/ul\u003e \u003cdiv class=\"foot\"\u003e \u003cstrong\u003e備註：\u003c/strong\u003e此為使用者回報之推測性 Bug（操作端僅可見 504，無後端 log）。實際打包耗時、Gateway 超時數值與是否已進入審核佇列，需由後端 APM / Gateway access log / 審核服務日誌進一步確認。建議工程側補上 \u003ccode\u003erequest_id\u003c/code\u003e 與打包任務關聯，以便下次復現時直接定位。\u003cbr\u003e \u003cspan style=\"color:var(--ink-2)\"\u003e分類：市集 · 上架流程 · 打包/審核 \u0026nbsp;|\u0026nbsp; 關鍵字：504 / timeout / async task / AI review\u003c/span\u003e \u003c/div\u003e \u003c/div\u003e","createdAt":1788014761384,"deletedAt":null,"displayMode":"artifact","embedRenders":{},"id":"9021496d162c3018b0251e13","isNew":false,"isPublic":true,"itemType":"NOTE","name":"CubeLV 平台 Bug 回報：上架組合包打包超時觸發 HTTP 504 未進入 AI 審核","parents":{"4465d0a863da5d1b345d888c":1788014761384},"preParentID":null,"updatedAt":1788094272928,"updatedBy":{"userId":"6a3dcfc700e9b9fd06d5ef","userName":"蔡其樺"},"version":17}]}