嚮導與排班
嚮導(領隊)在 cairn 有兩種身分:一個是名錄上的實體——你替他建檔、把他派到梯次帶團;另一個是受限 login 角色——開通帳號後,他只能透過自己的 portal 看到自己帶的梯次、填報代墊成本。本篇說明這兩者怎麼接起來。
整條流程是:先建檔,需要時開通登入帳號,把他派到梯次並確認,確認後該梯次才會進入他的 portal 可見範圍。
嚮導建檔
嚮導名錄走 guides 資源——和後台的嚮導管理頁完全等價,租戶範圍內共用(無 owner-scope)。
| 動作 | 端點 | 權限 |
|---|---|---|
| 列出 / 搜尋(可分頁、依狀態篩選) | GET /guides | guide.read |
| 依 slug 查單筆 | GET /guides?slug=… | guide.read |
| 建檔 | POST /guides | guide.manage |
| 明細 | GET /guides/{id} | guide.read |
| 編輯 | PATCH /guides/{id} | guide.manage |
封存(狀態轉 inactive) | POST /guides/{id}/archive | guide.manage |
建檔只需 name,其餘(slug、bio、specialties、yearsExperience、contactPhone、contactEmail、status…)皆選填。封存不刪資料,只把 status 轉成 inactive;要重啟用就 PATCH 回 active。
curl -X POST https://your-tenant.example.com/api/v1/guides \
-H "Authorization: Bearer $CAIRN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "王嚮導", "specialties": "高山,溯溪" }'
建檔只是名錄——這時嚮導還不能登入。能不能登入、能看到什麼,由下面的「開通帳號」與「派班」決定。
開通登入帳號(邀請)
要讓某個既有嚮導能登入自己的 portal,對他開通帳號:
POST /guides/{id}/invite-account(guide.manage),帶email與顯示name。- 回傳一個一次性暫時密碼(僅此一次回傳,請當下轉交給嚮導)。
- 這不是自助註冊——一律由後台 / 串接端主動邀請;一個嚮導至多綁一個登入帳號。
開通後嚮導以 guide 角色登入。guide 是受限角色:不在後台管理角色集合裡,無法碰使用者管理或其他後台端點,且強制 2FA(屬 staff-tier)。沒開通帳號的嚮導,就只是名錄上一筆可被派班的實體。
梯次派班與確認
把嚮導排進梯次走 guide-roster 資源(鏡像後台排班頁,租戶範圍內共用)。一筆指派有兩個維度:
- 角色
role:leader(領隊)或assistant(隨隊助理)。 - 狀態
status:tentative(預塞暫定)或confirmed(正式確認)。
| 動作 | 端點 | 權限 |
|---|---|---|
| 當月名冊 + 帶團負荷 / 可用度 | GET /guide-roster/guides | guide_roster.read |
| 當月梯次 + 其指派(領隊優先) | GET /guide-roster/departures | guide_roster.read |
| 指派 / 重派(upsert) | POST /guide-roster/assignments | guide_roster.manage |
| 確認某筆指派 | POST /guide-roster/assignments/{id}/confirm | guide_roster.manage |
| 移除某筆指派 | DELETE /guide-roster/assignments/{id} | guide_roster.manage |
| 換領隊 | POST /guide-roster/change-leader | guide_roster.manage |
tentative 是先把人預塞進去、還不算數;confirmed 才是正式確認。只有 confirmed 的指派才會讓該梯次進入嚮導 portal 的可見範圍(見下節)。
檔期衝突
同一個嚮導若在日期重疊的兩個梯次都是 confirmed,就構成排班衝突。confirm 在確認時會擋下衝突(fail-closed);你也可以事先預檢:
GET /guide-roster/conflict-check?departureId=…&guideId=…:回傳會撞到的那個梯次,或null(沒撞)。GET /guide-roster/conflicts?month=YYYY-MM:列出當月所有衝突配對,對應後台排班頁的衝突警示。
換領隊
換領隊用 change-leader 一個動作完成(移除原領隊、把新領隊升為 confirmed leader),需附 reason(記入稽核)。比起先 DELETE 舊指派再 POST 新指派,這個端點是原子的,且把換人原因留下軌跡。
嚮導 portal:能看什麼、能做什麼
開通帳號的嚮導用自己的 guide token 登入後,看到的是一個受限 portal,不是後台。範圍由伺服器依他的身分重新判定,不接受用參數覆寫:他只能看到自己被 confirmed 指派的梯次。存取別人的梯次一律 fail-closed(404 / 403)。
| 嚮導能做 | 說明 |
|---|---|
| 看自己帶的梯次 | 出團資訊、車 / 食 / 宿、成員名單、證件清單(唯讀) |
| 揭露旅客個資 | 名單預設遮罩身分證 / 電話;點開才解密,且寫入揭露稽核(只限自己梯次的旅客) |
| 填報代墊成本 / 發票 | 現場登記墊付金額與憑證,送出後即進後台覆核佇列 |
| 嚮導看不到 / 不能做 | 在哪裡 |
|---|---|
| 淨利、毛利、應收 / 實收等金流真相 | 後台(admin / accountant) |
| 覆核成本、轉請款、出款核簽 | 後台財務流程,見 請款與出款 |
| 別人帶的梯次、別的旅客 | 永遠超出範圍 |
嚮導填報的成本是「經手」紀錄,送出即進覆核、不會自動生效。它要等後台會計覆核通過後才計入帳;覆核、淨利分析、退款給嚮導全在後台完成,嚮導端不顯示這些。
與權限角色的關係
這篇牽涉到兩組不同的權限,別混淆:
- 管理嚮導與排班的權限(
guide.read/guide.manage/guide_roster.read/guide_roster.manage)給的是後台 / 串接端——你拿管理用的 token 建檔、派班、換領隊。 - 嚮導本人的權限(進 portal 讀自己梯次、填報成本)綁在
guide角色上,且額外受「只限自己confirmed梯次」的範圍閘二次收斂。
換句話說:派班是「你」在做的事,需要 roster 的管理權限;portal 裡看到的內容是「嚮導」在做的事,受他自己的角色與範圍限制。角色與權限的全貌(角色集、權限字串、owner-scope、模組閘)見 權限與角色。
下一步
- 出團準備與線控:分房、護照、裝備、請款等 per-departure 批次作業——嚮導 portal 看到的 dossier 多半源自這裡。
- 權限與角色:
guide角色、權限字串與範圍閘怎麼決定誰能呼叫什麼。 - guides API · guide-roster API:逐端點的參數與回應。