
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-app、django-admin startproject |
| Boilerplate | 預先寫好的樣板程式碼,可直接複製使用 | 通常聚焦在特定技術組合,缺乏團隊客製化 | GitHub 上的 react-boilerplate |
| Proto | 團隊定義的「生產環境等級專案原型」 | 包含完整基礎建設、團隊慣例、安全基線 | 本文所定義的 Proto |
為什麼 Proto 是正確的心智模型?
Scaffold 只給你框架的骨架;Boilerplate 只給你技術組合的範例;Template 只是程式碼生成。但 Proto 代表的是:這就是你的生產環境架構的原型(Prototype),它包含了你在生產環境中需要的一切基礎建設。
核心原則:COPY, not Reference
這是 Proto 哲學中最重要的一條原則:
每個新專案應該是 Proto 的完整獨立副本,而不是對 Proto 的引用或繼承。
為什麼?因為:
- 專案獨立性:每個專案可能有不同的演進速度,不應被 Proto 的更新綁架
- 可客製化:複製後可以自由修改,不需要擔心影響其他專案
- 完整性 > DRY:在專案層級,完整性比「不重複」更重要。每個專案都應該擁有完整的基礎建設,而不是依賴外部的共用模組
- 版本可追溯:透過記錄「從哪個版本的 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
每個階段的說明:
- 定義標準:先定義什麼是「完整」——也就是本文第五節的 10 大面向
- 選黃金版本:選一個團隊最熟悉的語言/框架,作為第一個實作的 Proto
- 實作:根據標準,在黃金版本上實作所有面向
- Gap Analysis:對比規劃文件與實際程式碼,找出落差
- 補齊:將落差逐一填補
- 穩定版本:通過所有檢查後,打 tag 釋出穩定版本
- 延伸到其他語言:以黃金版本為標準,逐一實作其他語言版本,並再次進行 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. 容器化 | Infra | Dockerfile、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 Pipeline | Infra | Pipeline 定義、部署策略、環境對應由 Infra 處理 |
| I. 文件 | Proto | README、API 文件、CHANGELOG |
| J. 程式碼品質 | Proto | Linter、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 build | Infra | Image 建構策略是部署問題 |
CI/CD Pipeline(.gitlab-ci.yml) | Infra | Pipeline 跨 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 與 Formatcommit-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 | 專案結構符合團隊命名規範 | ☐ |
| A | Base Classes 已建立且包含常用方法 | ☐ |
| A | 至少有一組完整 CRUD 範例 | ☐ |
| A | README 中有結構說明圖 | ☐ |
| B | 各環境設定檔已建立(dev / staging / prod) | ☐ |
| B | .env.example 存在且完整 | ☐ |
| B | .gitignore 已排除 .env 檔案 | ☐ |
| B | 機密資訊未出現在版本控制中 | ☐ |
| C | Dockerfile 使用 multi-stage build | ☐ |
| C | 容器以非 root 使用者運行 | ☐ |
| C | docker-compose 各環境版本已建立 | ☐ |
| C | 健康檢查端點 /health 已實作 | ☐ |
| C | .dockerignore 已設定 | ☐ |
| D | 認證機制骨架已實作 | ☐ |
| D | CORS 設定已完成且預設嚴格模式 | ☐ |
| D | CSRF 防護已啟用 | ☐ |
| D | RBAC 結構與範例已建立 | ☐ |
| D | HTTP Security Headers 已設定 | ☐ |
| E | GlobalExceptionHandler 已建立 | ☐ |
| E | 自訂例外階層已定義 | ☐ |
| E | 統一錯誤回應格式已實作 | ☐ |
| E | 生產環境不暴露 stack trace | ☐ |
| E | 至少有一個錯誤處理範例 | ☐ |
| F | 結構化日誌格式已設定(JSON) | ☐ |
| F | Access Log 中介層已建立 | ☐ |
| F | 各環境日誌等級已設定 | ☐ |
| F | 敏感資訊不出現在日誌中 | ☐ |
| F | 日誌設定檔已就緒 | ☐ |
| G | 單元測試結構與範例已建立 | ☐ |
| G | 整合測試使用 Testcontainers | ☐ |
| G | 測試設定檔獨立於主程式 | ☐ |
| G | CI Pipeline 包含測試步驟 | ☐ |
| H | Pipeline 設定檔已建立 | ☐ |
| H | Lint → Test → Build → Deploy 階段已定義 | ☐ |
| H | 分支與環境對應已設定 | ☐ |
| H | 部署策略已定義 | ☐ |
| I | README 範本完整 | ☐ |
| I | API 文件(Swagger / OpenAPI)已整合 | ☐ |
| I | CHANGELOG 格式已定義 | ☐ |
| I | ADR 範本已提供 | ☐ |
| J | Linter 已設定且規則已定義 | ☐ |
| J | Formatter 已設定 | ☐ |
| J | Git Hooks 已設定 | ☐ |
| J | .editorconfig 已建立 | ☐ |
| J | Commit 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 服務的完整骨架」——從請求進來到回應出去的每一層都有規範。
| 維度 | 必要項目 | 說明 |
|---|---|---|
| 套件管理 | 套件管理工具 + lockfile | Python: uv/poetry + lock, Node: pnpm + lock, Java: Gradle/Maven |
| 依賴分組(dev / test / lint / types) | 避免 production image 包含開發工具 | |
| 程式碼品質 | Linter + Formatter | Python: Ruff, Java: Checkstyle + google-java-format |
| Type Checker | Python: mypy + stubs, TypeScript: strict mode | |
| Pre-commit Hooks | format → lint → typecheck(至少) | |
| Conventional Commits | commitlint 或團隊規範 | |
| 環境設定 | Env Loader | 框架原生或 dotenv 系工具 |
| Boot-time Validation | 啟動時驗證必要環境變數,缺少則 fail fast | |
.env.example | 列出所有變數名 + 說明,不含實際值 | |
| Runtime Config | build-time vs runtime 分離策略 | |
| 資料庫 | Connection Config | 連線池、health check、timeout 設定 |
| Base Model | 共用欄位(UUID PK、soft delete、timestamps) | |
| Migration 策略 | 命名規範、zero-downtime migration 原則 | |
| API 架構 | Router / URL Convention | RESTful 命名、版本前綴(/api/v1/) |
| Serializer / DTO | 請求驗證 + 回應格式化 | |
| Pagination | Cursor-based + Offset-based 兩種 | |
| Filtering / Search | QueryParam 過濾規範 | |
| 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 Middleware | method, path, status, duration, traceId | |
| PII Masking | 密碼、Token、個資不入日誌 | |
| 業務層 | Service Pattern | 業務邏輯集中在 Service 層 |
| Repository Pattern | 資料存取抽象,方便測試 | |
| 完整 CRUD 範例 | 至少一組從 Router → Service → Repository 的範例 | |
| 測試 | Unit Test | Service 層邏輯測試 |
| Integration Test | API 端點完整流程測試 | |
| 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) |
| Stylelint | CSS/SCSS 規範 | |
| Git Hooks(Husky) | lint-staged: ESLint fix + Prettier + Stylelint | |
| Conventional Commits | commitlint 規範 | |
| 環境設定 | Env Loader(getEnv()) | 封裝環境變數存取,集中管理 |
| Env Validation(Zod) | 啟動時用 Schema 驗證,不合格就 fail fast | |
.env.example | 列出所有前端需要的環境變數 | |
| 路由 | Router 設定 | 路由表、lazy loading、route guards |
| Layout System | Base / Auth / Admin 等 Layout 切換 | |
| Navigation Guards | 認證檢查、權限檢查 | |
| 狀態管理 | Global Store | Auth Store(token、user info)、App Store(theme、locale) |
| Feature Store | 每個 feature module 獨立的 store | |
| Store Pattern | 統一的 action / getter 命名規範 | |
| API 層 | HTTP Client | Axios / Fetch 封裝 + Interceptors |
| Request/Response Interceptors | Token 注入、401 處理、Error 統一轉換 | |
| API 模組化 | 每個 feature 有自己的 api 檔案 | |
| 錯誤處理 | Error Boundary | 全域錯誤捕捉,避免白屏 |
| Fallback UI | Loading / Empty / Error 三態元件 | |
| Toast / Notification | 使用者友善的錯誤提示 | |
| 表單系統 | 表單驗證(Zod / Yup) | Schema-based validation |
| UX Pattern | 即時驗證、送出驗證、錯誤提示位置 | |
| 元件系統 | Design Tokens | Color / Typography / Spacing / Radius |
| Base Components | Button / Input / Select / Checkbox 等 | |
| Overlay Components | Modal / Drawer / Toast / Tooltip | |
| 命名規範 | Props / Events / Slots 的統一命名 | |
| Storage | localStorage 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 | 假資料產生器 | |
| Build | Pre-build Steps | lint → typecheck → env validate |
| Bundle Optimization | code splitting、tree shaking、chunk 策略 |
F2E 範圍外:Docker、CI/CD、PWA(選做)、Push Notification(選做)。
App(行動應用)Proto 標準
App Proto 的核心是「跨平台行動應用的完整骨架」——從原生功能整合到安全存儲的每一層都有規範。
| 維度 | 必要項目 | 說明 |
|---|---|---|
| 專案初始化 | 專案結構 | feature-based + Clean Architecture(data/domain/presentation) |
| Lint / Format | analysis_options(Flutter)或 ESLint(RN) | |
| Git Hooks | format → analyze → test(pre-commit) | |
| 環境設定 | Env Loader | flutter_dotenv / react-native-config |
| Env Validation | 啟動時檢查必要變數 | |
| Flavor / Scheme | dev / staging / prod 多環境切換(選做但建議) | |
| 狀態管理 | 全域狀態 | Auth State(token lifecycle)、App State(theme、locale) |
| Feature 狀態 | 每個 feature 獨立的 state 管理 | |
| 狀態方案 | BLoC / RxDart / Provider / Zustand 等 | |
| 路由與導航 | Router 設定 | 宣告式路由(GoRouter / React Navigation) |
| App Shell | BottomNav / Drawer / ShellRoute | |
| Deep Link | Universal Link / App Link 處理 | |
| API 層 | HTTP Client | Dio / Axios + Interceptors |
| Certificate Pinning | SHA-256 指紋驗證,防止 MITM | |
| Token Interceptor | 自動注入 Token、401 時 Refresh、Queue 機制 | |
| 認證 | JWT 生命週期 | Access + Refresh Token 完整流程 |
| OAuth(Google / Apple) | 社群登入整合 | |
| Biometric Auth | 指紋 / Face ID 支援 | |
| Secure Storage | flutter_secure_storage / Keychain / Keystore | |
| 錯誤處理 | Global Error Handler | 未捕捉例外的統一處理 |
| Fallback UI | Error Widget / Retry 機制 | |
| Crash Reporting | Sentry / Crashlytics 整合 | |
| UI 系統 | Theme(ThemeData / ThemeExtension) | Light / Dark mode 支援 |
| Design Tokens | Color / Typography / Spacing 集中定義 | |
| Base Widgets | Button / Input / Card 等基礎元件 | |
| Overlay 元件 | Dialog / BottomSheet / Toast / Snackbar | |
| 原生功能 | Push Notification | FCM / APNs 整合 |
| Network Connectivity | 連線狀態偵測、離線處理 | |
| App Lifecycle | 前背景切換處理 | |
| Permission 管理 | 相機、相簿、位置等權限請求 | |
| 國際化 | i18n 架構 | intl / arb pipeline / 多語言切換 |
| 測試 | Unit Test | 邏輯層測試(Service / UseCase) |
| Widget / Component Test | UI 元件測試 | |
| Integration Test | 完整流程測試 | |
| Mocking(mocktail / mockito) | Dependency 模擬 | |
| Coverage 策略 | 最低覆蓋率門檻 |
App 範圍外:CI/CD Pipeline、Android/iOS 簽章、Store 上架流程、Signing & Secrets(皆歸 Infra)。
Per-Track 完整度比對(實際 Gap Analysis 結果)
以下是根據實際 GitLab dev 分支程式碼,對照上述標準的結果:
| Track | Proto | 完成 | 部分完成 | 未完成 | 整體完成度 | 備註 |
|---|---|---|---|---|---|---|
| B2E | Django | 52 (64%) | 13 (16%) | 16 (20%) | ~72% | 未完成項多為 Multi-tenancy(已 Cut)和 Infra 項 |
| F2E | Vue 3 | 27 (69%) | 5 (13%) | 7 (18%) | ~76% | 未完成項為 Phase 8 可選項(Analytics、i18n) |
| App | Flutter | 33 (66%) | 10 (20%) | 7 (14%) | ~76% | 安全層 100%;未完成項為 CI/CD(已歸 Infra) |
| Infra | — | 31/31 | — | — | 100% | 知識庫文章系列已完成 |
扣除 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 為例):
| 面向 | 項目 | 規劃狀態 | 實作狀態 | 落差分類 | 優先順序 | 備註 |
|---|---|---|---|---|---|---|
| A | BaseService 建立 | 已規劃 | 已實作 | Planned & Built | - | 包含 CRUD 基本方法 |
| B | .env.staging | 已規劃 | 未實作 | Planned but Not Built | P1 | 下週 staging 部署需要 |
| C | multi-stage Dockerfile | 已規劃 | 部分完成 | Built but Incomplete | P1 | 缺少非 root 使用者設定 |
| D | JWT 認證骨架 | 已規劃 | 已實作 | Planned & Built | - | 含 refresh token |
| E | GlobalExceptionHandler | 已規劃 | 未實作 | Planned but Not Built | P0 | 影響所有 API 回應格式 |
| F | JSON 結構化日誌 | 已規劃 | 未實作 | Planned but Not Built | P1 | EFK 需要 JSON 格式 |
| G | Testcontainers 整合測試 | 已規劃 | 未實作 | Planned but Not Built | P2 | 目前用 SQLite 替代 |
| H | .gitlab-ci.yml | 已規劃 | 已實作 | Planned & Built | - | Lint + Test + Build |
| I | Swagger 文件 | 未規劃 | 已實作 | Built but Not Planned | - | 需補充到規劃文件 |
| J | pre-commit hooks | 已規劃 | 部分完成 | Built but Incomplete | P2 | 缺少 commit-msg 檢查 |
如何使用這份範本:
- 每個 Proto 建立一份 Gap Analysis 表
- 每次 Sprint 結束或每月固定做一次檢查
- 將 P0 的落差在當前 Sprint 內解決
- 將 P1-P2 排入下一個 Sprint 的 backlog
從單一語言到多語言的延伸策略
建立「黃金版本」
不要同時開發多個語言的 Proto——這是最常見的錯誤。正確的做法是:
- 選擇團隊最熟悉的語言作為第一個實作目標
- 在這個語言上完整實作所有 10 個面向
- 通過完整性檢查與 Gap Analysis 後,打上穩定版本的 tag
- 這個版本成為「黃金版本」(Golden Version),作為其他語言版本的參考標準
為什麼要有黃金版本?因為它定義了「完整」的基準線。其他語言版本不需要重新發明輪子,只需要回答一個問題:「黃金版本中的這個面向,在我的語言中怎麼實作?」
跨語言共同標準 vs 語言特定實作
並非所有面向都需要「完全一樣」。有些是跨語言的共同標準,有些是語言特定的實作方式:
| 面向 | 跨語言共同標準 | 語言特定實作 |
|---|---|---|
| A | 分層架構命名(Controller/Service/Repository) | 各語言的慣用命名(Python: snake_case, Java: camelCase) |
| B | 環境區分策略(dev/staging/prod)、boot-time validation | Django: Pydantic Settings, Spring: application-{profile}.yml, Vite: import.meta.env |
| D | JWT payload 結構、RBAC 模型、Token lifecycle | 各框架的 middleware/guard/interceptor 機制 |
| E | 統一錯誤回應 JSON 格式、例外階層 | 各框架的 exception handler 機制 |
| F | JSON 日誌格式、欄位命名、PII masking | structlog vs logback vs winston vs dart logging |
| G | 測試分層(unit / integration / e2e)、coverage 門檻 | pytest vs JUnit vs Vitest vs dart test |
| I | README 結構、CHANGELOG 格式 | API 文件工具(drf-spectacular vs springdoc vs swagger-jsdoc) |
| J | Commit message 規範(Conventional Commits)、.editorconfig | Ruff 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.toml | pnpm + package.json |
| 資料庫層 | 怎麼管連線、migration、base model? | Django ORM + migrations | Prisma / TypeORM + migrations |
| API 架構 | 路由、版本、序列化、分頁怎麼做? | DRF ViewSet + drf-spectacular | Express Router + Swagger |
| 認證授權 | JWT lifecycle、RBAC 怎麼做? | SimpleJWT + custom permissions | Passport.js + middleware |
| 錯誤處理 | 全域攔截、統一格式怎麼做? | DRF exception_handler | Express error middleware |
| 日誌 | 結構化 JSON、access log 怎麼做? | structlog + middleware | winston + morgan |
| 業務層 | Service/Repository pattern 怎麼做? | Python class + DI | Class + injectable |
| 測試 | 單元、整合、factory 怎麼做? | pytest + factory-boy | Jest/Vitest + faker |
F2E(前端)— 跨語言抽象:
不管是 Vue、React 還是 Angular,任何前端 Proto 都必須回答以下問題:
| 抽象需求 | 問的問題 | Vue 解法 | React 解法(舉例) |
|---|---|---|---|
| 狀態管理 | 全域和 feature 狀態怎麼管理? | Pinia stores | Zustand / Redux Toolkit |
| 路由 | 路由、layout、guard 怎麼做? | Vue Router + layouts | React Router + Outlet |
| API 層 | HTTP client、interceptor 怎麼做? | Axios + interceptors | Fetch / Axios wrapper |
| 表單 | 驗證和 UX pattern 怎麼做? | Zod + custom composable | React Hook Form + Zod |
| 元件系統 | design tokens、base 元件怎麼做? | Tailwind + Vue SFC | Tailwind + JSX components |
| 測試 | 單元、元件、E2E 怎麼做? | Vitest + VTU + Playwright | Jest + RTL + Playwright |
App(行動應用)— 跨語言抽象:
不管是 Flutter、React Native 還是 KMP,任何 App Proto 都必須回答以下問題:
| 抽象需求 | 問的問題 | Flutter 解法 | React Native 解法(舉例) |
|---|---|---|---|
| 狀態管理 | 全域和 feature 狀態怎麼管理? | RxDart + StateNotifier | Zustand / Redux |
| 路由導航 | 宣告式路由、deep link 怎麼做? | GoRouter | React Navigation |
| API 層 | HTTP client、cert pinning 怎麼做? | Dio + CertificatePinning | Axios + ssl-pinning |
| 認證 | JWT、OAuth、biometric 怎麼做? | custom + google_sign_in + local_auth | custom + expo-auth |
| 安全存儲 | 敏感資料怎麼存? | flutter_secure_storage | react-native-keychain |
| 原生功能 | push、permission、lifecycle? | FCM + permission_handler | FCM + react-native-permissions |
| 測試 | unit、widget/component、integration? | dart test + flutter_test | Jest + 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 audit、pip-audit、mvn dependency-check) - 每季:更新 minor 版本依賴
- 每年或按需:評估 major 版本升級
何時建立新的 Major 版本?
出現以下情況時,應建立新的 Major 版本而不是修改現有版本:
- 框架 major 版本升級(如 Vue 2 → Vue 3)
- 專案結構發生根本性變更
- 捨棄某個核心元件(如從 REST 轉向 GraphQL)
- 容器化策略改變(如從 Docker Compose 轉向 Kubernetes)
重要:舊的 Major 版本不應刪除。已經基於舊版本建立的專案可能還需要參考。
Proto 作為團隊最佳實踐的載體
Proto 不只是程式碼模板——它是團隊「如何開發軟體」的具體展現。當團隊學到新的最佳實踐時(例如更好的錯誤處理模式、更安全的 Docker 設定),應該回饋到 Proto 中。
建議流程:
- 在專案中發現更好的做法
- 在 Proto 的 repo 開 issue 討論
- 達成共識後更新 Proto
- 發布新版本
- 通知團隊(但不強制舊專案升級——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 是起點,不是枷鎖。