Day 23 我已經把 Git 加進專案,也建立了第一個基準 commit。
現在每次有修改,都可以先用 Git 看差異,再決定要不要保留。
所以 Day 24 我想換一種方式使用 Claude Code:
不讓它直接寫程式,而是先幫我檢查程式。
也就是今天的主題:
Code Review。
今天一樣不新增 Web App 功能,也不急著修目前已知的問題。
主要想確認:
Claude 能不能看懂目前程式
能不能找到真正的問題
能不能區分問題和推測
能不能只 Review,不直接修改
我目前先把 Code Review 理解成:
程式寫完之後,再從另一個角度檢查目前的程式或這次修改有沒有問題。
不是只看:
程式能不能跑
還會看:
邏輯有沒有問題
輸入驗證有沒有漏
錯誤處理是否一致
修改範圍是否合理
有沒有不必要的重複
有沒有違反目前專案架構
Claude Code 很適合拿來協助這件事,因為它可以同時讀:
CLAUDE.md
Git 狀態
程式碼
git diff
再依照目前專案的規則去檢查。
以前遇到問題時,我可能直接說:
幫我修這段程式
這樣 Claude 通常就會開始改檔案。
但今天我刻意把:
Review
和:
修改
分開。
Day 24 的流程是:
先 Review
↓
找出問題
↓
判斷問題是不是真的
↓
再決定要不要修
而不是一看到問題就全部交給 Claude 修改。
一開始,我先讓 Claude Code 對目前已存在的程式做一次 Review。
主要閱讀:
CLAUDE.md
app.py
models/task.py
models/category.py
Claude 為了對照,也看了:
schema.sql
config.py
db.py
我這次特別要求:
不要修改任何檔案
不要執行 git add
不要執行 git commit
不要直接幫我修
Prompt:
Day 24 要進行 Code Review。
目前 Git working tree 是乾淨的,
所以這次不是 Review 未提交的 git diff,
而是先對目前已 commit 的程式做 Baseline Review。
請先閱讀 CLAUDE.md,並檢查:
- app.py
- models/
今天不要修改任何檔案,
不要執行 git add 或 git commit,
也不要直接幫我修問題。
請從以下角度 Review:
1. 有沒有明顯的程式邏輯問題
2. 表單輸入驗證是否完整
3. HTTP 400 / 404 的處理是否一致
4. Task status 的處理是否一致
5. due_date 的處理是否一致
6. Category 查詢與 category_id 的處理有沒有不一致
7. 有沒有明顯重複程式碼
8. 有沒有違反 CLAUDE.md 目前的架構限制
9. 有沒有目前可以先記錄、但不需要立刻修正的問題
請把結果分成:
- 已確認的問題
- 可能的風險
- 目前沒有問題的部分
每一項請附上對應檔案與原因。
不要因為看到問題就自行修改。
我原本在 Prompt 裡寫:
working tree 是乾淨的
但 Claude 實際查看 Git 後,發現:
CLAUDE.md 有未 commit 的 Day 23 更新
也就是我的前提其實不完全正確。
不過:
app.py
models/
沒有未提交差異,所以 Baseline Review 本身還是可以進行。
後來我也把 Day 23 的 CLAUDE.md 更新 commit 掉,讓工作區重新回到:
nothing to commit, working tree clean
這次經驗也讓我發現,Code Review 時 Claude 不應該只是照著 Prompt 裡的前提回答,最好還是先確認實際專案狀態。
這次 Claude 找出的內容不少,但不是每一項都代表「一定要修」。
我最後把結果整理成三類:
✓ 已確認的問題
△ 可能的風險
○ 目前只是觀察或未來維護事項
這樣比較不會把 Claude 提出的每個建議都當成 Bug。
目前 new_task() 和 edit_task() 都是直接取得:
request.form.get("title", "")
然後寫入資料庫。
雖然 HTML 表單有:
required
但這只是瀏覽器端限制。
如果用 Postman 或直接送 Request,還是可以繞過。
另外:
nullable=False
主要是避免資料庫收到 NULL,不能直接解決:
""
或純空白文字的問題。
所以這項是可以直接從目前程式碼確認的驗證缺口。
目前合法 status 有:
todo
in_progress
done
update_status() 已經有檢查:
if new_status not in Task.STATUS_LABELS:
abort(400)
但是:
new_task()
edit_task()
沒有做相同驗證。
所以目前不同入口對 status 的處理方式不一致。
這也是可以直接從程式碼確認的問題。
目前:
resolve_category_id()
查不到分類名稱時會回:
None
正常情況下,使用者選「未分類」時,這是合理行為。
但如果繞過前端,送進一個不存在的 category 名稱,它也會變成 None。
在 edit_task() 裡,這代表原本的分類可能被清成未分類。
所以目前可以確定:
查不到 category
→ category_id = None
但這是不是一定要改成 400,還要看之後希望系統怎麼處理非法分類名稱。
因此我把它放在:
✓ 行為已確認
△ 是否需要修正還沒決定
Claude 有提醒:
new_task()
edit_task()
目前會讓未驗證的 status 往資料庫走。
但「非法值最後到底會發生什麼」並不能只靠現在的程式碼直接確定。
Claude 提到實際結果可能和:
MySQL sql_mode
有關。
所以這部分不能寫成:
非法 status 一定造成某種結果
目前只能確定:
Flask 這一層沒有先驗證
資料庫實際怎麼處理,要真的送 Request 測過才能確認。
Claude 還注意到一個比較細的地方。edit_task() 大概是:
先修改 task.title
先修改 task.description
先修改 task.status
↓
呼叫 resolve_category_id()
↓
執行 Category 查詢
SQLAlchemy 在執行查詢前可能進行:
autoflush
把目前 session 中尚未 commit 的修改先送往資料庫。
因此如果前面已經放入非法 status,理論上可能在後面的查詢階段就先發生問題。
不過這次沒有實際測試,所以 Claude 自己也把它標成:
可能風險
尚未驗證
今天就先不改。
Claude 注意到:
description 空白
→ ""
due_date 空白
→ NULL
兩者都是可空欄位,但表示方式不同。
這是事實,不過目前沒有功能上的問題。
因為一個是文字欄位,一個是日期欄位,本來就不一定需要使用完全相同的空值表示方式。
所以這項先當作觀察,不列成 Bug。
現在合法 status 同時寫在:
schema.sql
Task.STATUS_LABELS
db.Enum(...)
三個地方都包含:
todo
in_progress
done
目前功能沒有問題。
只是如果以後新增第四個狀態,就有漏改其中一處的可能。
所以這比較像未來維護風險,不是 Day 24 一定要重構的東西。
目前 requirements.txt 只有套件名稱,沒有指定版本。
代表之後重新建立環境時:
pip install -r requirements.txt
可能取得和目前不同版本的套件。
這也是合理的 Review 發現,但不影響現在 Web App 功能,所以先記錄即可。
Claude 也注意到 POST 路由目前沒有 CSRF 保護。
但它同時有對照 CLAUDE.md:
本機自用
沒有登入
沒有部署
目前不使用 Flask-WTF
所以沒有把它直接列成目前必修項目。
這點對我來說也很重要。
Code Review 不應該變成:
只要大型 Web 專案常見的東西,就全部要求現在加入。
還是要看目前專案本身的範圍。
Claude 不只找缺點,也確認了一些現有設計。
例如 due_date 現在統一走:
parse_due_date()
因此:
空白
→ NULL
格式錯誤
→ 400
new_task() 和 edit_task() 使用同一個 helper,這部分處理是一致的。
另外:
edit
delete
status update
都使用:
Task.query.get_or_404()
不存在的任務會統一得到 404。
Day 20 已經抽出的:
resolve_category_id()
parse_due_date()
也確實減少了一些重複。
剩下 new_task() 和 edit_task() 的欄位讀取雖然相似,但目前只有兩處,而且程式還很簡單,所以沒有必要為了消除一點重複就再增加新的架構。
這次 Claude 也檢查了目前專案架構。
目前仍然沒有:
Application Factory
services/
routes/
Flask-WTF
Flask-Migrate
AJAX
Claude API
路由仍然放在:
app.py
資料庫還是只有:
categories
tasks
也沒有提前加入 AI 欄位。
所以這次 Review 沒有因為想把程式「變得更完整」,就要求我提前擴大架構。
前面做的是:
Baseline Review
→ 檢查目前整體程式
但 Day 24 還想實際測一次:
Diff Review
→ 只檢查這一次修改
所以我先把 Day 23 的變更 commit,確認 Git 回到乾淨狀態。
接著故意在 CLAUDE.md 做一個非常小的修改。
原本:
## 目前已完成天數
暫時改成:
## 目前已經完成的天數
只改這一行。
先:
git status
Git 會顯示 CLAUDE.md 被修改。
接著:
git diff
就會看到:
-## 目前已完成天數
+## 目前已經完成的天數
這個例子很小,但剛好適合拿來測 Code Review。
如果 git diff 內容比較多,Git 可能會進到分頁檢視畫面。
畫面底下可能出現:
(END)
這時候要退出,直接按:
q
就會回到 PowerShell。
所以我先記:
git diff
↓
查看差異
↓
按 q 離開
如果 diff 很短,有時會直接顯示完並回到命令列,就不需要另外按 q。
接著我給 Claude:
請 Review 目前尚未 commit 的修改。
先查看 git status 和 git diff。
不要修改任何檔案,
不要執行 git add 或 git commit。
請告訴我:
1. 這次改了哪個檔案
2. 實際改了什麼
3. 這個修改是否合理
4. 有沒有影響專案功能或規則
只做 Review,不要修正。
這次 Review 的範圍非常明確:
只看現在這次未 commit 修改
Claude 確認:
只有 CLAUDE.md 被修改
沒有 untracked 檔案
diff 只有一行
它也判斷這個修改:
不影響 Web App 功能
不影響技術棧
不影響架構
不改變原本規則內容
但它還注意到一個細節。
雖然只是把:
目前已完成天數
改成:
目前已經完成的天數
但 CLAUDE.md 其他地方仍然使用:
目前已完成天數
作為這個區塊的名稱。
所以 Claude 判斷:
內容本身合理
但文件內的命名變得不一致
如果真的要改標題,就應該同步其他引用;否則就維持原名稱。
這次 Review 沒有把它誇張成嚴重 Bug,而是很清楚地區分:
功能沒有問題
文件一致性需要注意
這正是我想測的效果。
這次 Prompt 已經寫:
只做 Review
不要修正
Claude 也確實沒有改檔案。
我自己把測試文字改回:
## 目前已完成天數
再執行:
git status
確認工作區重新回到乾淨狀態。
實際做過一次之後,我比較能分清楚兩者用途。
Baseline Review
→ 看目前整體程式狀態
→ 適合找既有問題
Diff Review
→ 只看目前這次修改
→ 適合確認這次改動有沒有問題或超出範圍
它們不是互相取代。
如果正在整理既有專案,可以做 Baseline Review。
如果剛完成一個功能,則更適合 Review git diff。
今天另一個很重要的地方,是 Claude 有把一些內容明確標成「推測」。
例如:
非法 status 最後送到 MySQL
實際會發生什麼?
只讀程式碼還不能完全回答。
Code Review 能幫我找:
值得注意的地方
可能的邏輯問題
維護風險
修改範圍
但真正的執行結果還是要測。
所以之後比較完整的流程會是:
Claude Code 修改
↓
git status
↓
git diff
↓
Code Review
↓
實際測試
↓
確認結果
↓
git add
↓
git commit
而不是:
Claude 說沒問題
↓
直接 commit
今天實際做了兩種 Review,最後可以整理成:
Baseline Review ✓
Diff Review ✓
Claude 能找到已知驗證缺口 ✓
能區分確認問題和未驗證風險 ✓
能對照 CLAUDE.md 的架構限制 ✓
能發現 Prompt 前提和實際 Git 不一致 ✓
能指出小型 diff 的文件一致性問題 ✓
沒有擅自修改檔案 ✓
沒有擅自 git add / git commit ✓
知道 git diff 可以按 q 離開 ✓
測試後 working tree 恢復乾淨 ✓
做到今天,我開始發現 Claude Code 不一定只能當:
寫程式的人
它也可以當:
規劃者
除錯助手
Code Reviewer
而且不同角色,要使用不同的 Prompt。
Code Review 最重要的也不是:
Claude 找越多問題越好
而是:
它找到的問題,有沒有真的被程式碼、Git diff 和目前專案規則支持。
Day 24 沒有新增 Web App 功能。
但現在我的開發流程又多了一層:
修改前確認 Git
↓
Claude Code 修改
↓
git diff 看真正差異
↓
Claude Code 做 Review
↓
自己判斷問題是否成立
↓
實際測試
↓
最後才 commit
Day 23 解決的是:
Claude 到底改了什麼?
Day 24 再往前一步:
這些修改到底有沒有問題?
接下來,才要正式進入這個專案最重要的功能之一。
前面的任務新增、編輯、刪除、狀態、分類和資料庫都已經建立起來。
下一步要讓「AI 任務管理」裡的 AI 真正出現。