cover

Proto 規劃方法論:打造完整好用的專案原型

流程概覽

flowchart LR
    A[分類<br/>B2E / F2E / App] --> B[10 Dimensions<br/>完整性檢查]
    B --> C[Per-Track 標準<br/>各 Track 需求]
    C --> D[Gap Analysis<br/>落差分析]
    D --> E[補齊落差<br/>Fill Gaps]
    E --> F[黃金版本<br/>Stable Release]
    F --> G[多語言延伸<br/>Extend]
    G -->|回饋| D

    style A fill:#4CAF50,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#F44336,color:#fff
    style E fill:#9C27B0,color:#fff
    style F fill:#009688,color:#fff
    style G fill:#795548,color:#fff

文章概覽

在本篇文章中,您將學習到:

  • 為什麼每個團隊都需要一套完整的 Proto,而不是每次從零開始
  • Proto、Boilerplate、Scaffold、Template 的本質差異
  • 架構邊界:Proto 範圍 vs Infra 範圍的明確劃分
  • Proto 完整性的 10 大面向與逐項檢查清單
  • Per-Track 標準:B2E(後端)、F2E(前端)、App(行動應用)各自的具體需求
  • 如何透過 Gap Analysis 找出規劃與實作之間的落差
  • 從單一語言的「黃金版本」延伸到多語言 Proto 的策略
  • Proto 的長期維護與演進方法
  • 常見的 Proto 陷阱與避免方式

引言:每個專案都從某個起點開始

每一個新專案都從某個地方開始。問題在於——那個起點的品質,決定了後續開發的效率與品質。

在實務中,我們常常看到這樣的場景:團隊接到新專案需求,工程師興沖沖地開始寫業務邏輯,卻在第二週才發現——環境變數管理沒做、Docker 設定不完整、CI/CD Pipeline 根本沒有、錯誤處理各寫各的格式、Log 散落在 console.log 裡無法被 EFK 收集。於是,本該花在業務功能上的時間,有三分之一以上被消耗在「重複解決基礎建設問題」上。

這些問題有一個共通點:它們跟業務邏輯無關,但每個專案都需要。環境設定、容器化、CI/CD、錯誤處理、日誌格式、測試結構、安全基線——這些是「基礎建設層」的問題,應該被解決一次、複用多次。

這就是 Proto 存在的意義。

Proto 不是「Hello World + 框架」。它是一個生產環境等級的起始點——clone 下來之後,團隊可以立刻開始開發業務功能,而不需要花時間處理基礎建設。一個好的 Proto,應該讓工程師在第一天就能專注在「這個專案獨有的問題」上。


Proto vs Boilerplate vs Scaffold vs Template

在開始規劃 Proto 之前,我們需要先釐清幾個常被混用的概念:

概念定義特點範例
Template程式碼樣板,可透過變數替換產生新專案偏向程式碼產生器,產出後通常不回溯更新cookiecutter、GitHub Template Repo
Scaffold框架提供的專案初始化命令由框架官方維護,只包含框架本身的最小設定create-react-appdjango-admin startproject
Boilerplate預先寫好的樣板程式碼,可直接複製使用通常聚焦在特定技術組合,缺乏團隊客製化GitHub 上的 react-boilerplate
Proto團隊定義的「生產環境等級專案原型」包含完整基礎建設、團隊慣例、安全基線本文所定義的 Proto

為什麼 Proto 是正確的心智模型?

Scaffold 只給你框架的骨架;Boilerplate 只給你技術組合的範例;Template 只是程式碼生成。但 Proto 代表的是:這就是你的生產環境架構的原型(Prototype),它包含了你在生產環境中需要的一切基礎建設。

核心原則:COPY, not Reference

這是 Proto 哲學中最重要的一條原則:

每個新專案應該是 Proto 的完整獨立副本,而不是對 Proto 的引用或繼承。

為什麼?因為:

  1. 專案獨立性:每個專案可能有不同的演進速度,不應被 Proto 的更新綁架
  2. 可客製化:複製後可以自由修改,不需要擔心影響其他專案
  3. 完整性 > DRY:在專案層級,完整性比「不重複」更重要。每個專案都應該擁有完整的基礎建設,而不是依賴外部的共用模組
  4. 版本可追溯:透過記錄「從哪個版本的 Proto 複製」,就能追溯基礎建設的版本

實務做法:

# 建立新專案時,從 Proto 複製
cp -r proto/b2e/django-proto ./new-project-name
cd new-project-name
 
# 移除 Proto 的 git 歷史,建立全新的 git repo
rm -rf .git
git init
git add .
git commit -m "init: from django-proto v2.3.0"

Proto 規劃生命週期

以下是 Proto 從規劃到穩定再到延伸的完整生命週期:

flowchart LR
    A[定義標準<br/>Define Standards] --> B[選黃金版本<br/>Pick Golden Lang]
    B --> C[實作<br/>Implementation]
    C --> D[Gap Analysis<br/>落差分析]
    D --> E[補齊<br/>Fill Gaps]
    E --> F[穩定版本<br/>Stable Release]
    F --> G[延伸到其他語言<br/>Extend to Others]
    G --> D

    style A fill:#4CAF50,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#F44336,color:#fff
    style E fill:#9C27B0,color:#fff
    style F fill:#009688,color:#fff
    style G fill:#795548,color:#fff

每個階段的說明:

  1. 定義標準:先定義什麼是「完整」——也就是本文第五節的 10 大面向
  2. 選黃金版本:選一個團隊最熟悉的語言/框架,作為第一個實作的 Proto
  3. 實作:根據標準,在黃金版本上實作所有面向
  4. Gap Analysis:對比規劃文件與實際程式碼,找出落差
  5. 補齊:將落差逐一填補
  6. 穩定版本:通過所有檢查後,打 tag 釋出穩定版本
  7. 延伸到其他語言:以黃金版本為標準,逐一實作其他語言版本,並再次進行 Gap Analysis

