動作
Feature #1442
進行中[功能開發] CourseProfile 後台管理 API 與 FE 交接需求
開始日期:
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。 - 權限只提供
administratorrole。
名稱驗證¶
- 必填,儲存前 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_mgmtcourse_profile_mgmt_listcourse_profile_mgmt_createcourse_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 的單元/整合測試,涵蓋驗證、搜尋條件、不可變欄位、唯一性與狀態切換。
動作