一句話:每梯次的出團備辦工作台(
/admin/control/[depId]/departure-prep)—— 行前總檢查 / 證件追蹤 / 領隊協作 / 裝備需求調查 + 四軸營運作業(對款 · 派車 · 餐食 · 投保)。核心骨幹(對款 / 派車 / 餐食 / 投保 / 換領隊 / 行前檢查)不受任何模組 gate;只有入山/入園/山屋/登山險 deadline + 許可證文件 + 人頭使用次數限制屬登山專屬子集,受 模組化 的「登山」開關 gate。
departure_costs / payables)2026-06-23 user 裁決「登山是獨立可拆模組」:抽掉登山模組,出團準備的核心骨幹照常可用。本檔把功能切成兩半:
| 區塊 | 屬性 | gate |
|---|---|---|
| 行前總檢查 checklist(8 項) | 核心 | 無 |
| 領隊協作 / 換領隊(roster) | 核心 | 無 |
| 對款(團費收齊 + 供應商 / 裝備住宿對款,唯讀派生) | 核心 | 無 |
| 派車(台鐵 / 接駁 / 車資營運資訊) | 核心 | 無 |
| 餐食(訂餐 / 供應商 / 飲食禁忌) | 核心 | 無 |
| 投保(旅平險 per-head + 旅責險 per-梯次) | 核心 | 無 |
| 證件追蹤(入山證 / 入園證 / 床位核准證 / 營位核准證) | 登山專屬 | 登山 gate |
| deadline 警戒(入山申請 / 入山下載 / 登山險 / 旅責險工作天倒數) | 登山專屬 | 登山 gate |
| 人頭使用次數限制(國家公園 permit 配額,以身分證計次) | 登山專屬 | 登山 gate(enforcement 隨 climbing/lottery epic) |
| 裝備需求調查 + 跨梯次彙總 | 登山專屬 | 登山 gate(見 equipment-inventory) |
旅責險本身是所有出團團都要的(per-梯次旅行業責任險),故「投保」軸屬核心;登山險(per-head 山域意外險)的 deadline 警戒才屬登山子集。投保軸的
departure_insurance二類(旅平 / 旅責)核心永遠在;登山團多一條登山險 deadline。
行前檢查 / 證件 / 裝備需求三表 + 四軸營運資訊表皆已落地(schema 在 packages/core/src/schema/business.ts,repo 在 packages/core/src/departure-prep/repo.ts)。
departure_prep_checklist8 固定檢查項(CHECKLIST_ITEM_KEYS):payment / leader / transport / meal / insurance / documents / equipment / roster。toggle 勾 / 取消勾(upsert,UNIQUE departure_id + item_key);勾起記 checked_at + checked_by_user_id。
departure_documents(登山子集)4 種證件(DOCUMENT_TYPES):入山證 / 入園證 / 床位核准證 / 營位核准證。每種一列(upsert,UNIQUE departure_id + doc_type),追蹤申請狀態 apply_status(todo / applying / approved,時間戳只前進不回退)、file_ready / uploaded_to_cloud / file_uri(Drive 連結)/ note。
departure_equipment_needs(登山子集)見 equipment-inventory §4:per-departure 需求列 + summarizeEquipmentDemand 跨梯次彙總(surplus / shortage / 剩餘≤2 lowStock)。
成本一律走 departure_costs(登記在團控成本頁 / 嚮導 portal,分析在內外帳 nav),這三表只記營運欄位與完成狀態 —— *_note 是純文字備註,不是金額成本欄。
departure_insurance:kind(travel_accident 旅平險 / liability 旅責險)、insurer、policy_no、status(pending → done)、note。被保人身分證走既有 traveler reveal + audit,不在此表存 PII。保費成本走 departure_costs(category='保險',見 internal-external-ledger 的旅平 / 旅責 insurance 維度)。departure_transport:description(上下車 / 路段)、driver_name、vehicle_info、fare_note(純文字車資備註)、status(pending → arranged)。車資成本走 departure_costs(category='交通')。departure_catering:supplier、meal_plan、headcount_note、status(pending → arranged)。飲食禁忌仍在 travelers 備註,不在此表。餐費成本走 departure_costs(category='餐飲')。對款 tab 不寫任何成本 / charge,純讀的對帳檢查視圖:團費收齊度(getDepartureFinanceSummary 派生自金流模型)+ 供應商 / 裝備住宿應付未付(listDepartureCostRecon 把 departure_costs 與其轉出 payables 核付狀態 join,派生每列 paidState:paid(payable 已核付)/ billed(已轉未付)/ unbilled(未轉),彙總已付 / 未付)。成本的登記 / 編輯入口在團控成本登記頁(/admin/control/[depId]/costs,departure_cost.create)與嚮導 portal(2026-06-24 決策反轉「成本只在內外帳 nav」,見 internal-external-ledger §4);對款 tab 仍維持唯讀對帳,不重做成本 CRUD(避免兩入口打架)。淨利分析 / 證明單核簽仍在內外帳 nav(admin / accountant)。
GS「總表」對每團每類期限用 NETWORKDAYS.INTL(TODAY(), 期限, 假日表) 算工作天倒數,輸出醒目色狀態。已落地:departures 四個 nullable 期限日期欄(permit_apply_deadline 入山申請 / permit_download_deadline 入山證下載 / climbing_insurance_deadline 登山險 / liability_insurance_deadline 旅責險);工作天倒數查詢時計算(getDepartureDeadlineCountdowns,不落 DB,對齊證件效期),底層純函式 workingDaysUntil(packages/core/src/workdays.ts:扣週末 + 國定假日、補班日照算,4000 天防呆上限);今天用 Asia/Taipei 牆鐘日;色階門檻 deadlineTone:< 0 逾期 / ≤ 3 緊迫 / ≤ 7 注意 / 其餘充裕。團控「期限警戒」tab(prep-tabs.tsx,只在 climbingActiveFor 渲染 TabsTrigger + TabsContent)顯示倒數表 + 逾期/緊迫 Alert + 「設定期限」dialog(setDepartureDeadlinesAction,departure_prep.manage + requireClimbingModule 雙閘)。國定假日 / 補班來源見 §2.7。
public_holidays(deadline 倒數的資料源)per-tenant 表(date 自然鍵 / name / is_workday):is_workday=false 國定假日(不計工作天,即使平日)、true 補班日(彈性放假補上班的週末,照常計入工作天)。維護在獨立頁 /admin/holidays(跨梯次參考資料,比照團號對照表走獨立 nav,requiresClimbing 登山 gate 隱藏;public_holiday.read 檢視、public_holiday.manage〔op / admin〕維護,寫入 action 另過 requireClimbingModule)。資料源為荒野現行 GS「小編用」分頁,小編每年初匯入;未維護的年度 → 倒數僅扣週末(保守,不誤報)。repo:listPublicHolidays / getHolidayYearStats / upsertPublicHoliday(date upsert 覆寫)/ deletePublicHoliday / loadHolidayCalendar。
departure_prep.read;四軸 / checklist / 證件 / 裝備需求寫入走對應 departure_prep.* action(requirePermission(resource.action))。order.adjust / departure_costs CRUD)只在內外帳 nav,accountant 唯讀、sales 無、admin / op 可寫(見 control-finance §3)。UI 真相在 apps/wireframes/admin/control.html + /admin/control/[depId]/departure-prep。Tab 結構:核心永遠列(名單 & 總檢查 / 領隊 & 協作 / 對款 / 派車 / 餐食 / 投保),登山專屬僅 climbingActiveFor 時列(證件追蹤 / 裝備 & 住宿)。行前總檢查的 documents / equipment 兩項(入山證 / 登山裝備)同樣只在登山生效時納入分母。對款 / 派車 / 餐食 / 投保 / 證件四軸的 CRUD 走 requirePermission('departure_prep.manage'/.read)(對款唯讀)。per-departure 批次處理一律從 /admin/control 進,不開獨立 sidebar nav。
小編用(假日表)—— 已建可編輯 public_holidays 表 + /admin/holidays 維護頁(§2.7);小編每年初匯入官方國定假日 / 補班| 版本 | 日期 | 變更 | Commit |
|---|---|---|---|
| 1 | 2026-05-30 | 初版 stub:登錄缺口 + 資料模型草圖(財務 impact 1,佔位待排程) | — |
| 2 | 2026-06-23 | 從 stub 補滿:①核心骨幹 vs 登山專屬子集 gate 分界(對款/派車/餐食/投保/換領隊/行前檢查不 gate;入山入園山屋登山險 deadline + 證件 + 裝備 + 人頭限制屬登山子集)②落地資料模型(departure_prep_checklist 8 項 / departure_documents 4 種 / departure_equipment_needs / 四軸營運表 departure_insurance·departure_transport·departure_catering 皆只記營運資訊不存成本)③對款 tab 唯讀派生(成本只在內外帳 nav,finance/page.tsx CRUD 待收斂)④投保旅平/旅責二類。 | — |
| 3 | 2026-06-23 | 4 tab 落地(取代 PlaceholderTab):對款唯讀派生(listDepartureCostRecon paidState 已付/已轉未付/未轉)/ 投保·派車·餐食 CRUD(departure_prep.manage)+ 餐食彙總旅客飲食禁忌(listDepartureDietaryNotes,自 travelers.roommate_pref + orders.notes);prep-tabs 登山 gate 收斂到證件/裝備兩 tab + checklist documents/equipment 兩項(核心 tab 永遠列);裝備校準 summarizeEquipmentDemand 加 lowStock(剩餘 0~2)+ Alert 低水位段;finance/page.tsx 成本 CRUD 收斂為唯讀彙總(深連結內外帳)。 | — |
| 4 | 2026-06-24 | deadline 工作天倒數落地(§2.6/§2.7):departures 四期限日期欄 + 純函式 workdays.ts(NETWORKDAYS,扣週末+國定假日、補班照算、4000 天防呆)+ getDepartureDeadlineCountdowns 查詢時計算 + 團控「期限警戒」tab(登山 gate)+ 可編輯 public_holidays 表 + /admin/holidays 維護頁(public_holiday 權限、requiresClimbing nav)。migration 0019。tsc0/vitest1006/e2e54。 | — |
| 5 | 2026-06-24 | §2.4/§2.5 對齊成本登記反轉(覆寫 v2/v3「成本只在內外帳 nav」):成本登記入口回團控成本頁(/admin/control/[depId]/costs,departure_cost.create)+嚮導 portal;對款 tab 維持唯讀對帳不重做 CRUD;淨利 / 核簽仍在內外帳 nav。apps/web finance/page.tsx realign 待辦。詳見 internal-external-ledger §4。 | — |