注意第 7 步會回到第 4 步——這是一個持續的迴圈。每當延伸到新語言時,都需要重新做一次落差分析,確保每個語言版本都達到相同的完整性標準。


Proto 分類策略

Proto 的分類應該保持簡單。過多的分類會增加認知負擔與維護成本。以下是建議的 4 類分類法:

分類目的Proto 範例
b2e/後端服務(Backend)Django REST、Spring Boot、Express.js、FastAPI、Go Gin
f2e/前端應用(Frontend)Vue 3 + Vite、React + Next.js、Svelte
app/全端/行動應用(Fullstack / Mobile)Nuxt.js、React Native、Flutter
infra/基礎建設(Infrastructure)Nginx + Docker Compose、EFK Stack、Prometheus + Grafana

目錄結構:

protos/
├── b2e/
│   ├── django-proto/
│   ├── springboot-proto/
│   └── express-proto/
├── f2e/
│   ├── vue3-vite-proto/
│   └── react-nextjs-proto/
├── app/
│   ├── nuxtjs-proto/
│   └── react-native-proto/
└── infra/
    ├── nginx-docker-proto/
    └── efk-stack-proto/

為什麼只有 4 類?

  • 分類的目的是「快速找到」,不是「精確描述」
  • 4 類涵蓋了絕大多數的專案類型
  • 如果未來有新需求(如 ML Pipeline),再擴展即可
  • 過多分類反而會讓人猶豫「這個該放哪裡」

架構邊界:Proto 範圍 vs Infra 範圍

Proto 的 10 個面向中,並非每一項都屬於 Proto 本身的職責。在前後端完全分離的架構下,明確的邊界劃分至關重要:

核心原則:Proto 只負責應用層,基礎設施層由 Infra 處理。Infra 透過 Git Submodule 將 Proto 拉入部署流程。

面向歸屬說明
A. 專案結構Proto目錄規範、Base Class、CRUD 範例
B. 多環境設定Proto.env 管理、Profile 切換、Boot-time Validation
C. 容器化InfraDockerfile、docker-compose 由 Infra 定義;Proto 只需提供 health check endpoint
D. 安全基線Proto(部分 Infra)Auth / RBAC / Token 歸 Proto;CORS 歸 Infra(Nginx 層),因為前後端 100% 分離
E. 錯誤處理Proto全域 Exception Handler、統一回應格式
F. 日誌Proto結構化日誌、Access Log、PII Masking
G. 測試基線Proto單元 / 整合 / E2E 測試、Coverage 策略
H. CI/CD PipelineInfraPipeline 定義、部署策略、環境對應由 Infra 處理
I. 文件ProtoREADME、API 文件、CHANGELOG
J. 程式碼品質ProtoLinter、Formatter、Git Hooks、Commit 規範

這代表什麼?

  • Proto 負責 8 個面向(A、B、D 部分、E、F、G、I、J),加上各 track 的特定面向
  • C(容器化)和 H(CI/CD)由 Infra 負責,Proto 只需提供 Infra 所需的介面
  • D 中的 CORS 歸 Infra(Nginx),因為前後端百分百分離,不存在混合架構
  • 這種解耦讓前端/後端/App 工程師各自專注在應用層,不需要承擔 Infra 的 context

範圍外的常見誤區

