專案

一般

配置概況

動作

Feature #1442

進行中

[功能開發] CourseProfile 後台管理 API 與 FE 交接需求

是由 陳國瑋 於 約 1 個月 前加入. 於 約 1 個月 前更新.

狀態:
Resolved
優先權:
Normal
被分派者:
開始日期:
2026-08-17
完成日期:
完成百分比:

0%

預估工時:
(總計: 0.00 小時)

概述

目標

新增 CourseProfile 後台管理 API,讓 administrator 維護「療程項目」主檔;後端完成後交由 FE 實作 UI。

CourseProfile 是療程類型/主檔,Course 是學員實際建立的療程,關係為:

  • hm_course.pid → hm_course_profile.pid(邏輯 1:N,目前無實體 FK)
  • Booking 目前以 hm_booking.booking_item 儲存 CourseProfile.name,無 FK

本工作以 staging 驗證與開發,不操作 production。

已確認的 domain rule

  • CourseProfile.name 建立後永久不可修改。
  • name 全系統永久唯一,包含停用資料;停用後也不可重複使用名稱。
  • has_diary、has_satisfaction、has_post_event_card 建立後不可修改。
  • 建立後可修改欄位只有 description、enabled。
  • 不提供實體刪除;只能啟用/停用。
  • 新建 CourseProfile 一律為 enabled=false,後續由管理員手動啟用。
  • enabled=false 只阻止未來建立 Course/Booking 時被選取;既有 Course、Booking、歷史資料、日誌、提醒及排程行為均不受影響。
  • has_diary=false 仍可建立 Course;它是功能能力,不是可建立條件。
  • has_satisfaction、has_post_event_card 目前沒有程式行為,但必須可於建立時設定,供後續功能使用。
  • description 非必填、建立後可修改;空白內容正規化為 null。
  • 權限只提供 administrator role。

名稱驗證

  • 必填,儲存前 trim 前後空白。
  • 最長 255 字元。
  • 不限制中文、英文、數字或符號;保留內部空白。
  • API 驗證唯一性,並新增 DB unique index 雙重保護。
  • 唯一性包含 enabled=false 資料,依現有 DB collation 判斷。
  • 重複時回傳可讓 FE 對應到 name 欄位的 validation error。
  • 更新 API 不接受 name 與三個功能旗標,不能只依 FE disabled 防護。

API contract

1. 搜尋

POST /api/admin/course/profile/search

可選搜尋條件:

{
  "page": 1,
  "size": 10,
  "sidx": [],
  "sord": [],
  "keyword": "選填",
  "enabled": true,
  "hasDiary": true,
  "hasSatisfaction": false,
  "hasPostEventCard": true
}

規則:

  • keyword 對 name、description 做 OR 模糊搜尋。
  • enabled 與三個旗標皆為 optional Boolean。
  • 未選擇條件時,request 不得帶該 property;不是傳「全部」。
  • true 與 false 都是有效搜尋值,FE 不可用 truthy 判斷導致 false 被省略。
  • SS3A NativeSearch 欄位為 null 時不產生 SQL condition。
  • 預設 create_time DESC;支援既有 Datatable 分頁/排序。
  • Page content 至少回傳 id、name、hasDiary、hasSatisfaction、hasPostEventCard、enabled。

2. 取得單筆

GET /api/admin/course/profile/info/{id}

回傳完整 CourseProfile。FE 編輯頁將 name 與三個旗標顯示為唯讀,只可編輯 description、enabled。

3. 建立

POST /api/admin/course/profile/create

{
  "name": "必填",
  "description": "選填",
  "hasDiary": true,
  "hasSatisfaction": false,
  "hasPostEventCard": false
}

規則:

  • 三個旗標皆為 required Boolean,建立時必須明確傳 true 或 false。
  • enabled 不由 FE 傳入;後端固定建立為 false。
  • 建立前 FE 會二次確認 name 與三個不可變旗標。
  • description 空白轉 null。

4. 更新

POST /api/admin/course/profile/update

{
  "id": "Pxxxxxxx",
  "description": "選填",
  "enabled": true
}

