- Implemented OAuthClientsController for CRUD operations on OAuth clients. - Added SecurityController to manage security settings. - Created SubscriptionsController for handling subscriptions with export functionality. - Developed TenantsController for tenant management including create, edit, and delete operations. - Added views for each controller to facilitate user interaction. - Introduced layout and shared views for consistent admin UI. - Implemented model classes for handling data in views. - Added validation and error handling in forms.
9.5 KiB
9.5 KiB
Admin / Client UI 拆分工作計劃
目標
- 在同一個
MemberCenter.Web專案中,將會員端與管理端 UI 明確分區。 - 保持單一登入入口與單一帳號系統。
- 讓具有
admin權限的帳號同時可使用會員功能與管理功能。 - 將目前偏向後台的共用介面,調整為 client-first 的會員中心體驗。
- 補齊會員註冊、Google 第三方登入與訂閱資料銜接流程。
已確認決策
帳號與登入
Admin與Client共用同一個登入入口。Admin帳號同時也是會員帳號,可使用會員介面功能。- 不拆成兩套認證系統,不建立獨立 admin login。
UI 與導覽
- 會員端為主介面。
- 功能選單採分組方式呈現。
- 一般會員只看到會員功能。
- 具有
adminrole 的帳號,額外看到Admin功能分類。 Admin分類展開後顯示管理功能連結。- 目前先以
adminrole 做整包顯示,不先做細權限切分。
未授權存取
- 非 admin 使用者存取
/admin/*時,回應404。 - 不使用
403頁面暴露後台存在。
目標範圍
本次要做
- 調整
MemberCenter.Web路由與結構,將管理端移入Areas/Admin。 - 將現有共用 layout 改為 client-first 導覽。
- 將 admin 功能從全站共用導覽中抽離,改成 role-based 顯示。
- 建立 admin 路由未授權時回
404的處理方式。 - 補上會員註冊、第三方登入與訂閱綁定的工作規劃。
本次不做
- 細粒度權限模型,例如依功能模組拆
tenant.read、audit.read。 - 獨立的
AdminWeb/ClientWeb專案拆分。 - 大幅重做視覺設計。
- API 權限模型重構。
- 註冊確認信寄送實作。
實作策略
策略原則
- 先切 UI 邊界,再保留既有 Identity 與 role policy。
- 先做低風險結構重整,不同時引入細權限與大幅 UI redesign。
- 保持既有 URL 慣例,避免不必要的 route breakage。
預期結構
src/MemberCenter.Web/
├── Areas/
│ └── Admin/
│ ├── Controllers/
│ └── Views/
├── Controllers/ # client only
├── Views/
│ ├── Shared/
│ │ ├── _Layout.cshtml # client-first layout
│ │ └── ...
│ └── ...
分階段計劃
Phase 0: 會員註冊與帳號銜接規格補齊
狀態:已完成
目標:先將會員建立、第三方登入與訂閱資料綁定的規則固定,避免後續 UI 與 auth 重構互相衝突。
需求規則
- 會員帳號以
email為主要識別。 UserName強制等於Email。- 不提供獨立 username。
- 本地註冊完成後,帳號標記為未認證。
- 本階段先不寄送確認信。
- 未認證帳號仍可登入。
- 後續功能完整後,未認證帳號將可被限制部分功能;本階段先保留此狀態與擴充空間。
- 支援 Google 作為第一個第三方登入/註冊 provider。
- Google 第一次登入時,若系統已存在相同 email 的本地帳號,直接 auto-link。
- Google 回傳 email 即使未驗證,仍允許建立帳號或連接既有帳號。
- 使用者若先以本地帳號註冊,之後再以 Google 同 email 登入,應連接到同一個帳號,不建立第二個 user。
- 註冊成功後,若系統中已有相同 email 的訂閱資料,需將相關
newsletter_subscriptions.user_id補上。 - 訂閱綁定時必須保留既有訂閱狀態與偏好,不可覆蓋。
- 訂閱綁定完成後需補一筆 audit log。
- 後續若導入事件,保留發送
subscription.linked_to_user的擴充空間。
子工作
- 已完成:定義本地註冊後的帳號狀態與登入規則。
- 已完成:定義 Google external login / register / auto-link 流程。
- 已完成:定義訂閱資料綁定與 audit log 寫入時機。
- 已完成:將上述規則同步反映到目前的 Web / API 實作階段。
- 已完成:
subscription.linked_to_user事件發送。 - 註記:未認證帳號的功能限制屬後續能力擴充,不阻擋本 phase 完成。
- 註記:Google 實際整合驗證仍需提供 Google OAuth 設定,屬外部驗證條件,不阻擋本 phase 完成。
完成條件:
- 註冊、Google 登入、同 email 帳號連接、訂閱綁定規則均有明確定義。
- 後續 Phase 1 之後的 UI 與 auth 重構可直接依規則實作。
Phase 1: Route 與目錄切分
狀態:已完成
目標:先建立清楚的 UI 邊界。
- 將現有
Controllers/Admin/*移入Areas/Admin/Controllers/*。 - 將現有
Views/Admin/*移入Areas/Admin/Views/*。 - 調整 route 設定,讓
/admin/*由 area route 處理。 - 確認既有 admin URL 可維持不變。
完成條件:
- 所有 admin 頁面由
Areas/Admin提供。 - 會員端 controller 不再與 admin controller 混在同一層。
Phase 2: Layout 與導覽切分
狀態:已完成
目標:把 UI 改成 client-first,不再全站露出後台功能。
- 重構共用 layout,移除固定顯示的 admin 連結。
- 建立 client-first 功能選單。
- 若使用者具
adminrole,顯示Admin功能分類。 Admin分類底下先列出既有管理功能:- Tenants
- Newsletter Lists
- Subscriptions
- OAuth Clients
- Audit Logs
- Security
- Blacklist
完成條件:
- 一般會員不會在主選單看到 admin 連結。
- admin 使用者可從同一套主介面展開進入管理功能。
Phase 3: Admin 畫面容器整理
狀態:已完成
目標:讓進入 admin 區後有明確上下文。
- 規劃 admin area 是否使用獨立 layout。
- 若使用獨立 layout,保留回會員區入口。
- 若先共用 layout,至少在 admin 頁面標示目前位於管理區。
建議:
- 第一版可先採用共用主殼 + admin 區塊標示。
- 若後續 admin 功能持續增長,再抽
_AdminLayout。
目前進度:
- 已完成:獨立
Adminarea layout。 - 已完成:保留回會員區入口。
- 已完成:admin shell 基礎結構整理(top bar、side nav、active state、區域標示)。
- 已完成:補上可替換的基礎樣式 hooks,避免後續設計重做時需要拆 route 或 view 結構。
- 註記:後續若需進一步整理 admin/client 的整體體驗、內容層級、表格與表單版型,視為 UI/UX refinement,不阻擋本 phase 完成。
完成條件:
- 使用者進入 admin 頁面時,有清楚的區域辨識。
Phase 4: 未授權存取改為 404
狀態:已完成
目標:保留授權檢查,同時隱藏 admin surface。
- 保留
[Authorize(Policy = "Admin")]。 - 增加 admin 未授權時的統一處理,避免顯示預設
403。 - 確認未登入與已登入但非 admin 的行為符合預期。
已定案:
- 未登入進
/admin/*:直接回404 - 已登入但非 admin 進
/admin/*:直接回404
目前進度:
- 已完成:保留
[Authorize(Policy = "Admin")]。 - 已完成:admin 未授權時不顯示預設
403,改為404。 - 已完成:目前實作上,未登入與非 admin 存取
/admin/*均回404。 - 已完成:將「未登入也回
404」正式定案並同步到工作計劃。
Phase 5: 驗證與文件更新
狀態:已完成
目標:確保重構後行為可驗證、文件一致。
- 驗證會員端主要頁面仍可正常使用。
- 驗證 admin 帳號可以:
- 使用會員功能
- 看見
Admin選單 - 進入 admin 各頁
- 驗證非 admin 帳號無法看見 admin 選單,且直接進 admin URL 會得到
404 - 更新 README / UI 文件中的 web 結構描述
目前進度:
- 已完成:
dotnet build MemberCenter.sln -m:1 - 已完成:會員端主要頁面可用性驗證(首頁 / login / register)。
- 已完成:admin 帳號操作驗證(可登入、可進 member profile、可進 admin route)。
- 已完成:一般會員登入驗證(可登入、可進 profile、首頁不顯示 admin 群組)。
- 已完成:非 admin / 未登入情境驗證(匿名打
/admin/*回404)。 - 已完成:計劃文件、README、UI / Flow / Use Case / Design / OpenAPI 相關文件更新。
- 註記:Google 真實 round-trip 驗證需提供 Google OAuth 設定,屬外部條件,不阻擋本 phase 完成。
影響檔案預估
src/MemberCenter.Web/Program.cssrc/MemberCenter.Web/Views/Shared/_Layout.cshtmlsrc/MemberCenter.Web/Controllers/Admin/*src/MemberCenter.Web/Views/Admin/*- 新增
src/MemberCenter.Web/Areas/Admin/... - 視需要更新
docs/UI.md
風險與注意事項
- Area 導入後,view 路徑與 route mapping 容易有小錯誤,需要逐頁驗證。
- 若直接共用同一個 layout,需避免 client 與 admin 的語意混亂。
404偽裝策略要搭配真正的 authorization,不能只靠 route 隱藏。- 若未登入也直接回
404,可能會讓合法 admin 使用者失去登入引導;這點需明確決策。
建議執行順序
- 先完成 Phase 0,確認註冊、Google 登入與訂閱綁定規則。
- 再完成 Phase 1,做純結構重整。
- 接著做 Phase 2,修正選單與角色顯示。
- 然後決定 Phase 3 要共用 layout 還是抽 admin layout。
- 再做 Phase 4,補齊
404授權行為。 - 最後做 Phase 5 的驗證與文件更新。
本次文件用途
這份計劃作為後續逐步實作的工作底稿。後續每一步都應以「單一階段可驗證完成」為原則,避免一次改太多導致 routing、授權與 UI 問題混在一起。
目前總結
- 已完成:Phase 0、Phase 1、Phase 2、Phase 3、Phase 4、Phase 5
- 部分完成:Phase 5