Skip to content
keanu77 edited this page Jul 3, 2026 · 1 revision

Plan — 收斂執行計畫(P0 / P1 / P2)

本頁把 Tech-DebtRoadmap 的 near / mid 主題收斂成可執行的優先序清單。每項以動詞開頭、附對應檔案/模組驗收條件(DoD)。指令細節一律以 Maintenance 頁為準,本頁不重述本機開發/建置指令。

當前狀態 / 下一步

  • 當前狀態:功能可用、可部署(Zeabur / Docker),但工程安全網為零——實讀確認無任何自動化測試、無 CI、無 pre-commit(三個 package.json 皆無測試框架依賴),資料治理靠 backend/ 下約 47 支一次性腳本手動執行。
  • 下一步(本 session 建議只做 P0 前段):先立測試 + CI(P0-1),再升 Node runtime(P0-2,安全),此二者不動資料、風險最低,且是後續所有改動的護欄。
  • 執行節奏(呼應規範):本計畫合計 > 15 項,必須分 session 執行,每 session 只推進一個 phase(5–8 項),完成驗證後再進下一個。任何破壞性資料操作或資料模型變更(P1-4 移除亂數生成器、P1-5 Case schema 變更)一律 migration + 雙重確認:先 prisma db pull 等價的 db.collection.stats() 確認受影響集合、列 rollback、備份後才動;同時注意 Case.js 有 text index / compound index,避免整表 deleteMany 誤傷。任何改核心邏輯(regex 篩選、stats 聚合、路徑防護)的 commit 必須同 commit 補上對應測試

P0 — 工程健全化與安全(不可退讓)

P0-1. 建立測試框架與 CI 閘門

  • 動作:導入 Vitest + Supertest(+ mongodb-memory-server),為四條掛載路由寫 API 整合測試,並建 GitHub Actions(lint → build → test)。
  • 檔案/模組:新增 backend/**/*.test.js.github/workflows/ci.yml;覆蓋 backend/routes/casesFixed.jsstatsFixed.jseducation.jstue.js;root/backend package.jsontest script。
  • 對應:Tech-Debt zero-tests-no-ci(high/L);Roadmap N1。
  • DoD
    • casesFixedpunishmentType 六分支(casesFixed.js:56-96)與 statsFixed 禁賽時長 $switchstatsFixed.js:135-177)皆有邊界值測試且通過
    • escapeRegexcasesFixed.js:5)+ 搜尋長度 200 上限(casesFixed.js:42)有回歸測試
    • CI 在 PR 上跑 lint + build + test,紅燈可擋 merge
    • backend/test_db.jsbackend/test_route.js 已刪除或明確標為非測試

P0-2. 升級 Runtime 脫離 EOL Node 18

  • 動作:把 Node 從 18.x 升到 20 或 22 LTS。
  • 檔案/模組package.json:6-8engines)、Dockerfile:2/19/31(三個 stage 的 node:18-alpine);建議新增 .nvmrc
  • 對應:Tech-Debt node18-eol-runtime(medium/S)。
  • DoD
    • engines 與 Dockerfile 三處 base image 皆改為 20/22 LTS
    • 本地 build(見 Maintenance)通過,frontend Vite 7(要求 Node ^20.19 || >=22.12)不再倚賴無 engine-strict 才不 fail
    • 確認 mongoose 7 / mongodb 6 相容,站可正常啟動並連 DB

P0-3. 修正輸入驗證的 5xx 語意

  • 動作:為 /cases/:idObjectId.isValid() 前置檢查。
  • 檔案/模組backend/routes/casesFixed.js:196-221new ObjectId:205)。
  • 對應:Tech-Debt caseid-validation-500(low/S)。
  • DoD
    • 非法 id 回 400、查無回 404,不再落到 500(附測試)
    • education.js:46 POST /quizzes/:id/answeranswer 存在性驗證

P0-4. 收斂資料存取層與連線生命週期

  • 動作:抽單一共享 db 模組,消除 casesFixedstatsFixed 重複連線與樣板;補 graceful shutdown。
  • 檔案/模組:新增 backend/db.js;改 casesFixed.js:12-17statsFixed.js:13-18server.js:153-171 補 SIGTERM/SIGINT。
  • 對應:Tech-Debt per-route-mongo-connections(medium/M);Roadmap N2。
  • DoD
    • route 匯入共享 client/getter,不再各自 MongoClient.connect()
    • db 名 'sports-doping-db'casesFixed.js:14statsFixed.js:15)收進設定,與 MONGODB_URI 對齊
    • escapeRegex/errorResponse 抽成共用 util,兩檔不再各留一份
    • 收到 SIGTERM 時 serving 連線會 close(附整合測試)

P0-5. 讓健康檢查反映真實 DB 狀態

  • 動作/api/health 檢查 Mongoose 連線狀態再回應。
  • 檔案/模組server.js:68-70
  • 對應:Tech-Debt no-error-monitoring(強化項)。
  • DoD
    • DB 斷線時 /api/health 回非 200(供 Docker HEALTHCHECK / Zeabur 偵測)

P1 — 資料信譽、監控與結構清理

P1-1. 導入結構化日誌與錯誤追蹤

  • 動作:以 pino 取代散落 console.*,接 Sentry(或平台等價),至少對 DB connect 失敗與 500 告警。
  • 檔案/模組server.js(12 處 console、全域 handler :174-177)、statsFixed.js(11 處、DB fail :18)、casesFixed.js(5 處、DB fail :17、靜默 500 :22)。
  • 對應:Tech-Debt no-error-monitoring(medium/M);Roadmap L3。
  • DoD
    • 500 與 DB 連線失敗會上報並帶 request context
    • 三個 package.json 出現 logger/監控依賴,console.* 從請求路徑移除

