Day27 把網站部署到 Google Cloud,第一版總算能離開開發電腦,讓其他人從瀏覽器開啟。不過,軟體上線不代表從此不能動。真正開始使用後,通常才會發現按鈕不順手、規格少想了一種情況,或突然冒出一個很想加入的新功能。
這次要替 ProjectManagementWeb 加上「使用者大頭貼」。功能聽起來不大,實際上會同時碰到前端畫面、後端 API、資料庫與共用規格。如果直接對 Agent 說「幫忙加上傳大頭貼」,它為了把空白補起來,可能會自行決定圖片存放位置、誰能修改,甚至連舊圖要不要保留都一起猜掉。
所以這一篇先不急著寫 Code。要先替變更安排一條安全的路,再讓 Codex 盤點現況、提出問題,最後把確認過的決定寫成變更申請。這就像裝潢已經營業的店面:先把施工區圍起來、確認圖面,才開始敲牆。
Day25 已經介紹過 Git Flow。這次要把它真正用在第二版開發上。
可以先把幾種分支想成不同的工作區:
| 分支 | 白話理解 | 這次怎麼用 |
|---|---|---|
main |
目前可交付的展示品 | 不直接在上面施工 |
develop |
下一版的共用工作桌 | 收集已完成、準備進入下一版的修改 |
feature/* |
單一功能的施工區 | 開發大頭貼功能 |
bugfix/* |
一般問題的維修區 | 修正尚未發版的缺陷 |
release/* |
發版前的驗收區 | 只處理測試、版本與發版準備 |
hotfix/* |
正式環境的緊急維修區 | 從 main 修正,再同步回 develop |

圖上的箭頭是團隊約定的路線,不是 Git 自己會執行的自動規則。若 GitHub 還沒有分支保護,使用者仍可能直接 Push 到 main;若 CI/CD 還沒建立,Pull Request 也不會憑空多出 Build 與 Test。規範先告訴大家「應該怎麼走」,真正的自動檢查會留到 Day29。
ProjectManagementWeb 分成 Frontend、Backend 與 Spec 三個獨立 Repository。它們各自有自己的分支、Commit 與 Pull Request,所以不能只在其中一個 Repository 建立分支,就當作三邊都準備好了。
而且這不是全新專案。建立 feature/* 前,要先檢查 develop 是否包含功能需要的最新變更。如果 main 有尚未同步回來的正式版修正,應先處理分支差異;不要因為流程圖畫了一條箭頭,就假設兩邊內容相同。
一個人開發時,直接在 main 修改,出問題通常只會打亂自己的工作。多人同時開發就不同了。有人正在修改登入功能,另一個人正在調整資料庫;如果大家都在同一條分支上工作,很容易把尚未完成的內容一起推上去,也可能在解決衝突時誤刪別人的修改。
Git Flow 像是團隊共用的交通規則。每項工作先進入自己的 feature/* 或 bugfix/*,完成後再透過 Pull Request 回到 develop。其他成員可以在 PR 裡看到改了哪些檔案、測試是否執行,以及這次變更會影響誰,不必只靠聊天訊息拼湊現況。
develop 也提供一個正式發版前的集合點。兩項功能各自測試通過,不代表放在一起仍然正常;前端可能已經使用新的 API 欄位,後端卻還沒合併對應修改。先在 develop 整合,可以在進入 main 前發現這類落差。
遇到正式環境的緊急問題時,hotfix/* 會從 main 開出,修正後再同步回 develop。少了回合併這一步,下一版可能會把同一個錯誤重新帶回正式環境。
ProjectManagementWeb 又分成三個 Repository,因此多人協作時還要把相關 PR 互相連結。例如 Spec 先確認規格,Backend 提供 API,Frontend 才能依契約串接。三邊不一定同時完成,但每個人都要知道目前相容的是哪一組版本。
先請 Codex 讀取三個 Repository 的現況,再提出要新增或調整的檔案:
請分析目前專案的 Git Repository 結構、現有 Branch、Commit History、CI/CD 設定與專案類型,並為此專案建立一套可長期維護的 GitFlow 開發規範,並且寫在docs/git-flow.md。
目標是讓未來的人員與 AI Coding Agent 都能依照相同規則進行開發、版本管理與 Release。
請不要直接修改既有 Git History,也不要強制刪除目前存在的 Branch。
請採用以下 GitFlow 為基礎:
- main
- Production 正式版本
- 只能透過 Pull Request / Merge Request 合併
- 不允許直接開發
- develop
- 下一版本主要整合分支
- Feature 完成後合併到此分支
- feature/*
- 新功能開發
- 從 develop 建立
- 完成後合併回 develop
格式:
feature/<ticket-id>-<description>
例如:
feature/123-user-login
- bugfix/*
- 一般 Bug 修正
- 從 develop 建立
- 完成後合併回 develop
格式:
bugfix/<ticket-id>-<description>
- release/*
- Release Candidate
- 從 develop 建立
- 僅允許進行:
- Bug Fix
- Version Update
- Release Note
- Config 調整
- 完成後合併到:
- main
- develop
格式:
release/<version>
例如:
release/1.2.0
- hotfix/*
- Production 緊急修正
- 從 main 建立
- 修正後必須合併到:
- main
- develop
格式:
hotfix/<version>-<description>
例如:
hotfix/1.2.1-login-error
請採用 Conventional Commits:
格式:
<type>(<scope>): <description>
支援:
- feat
- fix
- refactor
- docs
- test
- chore
- build
- ci
- perf
- style
- revert
例如:
feat(auth): 新增 JWT 登入功能
fix(order): 修正訂單金額計算錯誤
refactor(api): 重構 API exception handling
Commit Description 請使用繁體中文。
所有以下 Branch 合併:
- feature → develop
- bugfix → develop
- release → main
- hotfix → main
都必須透過 Pull Request。
PR 必須包含:
說明此次修改內容。
列出主要修改項目。
說明:
- Unit Test
- Integration Test
- Manual Test
測試結果。
說明可能的影響範圍。
如果部署後發生問題,如何回復。
預設使用:
Squash Merge
但以下情況保留完整 Commit:
- release
- hotfix
禁止:
- 直接 Push main
- 直接 Push develop
- Force Push main
- Force Push develop
採用 Semantic Versioning:
MAJOR.MINOR.PATCH
例如:
1.0.0
1.1.0
1.1.1
2.0.0
定義:
MAJOR:
Breaking Change
MINOR:
Backward-compatible Feature
PATCH:
Backward-compatible Bug Fix
Release 合併到 main 後建立:
v<version>
例如:
v1.2.0
Tag 必須對應:
main branch 的 Release Commit。
標準 Release:
develop
↓
release/x.y.z
↓
QA / Test
↓
main
↓
Tag vX.Y.Z
↓
Production Deployment
↓
merge back develop
Production 問題:
main
↓
hotfix/x.y.z-description
↓
修正
↓
Test
↓
main
↓
Tag
↓
Production Deployment
↓
merge back develop
請依目前專案實際 CI/CD 平台調整。
預設:
feature/*
bugfix/*
→ Build + Test
develop
→ Build + Test
→ Deploy DEV
release/*
→ Build + Test
→ Deploy STAGING
main
→ Build + Test
→ Deploy PRODUCTION
Tag v*
→ Production Release
AI Agent 開始修改程式前必須:
1. 檢查目前 Branch
2. 不可直接在 main 修改
3. 不可直接在 develop 修改
4. 判斷工作類型:
- feature
- bugfix
- hotfix
- refactor
5. 建立符合規範的 Branch
例如:
feature/123-add-payment-api
完成修改後:
6. 執行 Build
7. 執行 Test
8. 檢查 git diff
9. 檢查是否包含敏感資訊
10. 產生 Conventional Commit
11. 提供 PR 說明
AI 不得自行:
- Force Push
- Rewrite Git History
- Delete Remote Branch
- Merge main
- Release Production
除非使用者明確要求。
請建立以下文件:
.github/PULL_REQUEST_TEMPLATE.md
內容包含:
- Summary
- Changes
- Test
- Risk
- Rollback
並建立:
docs/git-flow.md
內容說明:
- Branch Strategy
- Branch Naming
- Commit Convention
- Pull Request
- Release Flow
- Hotfix Flow
- Versioning
- Tagging
- CI/CD Mapping
如果 Repository 已存在:
- CONTRIBUTING.md
- AGENTS.md
- CLAUDE.md
請優先整合規則,而不是建立重複文件。
開始修改之前,請先:
1. 分析目前 Git Repository。
2. 顯示目前 Branch。
3. 顯示主要 Branch 關係。
4. 檢查是否已存在 GitFlow 或類似規則。
5. 檢查 CI/CD workflow。
6. 提出預計新增或修改的檔案。
請先提供:
目前 Repository Git 狀態。
建議 GitFlow。
預計修改檔案。
可能風險。
在完成分析後再進行修改。
不要修改現有 Commit History。
確認內容後,三個 Repository 各自有一份 docs/git-flow.md,並以 .github/PULL_REQUEST_TEMPLATE.md 提醒提交者填寫修改摘要、測試結果、風險與回復方式。
這裡要分清楚「文件」和「系統設定」。把「main 只能透過 PR 合併」寫進文件,是團隊規則;還要到 GitHub 設定 Branch protection 或 Ruleset,才會由平台幫忙阻擋違規操作。同樣地,文件裡列出的 CI/CD Mapping 目前是目標,不代表 GitHub Actions 已經開始執行。
規則確認後,接著替這次修改建立獨立的施工區。為了避免 Agent 一收到需求就開始改程式,Prompt 直接寫明「先不要開發」:
我想開發一個,使用者在帳號驗證過後,可以上傳大頭貼的功能,並且可以在使用者資料中顯示,請幫我開一個開發分支,先不要進行開發

畫面中 Codex 回報三個 Repository 都建立了同名分支,也核對本機與遠端的 Commit。名稱相同方便追蹤,但它們仍是三條獨立分支;日後也要各自 Commit、Push 與建立 Pull Request。
分支準備好後,可以開一個新的 Session,讓 Codex 專心處理這次變更。新的 Session 不應靠猜測理解前因後果,因此 Prompt 要把目標、限制與停止條件寫清楚:
請開發一個人資料上傳大頭貼的功能,內容如下:
1. 該功能需要經過信箱驗證過後才可以啟用
2. 該功能不用綁任何權限,但是只有自己的帳戶可以修改自己的大頭貼
3. 大頭貼的尺寸為 **1080 × 1080 像素,格式只支援**JPG / JPEG與PNG
4. 上傳的圖片超過尺寸,要提供畫面進行剪裁後,在進行顯示,上傳的圖檔要在Server存檔備份
請提出你的修改計劃跟目前與可能會遇到的風險,有問題請暫停並且跟我確認,我看到計劃,並且我確認沒問題後後,在進行修改

這次 Codex 沒有立刻動工,而是先發現幾個會改變設計的問題。例如圖片究竟要放在 SQL Server、伺服器檔案系統,還是物件儲存空間?原圖要不要保留?重新上傳時,舊圖該覆寫還是留下歷史版本?
這些不是換一個類別名稱就能解決的小事。保存方式會影響資料庫容量、備份、權限與部署架構,必須由需求提出者決定。
一開始的需求是「把上傳檔案存在 Server 備份」,討論後改成只保存剪裁完成的圖片,而且重新上傳就覆寫舊值。這兩句代表完全不同的資料生命週期。如果只把最後一句留在聊天視窗裡,幾天後很容易又回到原本的理解。
因此,需要請 Codex 把已確認的內容寫成變更申請:
1. 可以
2. 我想修改一下,資料庫欄位只存修改過後剪裁的圖片,並且「只存最終圖片、覆寫舊值」,不用存原圖的備份檔了
3. 有
若有問題請再提出,如果沒問題,請把修改計劃,寫在Modify的資料夾裡面,並且產生ChangeRequest_YYYYMMDD的markdown,以後做修改規格追縱,檔案建立完成後,我確認過後才開始進行修改

變更申請裡特別註明:「存進資料庫」代表圖片會隨資料保存,不等於已經有獨立備份。因為新圖片會覆寫舊值,如果未來想還原舊圖,還要另外設計版本保存或資料庫備份策略。
這也是留下文件的價值。它不只記錄要做什麼,也會記錄這次刻意不做什麼。
審閱變更申請後,先提交這份文件,替規格留下存檔點。以下保留當時實際使用的 Prompt:
修幫我下一個Commit與Push,並且用一句話說明修改的內容
這個 Commit 不是宣告功能已完成,而是替「開工前雙方同意的版本」留下可追查的基準。
規格確認後,才把施工許可交給 Agent:
修改計劃已確認,請根據ChangeRequest_20260927.md進行修改,並且附上對應的測試案例與修正,並且同步目前的文間與測試案例進行測試
整段流程可以拆成兩個階段。第一個階段先釐清需求、建立分支,再把確認過的決定寫進 Change Request:

規格確認並留下存檔點後,第二個階段才開始修改程式、執行測試與準備 Pull Request:

這套流程看起來多繞了一圈,實際上是在成本較低的階段找問題。需求文件改一句話很快;等 API、資料庫與畫面都完成後才發現理解錯誤,修改成本就高得多。
Day23 產生測試案例,Day24 也實際碰過「測試通過,但畫面操作不合理」的情況。大頭貼功能同樣不能只看綠色勾勾。
自動化測試適合守住格式、尺寸、授權與 API 回應;手動測試則要真的操作剪裁畫面,看看滑鼠和手機觸控是否順手、錯誤訊息看不看得懂,以及新圖片有沒有在該出現的位置更新。
至少要實際走過這些情況:
Viewer 可以修改自己的大頭貼,不能修改別人的。Agent 可以幫忙執行檢查,最後的操作感受與需求取捨仍要由人判斷。
這次後端是 ASP.NET Core,因此也查看了 .NET 團隊整理的 Agent Skills。Skill 可以想成給 Agent 使用的工作手冊:它會針對某一類任務補上檢查步驟與注意事項,但不會取代需求、測試環境或人工審查。
這個 Repository 目前把能力拆成多個 Plugin。和 ProjectManagementWeb 比較直接相關的有:
| Plugin | 適合處理的工作 |
|---|---|
dotnet-aspnetcore |
ASP.NET Core API、Middleware、Endpoint 等 Web 開發 |
dotnet-data |
EF Core、資料存取與查詢效能 |
dotnet-test |
執行、產生與分析 .NET 測試 |
dotnet-msbuild |
Build 失敗、MSBuild 設定與效能問題 |
dotnet-diag |
效能調查、Trace、Dump 與執行期診斷 |
dotnet-upgrade |
.NET 版本升級與相容性調整 |
目前官方 Repository 建議 Codex CLI 透過 Plugin Marketplace 安裝。先加入 Marketplace:
codex plugin marketplace add dotnet/skills
接著在 Codex 輸入 /plugins,打開 dotnet-agent-skills 分頁,再依專案需要安裝 Plugin。不要看到清單很長就全部套用;例如這次要修改 ASP.NET Core API、EF Core 與測試,就先選與這三項工作有關的 Skill。
Skill 也不是品質保證書。Agent 說「已執行測試」時,仍要確認實際指令、測試數量與結果;如果 SQL Server 測試環境沒有啟動,Integration Test 被略過,就不能把它寫成全部通過。
軟體完成第一版後,需求繼續變動很正常。這次沒有直接叫 Codex 修改大頭貼功能,而是先建立功能分支,再把模糊想法整理成可審核的變更申請。確認圖片格式、權限、保存方式與不做的項目後,才讓 Agent 開始實作。
Git Flow 負責把不同工作隔開,Change Request 留下「為什麼這樣改」,測試與人工驗收則回答「結果能不能交付」。三者處理的是不同問題,少掉任何一個,都可能讓後續維護只能靠記憶猜測。
目前這些檢查仍需要人提醒 Agent 執行。下一篇會接著把重複的 Build、Test 與部署步驟交給 CI/CD,讓每次 Push 或 Pull Request 都走過同一套檢查。