# ADR-036: FastAPI Strangler Migration，不作為前端 V3 前置條件

Status: Accepted
Date: 2026-05-12

## Context

前端 V3 視覺包已進入落地評估，同時出現「既然前端要一次到位，後端也應同步從 Flask 改為 FastAPI」的建議。

現有系統的重資產集中在 Python：爬蟲、AI 學習鏈、Telegram bot、APScheduler、SQLAlchemy models、pgvector、AutoHeal 與多個 service 模組。FastAPI 若被定位為 HTTP layer 轉換，理論上可沿用大部分 Python 業務邏輯；但目前 `app.py`、`routes/` 與 Jinja 頁面仍承接大量 HTTP glue、template context、CSRF/session、錯誤處理與部分業務邏輯。

同時，前端 V3 包內部分頁面仍有正式資料接線風險：若只為了視覺更新直接替換，就可能移除現有 PChome 比價、AI 挑品、歷史價格、AI 觀測台等真實功能，違反 CONSTITUTION 第 14.1 條。

## Decision

FastAPI 是可接受的中期目標，但不得作為前端 V3 落地的前置條件，也不得與前端視覺更新綁成同一個大爆炸工程。

採用以下順序：

1. 前端 V3 先在現有 Flask runtime 內落地，僅替換已確認接上真實資料、既有 route/API 與行為不退化的頁面。
2. 對於會移除現有功能的 V3 prototype 頁，先拒絕替換，保留現行正式頁。
3. 後端重構優先做 HTTP-agnostic service extraction：把 route 內資料組裝、查詢、匯出、狀態診斷逐步搬到 `services/`，讓 Flask route 變薄。
4. FastAPI 僅能以 strangler pattern 漸進引入：新 API 或已抽乾的 API 可掛在新 app，經 OpenAPI contract、測試與 Nginx path split 驗證後再切流。
5. 不採用 Node 重寫後端。Next.js 前端若需要型別，未來由 OpenAPI 產生 client/types，不以「前後端同語言」作為重寫理由。

## Alternatives Considered

### A. 前端 V3 與 FastAPI Phase 1 同時執行

拒絕。這會同時改動 template/rendering、API boundary、auth/session、CSRF、Nginx、Docker、health check 與 deploy rollback。對目前生產系統而言，風險面過大，也會把原本可獨立驗收的 UI 工作變成跨層遷移。

### B. 維持 Flask 永久不動

拒絕作為長期結論。Flask 可繼續承接現有 Jinja/route，但 OpenAPI、型別 client、async API 與新前端資料邊界確實更適合用 FastAPI 承接。問題不是是否能換，而是何時、以什麼切面換。

### C. Node/Next API 重寫

拒絕。核心業務與自動化資產都在 Python，改 Node 等同重寫爬蟲、AI、排程、Telegram 與資料層，收益不足以抵銷風險。

## Consequences

- 前端 V3 可以立即繼續落地，但每頁必須通過真實資料與行為不退化檢查。
- FastAPI migration 的第一步不是開新框架，而是清 route、補 contract、抽 services。
- 若未來建立 `momo-fastapi` service，必須先有：
  - endpoint inventory 與 owner mapping；
  - auth/session/CSRF 或 token strategy；
  - OpenAPI contract test；
  - `/health`、production smoke、rollback plan；
  - Nginx path split 只切已驗證 path。
- Flask、Jinja 與 `templates/` 的刪除只能在所有對應頁面完成遷移並通過 smoke 後進行。