P1-2. 清理死碼與孤兒 API 方法

  • 動作:移除 api.js 無對應後端的 stub。
  • 檔案/模組frontend/src/services/api.js:19-21(cases 寫入)、:43-44(education articles)。
  • 對應:Tech-Debt orphaned-api-methods(low/S);Roadmap N3。
  • DoD
    • 未實作方法已刪或標記待實作;contract 測試(見 P0-1)確認 api.js 方法皆對得上後端

P1-3. 修正文件漂移

  • 動作:更新 CLAUDE.mdREADME.mdbackend/package.json 使其符合現況。
  • 檔案/模組CLAUDE.md:86(已刪的 mockData.js/cases.js/stats.js/backend/server.js)、README.md:88-93(不存在端點)、README.md:117-118(結構圖 server.js 位置錯)、backend/package.jsonmain/start/dev 指向已不存在的 backend/server.js)、.env.exampleJWT_SECRET 標為預留)。
  • 對應:Tech-Debt docs-drift-dead-refs(medium/S);Roadmap N3。
  • DoD
    • 文件只描述實際存在的檔案與端點;backend/package.json 不再指向不存在檔或標為 deps-only

P1-4. 隔離/移除亂數案例生成器(破壞性,需雙重確認)

  • 動作:移除或封存 loadCompleteDatabase.js 的隨機生成邏輯,改為 curated 單一資料來源。
  • 檔案/模組backend/loadCompleteDatabase.js:124-166(14 處 Math.random()、合成物件)、:177 Case.deleteMany({})
  • 對應:Tech-Debt fabricated-case-data(high/L);Roadmap M1。
  • 前置(雙重確認):先確認 production DB 現況、備份、列 rollback;此腳本含整表 deleteMany,且另有 loadAllCases.js:397import_original_cases.js:57seedData.js:208 三支競爭的全量重置腳本,須先釐清 canonical 來源再動。
  • DoD
    • 生成器移除或隔離;新增資料完整性測試(無 sourceLinks 或符合模板句型者標記待審)
    • 案例真實性確認清單.md(57 個 ❓)逐案落實真偽標記

P1-5. 案例資料模型升級(資料模型變更,需 migration)

  • 動作Case schema 的 sourceLinks 改必填,新增 verificationStatuslastVerifiedAt
  • 檔案/模組backend/models/Case.js:70-77(現 sourceLinks 為選填陣列)。
  • 對應:Tech-Debt fabricated-case-data;Roadmap M1。
  • 前置(雙重確認):屬 schema 變更;注意 Case.js 既有 text index / compound index,migration 需回填既有案例的 verificationStatus 預設值,避免必填欄位讓舊資料讀取失敗。
  • DoD
    • 新案例強制帶可驗證來源;CaseDetail 前端顯示來源/查核狀態徽章
    • migration 腳本冪等、附 rollback

P1-6. 收斂 seed 腳本沼澤

  • 動作:把約 47 支一次性腳本移進 backend/scripts/archive/,整併成單一冪等 seed CLI。
  • 檔案/模組backend/*.jsadd_*/expansion_*/phase*/fix_*/remove_*/verify_*);特別處理 import-to-zeabur.js:5(硬編 prod Mongo URI 含帳密,屬 secret 外洩,需改用環境變數);9 支腳本連錯 db 名 .../antidoping(app 讀 sports-doping-db)。
  • 對應:Tech-Debt seed-scripts-sprawl(medium/M);Roadmap N3。
  • DoD
    • 正式 route 目錄不再與一次性腳本混放;seed 為單一冪等入口並納入文件
    • import-to-zeabur.js 不再硬編含帳密的連線字串(改環境變數,並輪換已外洩憑證)

P2 — 內容維運、後台與體驗(承載中期方向)

P2-1. 外移 TUE 內嵌內容並拆分過大元件

  • 動作:把 tue.jstueContent:5-273)+ wadaSubstances:274-444)外移到 backend/data/tue-content.json;拆分 TUE.jsx(1481 行)。
  • 檔案/模組backend/routes/tue.jsfrontend/src/pages/TUE.jsx
  • 對應:Tech-Debt oversized-files(medium/M);Roadmap M2。
  • DoD
    • TUE 內容改一句不需動 route 程式碼;TUE.jsx 依 basicInfo/applicationGuide/diseases/tools/checker 拆為子元件,單檔 < 800 行

P2-2. 統一 quiz 內容單一來源

  • 動作:擇一 SoT,消除 frontend/src/data/quiz.jsbackend/data/quizzes.json 雙份題庫漂移。
  • DoD
    • Quiz 頁與 Education 頁讀同一份題庫來源

P2-3. 身分驗證與內容管理後台

  • 動作:實作 JWT 登入 + editor/admin 角色,補齊 case 寫入端點與稽核日誌,提供輕量 CMS。
  • 檔案/模組server.js(新增 auth middleware)、api.js:19-21 stub 接真實後端、.env.exampleJWT_SECRET
  • 對應:Roadmap M2。
  • DoD
    • 內容審稿者可透過後台增修案例(含來源欄位驗證),無需執行 seed 腳本;寫入端點有 schema 驗證與分級 rate limit

相關頁面:Introduction · Roadmap · Tech-Debt · Maintenance · Home

Clone this wiki locally