UX 健檢批次 C(P0×2 + 9 項)。唯一新增對外訊息的批次,所有新通知必須走 claimNotification dedup。 - P0-5 審核結果回不到成員:新增 receipt 通知(至少 reject 帶原因 @ 當事人;verify 可選) - P0-6 成員繳費頁英文技術錯誤中文化(Discord 路徑的中文字串已存在) - C1 手動/CSV 入職零通知(nudge 勾選框因 diff 為空不出現;且該 nudge 未走 claim) / C2 個別催繳(sendPaymentNudge 已支援 people[]) / C3 成員「我的帳單」查詢 / C4 綁錯名字死路 / C5 成員 web 頁不可達+失效頁死路 / C6 兩套「你要繳多少」算法收斂(等 A 的改價語意定案) / C7 R2 未設定時 /繳費 截圖靜默丟棄 / C8 三繳費入口能力差異提前告知 / C9 未綁定成員後台可見(listUnboundUsers 已存在)
Activity
poterpan commentedon Aug 29, 2026
本 issue 分支的
0006_notification_event.sql與已部署的 #480006_overdue_daily.sql撞號。0006_overdue_daily.sql套用到 remote D1:notification_logs加了event欄(空字串 = 整期 slot;逾期列帶台北營業日)、UNIQUE 含event、重建表。0006_notification_event.sql也是重建notification_logs,加了event欄 +nudge/receipttype。合併前必須:
0007_notification_event.sql。0006的既有 schema 對齊:event欄已經存在,重建時要保留它、並把 type 的 CHECK 從現有值擴充為 nudge / receipt(不可假設表還是 0005 的舊結構)。0006檔名。poterpan commentedon Aug 29, 2026
🚨 高風險:本線遷移會靜默清空 #48 的正式資料
承上一則撞號警告,實際比對後發現不只是「檔名撞號」,內容也會造成資料流失。
packages/worker/migrations/0006_notification_event.sql的搬移語句目前是:第 4 個位置把
event硬寫成空字串''。在本線切出去的當下這是正確的(那時event欄還不存在)。但 #48(PR #49)已經上線,正式環境的notification_logs.event現在存著逐日催繳的 day-key(如2026-08-29)。若照現況套用,會把所有 day-key 清成
'':改法(改名
0007_notification_event.sql後)''→event,不可覆寫。event TEXT NOT NULL DEFAULT '',它已由0006建立;本次只需把 type 的 CHECK 從('billing_opened','overdue','receipt')擴充為加上'nudge'。0006_overdue_daily之後,且event現由三種語意共用——overdue = day-key、receipt =reject/verify、billing_opened/nudge =''。另外,rebase 會有實質衝突(非單純文字衝突)
本線的
core/notify.ts與core/scheduled.ts停在舊 main。#48 在同樣位置加了claimNotificationSlot/releaseSlot/dayKey逐日邏輯。rebase 時必須兩套語意都保留(#48 的逐日 + 本線的 receipt/nudge),不可二選一覆蓋。poterpan commentedon Aug 29, 2026
✅ 遷移危險已修復 + rebase 完成(2026-08-29)
分支
ux/45-member-feedback已 rebase 到含 #48 的 main(f246c71),前述資料流失風險已解除。處理內容:
0006_notification_event.sql→0007_notification_event.sqlINSERT ... SELECT的event改為原值傳遞(原本硬寫'')event欄,本次重建只把 type CHECK 擴充加入'nudge'core/notify.ts與core/billing.ts兩邊語意都保留——[Feature] 催繳邏輯改善 #48 的claimNotificationSlot/releaseSlot/dayKey逐日邏輯,與本線的releaseNotification/releaseReceiptSlots/ receipt / nudge 並存驗證方式(不只靠測試)
用
sqlite3實際重放0001 → 0007,模擬正式環境已有一筆帶 day-key 的 overdue 列:0007:event=2026-08-29保留 ✅''再跑一次 →event=''(確實會被清空)nudgetype 現已被 CHECK 接受 ✅誠實補充
新增的 schema 測試無法捕捉這個 bug——測試環境先跑完 migrations 才有資料,重建的
SELECT永遠碰不到測試列。這點已寫成註解留在test/schema.test.ts,避免後人誤以為有測試保護。真正的驗證是上面的 sqlite 重放。
現況
Worker tests 373 passed / 52 files,
tsc --noEmit綠。剩餘工作:Task 3–16(P0-5 回條主體、P0-6 中文化、C1–C9),共 14 項尚未開始。
Merge pull request #50 from poterpan/ux/45-member-feedback
feat(receipt): 確認回條改為可設定(預設關)+ 一鍵全部核准只發一則 (#45 Task 4)
fix(upload): 成員繳費頁的錯誤訊息全面中文化 (#45 P0-6)
fix(upload): 繳費頁金額改讀本期帳單,與 Discord 一致 (#45 C6)
feat(discord): 三個繳費入口的能力差異事先講清楚 (#45 C7+C8, P0-8)
feat(discord): 繳費提示可直接取得一次性網頁連結 (#45 C5b)
fix(web): 失效連結頁改指一條真的走得通的路 (#45 C5a)
feat(discord): 綁錯名字可自助解綁重綁 (#45 C4)
feat(discord): /我的帳單 — 成員第一次能自己查待繳與最近紀錄 (#45 C3)
feat(admin): 未綁定成員可見(計數 pill + 篩選)(#45 C9)
feat(admin): CSV 匯入與新增訂閱都能通知新成員 (#45 C1)
feat(admin): 成員審核頁可單獨催繳這一位 (#45 C2)
feat(admin): 同步彈窗說出 @ 不到的未綁定成員 (#45 C9)
feat(nudge): 催繳核心與端點,入職/個別催繳共用一條路 (#45 C1+C2, P2-4)
docs: 更新測試數與成員回饋迴路的功能說明 (#45)
poterpan commentedon Aug 29, 2026
✅ 全部 16 個 task 完成(2026-08-29)
分兩個 PR:
完成清單
/我的帳單自助查詢順帶修掉 healthcheck P0-8(
/繳費指令描述的「可選」)——批次 D(#46)請跳過此項。驗收
423 passed / 57 files(起始基準 355);
pnpm -r typecheck綠;admin + web build 綠。/繳費指令描述有變更,且新增了/我的帳單— 部署後必須到後台 → 設定 → 工具 → 註冊 Discord 指令按一次,否則成員在 Discord 看到的仍是舊的指令清單與描述。待辦
Codex 跨引擎收尾審查因額度用盡尚未執行,額度恢復後補送。
fix(nudge/upload): 依 Codex 審查修正三項 (#45)
poterpan commentedon Aug 30, 2026
🔍 Codex 跨引擎審查完成(2026-08-30)— 判定 DO-NOT-MERGE,三項全部修正
findings 與處置
core/nudge.ts送失敗時以 key 刪除 slot:併發的兩次 force 之間,B 可能在 A 的 claim 與 release 之間換掉那一列,A 的 keyed DELETE 會毀掉 B 的有效 slotcore/scheduled.ts修過的同一缺陷,nudge.ts又犯了一次claimNotificationSlot回傳的 row id +releaseSlotunbound恆為 0——「沒設定 Discord」與「沒有人需要通知」在 UI 上長得一模一樣transport欄位(no_channel/no_bot_token),nudgeSummary講出真正原因並仍列出未綁定的人size分支,成員看到「檔案太大(上限 10 MB)」——與事實相反InvalidImage.reason新增empty,文案改為「這個檔案是空的(0 KB)」回歸測試有真的驗過
第 1 項我沒有只寫測試就算數——把修法改回舊寫法,該測試確實會紅(
expected +0 to be 1,B 的 slot 被毀)。改回正確版本後才綠。第 2、3 項也各補一條測試。
驗收
Worker 測試 423 → 426,
pnpm -r typecheck綠,admin + web build 綠。README 徽章同步為 426。commit
d28e2d1Merge pull request #51 from poterpan/ux/45-member-feedback
merge: 併入 main(#45 成員回饋迴路),保留兩批的功能
docs(plans): add implementation plan for poterpan#45 UX-C member feed…
fix(migrations): 0006→0007 改名並保留 event 值,避免清空 poterpan#48 逐日 day-key (p…
feat(receipt): 退回必發回條給成員 (poterpan#45 P0-5)
fix(admin-ui): 同步預覽的「移除」標題不再誤導 (poterpan#46 P0-7)
fix(worker): 錯誤細節只給 Access 後的後台,成員與 Discord 路由維持不透明