跳至主要内容

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 換成框架類。CHANGELOG Added 條目已註明此遷移。

考量的方案 (Alternatives)

方案說明不採理由
維持 app 層重複(現狀)各 server 自帶 decorator三份等價碼各自漂移;scaffold 再複製會持續增殖
併入 MailernoticeSubjectPrefix郵件層已有主旨前綴 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 已記入 CHANGELOG Added

相關

  • m-app-release.md「版本的顯示面 / 部署環境標示(env marker)」——env marker 機制的權威定義
  • ADR-010: 事件驅動通知——通知子系統的整體架構
  • 框架 CHANGELOG [Unreleased] Added 條目