Schema 整合任務清單(可勾選進度):
schema-migration-checklist.mdDDL(真相來源):
../docs/latest_schema.sql導覽/枚舉:
../docs/database-schema-guide.md·../docs/schema-enums.md領域說明(含快照語意):
../docs/database-documents/PostgreSQL 開發 Seed:
../docs/seed/README.md
| 欄位 | 內容 |
|---|---|
| 目前定位 | 前端 Mock JSON 的資料語意、關聯與維護規格 |
| 更新日期 | 2026-07-21 |
| 不負責 | PostgreSQL Seed 載入順序、交易與執行方式 |
簡單說:本文件回答「前端 Mock 資料怎麼維持一致」;
docs/seed/README.md回答「PostgreSQL 本機展示資料怎麼建立」。兩者可以使用相同的固定 ID 與業務語意,但不會自動互相同步。
| 要處理的事情 | 先讀哪裡 |
|---|---|
| 修改前端 Mock JSON、localStorage overlay 或衍生資料 | 本文件 |
| 修改 PostgreSQL 開發展示資料 | docs/seed/README.md |
| 確認 API Request/Response 欄位 | docs/api/README.md 與對應 API Contract |
| 確認資料表、ENUM、FK、CHECK | docs/latest_schema.sql |
建議閱讀順序:
frontend/data/**。docs/seed/README.md 維護 docs/seed/**。latest_schema.sql 驗證,不可從 JSON 反推 Schema。| 項目 | 決策 |
|---|---|
| 會員訂單查詢 | 刪 customers.orders[] / rentals[],改 orders.customerId / camp-bookings.customerId FK |
| 租借庫存權威 | data/admin/rental-skus.json 為唯一寫入來源 → sync-rental-listings.cjs 衍生 camp-equipment.stock |
| 預約窗口 | bookingWindowDays = 90 |
| 折價券 | 會員中心僅 birthday + firstPurchase;結帳可輸入 promotion |
| 訂單 / 預約 | 下單當下寫快照(B) + 保留 productId / variantId 等 FK |
| 訂單付款 | payment=方式(ecpay-credit/ecpay-atm/ecpay-cvs/ecpay-other/cod);paymentStatus=狀態(unpaid/paid/refunded);勿把 cod 寫進 status;預約禁止 COD |
| 商品上下架 | active / inactive(勿用 disabled;disabled 僅折價券停用) |
| 會員登入 | 僅 OAuth,無 password |
| 部落格 | productId 統一 P001 格式、camelCase |
| 靜態內容(不進 DB) | FAQ、夥伴營地 PARTNER_DATA、rental-guide.html |
frontend/data/catalog/ products.json, campgrounds.json, camp-equipment.json
frontend/data/commerce/ orders.json, camp-bookings.json
frontend/data/customers/ customers.json
frontend/data/marketing/ articles.json, branches.json, brands.json
frontend/data/promotions/ coupons.json
frontend/data/admin/ reviews.json, movement.json, min-stock.json, rental-skus.json,
booking-policy.json, zone-blocks.json, campground-closures.json
磁碟來源位於 frontend/data/**;Vite 以 frontend/ 為網站根目錄,因此瀏覽器執行期使用 /data/**。這些 JSON 不是 PostgreSQL Seed,也不可直接複製成 SQL。
camp-equipment.json的 stock 為唯讀衍生,請勿手改;改庫存請改rental-skus.json後執行npm run sync:listings。
products.totalStock/products.branch亦為衍生(由variants[].branch加總)。
| 全域物件 | 用途 |
|---|---|
window.MockDataPaths |
Storefront Mock JSON 絕對路徑;定義於 frontend/storefront/js/api-mock.js |
window.API |
買家 Mock API |
window.BookingAPI |
預約 Mock API(含 getAvailability) |
window.BookingAvailability |
Zone 可用性計算(mock = 未來 SQL 查詢契約) |
AdminAPI |
後台 CRUD(mock 模式讀 DataPaths;configure({ useBackend: true }) 接真後端) |
MockStorageMerge |
localStorage overlay 合併(暫時層,後端以 DB transaction 取代) |
| ID | 說明 |
|---|---|
| C001 | 租借主倉(僅 rental-skus / 後台庫存,不在 campgrounds.json) |
| C002–C009 | 可預約營區(campgrounds.json) |
rental-skus.camp[]:{ campgroundId, name, quantity },名稱與 campgrounds 一致(C001 固定「租借主倉」)。
camp-equipment.campgroundId 僅能為 C002–C009。
camp-bookings.bookingInfo.campgroundId 同上。
| 檔案 | 對應未來 DB 表 | 說明 |
|---|---|---|
campgrounds.json > zones[] |
campground_zones |
totalSites = 庫存上限 |
camp-bookings.json |
bookings + booking_selected_zones |
佔用來源;區間 [checkIn, checkOut) |
booking-policy.json |
booking_policies |
bookingWindowDays: 90、佔用狀態枚舉 |
zone-blocks.json |
zone_blocks |
維修停售例外(扣減可賣數) |
campground-closures.json |
campground_closures |
營區公休(date_range 或 weekly) |
公休效果:該營區所有 zone 當晚 status: closed、remaining: 0。
| category | 會員中心列表 | 結帳輸入 | 資格 |
|---|---|---|---|
birthday |
✅ | ✅ | 當月生日 |
firstPurchase |
✅ | ✅ | firstPurchaseUsed === false |
promotion |
❌ | ✅ | 活動碼(如 YURUIKAMP20) |
預設:type: "fixed"、minOrder: 0(缺欄時前端 / 腳本補齊)。
下單當下寫入顯示用快照,並保留 FK 供關聯:
buyerName、address、buyerPhone(可選)…name、specLabel、productId、variantId、skubookingInfo.campgroundName / region;selectedRentals[].specLabel 等order.coupons[] 快照(code / type / discount / amount)specLabel 統一分隔符:/(非 、)。
| Key | 用途 | 後台 merge |
|---|---|---|
mockOrders |
Legacy Order 頁面暫存;新 Checkout 不再寫入 | orders.js ✅ |
mockCheckoutSessions |
契約化 CheckoutSession、冪等指紋與 Mock 更新/取消 | Checkout facade |
mockBookings |
僅 Mock 模式的預約結帳;Backend 模式不讀寫 | bookings.js ✅ |
mockReviews |
會員評價 | reviews.js ✅ |
mockCustomerOverlay |
點數 / 首購 / 個資 patch(語意 ≈ 未來 PATCH /customers/:id) |
API only |
mockCampgroundClosures |
公休規則 overlay | booking-calendar.js ✅ |
adminEmployees |
後台員工帳號 | permissions.js |
可用性為查詢結果,不另存日曆矩陣 JSON。
| Key | 用途 | 清除時機 |
|---|---|---|
checkoutIdempotencyKey |
建立商城 Checkout 的 UUID | 購物車變更、取消、逾時 |
checkoutCartFingerprint |
規格 ID 與數量指紋 | 購物車變更、取消、逾時 |
checkoutCompletedOrderId |
建立成功後阻止重複建立 | 購物車變更、取消、逾時 |
lastCheckoutSession |
暫存完整 Session 與後端金額 | 購物車變更、取消、逾時 |
這些資料只存在目前分頁的 sessionStorage,不是 PostgreSQL Seed,也不是 Mock 業務資料。
I-6 狀態 UI 只讀 lastCheckoutSession.checkoutStep、checkoutExpiresAt 與 pricing。取消或逾時會清除上述四個 key,但不會修改或清空 localStorage 購物車。
| 內容 | 位置 |
|---|---|
| FAQ | pages/faq.html、booking/pages/booking-faq.html |
| 夥伴營地 | js/pages/branches.js → PARTNER_DATA |
| 租借指南 | booking/pages/rental-guide.html |
orders.customerId === "U001" 查詢(不再寫在 customers 上)camp-bookings.customerId === "U001"id: 1(畫面顯示 ORD-0001,見 formatOrderDisplayId)地址快照:台南市東區長榮路二段200號以下指令從 frontend/ 執行;可用指令以 frontend/package.json 為準:
cd frontend
npm run validate:data # 驗證 Mock FK 與資料規則
npm run check:listings # 預覽租借 listing 是否需要同步
npm run sync:listings # 寫入 rental-skus 衍生的 camp-equipment.stock
npm run check:articles # 預覽文章商品 ID 修正
npm run fix:articles # 寫入文章商品 ID 修正
npm run check:normalize # 預覽第一階段資料正規化
npm run normalize:data # 寫入第一階段資料正規化
已移除的一次性整合腳本不再列為操作入口;需要追溯舊遷移流程時請查看 Git 歷史,不要重新建立同名腳本。
| 層級 | JSON | 說明 |
|---|---|---|
| SPU | products.json |
name 為主名(不含規格) |
| SKU | products.variants[] |
id = sku(例 v-P004-0) |
| Listing | camp-equipment.json |
每列一個 equipmentId + variantId + 營區 stock(衍生) |
| 訂單 | orders.items[] |
name + specLabel + variantId / sku |
以下舊 Mock 路徑已刪除(內容已併入 frontend/data/**;需要對照時查 git 歷史):
admin/data/*.json(含舊檔名 reantal.json)booking/data/*.jsondata/*.json、users.jsonequipment-id-map.json_archive/pre-integration/(過渡歸檔目錄,已清空)Mock 來源只改 frontend/data/**(Storefront 路徑見 frontend/storefront/js/api-mock.js,其他頁面依各自載入設定)。PostgreSQL 開發資料只改 docs/seed/**;若兩邊需要相同案例,必須分別依 API Contract 與 Schema 驗證後同步更新。