一句話:
travelers是訂單明細層的旅客 PII(綁order_id,非綁 user)——一個「人」可橫跨多筆訂單、出現為多筆 traveler,所以它不是會員/owner 的錨點。本檔是旅客實體的單一入口;欄位以 code 為準(packages/core/src/schema/business.ts的travelers),畫面以 wireframe 為準(§6)。定位:domain/core spec(實體與邏輯)。功能切片(分房 / 驗證 / 護照 / 同意書)在各自 spec,§5 索引串接。狀態見 roadmap。
travelers(schema:packages/core/src/schema/business.ts):
order_id(FK → orders.id,onDelete: cascade)。綁訂單,不綁 user。full_name、birth_date、id_number(身分證,存 id_number_enc jsonb envelope 加密欄)、passport_no(護照,存 passport_no_enc jsonb envelope 加密欄)、phone、email。emergency_contact_name / emergency_contact_phone。is_primary(是否同訂購人)、room_id(FK → departure_rooms.id,分房,onDelete: set null)、created_at。與
orders/ 訂購人user的關係:訂購人是orders.user_id(帳號);travelers 是該訂單的實際出行旅客(可含或不含訂購人本人,is_primary標記)。詳見 orders §1、member-ownership §「會員/旅客/customer 三者釐清」。
member_profiles / user,見 member-ownership)。id_number / passport_no 無明文欄,分別存 id_number_enc / passport_no_enc(jsonb EncryptedField)—— AES-256-GCM envelope(per-row 隨機 DEK,GCP Cloud KMS 管 KEK),AAD 綁 dbName:table:column:rowId:mask 防跨租戶/跨列/跨欄移植。讀取走持久化遮罩(零 KMS);全碼僅經 order-scoped reveal 解密 + traveler.decrypt audit(防 IDOR)。低敏感度欄(如 gender)解耦、可存明文。設計見 2026-06-11-kms-pii-encryption-design。room_id set null。travelers 沒有獨立 repo,一律隨訂單帶出(first arg db: ScopedDb):
getAdminOrderDetail → AdminOrderDetail.travelers: AdminTravelerRow[](packages/core/src/orders/admin-repo.ts)。getOrderById / getOrderByIdForUser → … & { travelers: TravelerInput[] }(packages/core/src/orders/repo.ts)。createOrderWithReservation 的 travelers[] 一併寫入(同 tx)。manifest.ts。分房讀寫:rooms/repo.ts(room_id 回寫)。無獨立 traveler resource——讀寫經訂單權限:order.read(看)、order.update(新增/編輯旅客)。可見範圍同訂單(owner-id query 層)。
| Spec | 擴充什麼 |
|---|---|
| room-assignment | gender(硬約束分房,明文)、room_preference / roommate_pref、room_id 配房 |
| traveler-validation | address / validation_exempt、身分證檢查碼 / 緊急聯絡 / 必填 / 金額一致即時驗證 |
| document-expiry | passport_expiry_date + 效期警戒(海外) |
| passport-ocr | 護照 OCR、20+ 護照欄位、purge cron(海外,KMS 前置) |
| orders | 母實體(訂單外殼 + 建單雙插) |
同意書(consent_signatures) | 每旅客/每訂單同意書簽署(append-only) |
../apps/wireframes/public/legacy/admin/order-detail.html../apps/wireframes/public/legacy/site/passport-upload.html../apps/wireframes/public/legacy/admin/passport-review.html../apps/wireframes/public/legacy/site/consent-sign.html| 版本 | 日期 | 變更 | Commit |
|---|---|---|---|
| 2 | 2026-06-11 | id_number / passport_no 改 envelope 加密欄(*_enc jsonb,KMS);補 AAD / 遮罩讀取 / reveal+audit 不變式,連結 KMS 設計 spec。 | — |
| 1 | 2026-06-01 | 初版:旅客實體核心 spec(order-scoped PII / 不變式 / 契約 / 擴充索引 / wireframe) | — |