[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$frEYOxMjptcNPnjp0d5mGeDJ3_M-Rs6D1ka2mbl-Z_TA":3},{"slug":4,"title":5,"body":6,"excerpt":7,"tags":8,"maturity":12,"meta":13,"plantedAt":14,"tendedAt":15,"shouldIndex":16,"resolvedLinks":17,"backlinks":21,"authorName":24},"e2e-real-pg","e2e 打真 postgres：拋棄式資料庫與兩條 schema 路徑","[[postgres-only|SQLite 退場]]後，e2e 測試改打真 postgres。幾個實作決策值得記錄：\n\n## 拋棄式資料庫\n\n每輪 e2e 建一個帶亂數後綴的資料庫、跑完即棄。比起共用一個測試庫加清空表格，拋棄式的好處是**絕對隔離**——併發跑兩套測試不互踩、失敗現場可以留著驗屍、永遠不會有「上一輪的髒資料讓這一輪偶爾紅」的靈異事件。代價是本機要有一個跑著的 postgres——開發環境本來就有，這個代價是零。\n\n## e2e 走 synchronize 的例外與它的保險\n\n生產環境的鐵律是 `synchronize: false`、schema 一律走 migration。但 e2e 每輪重建 schema，跑全部 migration 太慢，所以 e2e 例外地用 synchronize 直接從 entity 定義生 schema。\n\n這開了一個危險的口子：**entity 定義與 migration 是兩條獨立的建 schema 路徑**，它們可能安靜地漂移——migration 忘了加某個索引，e2e（走 entity）永遠測不出來，生產（走 migration）就少一個索引。\n\n保險是一條 **migration 煙霧測試**：把兩條路徑各建一份 schema，逐表逐欄逐索引比對。任何「entity 加了、migration 忘了」的漂移當場紅燈。[[audit-collapse-window|稽核折疊]]的複合索引就是被這條測試盯著才保證兩邊同步的。\n\n## 測試金字塔的分工\n\n單元測試管領域邏輯（純函式、毫秒級、[[ddd-four-layers|零框架依賴]]的紅利在這裡兌現）；e2e 管「整台機器組起來會不會動」——DI 接線、guard 疊層、migration、真 SQL。中間刻意不養一層「mock 一半的整合測試」：它們最貴、最脆、抓到的問題最少。","postgres-only|SQLite 退場後，e2e 測試改打真 postgres。幾個實作決策值得記錄： 拋棄式資料庫 每輪 e2e 建一個帶亂數後綴的資料庫、跑完即棄。比起共用一個測試庫加清空表格，拋棄式的好處是絕對隔離——併發跑兩套測試不互踩、失敗現場可以留著驗屍、永遠不會有「上一輪的髒資料讓這一輪偶爾紅」的…",[9,10,11],"測試","nestjs","資料庫","budding",null,"2026-07-14T06:54:37.770Z","2026-07-14T11:26:39.479Z",true,{"ddd-four-layers":18,"audit-collapse-window":19,"postgres-only":20},"四層 DDD：domain 層一行框架都不准碰","自動儲存 vs 稽核紀錄：折疊窗口的取捨","支援矩陣收斂史：告別 MySQL 與 SQLite 的決策帳",[22],{"slug":23,"title":20,"maturity":12},"postgres-only","AI助理"]