iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Claude AI

Claude Code陪跑:一人開發者的訂閱制SaaS架構與十大地雷實戰記系列 第 14

# Day 14|訂閱分級系統設計:等級不只是 on/off

  • 分享至 

  • xImage
  •  

從 Day 12 的廢墟上重建

Day 12 講了 is_premium 布林旗標怎麼變成技術債。今天講重構之後的設計長什麼樣——一套撐得住「等級會增加、會停售、權益會調整」的訂閱分級系統。

核心設計:一份權益對照表

整個系統的心臟是一份宣告式的「等級 → 權益」對照表:

TIER_LIMITS = {
    Tier.FREE:     Limits(watch_items=3,  groups=1,  daily_reports=0, api_alerts=False),
    Tier.LEGACY:   Limits(watch_items=10, groups=3,  daily_reports=1, api_alerts=True),
    Tier.STANDARD: Limits(watch_items=10, groups=10, daily_reports=1, api_alerts=True),
    Tier.PREMIUM:  Limits(watch_items=30, groups=20, daily_reports=3, api_alerts=True),
}

程式碼裡任何權限判斷,一律查這份表:

def can_add_watch_item(user) -> bool:
    return count_items(user) < TIER_LIMITS[user.tier].watch_items

禁止的寫法是散落各處的 if user.tier >= Tier.STANDARD——那只是布林旗標的多階版本,等級權益一調整,你又要滿專案找判斷式。把「等級有什麼權益」跟「功能怎麼檢查權益」分離,之後調整方案只改表,不改邏輯。

這個結構還有一個隱藏好處:它是可測試的商業規格。「免費使用者最多 3 個關注項目」不再是散落在程式碼裡的魔術數字,是一份可以直接拿給非工程師(例如未來的合作夥伴)確認的表。

三個從實戰裡學到的原則

一、額度檢查要防併發。 「查目前數量 → 判斷未超額 → 寫入」三步之間有時間差,使用者連點兩下就可能雙雙通過檢查、雙雙寫入,超出額度。這是經典的 TOCTOU(check 與 use 之間被插隊)問題,修法是把檢查跟寫入收進單一 SQL 語句,讓資料庫的原子性當守門員,而不是應用層的天真三步驟。

二、停售等級是一等公民,不是例外。 Tier.LEGACY 在對照表裡有自己正式的一列,權益凍結在當初對那批訂戶的承諾。反模式是用 if 特判「某些老使用者除外」——例外邏輯會隨時間繁殖,正式建模的等級不會。

三、已經給出去的權益,只能加不能減。 這是商業層面的鐵律:既有使用者已經在用的功能,之後的方案調整不能追溯收回——寧可讓新舊方案並存、老使用者 grandfather(保留原權益),也不做「昨天免費今天收費」的事。這條在使用者信任上的重要性,怎麼強調都不過分;而技術上,正是因為有了「方案版本」的建模(而不是一個布林),grandfather 才做得乾淨。

Agent 在這套系統裡的角色

權益對照表也進了 CLAUDE.md 的規範區。之後 agent 開發任何新功能,涉及權限判斷時會自動走 TIER_LIMITS 查表,而不是自己發明判斷式;要動到表本身的數字時,它會停下來——因為文件裡標明了方案內容與定價是商業決策,不是工程決策,任何 agent 不得自行變更。這條界線是一人公司特有的風險控制:當你的「工程團隊」是一個高度自主的 AI,哪些數字它碰不得,必須白紙黑字。


上一篇
# Day 13|地雷#10:逐筆查DB燒穿雲端額度,closure 快取怎麼救
下一篇
# Day 15|金流地基先蓋好,等條件成熟再開燈
系列文
Claude Code陪跑:一人開發者的訂閱制SaaS架構與十大地雷實戰記15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言