← 所有文章

工程 · 2026.10.01 · 4 min · 更新於 2026.10.26

SaaS 後台 Admin Console 設計:kill switch、廣播與 Telegram 通知的取捨

放貸平台長成有使用者與帳單的服務後補上的 admin console 與多通道通知:高風險開關要能在 runtime 調整、查得到權限、留下紀錄,每個通知通道各自失敗,點名和分群廣播的收件規則要分開。

閱讀設定
主題
字級
寬度

SaaS 後台的管理員如果只能直接查 DB 或改設定檔,既沒有權限界線,也沒有審計脈絡。

我把 admin console 拆成幾個 phase 做,原則只有一條:每個高風險控制都要能在 runtime 調整、權限查得到、動作留得下紀錄,不散落在環境變數裡。

通知那邊的原則是每個通道各自失敗,不拖累其他通道,也不影響交易主流程。

最近一次改動是讓廣播能點名發給特定使用者,難的地方在收件規則。點名和分群的規則不同,混在一起,畫面上的人數就解釋不了。

這套後台是我的自動放貸平台從一個 bot 長成有使用者、計費、公告與維運動作的服務之後補上的。計費的設計寫在從績效抽成改成訂閱制的帳單設計。

kill switch 要查得到、留得下

Admin console 拆成可以獨立交付的 phase。先做 shell、使用者查詢、稽核與代入使用者視角,接著是角色權限、計費、廣播、維護窗、feature flag 與 kill switch(一鍵停掉某項功能的緊急開關)。

幾個關鍵決策:

  • 權限用四種角色加一張 capability 矩陣(每個角色能做哪些動作的對照表)來判斷,不拿 UI 有沒有顯示那顆按鈕當權限。
  • Kill switch 影響所有使用者的資金操作,所以切換時要做 2FA step-up,也就是操作當下再驗證一次身分。
  • 維護窗共用同一個判斷點,不讓每個功能各自判斷現在是不是維護中。
  • 廣播要有 durable 的排程,而且在 transaction commit 之後才分發,避免交易還沒提交就送信,或排程只寫進 DB 卻沒發出去。

非同步分發如果要讀同一個 transaction 寫的資料,一定要在 commit 之後才觸發。

通知:每個通道各自失敗

Email 適合留紀錄,但對 API key 停用、全站 kill switch 這類事件太慢。

不同事件各自直接送通知,通道失敗與偏好設定也很難一致。所以我先把通知抽成一個共同的發送介面,Email 和 Telegram 是平行的兩個通道,可以各自失敗。

Telegram 由使用者主動對 bot 送出 /start {token} 綁定。這是 Telegram bot 的 deep linking 機制,啟動 bot 時可以帶一個參數,可以拿來把 Telegram 帳號接到別的平台的帳號。

綁定之後預設不開啟通知。綁定和「開啟」是分開的兩個動作,因為我不想把拿到 chat id 當成隱性同意。

只點過連結,不會開始收到訊息。

之後陸續加了每個使用者的通知紀錄、事件分類、偏好設定與站內通知頁,最後才加上瀏覽器的 Web Push 當第四個通道。

Web Push 能在使用者沒開著網頁時送達,所以每種通知類型能用哪些通道、使用者偏好怎麼設,都要能控。成交事件另外加了合併視窗,免得高頻事件變成推播轟炸。

這幾個 phase 是依序合併的,因為上方導覽列、API client、i18n 與樣式都是共用的檔案,平行改只會一直衝突。

示意圖:API key 停用、全站 kill switch、成交和公告等事件在交易 commit 後才分發,經過共同的發送介面,依通知類型能用的通道和使用者偏好,送到 Email、Telegram、站內通知、Web Push 四個通道;其中一個通道失敗,其他通道照送,也不影響交易主流程。

點名廣播與「放貸已暫停」

原本廣播的受眾只有分群(所有人、活躍、放貸執行中等),沒辦法只發給一兩個人。

Telegram 與 Email 還多一道公告通知偏好,預設是關的,照分群的規則幾乎誰都送不到。

我加了「指定使用者」:在 Telegram 或 Email 廣播裡搜尋 email 或名稱,點名 1 到 50 個人。規則是這樣定的:

  • 點名的人不看公告偏好,但尊重全域開關。點名是操作者對特定人的聯絡,不是大量公告;可是使用者把 Email 或 Telegram 通知整個關掉,照樣不送,選取器上會標出誰送不到。
  • 指定使用者跟其他分群互斥。分群要過公告偏好、點名不用,兩邊混在一起,畫面上的人數會解釋不了。
  • 站內公告不支援點名。站內公告在資料上是一列全站共用的公告,讀取時只能用分群過濾,後端直接回 400。
  • 名單跟著廣播那一列存。排程廣播在觸發時才解析收件人,名單必須跟著廣播走。

把 user id 編進原本存分群的字串欄位也想過,但那個欄位只有 200 字,歷史頁也要另外解析。

對照表:分群廣播要過預設關閉的公告通知偏好,指定使用者不看公告偏好;兩者都尊重 Email、Telegram 的全域開關,選取器會標出點名送不到的人;站內公告只支援分群,點名時後端回 400;分群存在原本的分群字串欄位,點名的 1 到 50 人跟著廣播那一列存。兩者互斥。

另外加了一個「放貸已暫停」的受眾:有啟用的 API key,而且自己關掉放貸或被帳務停權的人。

它跟後台使用者頁的 bot 狀態「已暫停」用同一個判定,兩邊的人數才對得上。全站 kill switch 造成的暫停不算在內。

收件規則不同的受眾不要混在同一次發送裡,否則人數會變成沒人解釋得了的數字。

#通知#後台#系統設計

留言

載入留言中…

下一篇

工程

GitHub Actions 加速 Rust 與 Next.js 的 CI:11 分半壓到 1 分半

後端換成 Rust 後,PR 的 backend job 從 11 分半壓到 1 分半,前端檢查從 81 秒壓到 30 秒。時間主要省在測試 DB、bcrypt 和幾個讓快取無聲失效的 bug。