訂閱制系統架構

要撐起新的定價方案,還缺哪些演算法/畫面/資料表——以及你可能沒想到的十件事

2026-07-27 更新 · 定價正本 最終定價方案;畫面規劃 畫面架構

整套訂閱制真正的難點不是收錢,是「排序」和「投放」

Pro 賣的是排序提前、Max 賣的是主動觸達——這兩件事沒有演算法就是空話, 而且它們是教練唯一會拿來質問你的東西(「我付了錢為什麼還排在他後面?」)。
所以下面的清單裡,排序與投放引擎的優先級高於訂閱金流本身:先有價值,才有得收錢。

已經完成的(2026-07-26 P1 / 2026-07-27 P2A+P2B+P2C 前半)

2026-07-27 這一批內容
規則層9 支 Gate + 165 tests:SearchRankGatesRankExplainGates(可解釋排序)、AudienceGates(興趣衰減)、MomentGates(對的時刻)、DeliveryGatesRecPrefsGates(投放與使用者出口)、SubscriptionGatesDowngradeGates(降級寬限)、ReferralGates(雙軌歸因)、CourseHubGatesMyLearningGatesDestinationGates
DB6 張表(興趣/版位/觸達/訂閱/推廣連結/點擊)+ 15 支 RPC + 2 個 cron(投放每日 09:00、月結與訂閱到期 02:30)。RLS 全開、每支函數點名 revoke anon
畫面7 頁:課程主頁「學」/我的學習/方案與訂閱(說明版)/推薦偏好/為什麼我排這裡/Max 曝光報表/推廣連結;主頁三處改動各自配 flag(附近的課膠囊、目的地模式、統一搜尋)
誠實缺口① 收款與電子發票未接(要先開公司)② 目前 0 位 Max 訂閱者 → 投放引擎跑起來是 0 筆(刻意:引擎先就位)③ 目的地模式與課程主頁欠實機 dogfood ④ 線上課本體仍卡影片託管(P3)

P1(2026-07-26)

項目內容
DBuser_profiles.coach_plan(free/pro/max)、模板公開讀 policy、arena_coach_public_profile RPC
GateCoachPlanGates(配額/功能閘/searchBoost)、WishGates(熱門日期/升級試算)— 25 tests
畫面教練公開主頁(改吃 RPC)、課程模板貨架+許願、許願牆+升級試算、開課配額閘

還缺的演算法(7 支,依重要性排序)

#演算法做什麼為什麼非做不可階段
1搜尋排序
SearchRankGates
score = 相關性 × 距離衰減 × 評價 × plan boost × 成效數據 × 新鮮度 Pro 值 399 的唯一理由。沒有排序,「排序提前」就是空話P2
2受眾建構
AudienceGates
從行為訊號(上過/搜過/點過/打過該運動)算出每個人的分類興趣分數,衰減舊訊號 Max 的投放對象從哪來。沒有受眾就沒有庫存可賣P2
3投放分配+頻率控制
DeliveryGates
誰該收到誰的推薦:可售庫存=受眾×上限−已投;多個 Max 競爭 → 加權輪替;每人每月上限 4 次 Max 的履約。做不好會兩頭死:教練沒效果、使用者被騷擾P2
4「對的時刻」偵測
MomentGates
Elo 停滯 N 場/連敗 ≥3/升段失敗/許願未被滿足 → 產生「可推薦時刻」 我們比 AmazingTalker 強的唯一理由。沒有它,Max 就只是普通廣告P2
5歸因
ReferralGates
推廣連結 → ref code → 記在報名/付款;歸因窗口(點擊後 N 天內成交算他的) 線上課雙軌分潤(10% vs 30%)的基礎。算錯就是拿錯錢P2
6旅行意圖
TravelIntentGates
五級訊號(興趣→搜尋→社群→明示行程→GPS 抵達)合成 region×日期的意圖分數 目的地模式與觀光導流的前提P3
7點數經濟
PointGates
發放(走平台付款回饋 3%)/有效期/兌換標的庫存/負債計算 P3;⚠️ 點數是負債,會計上要能算得出來P3
⚠️ 排序演算法有一個容易被忽略的硬需求:可解釋性。
教練付了 399 一定會問「為什麼我排在他後面」。如果你答不出來,那 399 就退了,而且他會到處講。
所以排序分數必須能拆解成人看得懂的幾項(評價 4.8/距離 1.2km/完課率 92%/方案加權), 而且教練後台要看得到自己的分項——這不是加分功能,是客訴防火牆

