已修复的 Bugs
Bug 20: Google OAuth Client Secret 輪換導致登入失敗 (2026-05-29)
- 根因: Google 自動輪換 OAuth client secret,Drive 上的 JSON 檔案未更新
- 修復: 從 Drive JSON 更新
GOOGLE_CLIENT_SECRETenv var 為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 - 注意: 若再出現
invalid_client,去 Google Cloud Console 下載最新 JSON
Bug 19: AI Rate Limit 跨 Worker fetch 失敗 (2026-05-29)
- 根因:
quotation-saasWorker fetchai.hsdesign.biz返回 1016(Worker-to-Worker 路由問題) - 修復: 改為直接呼叫 DeepSeek API(加入
DEEPSEEK_KEYenv var),不經 renovation-ai Worker - AI 上限: Free/Plus/Pro = 0,Pro Max = 999(無限)
Bug 18: Dashboard 被 chat-widget script 搞壞 (2026-05-29)
- 根因: 嘗試嵌入式 chat HTML/JS 時,模板字面量的
\'在 JavaScript 中是非法的 escape sequence - 修復: 將 chat widget HTML 上傳至 GitHub
chat-widget.html,Worker 執行時 fetch 注入
Bug 17: Markup 公式錯誤 x0.28 非 x1.28 (2026-05-29)
- 根因:
const sell = ct * mk中 mk = 28/100 = 0.28,應為ct * (1 + mk) - 修復: GitHub
quote-app.js改為ct * (1 + mk)(per-item + applyMarkupAll 都修)
Bug 16: Dashboard 顯示錯誤 plan badge (2026-05-29)
- 根因: 最小化 post script 移除 account fetch,plan badge 只從 JWT 讀取(過期值)
- 修復: post script 加入
fetch("/api/account"),從 D1 讀取實際 plan,更新 badge/avatar/dropdown/quota - 驗證: Playwright 測試三個方案帳號全部顯示正確方案 ✅
Bug 15: Pricing 頁讀 JWT 而非 D1 (2026-05-29)
- 根因: Pricing script 從 JWT
plan欄位讀取方案,但 JWT 不會在 Stripe 升級後自動更新 - 修復: Pricing script 改為呼叫
/api/account從 D1 讀取實際 plan - 驗證: Playwright 測試 Plus/Pro/Pro Max 全部顯示 Current Plan ✅
Bug 14: Dashboard 空白 — post script 被截斷 + 重複宣告 (2026-05-29)
- 根因: 多次
-e修補導致var post =被截斷至第一個;,且後續patched.replace程式碼被移除 - 修復: 清除重複的
var post =宣告,重建單一乾淨 post script - 教訓: 不要在 Worker 代碼中用
-e做複雜字串操作,改用檔案
Bug 13: Stripe Live Key 失效 (2026-05-29)
- 根因: 原
sk_livekey 被 Stripe 撤銷(可能因暴露在程式碼中被自動輪換) - 修復: 換為
rk_liverestricted key(使用者從 Stripe Dashboard 手動產生),設定為 Cloudflare env var - 筆記: 所有 secrets 已從 Worker 代碼移到 env var,之後如需更換 key →
CF Workers → quotation-saas → Variables - Price IDs (live):
plus→price_1Tbt7S17t9NNR8bpw5uQ8Id8pro→price_1Tbt7T17t9NNR8bpaCv1XOQVpromax→price_1Tbt7U17t9NNR8bpuMWIrrrt
Bug 12: Pricing 頁方案高亮不生效 — Script 在 DOM 載入前執行 (2026-05-29)
- 根因: Pricing script 放在
<head>,querySelectorAll("a")執行時 DOM 還沒解析 → 找到空 NodeList → 什麼都不做 - 修復: Script 包裹在
setTimeout(function(){...}, 100)確保 DOM 就緒才執行 - 匹配邏輯: 透過
onclick="checkout('X')"屬性提取方案名稱,與 JWTplan欄位比對
Bug 11: Markup % 改動不影響現有 Items (2026-05-29)
- 根因:
mk-input變更只影響後續點擊 markup 按鈕,不自動重新計算 - 修復: 新增
applyMarkupAll()函式,遍歷所有 items 重新計算sell = cost * (mk% / 100),綁定到mk-input的change/input事件 - 涉及: GitHub
quote-app.js
Bug 10: Pages frontend 完全消除 — Worker 接管所有路由 (2026-05-28)
- 根因:
/auth/registerGET 無 return → fallthrough → Pages frontend 舊版 SPA;PAGES_URL全站 fallback - 修復:
/auth/registerGET 改為由 Worker fetch GitHub API 的login.html直接 serve- 移除
PAGES_URLfallback 代碼,unmatched route 改回 404 - Dashboard 重整時無 token → 檢查 localStorage 後 redirect(不跳到 Pages)
- 狀態: Pages frontend 完全脫離,所有請求由 Worker handle
Bug 9: 方案名稱 DB/前端不一致 — badge 顯示 “beta” (2026-05-28)
- 根因: D1 仍存
plan="beta"、plan="200"、plan="adfree",但 Worker 已換新 key - 修復:
- DB 執行
UPDATE accounts SET plan='promax' WHERE plan='beta' UPDATE accounts SET plan='pro' WHERE plan='200'UPDATE accounts SET plan='plus' WHERE plan='adfree'- Worker 端 plan label mapping 統一使用新 key
- DB 執行
- 新方案命名: Free / Plus (RM2) / Pro (RM3) / Pro Max (RM5)
- 2026-06-01 价格升级: Free / Plus (RM4) / Pro (RM7) / Pro Max (RM10),Free 配额 100→10
- 详见
projects/quotation-saas-complete.md订阅方案章节
Bug 8: Markup % 更改不影響 item 計算 (2026-05-28)
- 根因:
applyMarkup()硬編碼const sell = ct * 1.25,無視工具列的 % 輸入 - 修復: GitHub
quote-app.js改為var mk = parseFloat(document.getElementById("mk-input")?.value||25)/100; const sell = ct * mk; - 效果: 改工具列的 % 後點 item markup 按鈕即套用新值
Bug 7: Avatar dropdown 無內容 + 無 Email 顯示 (2026-05-28)
- 根因: 注入的 post-load script 未找到 dropdown 元素(舊版 mapping script 已改但 dropdown JS 未更新)
- 修復: 在
loadQuotes()後注入新的 account fetch JS,同時 fallbackqs_token/token - 效果: Hover avatar 顯示 Email / 方案 / 推薦碼 / Logout
Bug 6: data.quotation.id → data.id 造成 Network error (2026-05-28)
- 根因:
saveQuote()用data.quotation.id,Worker POST 返回{id, success}(嵌套quotation已移除) - 修復: GitHub
quote-app.jsdata.quotation.id→data.id - 效果: 新建報價 autosave 不再 Network error
Bug 5: 前端 PUT / Worker PATCH 不匹配 (2026-05-28)
- 根因:
saveQuote()用method:'PUT',Worker route 只檢查method === "PATCH" - 修復: Worker 端
request.method === "PATCH" || request.method === "PUT" - 效果: 編輯已有報價 autosave 不再 404
Bug 4: fmt() 殘留 → 25% 賣價歸零 (2026-05-28)
- 根因:
sellInput.value = fmt(sell)→ 三位數以上有逗號 →type=numberinput 歸零 - 修復: GitHub
quote-app.jssellInput.value = sell.toFixed(2)
Bug 3: quote-app.js 開頭有 CSS 導致 JS 不執行
- 症狀: Dashboard 點 “+New” 無反應
- 根因:
quote-app.js前 7 行是 CSS(.section-block{...}),<script>加載時報Unexpected token '.' - 修復: Worker
_app.jsroute 返回前切掉// ─── CONFIG之前的內容
Bug 2: Save 按鈕消失
- 根因: HTML 硬編碼
style="display:none",gate 移除後沒補 - 修復: Directly remove Save button (autosave 取代)
Bug 1: 重開網站顯示舊版 Pages frontend dashboard
- 根因: 無 cookie → redirect
/auth/register→ Pages frontend → localStorage 有 token → 跳到舊 dashboard - 修復:
/handler 無 cookie 時返回 localStorage 檢測頁面
Worker 崩潰歷史 (2026-05-28)
多次 -e 修補導致 Worker 損壞,以下功能丟失後重新加回:
- Stripe webhook handler — 遺失
- Stripe config vars (STRIPE_SECRET, PRICE_IDS) — 遺失
_app.jsCSS 裁剪 — 遺失requireAuth2()函式 — 遺失- Pricing page — 遺失
/ads.txtroute — 遺失- 教訓: 用檔案部署,避免
-e片段修補 - 症状: Dashboard 点击 “+New” 无反应
- 根因:
quote-app.js在 GitHub 上前 7 行是 CSS(.section-block{...}),浏览器加载为<script>时报Unexpected token '.'语法错误,整个 JS 停止 - 修复: Worker 的
_app.jsroute 返回前切掉// ─── CONFIG之前的内容 - 涉及文件: Worker
_app.jshandler →fetch(GITHUB_RAW + "/quote-app.js")
Bug 2: Save 按钮永远 hidden
- 症状: 编辑报价没有 Save 选项
- 根因: HTML 硬编码
style="display:none",原版靠 gate 认证后显示,SaaS 版 gate 移除后没补 - 修复: 既然有 autosave(3s),直接移除 Save 按钮
- 涉及代码: Dashboard HTML patching
Bug 3: API 返回 data.id 但前端读 data.quotation.id
- 症状: 新建报价 autosave 后显示 “Network error”
- 根因:
saveQuote()用data.quotation.id,但 Worker POST/api/quotations返回{ id, success: true }(没有quotation嵌套) - 修复: 在
_app.js返回前做 string replace
Bug 4: 前端用 PUT 但 Worker 只处理 PATCH
- 症状: 编辑已保存的报价 autosave 报 404
- 根因:
saveQuote()用method: 'PUT',Worker route 只检查method === "PATCH" - 修复: Worker route handler 同时接受 PUT 和 PATCH
- 涉及代码: Worker quotations route handler
Bug 5: Save 按钮已移除(autosave 取代)
- 确认 autosave 正常工作(编辑后 3 秒自动保存)
- 直接从 HTML 中移除了 Save 按钮
新增功能 (2026-05-27)
Stripe 支付集成
- 创建 Stripe Products/Prices(sandbox): Ad-Free RM2, 200 Quota RM3, Beta RM5
POST /api/create-checkout— 创建 Stripe Checkout SessionPOST /api/webhook/stripe— Webhook 处理付款成功/取消- 订阅后自动更新 D1
accounts.plan+subscriptions表 - Price IDs:
- adfree:
price_1Tbg1T06BaZD1u5Pgy3MO5l7 - quota200:
price_1Tbg1U06BaZD1u5PZSMkwQd3 - beta:
price_1Tbg1U06BaZD1u5POR4Ip4as
- adfree:
Pricing 页面
/pricing路由,4 方案卡片对比- Upgrade 按钮调用
/api/create-checkout - Dashboard 工具栏绿色 Upgrade 按钮(Free 用户显示)
Email 发送报价
POST /api/send-quote— 通过 Resend API 发送- Dashboard 工具栏 ✉️ Email 按钮
- 弹出输入框填客户邮箱,自动生成报价 HTML 邮件
- Resend Key:
re_Qr5yUbT5_72JBvNPPskYK5qvEByNHJ6mS
Google AdSense
- Auto Ads script 添加到所有页面
<head> - Publisher ID:
ca-pub-8381241232407113 - 覆盖页面: Dashboard, Pricing, Root (
/) - 待 Google 审核通过后广告才会显示
推荐码系统
GET /api/referral-stats— 返回推荐码、人数、奖励月数- Dashboard 工具栏显示 🎯 推荐码 badge
- 点击弹出分享提示(每 3 人送 1 个月)
- 注册时支持
referral_code参数
Worker 崩溃修复 (2026-05-28)
多次 -e 修补导致 Worker 代码损坏,以下功能丢失后重新加回:
- Stripe webhook handler (
/api/webhook/stripe) — 丢失 - Stripe config vars (STRIPE_SECRET, PRICE_IDS) — 丢失
_app.jsCSS 裁剪(+New 按钮修复)— 丢失requireAuth2()函数 — 丢失- Pricing page (
getPricingPage) — 丢失 /ads.txtroute — 丢失
修复方式: 完整下载 Worker 源码后直接插入缺失代码段,避免 -e 片段修补。
fmt() 殘留: 25% 賣價歸零 (2026-05-28)
- 根因:
sellInput.value = fmt(sell)在 markup 計算後用fmt()設值,超過三位數產出逗號 → type=number input 歸零 - 修復: GitHub 上改為
sellInput.value = sell.toFixed(2)
Worker PUT → PATCH 對齊 (2026-05-28)
- 問題: Autosave 顯示 “Network error”
- 根因: 前端用
method: 'PUT',Worker 只處理PATCH - 修復: Worker PATCH handler 同時接受 PUT
hsdesign.biz landing page (2026-05-28)
- 原 Cloudflare Pages 项目返回 500,改用 Worker 提供
- Worker 从 GitHub raw 获取
index.html+ 静态文件(图片等) - 注入 AdSense meta tag + script + 右上角报价工具链接
- 将中文 hero 文案从报价营销改为公司介绍
Bug 6: 重开网站显示旧版 Pages frontend dashboard
- 症状: 关闭浏览器再打开 quotation.hsdesign.biz,看到的是旧版报价工具(非 Worker dashboard)
- 根因:
- 用户通过 token URL 参数登录(无 session cookie)
- 重开网站 → Worker 的
/handler 没找到 cookie → 重定向到/auth/register /auth/registerGET 没有 Worker handler → 落到 Pages frontend- Pages frontend 的 JS 检查 localStorage 发现 token → 跳转到它的旧 dashboard
- 修复: 修改 Worker 的
/handler,当没有 cookie 时返回一个检测 localStorage 的页面
Bug 21: Dashboard 按钮 onclick 调用缺失函數 — duplicateQuote() / showFeedback() 未定義 (2026-06-27)
- 症狀: 切換瀏覽器/刷新後 Dashboard 空白 — 瀏覽器報
Uncaught ReferenceError: showFeedback is not defined和duplicateQuote is not defined,JS 後續程式碼全部停止執行 - 根因:
- Dashboard HTML 模板中有
onclick="showFeedback()"(💬 按鈕)和onclick="duplicateQuote()"(Duplicate 按鈕) - 但 GitHub
JakeBilu/Landing-Page/quote-app.js(即_app.js)缺失這兩個函式的定義 - 瀏覽器解析到 onclick 時找不到函式 → 拋 ReferenceError → JS 停止 → Dashboard 白屏
- Dashboard HTML 模板中有
- 調查路徑:
- 搜索
_app.js(GitHub)→ 找不到 - 搜索 Cloudflare Worker 代碼 → 找不到
- 搜索 Dashboard HTML → 找到 onclick 引用,但函式不存在於任何 JS 檔案
- 結論:兩個函式從未被寫入
quote-app.js
- 搜索
- 修復: 在 GitHub
quote-app.js的delQuote()結束後插入兩個函式:async function duplicateQuote()— 複製當前報價為新報價(POST/api/quotations),自動填入 “(Copy)” 名稱function showFeedback()— prompt 收集用戶反饋,POST/api/feedback
- Commit:
93cd063fd5b5→JakeBilu/Landing-Pagerepo - 驗證:
- CDN 傳播後
/_app.js✅duplicateQuote存在 ✅showFeedback存在 - Node.js syntax check ✅
- 瀏覽器登入頁面正常顯示
- CDN 傳播後
- 涉及檔案: GitHub
JakeBilu/Landing-Page/quote-app.js