一句話:
orders是與產品種類無關的營運預訂外殼;「買了什麼」在order_lines,產品專屬明細在tour_booking_lines/lodging_booking_lines,金額與收退款真相在 訂單金流模型。本檔是訂單實體的單一入口:模型、狀態、不變式、存取契約、權限,以及「哪些功能 spec 擴充訂單」的索引。精確欄位以 code 為準(
packages/core/src/schema/business.ts、packages/core/src/orders/*);狀態見 roadmap;畫面以 wireframe 為準(§7)。
訂單分四層,避免把產品欄位或金額欄位塞回外殼:
orders(營運外殼,kind-agnostic):order_number、user_id(原生 FK 同庫 user)、kind(tour / lodging / future package)、三軸狀態快取(booking_state / payment_state / refund_state)、notes、timestamps,以及派發欄位(created_by_user_id / assigned_to_user_id / assignment_status / assigned_at / assigned_by_user_id)。order_lines(買了什麼,product-neutral):一張訂單可有多個 line,line_kind 可為 tour / lodging / addon / fee;snapshot 只做顯示與稽核,不是第二份金額真相。tour_booking_lines(行程產品明細):一個 tour line 對應一筆,存 departure_id、party_size、unit_price_twd_snapshot、price_channel_snapshot。席次預留看這裡。lodging_booking_lines(訂房產品明細):一個 lodging line 對應一筆,存旅宿/房型、入住退房區間、間數、入住人數;逐晚價格快照在 lodging 相關表。
orders不擁有財務真相:訂單外殼不保存總額、單欄付款狀態、訂金/尾款 due 欄或付款方式。訂單應收、已收、餘款、退款狀態都由 訂單金流模型 的分類帳與 helper 派生。
orders 使用三軸狀態,而不是單一狀態欄:
| 軸 | 欄位 | 語意 |
|---|---|---|
| 履約 | booking_state | pending_payment / confirmed / cancelled / completed |
| 收款 | payment_state | unpaid / partially_paid / deposit_paid / paid / overpaid,由金流 helper 重算並快取 |
| 退款 | refund_state | none / partially_refunded / refunded,只反映面向客戶的退款 |
UI 顯示狀態一律走 deriveOrderDisplayStatus(booking_state, payment_state, refund_state),不要單獨把 payment_state 當 badge。退款、取消、完成等狀態有明確 precedence,見 訂單金流模型 §5。
派發子狀態與上述三軸正交:assignment_status = pending_review | assigned | reassigned,見 訂單派發。
departure_id、party_size、房型/房晚、入住日等產品欄位都在 product line;不要加回 orders。SUM(order_charge_lines.amount_twd);現金 = payment_transactions;收款計畫 = payment_schedules。新功能不得把總額、付款狀態或收款計畫塞回訂單外殼。order_lines + tour_booking_lines 取 departure_id / party_size,並刻意排除 lodging。UPDATE departures ... WHERE booked_count + N <= capacity + CHECK constraint,不靠讀後寫。W{YYMMDD}{NNNNN},每 DB 一個 Postgres sequence + next_order_number() SQL function(setup-business-extras.ts)。audit_log;財務真相的 append-only 規則見 訂單金流模型。repo first arg 一律
db: ScopedDb;錯誤走 result-object。完整型別/簽名以 code 為準。
Customer(packages/core/src/orders/repo.ts) — kind-aware:
orders → order_lines(tour) → tour_booking_lines → order_charge_lines / payment_schedules / payment_intents。listOrdersForUser / getOrderById / getOrderByIdForUser 回 kind-aware DTO,依 orders.kind 分流呈現 tour / lodging。getDepartureForCheckout 只負責 checkout 所需的梯次資料;價格與收款切分由定價與金流 helper 決定。Admin(packages/core/src/orders/admin-repo.ts) — order detail / list / status mutation:
tour_booking_lines 取行程明細;通用金流資訊從 money helper / ledger 聚合取。refunds 工作流。其他訂單模組:assignment.ts、assignment-repo.ts、control-stats.ts、dashboard-stats.ts、manifest.ts、money.ts、money-state.ts、validation.ts。
order resource)statement catalog 在 packages/core/src/permissions-ac.ts,閘走 auth.api.userHasPermission(點格式 order.action):
| action | 用途 | spec |
|---|---|---|
order.read | 看訂單(含詳情頁進入閘) | 本檔 / system-design |
order.create | 建單 | 本檔 |
order.update | 改單 / 取消 / 履約狀態 | 本檔 |
order.review | 審核 pending_review | order-assignment |
order.assign / order.reassign | 指派 / 改派業務(受派池 ASSIGNABLE_ROLES=['sales','admin']) | order-assignment |
customer 薄權限片(角色 customer);「只看自己」靠 query 層 owner-id 過濾,不靠 AC。
訂單是中央實體,下列 spec 各擴充它的一面——改訂單相關功能前先看這裡:
| Spec | 擴充什麼 |
|---|---|
| order-money-model | 金流 SSOT:charge lines / schedules / intents / attempts / transactions / refunds / payables、三軸狀態與公式 |
| order-assignment | 派發子狀態 / 指派改派 / sales 歸屬 / review |
| trip-pricing | 直客/同業價、訂金規則、尾款 schedule、包團定價 |
| control-finance | 掛帳折讓(order_charge_lines(type='manual_adjustment'))、成本、payables |
| discount-code | 結帳折扣碼 + KOL 分潤快照;折扣以負 charge line 表達,order_discounts 保留兌換快照 |
| lodging-direct-booking | lodging line / kind-aware 讀取 / 每晚庫存扣減 |
| room-assignment | 旅客分房、房型升級補款 charge line / adjustment schedule |
| climbing-screening | 下單時資格審核 hook、order_screenings |
| traveler-validation | 旅客資料即時驗證、完整度、訂單金額一致檢查 |
| member-ownership | 客戶/同業分類、owner 解析 → 指派輸入 |
| dashboard / control-finance | 角色化統計 / 團控聚合(tour-centric 讀取) |
訂單相關畫面的視覺真相在 wireframe;spec 只描述行為、連結至此(不另寫散文版面):
../apps/wireframes/public/legacy/admin/orders.html../apps/wireframes/public/legacy/admin/order-detail.html../apps/wireframes/public/legacy/admin/orders-new.html../apps/wireframes/public/legacy/admin/orders-review.html../apps/wireframes/public/legacy/site/order-complete.html| 版本 | 日期 | 變更 | Commit |
|---|---|---|---|
| 2 | 2026-06-05 | 改為現在式 SSOT:訂單外殼 + order_lines + product lines + 金流分類帳;移除舊訂單總額/單欄狀態/一單一筆產品表模型描述 | — |
| 1 | 2026-06-01 | 初版:訂單實體核心 spec(模型/狀態機/不變式/契約/權限/擴充索引/wireframe)— 實體核心 spec 格式 pilot | — |