還缺的資料表(8 組)

表/欄位重點階段
訂閱 arena_coach_subscriptions(profile_id, plan, status, period_start, period_end, payment_id, auto_renew, cancelled_at) user_profiles.coach_plan 變成快照,真相在這張表(要記歷史、到期、續訂、退款)P2
線上課 coach_online_courses(video_asset_id, duration_sec, chapters jsonb, price, status)
coach_online_enrollments(course_id, student, payment_id, progress_sec, ref_code)
⚠️ 需要影片託管帳號(Cloudflare Stream)才有意義卡住
歸因 arena_referral_links(code, coach_profile_id, kind)
arena_referral_clicks(code, profile_id, clicked_at)
既有付款表加 ref_code
雙軌分潤的基礎;歸因窗口建議 7 天P2
受眾 arena_user_interests(profile_id, category, score, last_signal_at) 由行為訊號 cron 累積;score 要會衰減,否則三年前搜過瑜伽的人永遠在池子裡P2
投放 arena_ad_placements(coach, category, guaranteed_impressions, delivered, period)
arena_ad_impressions(placement, profile, channel, shown_at, clicked_at)
頻率控制與效果保證都靠 impressions 表;它會長很快,要設保留期限P2
推播偏好 user_profiles.notify_prefs jsonb(分類開關、頻率上限) 沒有這個,使用者只能整批關通知 → 你的庫存直接歸零P2
旅行意圖 arena_travel_intents(profile_id, region, date_from, date_to, source, confidence) 明示行程與 GPS 抵達都寫這裡P3
點數 arena_points_ledger(profile_id, delta, reason, ref, expires_at)
arena_point_rewards(kind, cost, stock, provider_profile_id)
⚠️ 分錄式(不可只存餘額),⛔ 不可提現、不可轉讓(一儲值就踩電支)P3

畫面清單(含已完成)

畫面狀態備註
教練公開主頁/模板貨架/許願牆✅ 完成2026-07-26
課程主頁「學」✅ 完成2026-07-27・入口=主頁膠囊「附近的課」
我的學習✅ 完成2026-07-27・個人頁一列(帶摘要)
目的地模式✅ 完成2026-07-27・欠實機 dogfood
訂閱與方案(說明版)✅ 完成2026-07-27・誠實鈕有測試釘死
搜尋結果頁(統一搜尋)✅ 完成2026-07-27・主頁搜尋列擴到教練(課程/地點待補)
推廣連結管理(教練端)✅ 完成2026-07-27・線上課上線前導向公開主頁
推播與推薦偏好(學員端)✅ 完成2026-07-27・總開關/每月上限/分類靜音
「為什麼我排這裡」(教練端)✅ 完成2026-07-27・6 分項+與前一名逐項比
線上課上架/播放卡住缺影片託管帳號
Max 曝光報表✅ 完成2026-07-27・沒買 Max 不給假數字
旅遊體驗/點數/投放庫存監控P3要規模才有意義

⭐ 你可能沒想到的十件事