容易被誤放進 Proto 的項目正確歸屬原因
Docker multi-stage buildInfraImage 建構策略是部署問題
CI/CD Pipeline(.gitlab-ci.ymlInfraPipeline 跨 repo 共用,由 Infra 統一管理
CORS 設定Infra (Nginx)前後端分離架構,CORS 在反向代理處理
部署策略(Rolling / Blue-Green)Infra部署是基礎設施層面的決策
備份與災難復原Infra資料備份是維運層面的事
Multi-tenancy產品層多租戶是產品架構決策,不是 Proto 基礎建設
Realtime / WebSocket按需不是每個專案都需要,不應預設在 Proto 中

Proto 完整性標準(10 Dimensions)

這是本文最核心的章節。一個 Proto 是否「完整好用」,取決於它是否覆蓋了以下 10 個面向。每個面向都不是 nice-to-have,而是生產環境的 must-have。

A. 專案結構與基礎類別(Project Structure & Base Classes)

涵蓋範圍:目錄命名規範、分層架構、基礎抽象類別

為什麼重要:統一的專案結構讓任何團隊成員都能在 30 秒內找到他要找的檔案。不一致的結構會導致每個人用不同的方式組織程式碼,最終讓 codebase 變成一團混亂。

完整實作標準

  • 目錄命名採用統一規範(例如後端用 controllers/services/repositories/
  • 提供 BaseController / BaseService / BaseRepository 等基礎類別
  • 基礎類別中內建常見功能(如分頁查詢、統一回應格式、交易管理)
  • 包含至少一個完整的 CRUD 範例(從 Controller 到 Repository)

檢查項目

  • 專案結構符合團隊命名規範
  • Base Classes 已建立且包含常用方法
  • 至少有一組完整 CRUD 範例
  • README 中有結構說明圖

B. 多環境設定(Multi-Environment Config)

涵蓋範圍:環境變數管理、Profile 切換機制、機密資訊隔離

為什麼重要:開發環境連開發的 DB、Staging 連 Staging 的 DB、Production 連 Production 的 DB——這聽起來理所當然,但如果沒有在 Proto 中就建立好多環境設定的機制,團隊往往會在第一次部署時才臨時處理,導致設定散落各處。

完整實作標準

  • 每個環境有獨立的設定檔(.env.dev.env.staging.env.prod
  • 提供 Profile 或 Environment 切換機制
  • 機密資訊(密碼、API Key)絕不進入版本控制
  • 提供 .env.example 作為範本,列出所有需要的環境變數

檢查項目

  • 各環境設定檔已建立(dev / staging / prod)
  • .env.example 存在且完整
  • .gitignore 已排除所有 .env 檔案(除 .env.example
  • 機密資訊未出現在版本控制中

C. 容器化(Dockerization)

涵蓋範圍:Dockerfile、docker-compose、健康檢查

為什麼重要:容器化是現代部署的基礎。如果 Proto 沒有提供完善的 Docker 設定,每個專案都要從頭寫 Dockerfile,不同專案的容器品質參差不齊。

完整實作標準

  • Dockerfile 採用 Multi-stage build(減少 image 大小)
  • 容器以非 root 使用者運行
  • 提供各環境的 docker-compose 檔案
  • 包含健康檢查端點(/health
  • .dockerignore 排除不必要的檔案
# Multi-stage build 範例
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
 
FROM python:3.12-slim
RUN useradd --create-home appuser
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY . .
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:8000/health || exit 1
CMD ["gunicorn", "app:create_app()", "--bind", "0.0.0.0:8000"]

檢查項目

  • Dockerfile 使用 multi-stage build
  • 容器以非 root 使用者運行
  • docker-compose 各環境版本已建立
  • 健康檢查端點 /health 已實作
  • .dockerignore 已設定

D. 安全基線(Security Baseline)

涵蓋範圍:認證骨架、CORS 設定、CSRF 防護、RBAC 結構

為什麼重要:安全性不是事後補上的東西。如果 Proto 沒有內建安全基線,團隊容易在趕進度時忽略安全措施,等到資安事件發生才後悔。

完整實作標準

  • 提供認證機制骨架(JWT 或 Session-based),包含 login/logout/refresh 端點
  • CORS 設定已就緒,預設為嚴格模式
  • CSRF 防護已啟用(針對 Session-based 認證)
  • RBAC(Role-Based Access Control)結構已建立,包含角色與權限模型
  • HTTP Security Headers 已設定(X-Frame-Options、Content-Security-Policy 等)

檢查項目

  • 認證機制骨架已實作(JWT 或 Session)
  • CORS 設定已完成且預設為嚴格模式
  • CSRF 防護已啟用
  • RBAC 結構與範例已建立
  • HTTP Security Headers 已設定

E. 錯誤處理(Error Handling)

涵蓋範圍:全域例外處理器、自訂例外階層、統一錯誤回應格式

為什麼重要:沒有統一錯誤處理的專案,API 回傳的錯誤格式千奇百怪——有的回傳 { "error": "..." },有的回傳 { "message": "..." },有的直接回傳框架的 stack trace。前端工程師無法建立統一的錯誤處理邏輯,除錯時也難以快速定位問題。

完整實作標準

  • 建立 GlobalExceptionHandler,攔截所有未處理的例外
  • 建立自訂例外階層(BusinessException、ValidationException、AuthenticationException 等)
  • 統一錯誤回應格式:
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "帳號格式不正確",
    "details": [
      { "field": "email", "message": "必須是有效的電子郵件格式" }
    ],
    "timestamp": "2024-09-15T10:30:00Z",
    "traceId": "abc-123-def"
  }
}
  • 不同 HTTP 狀態碼對應不同錯誤類型(400 for validation, 401 for auth, 403 for permission, 500 for server error)
  • 生產環境不暴露 stack trace

檢查項目

  • GlobalExceptionHandler 已建立
  • 自訂例外階層已定義
  • 統一錯誤回應格式已實作
  • 生產環境不暴露 stack trace
  • 至少有一個錯誤處理的範例

F. 日誌(Logging)

涵蓋範圍:結構化日誌格式、Access Log、日誌設定

為什麼重要:在生產環境中,日誌是唯一的除錯工具。如果日誌格式不統一,EFK(Elasticsearch + Fluentd + Kibana)無法正確解析;如果沒有 Access Log,就無法追蹤 API 的呼叫情況;如果日誌等級沒有正確設定,生產環境可能被 DEBUG 等級的日誌灌爆。

完整實作標準

  • 結構化日誌格式(JSON),方便 EFK 收集與解析
  • Access Log 記錄每個 HTTP 請求的 method、path、status、duration
  • 日誌設定檔(logback.xml / log4j2.xml / Python logging config)
  • 不同環境使用不同的日誌等級(dev: DEBUG, staging: INFO, prod: WARN)
  • 敏感資訊(密碼、Token)不出現在日誌中
{
  "timestamp": "2024-09-15T10:30:00.123Z",
  "level": "INFO",
  "logger": "com.example.UserService",
  "message": "User login successful",
  "traceId": "abc-123-def",
  "userId": "user-001",
  "method": "POST",
  "path": "/api/v1/auth/login",
  "duration": 125
}

檢查項目

  • 結構化日誌格式已設定(JSON)
  • Access Log 中介層已建立
  • 各環境日誌等級已設定
  • 敏感資訊不出現在日誌中
  • 日誌設定檔已就緒

G. 測試基線(Testing Baseline)

涵蓋範圍:單元測試結構、整合測試、CI 中的測試執行

為什麼重要:沒有測試的 Proto 就像沒有安全帶的車——它能動,但出事時沒有保護。如果 Proto 就不包含測試範例,團隊成員很容易「等有空再寫測試」,而那個「有空」永遠不會來。

完整實作標準

  • 單元測試目錄結構與範例(至少涵蓋 Service 層)
  • 整合測試使用 Testcontainers 或類似工具(避免依賴外部服務)
  • 測試設定獨立於主程式設定(使用測試專用的設定檔或 in-memory 資料庫)
  • 測試在 CI Pipeline 中自動執行

檢查項目

  • 單元測試結構與範例已建立
  • 整合測試使用 Testcontainers(或等效工具)
  • 測試設定檔獨立於主程式
  • CI Pipeline 包含測試步驟

H. CI/CD Pipeline

涵蓋範圍:Pipeline 設定檔、階段定義、分支與環境對應

為什麼重要:CI/CD 是現代軟體開發的血管系統。沒有它,程式碼的建置、測試、部署都是手動操作,既慢且容易出錯。在 Proto 中就內建 CI/CD Pipeline,確保每個新專案從第一天就有自動化流程。

完整實作標準

  • Pipeline 設定檔(.gitlab-ci.yml / Jenkinsfile / .github/workflows
  • 階段定義:Lint → Test → Build → Deploy
  • 分支與環境對應:develop → dev、staging → staging、main → production
  • 部署策略(Rolling Update / Blue-Green)已定義
  • Pipeline 變數與 Secrets 管理
# .gitlab-ci.yml 範例結構
stages:
  - lint
  - test
  - build
  - deploy
 
lint:
  stage: lint
  script:
    - npm run lint
 
test:
  stage: test
  script:
    - npm run test:ci
  coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
 
build:
  stage: build
  script:
    - docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .
    - docker push $IMAGE_NAME:$CI_COMMIT_SHA
 
deploy-dev:
  stage: deploy
  script:
    - deploy.sh dev
  only:
    - develop
 
deploy-prod:
  stage: deploy
  script:
    - deploy.sh prod
  only:
    - main
  when: manual

檢查項目

  • Pipeline 設定檔已建立
  • Lint → Test → Build → Deploy 階段已定義
  • 分支與環境對應已設定
  • 部署策略已定義

I. 文件(Documentation)

涵蓋範圍:README 範本、API 文件、CHANGELOG 格式

為什麼重要:程式碼會說話,但只說「怎麼做」,不說「為什麼」和「怎麼用」。一個沒有文件的 Proto,對新成員來說跟一堆亂碼沒有兩樣。README 是一個專案的門面——如果連 README 都寫不好,怎麼期待程式碼品質?

完整實作標準

  • README 範本包含:專案介紹、系統需求、安裝步驟、常用指令、專案結構說明
  • API 文件使用 Swagger / OpenAPI,且可自動產生
  • CHANGELOG 遵循 Keep a Changelog 格式
  • ADR(Architecture Decision Records)範本已提供

README 範本結構

# 專案名稱
 
> 一句話描述
 
## 系統需求
- Node.js >= 20
- Docker >= 24
- ...
 
## 快速開始
1. 複製環境設定檔
2. 啟動服務
3. 執行 migration
 
## 常用指令
| 指令 | 說明 |
|------|------|
| `make dev` | 啟動開發環境 |
| `make test` | 執行測試 |
| `make lint` | 執行 Lint |
 
## 專案結構
(略)
 
## 環境設定
(略)
 
## 部署
(略)

檢查項目

  • README 範本完整(包含結構、需求、安裝、指令)
  • API 文件(Swagger / OpenAPI)已整合
  • CHANGELOG 格式已定義
  • ADR 範本已提供

J. 程式碼品質(Code Quality)

涵蓋範圍:Linter / Formatter 設定、Git Hooks、EditorConfig

為什麼重要:程式碼風格的不一致是團隊協作中最常見的摩擦來源。Tab vs Space、單引號 vs 雙引號、尾端逗號要不要——這些爭論毫無技術價值,應該由工具自動處理。在 Proto 中就預設好所有規則,讓團隊成員從第一行程式碼就遵循相同標準。

完整實作標準

  • Linter 設定(ESLint / Pylint / Checkstyle 等)
  • Formatter 設定(Prettier / Black / google-java-format 等)
  • Git Hooks 設定:
    • pre-commit:自動執行 Lint 與 Format
    • commit-msg:檢查 commit message 格式(Conventional Commits)
  • .editorconfig 統一編輯器行為
  • 拼字檢查(cspell / codespell)

檢查項目

  • Linter 已設定且規則已定義
  • Formatter 已設定
  • Git Hooks(pre-commit, commit-msg)已設定
  • .editorconfig 已建立
  • Commit message 格式規範已定義

完整性總檢查清單(Master Checklist)

以下是所有 10 個面向的完整檢查清單。建立新 Proto 或審查現有 Proto 時,逐項確認:

面向項目狀態
A專案結構符合團隊命名規範
ABase Classes 已建立且包含常用方法
A至少有一組完整 CRUD 範例
AREADME 中有結構說明圖
B各環境設定檔已建立(dev / staging / prod)
B.env.example 存在且完整
B.gitignore 已排除 .env 檔案
B機密資訊未出現在版本控制中
CDockerfile 使用 multi-stage build
C容器以非 root 使用者運行
Cdocker-compose 各環境版本已建立
C健康檢查端點 /health 已實作
C.dockerignore 已設定
D認證機制骨架已實作
DCORS 設定已完成且預設嚴格模式
DCSRF 防護已啟用
DRBAC 結構與範例已建立
DHTTP Security Headers 已設定
EGlobalExceptionHandler 已建立
E自訂例外階層已定義
E統一錯誤回應格式已實作
E生產環境不暴露 stack trace
E至少有一個錯誤處理範例
F結構化日誌格式已設定(JSON)
FAccess Log 中介層已建立
F各環境日誌等級已設定
F敏感資訊不出現在日誌中
F日誌設定檔已就緒
G單元測試結構與範例已建立
G整合測試使用 Testcontainers
G測試設定檔獨立於主程式
GCI Pipeline 包含測試步驟
HPipeline 設定檔已建立
HLint → Test → Build → Deploy 階段已定義
H分支與環境對應已設定
H部署策略已定義
IREADME 範本完整
IAPI 文件(Swagger / OpenAPI)已整合
ICHANGELOG 格式已定義
IADR 範本已提供
JLinter 已設定且規則已定義
JFormatter 已設定
JGit Hooks 已設定
J.editorconfig 已建立
JCommit message 格式規範已定義

注意:上表中 C 和 H 面向的項目,在前後端分離架構中屬於 Infra 範圍。Proto 只需確保應用層提供必要介面(如 health check endpoint),實際的 Docker 建構與 CI/CD Pipeline 由 Infra 定義。詳見前面的「架構邊界」段落。


Per-Track Proto 標準

通用的 10 Dimensions 是基線,但不同 track 有不同的重點。以下根據實際 Gap Analysis 的結果,定義每個 track 的具體標準。

B2E(後端)Proto 標準

後端 Proto 的核心是「API 服務的完整骨架」——從請求進來到回應出去的每一層都有規範。

維度必要項目說明
套件管理套件管理工具 + lockfilePython: uv/poetry + lock, Node: pnpm + lock, Java: Gradle/Maven
依賴分組(dev / test / lint / types)避免 production image 包含開發工具
程式碼品質Linter + FormatterPython: Ruff, Java: Checkstyle + google-java-format
Type CheckerPython: mypy + stubs, TypeScript: strict mode
Pre-commit Hooksformat → lint → typecheck(至少)
Conventional Commitscommitlint 或團隊規範
環境設定Env Loader框架原生或 dotenv 系工具
Boot-time Validation啟動時驗證必要環境變數,缺少則 fail fast
.env.example列出所有變數名 + 說明,不含實際值
Runtime Configbuild-time vs runtime 分離策略
資料庫Connection Config連線池、health check、timeout 設定
Base Model共用欄位(UUID PK、soft delete、timestamps)
Migration 策略命名規範、zero-downtime migration 原則
API 架構Router / URL ConventionRESTful 命名、版本前綴(/api/v1/
Serializer / DTO請求驗證 + 回應格式化
PaginationCursor-based + Offset-based 兩種
Filtering / SearchQueryParam 過濾規範
API 文件Swagger / OpenAPI 自動產生
認證授權JWT / Session 骨架Login / Logout / Refresh 端點
Token 管理Access + Refresh Token lifecycle
RBAC 結構角色模型 + 權限檢查 Decorator/Middleware
錯誤處理Global Exception Handler攔截所有未處理例外
自訂例外階層Business / Validation / Auth / Permission
統一回應格式{ success, data, error: { code, message, details } }
日誌結構化 JSON 日誌方便 EFK/ELK 收集
Access Log Middlewaremethod, path, status, duration, traceId
PII Masking密碼、Token、個資不入日誌
業務層Service Pattern業務邏輯集中在 Service 層
Repository Pattern資料存取抽象,方便測試
完整 CRUD 範例至少一組從 Router → Service → Repository 的範例
測試Unit TestService 層邏輯測試
Integration TestAPI 端點完整流程測試
Factory + Faker測試資料產生器
Coverage 策略最低覆蓋率門檻(建議 80%+)
文件README(含結構、安裝、指令)clone 下來就知道怎麼跑
API 文件(Swagger)自動產生,不手寫

B2E 範圍外:Docker、CI/CD、CORS、部署、備份、Multi-tenancy、WebSocket。


F2E(前端)Proto 標準

前端 Proto 的核心是「SPA 應用的完整骨架」——從路由到元件到狀態管理的每一層都有規範。

維度必要項目說明
專案初始化建置工具設定Vite config(aliases、proxy、build optimization)
TypeScript 嚴格模式strict: true + path aliases
CSS 方案Tailwind / CSS Modules / Styled Components
程式碼品質ESLint + Prettier含 framework-specific plugins(vue, react)
StylelintCSS/SCSS 規範
Git Hooks(Husky)lint-staged: ESLint fix + Prettier + Stylelint
Conventional Commitscommitlint 規範
環境設定Env Loader(getEnv()封裝環境變數存取,集中管理
Env Validation(Zod)啟動時用 Schema 驗證,不合格就 fail fast
.env.example列出所有前端需要的環境變數
路由Router 設定路由表、lazy loading、route guards
Layout SystemBase / Auth / Admin 等 Layout 切換
Navigation Guards認證檢查、權限檢查
狀態管理Global StoreAuth Store(token、user info)、App Store(theme、locale)
Feature Store每個 feature module 獨立的 store
Store Pattern統一的 action / getter 命名規範
API 層HTTP ClientAxios / Fetch 封裝 + Interceptors
Request/Response InterceptorsToken 注入、401 處理、Error 統一轉換
API 模組化每個 feature 有自己的 api 檔案
錯誤處理Error Boundary全域錯誤捕捉,避免白屏
Fallback UILoading / Empty / Error 三態元件
Toast / Notification使用者友善的錯誤提示
表單系統表單驗證(Zod / Yup)Schema-based validation
UX Pattern即時驗證、送出驗證、錯誤提示位置
元件系統Design TokensColor / Typography / Spacing / Radius
Base ComponentsButton / Input / Select / Checkbox 等
Overlay ComponentsModal / Drawer / Toast / Tooltip
命名規範Props / Events / Slots 的統一命名
StoragelocalStorage Wrapper統一封裝,支援 JSON 序列化
Secure Storage敏感資料加密存取(如 AES-GCM)
Composables / Hooks共用邏輯抽取useAsyncState / useDebounce / useTheme 等
測試Unit Test(Vitest / Jest)Store、Composables、Utils 測試
Component Test元件渲染 + 互動測試
E2E Test(Playwright / Cypress)關鍵流程端對端測試
Mocking(MSW / Adapter)API 模擬策略
Factories假資料產生器
BuildPre-build Stepslint → typecheck → env validate
Bundle Optimizationcode splitting、tree shaking、chunk 策略

F2E 範圍外:Docker、CI/CD、PWA(選做)、Push Notification(選做)。


App(行動應用)Proto 標準

App Proto 的核心是「跨平台行動應用的完整骨架」——從原生功能整合到安全存儲的每一層都有規範。

維度必要項目說明
專案初始化專案結構feature-based + Clean Architecture(data/domain/presentation)
Lint / Formatanalysis_options(Flutter)或 ESLint(RN)
Git Hooksformat → analyze → test(pre-commit)
環境設定Env Loaderflutter_dotenv / react-native-config
Env Validation啟動時檢查必要變數
Flavor / Schemedev / staging / prod 多環境切換(選做但建議)
狀態管理全域狀態Auth State(token lifecycle)、App State(theme、locale)
Feature 狀態每個 feature 獨立的 state 管理
狀態方案BLoC / RxDart / Provider / Zustand 等
路由與導航Router 設定宣告式路由(GoRouter / React Navigation)
App ShellBottomNav / Drawer / ShellRoute
Deep LinkUniversal Link / App Link 處理
API 層HTTP ClientDio / Axios + Interceptors
Certificate PinningSHA-256 指紋驗證,防止 MITM
Token Interceptor自動注入 Token、401 時 Refresh、Queue 機制
認證JWT 生命週期Access + Refresh Token 完整流程
OAuth(Google / Apple)社群登入整合
Biometric Auth指紋 / Face ID 支援
Secure Storageflutter_secure_storage / Keychain / Keystore
錯誤處理Global Error Handler未捕捉例外的統一處理
Fallback UIError Widget / Retry 機制
Crash ReportingSentry / Crashlytics 整合
UI 系統Theme(ThemeData / ThemeExtension)Light / Dark mode 支援
Design TokensColor / Typography / Spacing 集中定義
Base WidgetsButton / Input / Card 等基礎元件
Overlay 元件Dialog / BottomSheet / Toast / Snackbar
原生功能Push NotificationFCM / APNs 整合
Network Connectivity連線狀態偵測、離線處理
App Lifecycle前背景切換處理
Permission 管理相機、相簿、位置等權限請求
國際化i18n 架構intl / arb pipeline / 多語言切換
測試Unit Test邏輯層測試(Service / UseCase)
Widget / Component TestUI 元件測試
Integration Test完整流程測試
Mocking(mocktail / mockito)Dependency 模擬
Coverage 策略最低覆蓋率門檻

App 範圍外:CI/CD Pipeline、Android/iOS 簽章、Store 上架流程、Signing & Secrets(皆歸 Infra)。


Per-Track 完整度比對(實際 Gap Analysis 結果)

以下是根據實際 GitLab dev 分支程式碼,對照上述標準的結果:

TrackProto完成部分完成未完成整體完成度備註
B2EDjango52 (64%)13 (16%)16 (20%)~72%未完成項多為 Multi-tenancy(已 Cut)和 Infra 項
F2EVue 327 (69%)5 (13%)7 (18%)~76%未完成項為 Phase 8 可選項(Analytics、i18n)
AppFlutter33 (66%)10 (20%)7 (14%)~76%安全層 100%;未完成項為 CI/CD(已歸 Infra)
Infra31/31100%知識庫文章系列已完成

扣除 Infra 範圍項目後的有效完成度

Track有效項目數完成 + 部分有效完成度
B2E (Django)~62~55~89%
F2E (Vue 3)~37~32~86%
App (Flutter)~42~36~86%

Gap Analysis 方法:找出規劃與實作的落差

Proto 規劃得再漂亮,如果沒有對應的實作,就只是一份漂亮的文件。Gap Analysis(落差分析)是確保「規劃 = 實作」的關鍵方法。

為什麼需要 Gap Analysis?

在實務中,「規劃文件中寫了但沒實作」的情況比想像中常見得多。原因可能是:

  • 規劃時覺得重要,但開發時因為趕進度而跳過
  • 規劃時定義了功能,但實作時發現技術難度高而暫時擱置
  • 多人協作時,以為別人會做,結果沒人做
  • 規劃文件更新了,但 Proto 程式碼沒跟上

Gap Analysis 四步驟

Step 1:列出所有規劃項目

從 Notion、Confluence 或其他文件平台中,列出 Proto 應該包含的所有功能與模組。這份清單應該來自上一節的「10 Dimensions 檢查清單」。

Step 2:檢查實際程式碼

逐項對照規劃清單,檢查 Proto repo 中是否有對應的實作。不只是「檔案存在」,而是「功能完整且可用」。

Step 3:分類落差

將每個項目分為以下四類:

分類說明行動
Planned & Built規劃中有,實作也完整維護即可
Planned but Not Built規劃中有,但沒有實作需要補建
Built but Not Planned實作中有,但規劃文件沒提到補充文件或移除
Built but Incomplete有實作,但不完整或品質不足需要補強

Step 4:排定優先順序並補齊

根據影響範圍與緊急程度,決定填補落差的優先順序。一般來說,安全(D)、錯誤處理(E)、容器化(C)的優先順序最高,因為它們直接影響生產環境的穩定性與安全性。

Gap Analysis 範本

以下是一個可直接使用的 Gap Analysis 範本(以 Django Proto 為例):

面向項目規劃狀態實作狀態落差分類優先順序備註
ABaseService 建立已規劃已實作Planned & Built-包含 CRUD 基本方法
B.env.staging已規劃未實作Planned but Not BuiltP1下週 staging 部署需要
Cmulti-stage Dockerfile已規劃部分完成Built but IncompleteP1缺少非 root 使用者設定
DJWT 認證骨架已規劃已實作Planned & Built-含 refresh token
EGlobalExceptionHandler已規劃未實作Planned but Not BuiltP0影響所有 API 回應格式
FJSON 結構化日誌已規劃未實作Planned but Not BuiltP1EFK 需要 JSON 格式
GTestcontainers 整合測試已規劃未實作Planned but Not BuiltP2目前用 SQLite 替代
H.gitlab-ci.yml已規劃已實作Planned & Built-Lint + Test + Build
ISwagger 文件未規劃已實作Built but Not Planned-需補充到規劃文件
Jpre-commit hooks已規劃部分完成Built but IncompleteP2缺少 commit-msg 檢查

如何使用這份範本

  1. 每個 Proto 建立一份 Gap Analysis 表
  2. 每次 Sprint 結束或每月固定做一次檢查
  3. 將 P0 的落差在當前 Sprint 內解決
  4. 將 P1-P2 排入下一個 Sprint 的 backlog

從單一語言到多語言的延伸策略

建立「黃金版本」

不要同時開發多個語言的 Proto——這是最常見的錯誤。正確的做法是:

  1. 選擇團隊最熟悉的語言作為第一個實作目標
  2. 在這個語言上完整實作所有 10 個面向
  3. 通過完整性檢查與 Gap Analysis 後,打上穩定版本的 tag
  4. 這個版本成為「黃金版本」(Golden Version),作為其他語言版本的參考標準

為什麼要有黃金版本?因為它定義了「完整」的基準線。其他語言版本不需要重新發明輪子,只需要回答一個問題:「黃金版本中的這個面向,在我的語言中怎麼實作?」

跨語言共同標準 vs 語言特定實作

並非所有面向都需要「完全一樣」。有些是跨語言的共同標準,有些是語言特定的實作方式:

面向跨語言共同標準語言特定實作
A分層架構命名(Controller/Service/Repository)各語言的慣用命名(Python: snake_case, Java: camelCase)
B環境區分策略(dev/staging/prod)、boot-time validationDjango: Pydantic Settings, Spring: application-{profile}.yml, Vite: import.meta.env
DJWT payload 結構、RBAC 模型、Token lifecycle各框架的 middleware/guard/interceptor 機制
E統一錯誤回應 JSON 格式、例外階層各框架的 exception handler 機制
FJSON 日誌格式、欄位命名、PII maskingstructlog vs logback vs winston vs dart logging
G測試分層(unit / integration / e2e)、coverage 門檻pytest vs JUnit vs Vitest vs dart test
IREADME 結構、CHANGELOG 格式API 文件工具(drf-spectacular vs springdoc vs swagger-jsdoc)
JCommit message 規範(Conventional Commits)、.editorconfigRuff vs ESLint vs Checkstyle vs flutter_lints

注意:面向 C(容器化)和 H(CI/CD)不在此表中,因為這些屬於 Infra 範圍,由 Infra 統一管理。

跨語言 Per-Track 抽象標準

除了通用的 10 Dimensions,每個 track 有自己的「不管用什麼框架都必須有」的抽象標準:

B2E(後端)— 跨語言抽象

不管是 Django、Express、Spring Boot 還是 Go Gin,任何後端 Proto 都必須回答以下問題:

抽象需求問的問題Django 解法Express 解法(舉例)
套件管理怎麼管理依賴和 lockfile?uv + pyproject.tomlpnpm + package.json
資料庫層怎麼管連線、migration、base model?Django ORM + migrationsPrisma / TypeORM + migrations
API 架構路由、版本、序列化、分頁怎麼做?DRF ViewSet + drf-spectacularExpress Router + Swagger
認證授權JWT lifecycle、RBAC 怎麼做?SimpleJWT + custom permissionsPassport.js + middleware
錯誤處理全域攔截、統一格式怎麼做?DRF exception_handlerExpress error middleware
日誌結構化 JSON、access log 怎麼做?structlog + middlewarewinston + morgan
業務層Service/Repository pattern 怎麼做?Python class + DIClass + injectable
測試單元、整合、factory 怎麼做?pytest + factory-boyJest/Vitest + faker

F2E(前端)— 跨語言抽象

不管是 Vue、React 還是 Angular,任何前端 Proto 都必須回答以下問題:

抽象需求問的問題Vue 解法React 解法(舉例)
狀態管理全域和 feature 狀態怎麼管理?Pinia storesZustand / Redux Toolkit
路由路由、layout、guard 怎麼做?Vue Router + layoutsReact Router + Outlet
API 層HTTP client、interceptor 怎麼做?Axios + interceptorsFetch / Axios wrapper
表單驗證和 UX pattern 怎麼做?Zod + custom composableReact Hook Form + Zod
元件系統design tokens、base 元件怎麼做?Tailwind + Vue SFCTailwind + JSX components
測試單元、元件、E2E 怎麼做?Vitest + VTU + PlaywrightJest + RTL + Playwright

App(行動應用)— 跨語言抽象

不管是 Flutter、React Native 還是 KMP,任何 App Proto 都必須回答以下問題:

抽象需求問的問題Flutter 解法React Native 解法(舉例)
狀態管理全域和 feature 狀態怎麼管理?RxDart + StateNotifierZustand / Redux
路由導航宣告式路由、deep link 怎麼做?GoRouterReact Navigation
API 層HTTP client、cert pinning 怎麼做?Dio + CertificatePinningAxios + ssl-pinning
認證JWT、OAuth、biometric 怎麼做?custom + google_sign_in + local_authcustom + expo-auth
安全存儲敏感資料怎麼存?flutter_secure_storagereact-native-keychain
原生功能push、permission、lifecycle?FCM + permission_handlerFCM + react-native-permissions
測試unit、widget/component、integration?dart test + flutter_testJest + RNTL + Detox

重點:跨語言的抽象標準不是要求「所有語言做法一樣」,而是要求「所有語言回答同樣的問題」。問題是固定的,答案隨語言和框架而異。

各語言版本檢查清單

每當延伸到一個新的語言版本時,使用以下檢查清單:

  • 該 track 的所有 Per-Track 維度都已實作
  • 跨語言共同標準(錯誤格式、日誌格式、commit 規範)與黃金版本一致
  • 語言特定實作符合該語言的社群慣例(命名、目錄結構、慣用 pattern)
  • 所有範例程式碼可正常執行
  • Health check endpoint 已實作(供 Infra 整合用)
  • README 已更新為該語言的相關資訊
  • Gap Analysis 已完成且無 P0/P1 落差
  • 架構邊界正確——沒有包含 Infra 範圍的東西(Docker、CI/CD、CORS)

版本管理策略

Proto 也需要版本管理。建議採用以下策略:

# 版本命名規範
v{major}.{minor}.{patch}

# 範例
v1.0.0  -- 首個穩定版本
v1.1.0  -- 新增 RBAC 範例
v1.1.1  -- 修正 Docker health check
v2.0.0  -- 升級 Python 3.12, 重大結構變更
  • Major:重大結構變更、框架升級(如 Django 4 → Django 5)
  • Minor:新增面向或功能(如新增 RBAC 範例)
  • Patch:修正錯誤、更新依賴版本

每個穩定版本都應該打 Git tag,讓新專案在建立時可以明確標記「從哪個版本的 Proto 複製」。同時,定期(例如每季)同步更新所有語言版本的依賴。


Proto 的演進與維護

Proto 不是建立一次就結束的。它是一份「活的文件」,反映了團隊當前的最佳實踐。

依賴更新策略

  • 每月:檢查安全性更新(npm auditpip-auditmvn dependency-check
  • 每季:更新 minor 版本依賴
  • 每年或按需:評估 major 版本升級

何時建立新的 Major 版本?

出現以下情況時,應建立新的 Major 版本而不是修改現有版本:

  • 框架 major 版本升級(如 Vue 2 → Vue 3)
  • 專案結構發生根本性變更
  • 捨棄某個核心元件(如從 REST 轉向 GraphQL)
  • 容器化策略改變(如從 Docker Compose 轉向 Kubernetes)

重要:舊的 Major 版本不應刪除。已經基於舊版本建立的專案可能還需要參考。

Proto 作為團隊最佳實踐的載體

Proto 不只是程式碼模板——它是團隊「如何開發軟體」的具體展現。當團隊學到新的最佳實踐時(例如更好的錯誤處理模式、更安全的 Docker 設定),應該回饋到 Proto 中。

建議流程:

  1. 在專案中發現更好的做法
  2. 在 Proto 的 repo 開 issue 討論
  3. 達成共識後更新 Proto
  4. 發布新版本
  5. 通知團隊(但不強制舊專案升級——COPY, not Reference)

常見問題與風險

Proto 太重(Over-engineered)

症狀:clone 下來後,有一半的程式碼需要刪除才能開始用。

原因:把太多「可能會用到」的功能放進 Proto,例如內建了 WebSocket、GraphQL、Message Queue 等不是每個專案都需要的東西。

解法:Proto 只包含「每個專案都需要」的基礎建設(也就是 10 Dimensions),進階功能以獨立的「擴展包」形式提供,需要時再加入。

Proto 太舊(Stale)

症狀:依賴版本過舊,安全漏洞未修復,新專案 clone 下來第一件事就是大量升級依賴。

原因:沒有人負責維護,或沒有定期更新的流程。

解法:指定 Proto 的 Owner(通常是 Tech Lead 或資深工程師),建立每月/每季的更新 SOP。可以設定 Dependabot 或 Renovate Bot 自動提 PR。

Proto 脫離現實(Disconnected)

症狀:Proto 中有些功能從來沒有專案使用過,或是 Proto 的做法與實際專案的做法已經分道揚鑣。

原因:Proto 在建立後沒有根據實際專案的回饋持續調整。

解法:每季做一次 Proto Review,將最近幾個新專案的做法與 Proto 對比。如果大多數專案都修改了 Proto 的某個部分,那這個部分可能需要在 Proto 中調整。

面向缺失(Missing Dimensions)

症狀:有 Docker 但沒有 CI/CD,有 CI/CD 但沒有測試,有測試但沒有統一的錯誤處理。10 個面向不是獨立存在的,而是環環相扣。

原因:建立 Proto 時只做了「容易做的」,跳過了「困難但重要的」。

解法:使用本文的 Master Checklist 逐項檢查。缺失的面向用 Gap Analysis 方法排定優先順序並補齊。

規劃與實作的落差(The Exact Problem)

症狀:Notion 文件中寫了一堆,但打開 Proto repo 發現很多東西根本沒做。

原因:缺乏定期的 Gap Analysis 流程。

解法:導入本文的 Gap Analysis 四步驟,每月固定做一次對照檢查。將結果公開在團隊的看板上,讓落差可見化。


結語:好的 Proto 讓團隊專注在對的事情上

Proto 的終極目標不是「有一套漂亮的模板」,而是讓團隊能夠在新專案的第一天就專注在業務邏輯上,而不是花時間重新發明基礎建設。

一個好的 Proto 具備以下特質:

  • 完整:覆蓋該 track 的所有必要面向,沒有缺失
  • 邊界清晰:Proto 只管應用層,Infra 的事交給 Infra
  • 實用:clone 下來就能用,不需要大量修改或刪除
  • 一致:多語言版本遵循相同的跨語言標準
  • 活著:持續根據團隊的實務經驗演進
  • 有差距分析:規劃與實作的落差可追蹤、可量化

最後,記住 Proto 的核心原則:

COPY, not Reference. 專案完整性 > DRY。

每個專案都應該是一個完整的、獨立的個體。Proto 是起點,不是枷鎖。


延伸閱讀

  • 系統規劃方法論:從需求到上線的完整流程,與 Proto 規劃互相補充
  • 測試策略:Proto 中測試基線(面向 G)的完整展開
  • API 設計:Proto 中 RESTful API 的設計標準與錯誤格式定義
  • Monorepo vs Multirepo:Proto 的版本控管策略,與 Submodule 模式的取捨
  • 環境分離策略:Proto 中多環境設定(面向 B)的深入探討
  • CD 範本:Infra 端的 CI/CD 實作(Proto 透過 Submodule 被 Infra 整合)
  • 應用安全:Proto 安全基線(面向 D)的完整展開,含 OWASP Top 10