規則:

  • 只允許更新 description、enabled。
  • name、hasDiary、hasSatisfaction、hasPostEventCard 不可出現在 update DTO。
  • description 與 enabled 在同一 transaction 更新。
  • 若 enabled 有變更,FE 必須先取得 impact 並確認;若只改 description 可直接更新。

5. 狀態影響資訊

GET /api/admin/course/profile/status/impact/{id}

回傳:

{
  "id": "Pxxxxxxx",
  "name": "療程名稱",
  "enabled": true,
  "courseCount": 123,
  "bookingCount": 45
}

計數規則:

  • courseCount:hm_course.pid = CourseProfile.pid 的歷史總數,包含所有 Course status。
  • bookingCount:hm_booking.booking_item = CourseProfile.name 的歷史總數,包含所有 Booking status。
  • 此 API 於列表 Switch 或編輯頁變更 enabled 前呼叫。
  • 統計獨立查詢,不放入列表 search,避免每頁資料都執行聚合。

6. 列表狀態切換

POST /api/admin/course/profile/status/switch

沿用既有 ReqSwitchStatus:

{
  "id": "Pxxxxxxx",
  "newStatus": false
}

FE 先呼叫 impact,顯示名稱、Course/Booking 歷史總數與影響說明;管理員確認後才呼叫 switch。取消時不得改變畫面狀態。

不提供 delete API。

DB/SS3A

  • hm_course_profile.name 新增 unique index;migration 前先檢查重複與空值資料。
  • 不新增 bookable、course_creatable 等欄位,維持現有 enabled 單一邏輯。
  • 新增 SS3A function、i18n、API mapping 與 role mapping。
  • 選單位於 Common Lists,名稱「療程項目管理」。
  • 建議 function IDs:
    • course_profile_mgmt
    • course_profile_mgmt_list
    • course_profile_mgmt_create
    • course_profile_mgmt_edit
  • 不建立 delete function。
  • 上述 function 只 mapping 給 administrator。
  • impact 與 status/switch 歸 course_profile_mgmt_edit 權限。

FE handoff requirement(本 ticket 不實作 FE)

  • 列表沿用既有 SectionTitle、WrapperTable、Datatable、ActionButton、Switch 與搜尋元件。
  • 列表欄位:ItemId、名稱、日誌、滿意度、關懷卡、狀態、編輯操作。
  • 不在列表顯示 Course/Booking 數量;只在狀態確認視窗顯示。
  • 不顯示刪除操作。
  • 搜尋:keyword、enabled、三個旗標。Boolean 選項只有「有/無」;未選擇就不帶 request property。
  • 新增頁:name、description、三個旗標;建立前二次確認;建立結果固定停用。
  • 編輯頁:name 與三個旗標唯讀;description、enabled 可修改。
  • 列表 Switch 與編輯頁修改 enabled 都必須顯示 impact 確認視窗。
  • 啟用提示:啟用後會出現在新建 Course 與 Booking 的選單。
  • 停用提示:停用後不再出現在新建 Course 與 Booking 的選單;既有資料與流程不受影響。

驗收條件

  • 僅 administrator 能存取管理 API 與選單 function。
  • 可搜尋、分頁、排序 CourseProfile;optional Boolean 未帶時不產生條件,false 可正確搜尋。
  • 新增時 enabled 固定為 false;name 與三個旗標建立後無法由 API 修改。
  • 相同名稱(含停用資料)無法再次建立;併發建立亦由 DB unique index 阻擋。
  • 更新只影響 description、enabled。
  • 狀態 impact 回傳正確歷史總數。
  • 停用後不再出現在既有 Course/Booking 建立選單;既有 Course、Booking 及後續歷史行為不受影響。
  • 無 delete API/delete function。
  • 補齊 service、repository、controller 的單元/整合測試,涵蓋驗證、搜尋條件、不可變欄位、唯一性與狀態切換。

子任務 1 (1 進行中 — 0 已結束)

Feature #1443: [介面修改] CourseProfile 後台管理 UIResolved鍾正剛2026-08-17

動作
動作

匯出至 Atom PDF