ADR-019: 通知主旨 env 前綴上收框架(EnvSubjectPrefixNotificationTemplateResolver)
ADR 編號: 019 狀態: 已接受 (Accepted) 決策日期: 2026-07-20 決策者: Development Team 取代: 無 被取代: 無
摘要
把「通知主旨的部署環境前綴(env marker)」decorator 從參考實作 app 層上收為框架內建:notification 模組新增 EnvSubjectPrefixNotificationTemplateResolver,與既有 BannerNotificationTemplateResolver 並列(一標主旨、一標內文),下游移除各自的重複實作、改接框架版。
背景 (Context)
問題陳述
env marker 機制(見 m-app-release.md「部署環境標示」)規定:app.env 有設時,通知主旨(Email / LINE / 站內信)前加 [{env}] 前綴,讓收件者辨識來源環境、避免測試通知誤認為正式信;正式環境不設 app.env → 不加前綴(零 PROD 硬編碼)。
此 decorator 最初(FU-37)落在參考實作 app 層(EnvSubjectPrefixTemplateResolver),經 scaffold 與人工搬運,fleet 中已存在三份等價重複:app-server 與兩個下游 server 各一份。每次演進(如措辭、邊界行為)都須三處同步——這正是「app 層沉澱成熟後上收框架」的收編訊號。
前例與時機
- 同性質前例已在框架:
BannerNotificationTemplateResolver(內文橫幅,標記非正式環境通知)為框架內建 decorator;env 主旨前綴是它的「主旨版兄弟」,性質、接線位置(resolver 鏈最外層)、no-op 語意完全同構。 - 沉澱已足:app 層版本自 FU-37(2026-07-02)誕生後行為與 API 未再變更(僅 Javadoc 措辭與 package 重整),符合「沉澱 1–2 版本再上收」的節奏(同 FU-11 / ConfigCheckEndpoint 的治理慣例)。
- 搭 4.0.0 班車:框架
[Unreleased]已累積 ADR-017 的 MAJOR 變更,下游本就要做一次升級遷移,順路移除副本成本最低。
決策 (Decision)
D-A:框架內建 decorator,維持「plain class + app 接線」慣例
io.leandev.appfuse.notification.EnvSubjectPrefixNotificationTemplateResolver:
- 命名對齊既有
XxxNotificationTemplateResolver慣例(Db/Nls/Banner)。 - 不做 auto-configuration——同 Banner,框架出 plain class,應用在通知接線(參考實作為
NotificationConfig)以@Bean組裝、包在 resolver 鏈最外層。 - 行為與 app 層版本一致:env 有設 → 已渲染主旨前加
[{env}]、內文不變;env null / 空白或渲染主旨為空 → 原樣回傳(no-op)。delegate為必要參數(null 建構即拒),與 Banner 一致。
D-B:開關即 app.env 本身,不另設啟用旗標
不新增 app.notification.env-prefix.enabled 之類的屬性——env marker 機制的既有慣例就是「app.env 有設即顯示、不設(= PROD)即隱藏」,前端 tooltip、/actuator/info、通知主旨三個顯示面同源同開關。另設旗標會製造第二套語意(env 有設但前綴關閉),沒有已知需求、徒增設定面。
D-C:下游移除副本、改接框架版
- 參考實作 app-server 即刻改接(本 ADR 落地的一部分),刪除
feature/notification/template/EnvSubjectPrefixTemplateResolver與其測試。 - 下游隨
/upgrade-appfuse-server(4.0.0)移除各自副本、把通知接線的最外層 decorator 換成框架類。CHANGELOGAdded條目已註明此遷移。
考量的方案 (Alternatives)
| 方案 | 說明 | 不採理由 |
|---|---|---|
| 維持 app 層重複(現狀) | 各 server 自帶 decorator | 三份等價碼各自漂移;scaffold 再複製會持續增殖 |
併入 Mailer 的 noticeSubjectPrefix | 郵件層已有主旨前綴 chokepoint | 層次不同:noticeSubjectPrefix 是 EMAIL-only 的轉址註記;env marker 須涵蓋所有通道(LINE / 站內信),且語意正交、不宜混併 |
| auto-configuration + 屬性開關 | 框架自動組裝 decorator | 違反 notification 模組「plain class + app 接線」慣例(Banner 亦非 auto-config);且 resolver 鏈由應用組裝,框架自動包最外層反而與應用的鏈序決策衝突 |
後果 (Consequences)
正面
- 一份實作、全 fleet 共用;行為演進單點生效。
- 與 Banner 成對,通知的「非正式環境標記」(主旨 + 內文)齊備於框架。
負面 / 成本
- 下游需在升級 4.0.0 時做一次副本移除(機械替換 import + 建構呼叫,無行為變更)。
中性
- 框架公開 API 增加一個類;依
30-public-api.md已記入 CHANGELOGAdded。
相關
m-app-release.md「版本的顯示面 / 部署環境標示(env marker)」——env marker 機制的權威定義- ADR-010: 事件驅動通知——通知子系統的整體架構
- 框架 CHANGELOG
[Unreleased]Added條目