1. 降級時,他還有 3 堂課在招生怎麼辦?
不能直接關掉別人報名中的課(那是消費者的權益)。需要寬限政策: 降級後既有課程跑完,但不能再新開,直到降到配額內。這條沒設計清楚,第一個退訂的人就會出事。
2. 訂閱要開發票。訂閱是你的營收 → 電子發票、營業稅。 P2 一收錢就必須有,不能等。而且這也代表——收訂閱那天就要有公司 (之前算的「代收才需要公司」不完整:只要你自己收錢也要開發票)。
3. 教練怎麼知道要「去網頁訂閱」?App 內不能放外部付款連結(台灣 storefront 仍受 anti-steering 限制)。 出路:email/週報/教練後台的文字說明(不可做成按鈕)。這件事會直接影響轉換率,要提早設計。
4. 推播疲勞要有使用者端出口。沒有「少推薦一點/不要這個分類」的開關, 使用者只會做一件事:整批關通知。那等於你的 Max 庫存瞬間歸零。這是投放引擎的一部分,不是設定頁的小功能。
5. 效果保證要能履約。Max 賣「保證 300 次觸達」→ 月結時達不到要退費或延長。 需要自動對帳與補償,否則你會在每個月底手動算,而且算不清。
6. 許願會被灌水。教練叫朋友去許願,做出假的升級動機。
✅ 目前無害(他升級了但沒學生,傷的是自己)。
但絕對不能把「許願數」放進搜尋排序——一放進去就會被洗,整個排序信任崩掉。
7. 線上課的退款規則。看了一半要退嗎?業界標準是觀看超過 X%(常見 20~30%)不退。 這條沒寫進去,第一個爭議就會變成客訴。
8. 影片內容審核與下架。有人上傳不當內容或盜片 → 需要檢舉入口與下架流程。 平台責任在你身上,不是教練身上。
9. 興趣訊號的隱私。用行為做投放 → 隱私政策要寫清楚、要能關閉、 最好讓使用者自己也能設定興趣(既提高精準度也是合規出口)。
10. 「你的區域只有 2 位教練」需要基準數字。 冷啟動的稀缺性可視化很有效,但要能算出區域教練密度平台平均曝光—— 這需要一支統計 cron,不是隨手就有的數字。

Phase 逐步施工單

P1 ・ 讓教練被看見 ✅ 已完成 2026-07-26
步驟內容狀態
1.1coach_plan 欄位+模板公開讀+公開檔案 RPC
1.2CoachPlanGates/WishGates(25 tests)
1.3教練公開主頁/模板貨架/許願牆/配額閘
P2A ・ 現在就能做完的四個畫面 ✅ 已完成 2026-07-27
步驟內容依賴
2.1課程主頁「學」:分類切換/附近的課/推薦教練 S68
2.2我的學習:報名中/課包餘額/許願紀錄(掛在個人頁一列,帶摘要) S69
2.3目的地模式:地圖切換目的地+日期;離開 60km 自動切回「我附近」 S67
欠實機 dogfood
2.4訂閱與方案(說明版):三層比較表+降級寬限政策;付款誠實標「尚未開放」(有測試釘死不得出現假 CTA) S70
P2B ・ 排序與投放引擎 ✅ 引擎已就位 2026-07-27(0 位 Max 訂閱者 → 投放跑起來是 0 筆,刻意的)
步驟內容依賴
2.5SearchRankGates + 統一搜尋(場館+教練)+ 「為什麼我排這裡」(6 分項逐項拆解) S71
2.6arena_user_interestsAudienceGates(半衰 60 天)+ 訊號接線(報名/許願/瀏覽/搜尋) S72
2.7MomentGatesarena_detect_moment:許願未滿足/連敗/Elo 停滯/久未出現;⭐ 剛比完賽 24h 不推 S72
2.8DeliveryGatesarena_run_ad_delivery(每日 cron)+ 推薦偏好頁(總開關/上限/分類靜音) S72
2.9Max 曝光報表+arena_settle_placements(達標/自動延長/應退) S72
沒買不給假數字
P2C ・ 收錢 ⚠️ 規則與歸因已就位;收款仍卡「要先開公司開發票」
步驟內容依賴
2.10arena_coach_subscriptions + 生命週期;⭐降級只擋新開課,既有課程照上完 S73
2.11web 訂閱收款(綠界)+ 電子發票公司
2.12歸因:推廣連結管理 + ReferralGates(7 天 last-touch+self-deal 防呆) S74
P3 ・ 加厚 需要規模與外部依賴
步驟內容依賴
3.1線上課(上架/播放/購買/雙軌分潤/退款規則/內容檢舉)Cloudflare Stream 帳號
3.2旅行意圖 + 旅遊體驗 + 觀光體驗課代收目的地模式
3.3點數經濟(分錄式帳本/有效期/兌換標的)足夠教練提供體驗課
3.4投放庫存監控(operator)+ 區域密度統計 cron2.8
順序的邏輯:先做「有價值」,再做「收錢」。
P2A 讓學員找得到課、教練被看見;P2B 讓 Pro/Max 真的值那個錢;P2C 才收錢。
如果順序顛倒——先收錢後給價值——教練會覺得被騙,而信任只能失去一次。