標籤: AI 輔助開發

  • 會用 vs 不會用 Claude Code:醫療、股市、電商三場景對比

    重點摘要

    • 差距不在「會不會用 AI」,在「有沒有給 AI 做事的結構」
    • 不會用的人:一句話丟需求 → 結果跑偏 → 多輪修正 → 累積沮喪
    • 會用的人:CLAUDE.md + 設計文件 + 分段驗證 → 第一次就對
    • 三個真實場景(醫療 / 股市 / 電商)示範具體差距

    「Claude Code 對我沒用,我試過,它做出來的東西都不對。」

    這句話我聽過很多次。幾乎每次深入問,問題都不在 Claude,在提問的方式。

    這篇文章用三個真實的軟體開發場景,直接模擬「不會用的人」和「會用的人」各自怎麼做,讓你看清楚差距在哪裡。

    核心差距:有沒有給 AI 做事的結構

    不會用 Claude Code 的人,把它當成「很聰明的搜尋引擎」,問一句,期待完美答案。

    會用的人,把它當成「需要完整簡報才能開工的新進工程師」:你給的資訊越清楚,他做出來的東西越準確。

    差距的本質是:你的輸入有沒有結構

    場景一:醫療預約系統(門診掛號)

    痛點

    診所要做線上掛號,需要處理:醫師排班、假日停診、同時段人數上限、患者重複掛號防止。每個規則都有例外,例外裡還有例外。

    不會用的人怎麼做

    直接開口:

    幫我寫一個門診預約系統的 API,要能掛號、取消、查詢。

    Claude 給了一個乾淨的 REST API,CRUD 完整,code 看起來不錯。

    開始整合後發現問題一個接一個:

    • 沒處理同時段上限(診所每診次只收 20 人,API 沒有 capacity 邏輯)
    • 沒有重複掛號檢查(同一個患者可以掛同一診次兩次)
    • 沒有假日判斷(系統不知道什麼是醫院休診日)
    • 時區沒處理(台灣 UTC+8,stored as UTC,前端顯示全錯)

    開始補需求:「喔對,要加上每診次人數上限」→ Claude 修改。「還有重複掛號要擋掉」→ Claude 再改。「假日要停診」→ 再改。每次修改都可能動到之前改好的邏輯,三輪之後代碼開始難以追蹤。

    結果:8 小時,仍有未發現的 bug,信心不足。

    會用的人怎麼做

    第一步:CLAUDE.md 裡早就寫好領域規則

    ## 醫療領域規則
    - 所有時間以 UTC+8 儲存,API 回應包含 timezone 欄位
    - 患者 ID 採用身分證字號格式,需驗證格式(字母+9位數字)
    - 診次 (session) 為最小預約單位,每診次有 capacity 上限
    - 相同患者在同一診次只能有一筆有效預約
    
    ## 錯誤處理標準
    - 業務邏輯錯誤:HTTP 422 + { code, message, field }
    - 驗證錯誤:HTTP 400 + 同上格式

    第二步:先寫設計文件(20 分鐘)

    # 功能:門診掛號 API
    
    ## 輸入
    { patientId: string, sessionId: string }
    
    ## 驗證順序(按此順序,遇錯即停)
    1. patientId 格式是否合法
    2. sessionId 是否存在且為未來時間
    3. 該診次是否已達 capacity
    4. 該患者是否已有此診次的有效預約
    
    ## 邊界條件
    - capacity 滿:422,code: SESSION_FULL
    - 重複掛號:422,code: DUPLICATE_BOOKING
    - 患者格式錯:400,code: INVALID_PATIENT_ID
    - 診次已過去:422,code: SESSION_EXPIRED
    
    ## Done When
    - 所有邊界條件有單元測試
    - integration test 驗證完整掛號流程
    - 0 TypeScript errors

    第三步:分段給任務

    請先閱讀 CLAUDE.md 和這份設計文件。
    閱讀完告訴我你的理解,特別是驗證順序的邏輯,再開始實作。
    先只實作 validateBooking() 函數和對應單元測試,不要動 API 層。

    確認驗證邏輯正確後,再說「現在依照這個驗證函數實作 POST /bookings endpoint」。

    結果:2.5 小時,第一次就通過所有測試,零修改。

    場景二:股市回測系統

    痛點

    想驗證一個交易策略:當 5 日均線上穿 20 日均線時買進,死亡交叉時賣出。聽起來簡單,但台股有漲跌停、只能在交易日交易、最小交易單位是 1000 股、手續費和證交稅要扣掉,每個細節都會影響回測結果。

    不會用的人怎麼做

    幫我寫一個台股回測程式,策略是 5 日均線上穿 20 日均線買進,死叉賣出。

    Claude 給了一個 Python 回測,用 pandas 計算均線,邏輯清楚。跑了一下,報酬率看起來很漂亮。

    仔細看才發現:

    • 買賣都用收盤價,但實際上收盤價買不到(要用隔日開盤)
    • 沒有漲跌停限制,假設任何價格都能成交
    • 沒扣手續費(0.1425%)和證交稅(0.3%)
    • 沒有最小交易單位,0.1 張也買
    • 跑到非交易日(週末)的資料也在交易

    這些問題加起來,讓回測結果虛報了約 30–40%。一個看起來賺錢的策略,修正後可能是虧損的。

    結果:6 小時修修改改,最後不確定結果是否可信。

    會用的人怎麼做

    設計文件把所有台股規則先寫清楚:

    # 功能:台股均線策略回測引擎
    
    ## 市場規則(必須完整實作)
    - 交易日:排除週末 + 台灣國定假日(用 holidays-tw 套件)
    - 成交價:訊號發生在收盤,執行在「隔一個交易日開盤價」
    - 漲跌停:每日最大漲跌幅 ±10%,超過範圍無法成交,標記 LIMIT_HIT
    - 最小交易單位:1000 股,不足整張無法下單
    - 手續費:買賣各 0.1425%(可設定),最低 20 元
    - 證交稅:賣出 0.3%(ETF 為 0.1%)
    
    ## 回測輸出格式
    {
      total_return_pct: float,    # 扣除所有費用後
      trades: [{ date, action, price, shares, cost, tax, net_pnl }],
      unfilled: [{ date, reason }],   # LIMIT_HIT 等無法成交紀錄
      sharpe_ratio: float,
      max_drawdown_pct: float
    }
    
    ## 邊界條件
    - 漲停無法賣出(LIMIT_HIT_SELL)
    - 跌停無法買入(LIMIT_HIT_BUY)
    - 資金不足一張:跳過,記錄 INSUFFICIENT_FUNDS
    - 最後持倉:回測結束日強制以收盤價平倉

    提示方式:

    請先閱讀這份設計文件,告訴我:
    1. 成交時間點的邏輯(訊號日 vs 執行日)你的理解
    2. 漲跌停時的處理流程
    
    確認理解正確後,先只實作 TaiwanMarketRules 類別和測試,
    包含漲跌停判斷、交易日判斷、手續費計算三個方法。
    不要實作策略邏輯或回測引擎。

    結果:3 小時,回測結果可信,且有完整的無法成交紀錄供分析。

    場景三:電商金流串接(綠界 ECPay)

    痛點

    要串接台灣最常用的金流服務商,支援信用卡一次付清 + ATM 虛擬帳號。牽涉到加密簽章驗證、非同步回調(ReturnURL / OrderResultURL)、以及各種付款失敗情境。

    不會用的人怎麼做

    幫我串接綠界金流,支援信用卡和 ATM 付款。

    Claude 寫了一個串接,看起來完整。測試環境跑起來。上線後三天,開始收到客訴:

    • 付款成功但訂單沒更新(沒有正確處理綠界的非同步通知)
    • ATM 超時未付款,訂單卡在「待付款」沒有自動取消
    • CheckMacValue 驗簽偶發失敗(特殊字元的 URL encode 方式不對)
    • 退款流程完全沒實作(以為付款和退款是同一組 API)

    每個問題單獨看都能修,但修一個又會影響另一個。金流 bug 是最難測試的,因為要模擬真實付款行為。

    結果:上線後 bug,緊急修補兩天,損失用戶信任。

    會用的人怎麼做

    先用 Plan Mode 讓 Claude 梳理所有狀態流:

    【背景】
    我要串接綠界 ECPay,使用 Node.js + PostgreSQL,
    CLAUDE.md 中規定所有金流操作要記 audit log。
    
    【目標】
    支援信用卡一次付清和 ATM 虛擬帳號,訂單狀態要與付款狀態完全同步。
    
    【約束條件】
    - 不能有「已付款但訂單未更新」的狀態
    - ATM 超過 3 天未付款自動取消訂單並釋放庫存
    - CheckMacValue 驗簽失敗必須記錄並告警
    
    請制定實作計劃,列出所有需要處理的狀態流轉,
    等我確認計劃後再開始實作。

    Claude 在計劃中列出了 14 個狀態節點,包含「非同步通知重複到達」、「驗簽失敗的處理」這些不明顯的情境。確認計劃後再開始做。

    設計文件特別標明的邊界條件:

    ## 邊界條件(金流特有)
    - ReturnURL(非同步)和 OrderResultURL(同步)可能「都」被呼叫
      → 用 idempotency key 確保同一筆交易只更新一次訂單
    - CheckMacValue 驗簽:URL encode 順序必須按綠界規範(非標準 encodeURIComponent)
      → 測試案例需包含含特殊字元的 MerchantTradeNo
    - ATM 逾期:用 pg-cron 排程,不要依賴前端觸發
    - 退款:獨立 API,與付款 API 完全分離,需要人工審核 flag

    結果:4 小時,上線零 bug,audit log 完整。

    差距總結

    面向 不會用的人 會用的人
    提示方式「幫我做 X」「背景 + 目標 + 約束條件 + 邊界條件」
    領域規則每次用到才補說寫進 CLAUDE.md,一次設定永久生效
    邊界條件做完後才發現沒處理設計文件裡最前面就列清楚
    複雜任務一次丟,結果跑偏再修Plan Mode 確認方向,分段執行
    驗證方式全部做完再整體測試每段完成後先確認,錯誤早期發現
    對話輪數8–15 輪2–4 輪
    結果品質能跑,但邊界不完整完整,測試覆蓋所有邊界

    為什麼大多數人卡在「不會用」

    不是因為懶,是因為直覺錯了。

    我們習慣搜尋引擎:問一句,得到答案。Claude Code 不是搜尋引擎,它是一個需要簡報才能開工的工程師。你給的資訊越完整,它做出來的東西越準確。

    轉換這個直覺需要時間,但一旦轉過來,你就不會想回頭了。

    從下一個任務開始,試著在開口前先回答三個問題:

    1. 這個功能的輸入和輸出各是什麼格式?
    2. 哪些邊界條件會讓它失敗?
    3. 我怎麼確認它做對了?

    把這三個問題的答案寫下來,你的 Claude Code 使用效果會立刻不一樣。

    常見問題

    Q:每次都要先寫設計文件,不會很花時間嗎?

    一份最小版設計文件 20 分鐘。省下的多輪修改至少 2–4 小時。這筆帳很好算。

    小功能(一個函數、修一個 bug)不需要設計文件,直接做。設計文件是為了「有多個邊界條件、或跨越兩層以上架構」的任務。

    Q:CLAUDE.md 不是每個專案都要重寫一遍嗎?

    寫一次,維護成本低。每次發現 Claude 做了一個你不喜歡的決定,把那條規則加進 CLAUDE.md,下次就不會再發生。它是越用越省力的資產。

    Q:我的需求很複雜,文件要寫到多詳細?

    詳細到「可以讓另一個工程師依照這份文件實作,不需要問你問題」。如果你寫完文件還是覺得有地方模糊,那就是還有沒想清楚的需求,先想清楚再開始比較省事。

    從不會用到會用:各情境的具體升級路徑

    看完上面三個場景,你可能知道差距在哪,但還不知道今天要改什麼。這一節給你一條明確的路,從第一步到進階,每步都有可以直接複製的東西。

    第一步:今天就能做到(不需要任何準備)

    在你現在的任何提示最後加上這一句:

    先告訴我你的理解和假設,再開始實作。

    就這一句。它會讓 Claude 在動手前先說出它的假設,你可以在它寫出一堆錯誤代碼前糾正它。成本 0,效果立竿見影。

    三個情境的具體升級示範:

    醫療場景:Level 0 → Level 1

    不會用(Level 0) 初步會用(Level 1)
    幫我寫門診預約系統(見下方)
    幫我寫門診掛號的 API。
    
    輸入:{ patientId: string, sessionId: string, phone: string }
    輸出:{ bookingNo: string, status: "SUCCESS" | "FULL" | "DUPLICATE" }
    
    必須處理:
    - 同一診次超過容量上限 → 回傳 FULL
    - 同一患者重複掛同一診次 → 回傳 DUPLICATE
    - 所有時間以 UTC+8 處理
    
    先告訴我你的理解,特別是這三種情況你打算怎麼處理,再開始實作。

    改變了什麼:加了輸入輸出格式、三個邊界條件、確認步驟。這 5 分鐘的準備,省掉事後發現「沒處理重複掛號」的 2 小時修改。

    股市場景:Level 0 → Level 1

    幫我寫台股均線回測。策略:5日均線上穿20日均線買進,死叉賣出。
    
    台股特有規則(全部都要實作):
    - 訊號發生在收盤,執行在隔交易日開盤價(不是同日收盤)
    - 漲跌停 ±10%,超過無法成交,記錄 LIMIT_HIT
    - 手續費:買賣各 0.1425%,最低 20 元
    - 證交稅:賣出 0.3%
    - 最小交易單位 1000 股,不足不下單
    
    先告訴我這些規則你的理解,特別是成交時間點的邏輯,再開始寫。

    電商金流場景:Level 0 → Level 1

    幫我串接綠界 ECPay,支援信用卡一次付清。
    
    必須處理的情況:
    - ReturnURL(非同步)和 OrderResultURL(同步)可能都會被呼叫,
      同一筆交易只能更新訂單一次(要有 idempotency 機制)
    - CheckMacValue 驗簽失敗:記 log,不更新訂單,回傳 0|Error
    - 付款成功後訂單狀態必須立刻更新
    
    先告訴我你打算怎麼處理「非同步和同步通知都到達」這個情況,再開始實作。

    第二步:下週可以做到(CLAUDE.md)

    把你的領域規則寫成一個檔案,放在專案根目錄,命名 CLAUDE.md。之後每次對話都不用再重複說這些規則。

    先從最小版開始,15 分鐘寫完:

    # 專案規則
    
    ## Tech Stack
    [填你用的技術]
    
    ## 這個領域的特殊規則
    [把你每次都要補充說明的規則寫在這裡]
    例:
    - 台股交易日排除週末 + 台灣國定假日
    - 醫療系統所有時間 UTC+8
    - 金流驗簽失敗一律記 log 不更新訂單
    
    ## 代碼標準
    [你每次都要糾正的習慣寫在這裡]
    例:
    - 禁止 any 類型
    - 每個函數必須有對應測試
    - API 錯誤格式統一:{ code, message, field }
    
    ## 邊界條件規則
    [這個專案特有的邊界處理方式]

    寫好之後,下次開口前說「請先讀 CLAUDE.md」或什麼都不用說(Claude Code 會自動載入)。

    第三步:一個月後的進化(設計文件 + Plan Mode)

    當你習慣 Level 1 之後,下一步是在動手前多寫一份設計文件。這份文件不是給人看的,是給 Claude 看的,20 分鐘寫完,節省的是事後 4–6 小時的修改。

    設計文件的最小格式:

    # 功能:[名稱]
    
    ## 輸入 / 輸出
    輸入:[JSON 範例]
    輸出:[JSON 範例]
    
    ## 邊界條件(必須處理)
    - [條件 A] → [預期行為]
    - [條件 B] → [預期行為]
    
    ## 完成定義
    - [ ] 所有邊界條件有對應單元測試
    - [ ] TypeScript 0 errors

    有了設計文件之後,任務的啟動提示變成:

    請先閱讀 CLAUDE.md 和 [設計文件名]。
    閱讀完告訴我你的理解,特別是邊界條件部分。
    確認後先只實作 [最小單元],不要動其他層。

    當任務更複雜(跨 5 個以上文件、不可逆的架構改動),改用 Plan Mode 啟動:

    請先制定實作計劃,列出方案選項和取捨,等我確認後再開始執行。
    階段 做什麼 時間投資 節省的來回
    Level 0直接說需求00
    Level 1(今天)加輸入/輸出/邊界 + 確認步驟5 分鐘/次2–4 輪
    Level 2(下週)CLAUDE.md 寫入領域規則15 分鐘(一次性)每次省 1–2 輪
    Level 3(一個月後)設計文件 + Plan Mode20 分鐘/功能第一次就對
  • Claude Code 系列文 (5/5):實戰 — 3 天完成 Taiwan Invoice 系統

    ⚡ 重點摘要

    • Day1規劃6小時:需求+CLAUDE.md+設計文檔+Hook
    • Day2實施8小時:Claude一次到位,200+測試通過
    • Day3部署4小時:安全審查+文檔+上線
    • 總計18小時,vs傳統方式40-50小時

    前提:讀過第 1-4 篇,理解整個工作流 目標:看一個真實的「一人公司 3 天完成功能」案例 收穫:知道如何套用到你的項目


    案例背景

    公司:一人 SaaS 公司(會計軟件) 需求:完整的台灣統一發票系統 期限:3 天內完成 MVP 資源:1 個人 + Claude Code 目標:一次到位,最少改動


    🗓️ Day 1:規劃 + 準備(6 小時)

    上午(3 小時):理清需求

    # Taiwan Invoice System - Requirement Doc
    
    ## 為什麼要做
    目前手工開發票,容易出錯,無法追蹤
    
    ## 用戶故事
    "As a freelancer with 50+ monthly invoices,
     I want to generate invoices in Taiwan GUN format,
     so I can legally submit to tax authority"
    
    ## MVP Scope(3 天內)
    ✅ 建立發票 (可編輯草稿)
    ✅ 查看發票列表
    ✅ 匯出 PDF (GUN 格式)
    ✅ 基本驗證 (金額、格式)
    
    ⏳ Phase 2 (1 個月後)
    - 批量操作
    - 進階篩選
    - 政府系統整合

    花時間:30 分鐘(邊想邊寫)

    中午(3 小時):建立項目規則 + 設計

    建立 CLAUDE.md

    # Taiwan Invoice System
    
    ## Tech Stack
    - Frontend: React 18 + TypeScript
    - Backend: Node.js + Express
    - Database: PostgreSQL
    - Styling: Tailwind CSS
    
    ## Code Standards
    - TypeScript strict mode
    - Test coverage > 80%
    - JSDoc for public API
    - Prettier + ESLint
    
    ## Business Rules (Critical!)
    
    ### Invoice Format (GUN)
    必須符合台灣政府格式:
    - 發票號碼:8 位數 (格式:AAA12345)
    - 序列必須連續
    - 日期:民國年 (e.g., 112/03/25)
    - 必填欄位:公司統編、客戶統編、品項、金額
    
    ### Tax Rules
    - 標準稅率:5% (大部分)
    - 零稅率:0% (出口商品)
    - 免稅:0% (政府單位等)
    - 進項稅:同月內計算,超過月份無法扣
    
    ### Immutability
    已提交的發票不可修改,只能作廢重新開
    
    ## Architecture Decision
    使用 Strategy Pattern 處理不同稅率
    → 易於新增新稅種
    
    ## Important
    必須通過以下檢查:
    - 發票序列連續
    - 日期格式正確 (民國年)
    - 金額計算正確
    - 必填欄位都有

    花時間:1 小時

    寫設計文檔

    # Feature: Create Invoice
    
    ## User Flow
    1. 使用者點「新建發票」
    2. 看到表單:日期、客戶、品項清單、稅率
    3. 填完按「儲存為草稿」
    4. 發票編號自動產生 (取自上一張+1)
    5. 顯示「草稿已保存」訊息
    
    ## Data Structure
    ```typescript
    interface Invoice {
      id: UUID;
      invoiceNumber: string;      // e.g., "AAA00001"
      invoiceDate: Date;          // ROC year format
      companyId: string;          // 公司統編
      companyName: string;
      customerId: string;         // 客戶統編
      customerName: string;
      items: InvoiceItem[];       // 品項清單
      taxRate: 5 | 0;            // 稅率
      subtotal: number;
      taxAmount: number;
      total: number;
      status: "DRAFT" | "SUBMITTED" | "VOIDED";
      createdAt: Date;
      updatedAt: Date;
    }
    
    interface InvoiceItem {
      id: UUID;
      name: string;
      quantity: number;
      unitPrice: number;
      amount: number;             // qty * price
    }
    ```
    
    ## API
    ```
    POST /api/invoices
    {
      invoiceDate: "2024-03-25",
      customerId: "12345678",
      customerName: "ABC Company",
      items: [{name, quantity, unitPrice}, ...],
      taxRate: 5
    }
    → 201 Created
    {
      id: "uuid",
      invoiceNumber: "AAA00123",
      ...
    }
    
    GET /api/invoices/:id
    → 返回完整發票資料
    
    PUT /api/invoices/:id
    {...updates}
    → 200 OK (只有 DRAFT 狀態可修改)
    ```
    
    ## Validation
    - [ ] 發票號碼格式:AAA + 5 位數
    - [ ] 客戶統編:8 位數
    - [ ] 日期:不能是未來日期
    - [ ] 品項至少 1 個
    - [ ] 金額都是正數
    - [ ] 稅率只能是 5 或 0
    
    ## Edge Cases
    - 新使用者,沒有上一張發票?→ 自動從 AAA00001 開始
    - 修改數量後,金額要自動計算 ✅
    - 刪除品項要更新小計 ✅
    - 同一天多張發票?→ 號碼自動遞增 ✅
    
    ## Acceptance Criteria
    - [ ] 表單能填入資料
    - [ ] 發票自動編號
    - [ ] 計算正確
    - [ ] 驗證有效
    - [ ] 錯誤訊息清晰(中文)
    - [ ] 所有測試通過

    花時間:1.5 小時

    設置 Hook(複製 settings.json):

    花時間:30 分鐘

    下午成果

    Day 1 完成:
    ✅ 需求清晰(RFC 格式)
    ✅ CLAUDE.md 完成(規則明確)
    ✅ 設計文檔完成(API + UI + 驗證規則)
    ✅ Hook 已設置(自動格式化和測試)
    ✅ Git 提交
    
    Code ready for Claude!

    🗓️ Day 2:實施 + 驗證(8 小時)

    早上(4 小時):Claude 實施後端 + API

    Prompt 給 Claude

    這是我們的 Taiwan Invoice 系統。
    
    CLAUDE.md(規則):[貼上 CLAUDE.md]
    
    設計文檔(需求):[貼上設計文檔]
    
    請按照設計實施:
    1. 建立 Invoice 數據模型
    2. 建立 API endpoints (POST /invoices, GET /invoices/:id, PUT)
    3. 實施驗證邏輯
    4. 寫單元測試(coverage > 80%)
    
    注意:台灣稅法很嚴格,邊界情況要測試完整。

    Claude 做的事

    • 自動讀 CLAUDE.md(知道 TypeScript strict,要測試)
    • 自動讀設計文檔(知道確切的 API 格式和驗證規則)
    • 一次性實施,不猜測
    • 自動加測試(因為 CLAUDE.md 要求)
    • 自動格式化和 lint(Hook 搞定)

    結果(2 小時):

    ✅ models/Invoice.ts (50 行)
    ✅ services/InvoiceService.ts (200 行)
    ✅ routes/invoices.ts (80 行)
    ✅ __tests__/invoiceService.test.ts (150 行,30 個測試)
    
    所有測試通過 ✅
    代碼 lint 通過 ✅
    覆蓋率 > 85% ✅

    中午(2 小時):Claude 實施前端 + 表單

    Prompt

    前端現在需要:
    1. 發票新建表單(日期、客戶、品項清單)
    2. 發票列表頁面
    3. 發票詳情頁面
    
    用設計文檔中的 API,請實施 React 組件。
    
    要點:
    - 表單驗證(錯誤訊息用中文)
    - 品項動態新增/刪除
    - 自動計算小計和稅額
    - 載入中和錯誤狀態要顯示

    結果(2 小時):

    ✅ components/InvoiceForm.tsx (300 行)
    ✅ pages/InvoiceList.tsx (150 行)
    ✅ pages/InvoiceDetail.tsx (200 行)
    ✅ hooks/useInvoice.ts (100 行,API 調用)
    ✅ __tests__/InvoiceForm.test.tsx (200 行)
    
    測試通過 ✅
    外觀符合預期 ✅

    下午(2 小時):整合測試 + Bug 修復

    做法

    1. 連接前後端
    2. 手動測試端到端流程
    3. 發現 2 個小 bug(日期格式,驗證訊息)
    4. Claude 修復
    5. 再測一遍,沒問題

    結果

    ✅ 前後端連接
    ✅ 表單能提交
    ✅ 發票能保存到 DB
    ✅ 列表能顯示
    ✅ 所有驗證工作
    ✅ 錯誤訊息清晰

    Day 2 成果

    ✅ 後端 API 完成
    ✅ 前端 UI 完成
    ✅ 單元測試通過(200+ 測試)
    ✅ 整合測試通過
    ✅ 0 console.log,0 TODO
    ✅ 準備上線

    🗓️ Day 3:優化 + 部署(4 小時)

    早上(1 小時):性能 + 安全檢查

    # 代碼審查
    npm run lint           # 0 錯誤 ✅
    npm test              # 200+ 測試通過 ✅
    npm run type-check    # TypeScript: 0 錯誤 ✅
    
    # 安全檢查
    npm audit             # 0 高風險漏洞 ✅
    grep -r "console.log" src/   # 0 結果 ✅
    grep -r "TODO" src/          # 0 結果 ✅

    中午(1 小時):文檔 + README

    # Taiwan Invoice System
    
    ## Features
    - ✅ Create/Edit/View invoices in GUN format
    - ✅ Automatic invoice numbering
    - ✅ Tax calculation (5% / 0% / exempt)
    - ✅ Form validation (Taiwan rules)
    - ✅ PDF export (coming v1.1)
    
    ## API
    [自動生成 API 文檔]
    
    ## Setup
    ```bash
    npm install
    npm run dev
    ```
    
    ## Testing
    ```bash
    npm test
    npm run test:coverage
    ```
    
    ## Deployment
    [部署指令]

    下午(2 小時):部署 + 監控

    # 部署
    npm run build         # 0 警告
    deployment-script    # 部署到 staging
    
    # 煙霧測試
    curl http://staging/api/invoices
    # 確保 API 正常
    
    # 監控設置
    [設定錯誤告警]
    [設定性能監控]

    Day 3 成果

    ✅ 代碼審查通過
    ✅ 安全檢查通過
    ✅ 文檔完整
    ✅ 部署到 Staging
    ✅ 煙霧測試通過
    ✅ 準備上線

    📊 3 天總結

    時間分配

    Day 1 規劃:6 小時
      ├─ 需求文檔:30 min
      ├─ CLAUDE.md:1 hour
      ├─ 設計文檔:1.5 hours
      ├─ Hook 設置:30 min
      └─ Git 提交:30 min
    
    Day 2 實施:8 小時
      ├─ 後端實施 + 測試:4 hours
      ├─ 前端實施 + 測試:2 hours
      ├─ 整合 + Bug 修復:2 hours
      └─ 無重複改動 ✅
    
    Day 3 優化:4 小時
      ├─ 性能 + 安全:1 hour
      ├─ 文檔:1 hour
      ├─ 部署 + 測試:2 hours
      └─ 準備上線
    
    總計:18 小時 = 2.25 天工作量

    成果

    代碼行數:~1500 行(含測試)
    測試數:200+ 個
    測試覆蓋率:85%+
    Bug 數:0 個(在 staging)
    改動次數:0 次(一次到位)
    
    典型方式的對比:
    傳統(沒規劃):40-50 小時,改 5-6 次
    規劃優先(本案例):18 小時,0 次改動

    關鍵成功因素

    因素為什麼重要這次是否做到
    CLAUDE.mdClaude 知道規則,不猜測
    設計文檔Claude 知道確切需求,一次對
    Hook自動化質量檢查,省手動操作
    TypeScript類型安全,邊界情況早發現
    完整測試回歸測試保證不破壞舊功能
    Git 提交每個功能清楚的 commit

    🎯 如何套用到你的項目

    Step 1:這週做

    • ☐ 為你的項目寫 CLAUDE.md(1 小時)
    • ☐ 選一個新功能,寫設計文檔(30 分鐘)
    • ☐ 給 Claude,看效果

    Step 2:下週做

    • ☐ 設置 Hook(15 分鐘)
    • ☐ 再試 2 個功能用設計文檔
    • ☐ 感受時間節省

    Step 3:成習慣

    • ☐ 所有新功能都先寫設計文檔
    • ☐ Hook 自動化所有品質檢查
    • ☐ CLAUDE.md 定期更新

    💡 一人公司老闆應該學到的

    1. 規劃比實施更值得

    傳統思維:「趕快寫代碼!」
    結果:寫很多,改很多,還是有 bug
    
    正確思維:「花 2 小時規劃,用 8 小時實施」
    結果:代碼一次對,沒有重複

    一人公司必須這樣思考,因為時間最貴。

    2. 文檔不是累贅,是投資

    成本:30-60 分鐘寫設計文檔
    收益:省 6-8 小時改動
    
    ROI = 600-800%

    最好的投資

    3. 自動化不是選項,是必須

    每週 5 小時手動 lint/test
    一年 260 小時
    相當於 1.5 個全職開發者成本
    
    用 15 分鐘設置 Hook,省這麼多

    不設置 Hook 的一人公司,在浪費金錢

    4. 一個人不代表不能有系統

    一人公司有一個優勢:決策快
    
    用 CLAUDE.md + 設計文檔 + Hook
    建立「個人系統」:
    - 代碼風格一致
    - 質量有保證
    - 規律可預測
    - 未來能擴招
    
    這是一個小公司變成可擴展企業的基礎。

    📈 一人公司的進化路徑

    Month 1:學習 (讀這 5 篇文章,試一個功能)
    Month 2:習慣 (所有新功能都用規劃優先)
    Month 3:系統 (CLAUDE.md + Hook 成為日常)
    Month 4-6:收穫 (月開發速度 ×3, bug ÷2)
    Month 6+:擴招 (有文檔,新人能快速上手)
    
    最後變成一個「可擴展的一人公司」
    而不是「永遠只能一人」的公司

    核心觀點回顧

    ┌─────────────────────────────────────┐
    │ 一人公司的黃金工作流                │
    ├─────────────────────────────────────┤
    │ 規劃(30%)                         │
    │  ├─ CLAUDE.md:寫一次,永遠用      │
    │  └─ 設計文檔:每功能寫一份          │
    │     ↓                                │
    │ 實施(50%)                         │
    │  ├─ Claude 一次對                  │
    │  └─ Hook 自動檢查                  │
    │     ↓                                │
    │ 驗收(20%)                         │
    │  ├─ 測試自動通過                   │
    │  └─ 文檔已完整                     │
    │     ↓                                │
    │ 上線                               │
    │                                    │
    │ 結果:                              │
    │ - 時間 -70%                        │
    │ - Bug -80%                         │
    │ - 心理壓力 -90%                    │
    └─────────────────────────────────────┘

    最後的話

    這個系列文教你的不是「怎麼用 Claude Code」

    而是「怎麼用 Claude Code 作為一人公司老闆活得更輕鬆」

    你的時間 ≠ 開發者的時間
    你的時間 = 企業的命脈
    
    所以:
    不要做「重複的手動工作」
    不要「改」代碼(要「規劃」代碼)
    不要「猜測」用戶需求(要「寫下來」)
    
    文檔優先,自動化第二,代碼最後。
    
    這是一人公司的生存法則。

    行動清單(現在就做)

    Week 1

    • ☐ 讀完這 5 篇文章(2 小時)
    • ☐ 為你的項目寫 CLAUDE.md(1 小時)
    • ☐ 設置 Hook(15 分鐘)

    Week 2

    • ☐ 選一個新功能,寫設計文檔
    • ☐ 用新工作流實施,看效果
    • ☐ 記錄時間(和傳統方式比較)

    Week 3-4

    • ☐ 再用 2-3 個功能測試
    • ☐ 調整 CLAUDE.md(發現遺漏的規則)
    • ☐ 分享給朋友(看看他們的反應)

    資源總結

    你現在有:

    📚 5 篇教學文
    📋 3 個可直接用的模板
    ✅ 4 個檢查清單
    🔧 1 個實戰案例 (Taiwan Invoice)
    📖 完整的 Claude Code 指南庫 (~/claude-code-guide/)

    一切你需要的都在了。


    致謝

    感謝你讀完這個系列。

    如果有問題、改進建議或你的實踐心得,歡迎分享。

    下一步:不是讀更多,是實踐

    選一個功能,按照 Day 1-3 的流程試試看。

    你會驚嘆「怎麼忽然快這麼多」。


    THE END – 系列完! 🎉


    系列文快速導航

    #標題你學到時間
    1為什麼規劃優先理解痛點15 min
    2CLAUDE.md – 編碼憲法寫規則文檔30 min
    3設計文檔 – 讓 Claude 一次對寫需求文檔30 min
    4Hook 自動化 – 省手動工作設置自動化15 min
    5實戰 – 3 天完成系統看完整案例20 min

    總時間:1.5 小時讀 + 2 小時實踐 = 3.5 小時 收益:未來每週省 5-10 小時,一年省 260-520 小時!

  • Claude Code 系列文 (4/5):Hook 自動化 — 讓機器做重複工作

    ⚡ 重點摘要

    • Hook讓機器自動做重複的lint和測試工作
    • 3個必備Hook:after-edit、before-commit、scheduled
    • 15分鐘設置,每週節省5-10小時手動操作
    • 永遠不提交有bug的代碼,主分支永遠綠色

    前提:已有 CLAUDE.md + 設計文檔 時間投入:15 分鐘設置 + 自動化 省時:每週 5-10 小時(再也不用手動 lint/test)


    核心觀點

    傳統流程:
    1. 你寫代碼
    2. 你手動 npm run lint
    3. 你修復 lint 錯誤
    4. 你手動 npm test
    5. 你看測試結果... 有 bug
    6. 你修復 bug
    7. 你再手動 lint 一遍
    8. 最後才提交
    
    時間:45 分鐘 / 功能
    
    ===
    
    Hook 自動化:
    1. 你寫代碼
    2. 保存檔案 → Hook 自動 lint + fix ✅
    3. 提交 git → Hook 自動測試 ✅
    4. 測試通過 → 允許提交 ✅
    
    時間:10 分鐘 / 功能

    節省時間:35 分鐘 × 10 功能 / 月 = 6 小時 / 月!


    一人公司最需要的 3 個 Hook

    Hook 1: after-edit(保存檔案時自動格式化)

    作用:自動執行 prettier + eslint –fix

    好處

    • 不用手動 npm run lint
    • 代碼永遠符合格式
    • Code review 不再被卡在「縮排問題」

    設置(5 分鐘):

    # 編輯 ~/.claude/settings.json
    cat >> ~/.claude/settings.json << 'EOF'
    {
      "hooks": {
        "after-edit": {
          "enabled": true,
          "commands": [
            {
              "patterns": ["**/*.ts", "**/*.tsx", "**/*.js"],
              "run": "prettier --write {file_path} && eslint --fix {file_path}",
              "on_failure": "warn",
              "timeout": 5000
            }
          ]
        }
      }
    }
    EOF

    驗證(1 分鐘):

    # 寫一個格式很爛的檔案
    echo "const  x   =   1" > src/test.ts
    
    # 通過 Claude 編輯它(或手動編輯)
    # 檢查:是否自動格式化為 "const x = 1;"
    cat src/test.ts

    Hook 2: before-commit(提交前自動測試)

    作用:提交前必須通過所有測試

    好處

    • 永遠不會提交有 bug 的代碼
    • 主分支永遠綠色(測試都通過)
    • 不用事後才發現 bug

    設置(5 分鐘):

    cat >> ~/.claude/settings.json << 'EOF'
    {
      "hooks": {
        "before-commit": {
          "enabled": true,
          "commands": [
            {
              "name": "test",
              "run": "npm test -- --onlyChanged --passWithNoTests",
              "on_failure": "block",
              "timeout": 60000,
              "message": "Tests failed. Fix before committing."
            },
            {
              "name": "lint",
              "run": "npm run lint -- {staged_files}",
              "on_failure": "warn"
            }
          ]
        }
      }
    }
    EOF

    驗證(1 分鐘):

    # 破壞一個測試
    echo "test('fail', () => expect(1).toBe(2));" > src/__tests__/test.ts
    
    # 嘗試提交
    git add .
    git commit -m "test: add failing test"
    
    # 結果:被 Hook 擋住 ✅
    # 訊息:Tests failed. Fix before committing.

    Hook 3: scheduled(每週自動檢查依賴)

    作用:每週一自動檢查 npm 依賴更新 + 安全漏洞

    好處

    • 不用手動 npm audit
    • 自動 npm audit fix(修復已知漏洞)
    • 依賴永遠最新,安全性更好

    設置(5 分鐘):

    cat >> ~/.claude/settings.json << 'EOF'
    {
      "hooks": {
        "scheduled": {
          "enabled": true,
          "jobs": [
            {
              "name": "weekly_dependency_audit",
              "cron": "0 10 * * MON",
              "run": "npm audit fix --audit-level=moderate",
              "description": "Check and fix dependencies every Monday 10 AM"
            }
          ]
        }
      }
    }
    EOF

    Hook 完整配置(給一人公司)

    把這個存到 ~/.claude/settings.json

    {
      "hooks": {
        "after-edit": {
          "enabled": true,
          "description": "Auto-format and lint after editing files",
          "commands": [
            {
              "patterns": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
              "run": "prettier --write {file_path} && eslint --fix {file_path}",
              "on_failure": "warn",
              "timeout": 5000
            },
            {
              "patterns": ["**/*.json"],
              "run": "prettier --write {file_path}",
              "on_failure": "warn",
              "timeout": 3000
            }
          ]
        },
    
        "before-commit": {
          "enabled": true,
          "description": "Run tests and lint before committing",
          "commands": [
            {
              "name": "test",
              "run": "npm test -- --onlyChanged --passWithNoTests",
              "on_failure": "block",
              "timeout": 60000,
              "message": "Tests failed. Fix before committing."
            },
            {
              "name": "lint",
              "run": "npm run lint",
              "on_failure": "warn",
              "timeout": 30000
            }
          ]
        },
    
        "scheduled": {
          "enabled": true,
          "description": "Automated background tasks",
          "jobs": [
            {
              "name": "weekly_dependency_audit",
              "cron": "0 10 * * MON",
              "description": "Check and fix dependencies every Monday 10 AM",
              "run": "npm audit fix --audit-level=moderate || true"
            },
            {
              "name": "daily_test_report",
              "cron": "0 9 * * *",
              "description": "Run full test suite daily at 9 AM",
              "run": "npm test"
            }
          ]
        }
      }
    }

    一週省下的時間

    假設你一週寫 5 個功能

    任務次數時間 / 次舊方式Hook 方式省下
    手動 lint52 min10 min0 min10 min
    手動測試55 min25 min0 min25 min
    修復 lint bug53 min15 min0 min15 min
    手動 npm audit110 min10 min0 min10 min
    總計60 min0 min60 min

    一週省 1 小時,一年省 52 小時!


    一人公司老闆應該知道的 Hook 細節

    細節 1: on_failure 的三種選擇

    "on_failure": "block"   ← Hook 失敗就停止
                (測試失敗時用)
    
    "on_failure": "warn"    ← Hook 失敗但繼續
                (建議性檢查,不強制)
    
    "on_failure": "ignore"  ← Hook 失敗完全忽視
                (做了無關的操作時)

    建議

    • 測試失敗 → block(必須通過)
    • 格式化失敗 → warn(不影響功能)
    • npm audit → warn(有漏洞但不阻止提交)

    細節 2: timeout 設定

    "timeout": 5000   ← 5 秒超時(快速操作)
    "timeout": 30000  ← 30 秒超時(複雜操作)
    "timeout": 60000  ← 60 秒超時(完整測試)

    建議

    • prettier/eslint:5 秒
    • 單個檔案 lint:10 秒
    • 單個 component 測試:30 秒
    • 全部測試:60 秒

    細節 3: patterns(針對特定檔案類型)

    "patterns": ["**/*.ts", "**/*.tsx"]
                ↓ 只對 TypeScript 檔案執行
    
    "patterns": ["**/*.js"]
                ↓ 只對 JavaScript 檔案執行
    
    "patterns": ["src/**"]  (可選)
                ↓ 只對 src/ 資料夾執行

    常見問題

    Q: Hook 會拖慢我的開發速度嗎?

    A: 不會,反而加快。

    Hook 執行時間:< 5 秒
    傳統修復時間:15-30 分鐘
    
    所以快 180-360 倍。

    Q: 如果我想跳過 Hook(緊急情況)?

    A: 可以,但不推薦。

    # 跳過 before-commit hook
    git commit -m "message" --no-verify
    
    # 但這很危險!只在真正緊急時用

    一人公司建議:不要跳過。多花 1 分鐘讓 Hook 通過,比之後修 bug 便宜。

    Q: 我已經有自己的 lint 設定,怎樣整合?

    A: Hook 尊重你的 .eslintrc 和 .prettierrc

    # 如果你已經有這些檔案,Hook 會自動用它
    ls -la .eslintrc .prettierrc
    
    # 如果沒有,建議建立預設的
    touch .eslintrc.json .prettierrc.json

    設置 Hook 的完整步驟

    Step 1: 確認已安裝工具(2 分鐘)

    npm --version          # Node.js
    npm list prettier      # Prettier 已裝
    npm list eslint        # ESLint 已裝
    
    # 如果沒裝,安裝它們
    npm install --save-dev prettier eslint

    Step 2: 複製配置(3 分鐘)

    # 如果你沒有 settings.json
    touch ~/.claude/settings.json
    
    # 貼上上面「完整配置」的內容
    # 或用模板
    cp ~/claude-code-guide/templates/settings.json.template \
       ~/.claude/settings.json

    Step 3: 驗證設置(5 分鐘)

    按照上面「驗證」部分,測試 3 個 Hook 是否工作。

    Step 4: 提交到 Git(1 分鐘)

    # 可選:把配置存在 repo 裡(方便分享給團隊)
    cp ~/.claude/settings.json .claude/settings.json
    git add .claude/settings.json
    git commit -m "chore: add hooks configuration"

    進階:自訂你的 Hook

    假設你想在每次提交前自動檢查台灣稅務規則:

    {
      "before-commit": {
        "commands": [
          {
            "name": "tax_rule_check",
            "run": "grep -r 'TODO.*tax' src/ && echo 'WARNING: Tax rules need attention' || true",
            "on_failure": "warn"
          }
        ]
      }
    }

    一人公司的 Hook 最佳實踐

    ✅ DO

    1. 保持 Hook 快(< 10 秒)
    2. 從必須有的開始(測試、格式化)
    3. 定期檢查 Hook 日誌

    bash tail -50 ~/.claude/logs/hooks.log

    1. 團隊共享 Hook 配置

    bash git commit .claude/settings.json

    ❌ DON’T

    1. 不要太多 Hook(> 5 個會累)
    2. 不要 Hook 做複雜邏輯(只做檢查和格式化)
    3. 不要在 Hook 裡執行部署(太危險)

    下一步

    現在就做

    1. 複製完整配置到 ~/.claude/settings.json
    2. 測試 3 個 Hook(1-2 分鐘)
    3. 編輯一個檔案,檢查是否自動格式化
    4. 提交代碼,檢查是否自動測試
    5. 享受節省下來的時間!

    重點回顧

    CLAUDE.md:規則(永遠不變)
    設計文檔:需求(每功能一份)
    Hook:自動化(一次設置,永遠運行)
    
    一人公司工作流:
    規劃 → 寫代碼(自動格式化)
       → 提交(自動測試)
       → 完成
    
    時間:30% 規劃 + 70% 實施(不是傳統的 20% 規劃 + 80% 改動)

    下一篇預告

    第 5 篇:實戰案例 – Taiwan Invoice 3 天完成

    前四篇教了理論和細節。

    最後一篇會示範完整的一人公司工作流:

    1. Day 1:規劃 + 寫 CLAUDE.md + 設計文檔
    2. Day 2:Claude 實施 + 自動化驗證
    3. Day 3:部署 + 監控

    看完了,你就可以套用到自己的項目。


    現在就設置 Hook,開始自動化! 👋

    還有一篇,堅持到最後!💪

  • Claude Code 系列文 (2/5):CLAUDE.md — 你的編碼憲法

    ⚡ 重點摘要

    • CLAUDE.md是讓Claude永遠記住你規則的配置文件
    • 包含代碼標準、命名約定、業務規則、技術決策
    • 30分鐘投入,每週節省3-5小時重複prompt
    • 具體規則 > 模糊描述,MUST/NEVER > 建議

    前提:讀過第 1 篇,理解「規劃優先」的理念 時間投入:30 分鐘讀 + 30 分鐘寫你自己的 CLAUDE.md 收益:從此每次 prompt 少打 50% 重複內容


    這一篇的核心觀點

    傳統用法:
    prompt #1: "用 TypeScript 寫"
    prompt #2: "按照我們的命名規則..."
    prompt #3: "記得加 unit tests"
    prompt #4: "遵守這些安全規則..."
    
    === vs ===
    
    CLAUDE.md 方法:
    寫一次(CLAUDE.md 裡記錄所有規則)
    之後:Claude 自動遵守,不用每次都提醒

    實際節省:每個 prompt 減少 50-70% 的文字。


    CLAUDE.md 是什麼

    CLAUDE.md 是一份你放在項目根目錄的文檔。

    Claude Code 啟動時會自動讀取它,並把規則記住。

    # 檔案位置
    ~/your-project/CLAUDE.md
    
    # Claude 行為
    claude
     ├─ 讀取 CLAUDE.md
     ├─ 記住所有規則
     ├─ 每次你輸入 prompt 時遵守
     └─ 不再需要你重複告訴它

    類比

    • 傳統方式 = 每次進公司都告訴員工「要穿正式服裝」
    • CLAUDE.md 方式 = 第一天讀 dress code,以後自動遵守

    一人公司應該在 CLAUDE.md 裡寫什麼

    第一層:基本信息(不改的東西)

    # Project: Taiwan Invoice System
    
    **Stack**: React 18 + Node.js 18 + PostgreSQL
    **Language**: TypeScript (strict mode)
    **Main concern**: Taiwan tax law compliance
    
    ---
    
    ## Architecture Decision Log
    
    ### Decision 1: Use Strategy Pattern for tax calculation
    **Why**: Taiwan tax law changes frequently (new government = new rates)
    **Impact**: New tax type can be added in 30 min, not 8 hours
    **Done**: ✅
    
    ### Decision 2: Keep invoice data immutable once submitted
    **Why**: Taiwan tax audit requires unmodifiable records
    **Impact**: No delete/edit after submit, only void new ones
    **Done**: ✅

    好處

    • 6 個月後你自己看,能快速想起設計邏輯
    • 新人(或外包)接手,有據可查
    • Claude 理解你的業務優先級

    第二層:代碼標準(重複最多的東西)

    ## Code Standards
    
    ### File Structure
    ```
    src/
    ├── components/       # React components
    ├── pages/           # Page-level components
    ├── services/        # API calls & business logic
    ├── utils/           # Helpers
    ├── hooks/           # Custom React hooks
    ├── styles/          # CSS modules
    └── __tests__/       # Test files (mirror structure)
    ```
    
    ### Naming Conventions
    - Components: PascalCase (e.g., InvoiceForm.tsx)
    - Utilities: camelCase (e.g., calculateTax.ts)
    - Constants: UPPER_SNAKE_CASE (e.g., MAX_INVOICE_AMOUNT)
    - Database tables: snake_case (e.g., c_invoice)
    
    ### Code Quality Rules
    
    **MUST HAVE**:
    - [ ] TypeScript (no `any` type)
    - [ ] Unit tests for all logic (TDD)
    - [ ] JSDoc for public functions
    - [ ] Error handling (no silent failures)
    
    **NEVER**:
    - ❌ Hardcode config values (use .env)
    - ❌ Leave console.log() in production code
    - ❌ Commit commented-out code
    - ❌ Use var (only let/const)

    為什麼重要

    • Claude 有了標準,自動遵守
    • 省去每個 prompt 都要說「按 TypeScript best practices」
    • 代碼風格一致,review 更快

    第三層:業務邏輯(最容易被遺忘的)

    ## Taiwan-Specific Rules
    
    ### Tax Calculation
    - Standard VAT: 5% (applies to most goods)
    - Zero-rated: 0% (exports, specific items)
    - Tax-exempt: 0% (non-profit, some services)
    - Input tax can be deducted if invoice dated in same month
    
    ### Invoice Rules
    - Invoice number format: GUN (Government Uniform Number)
    - Sequence must be continuous
    - Cannot be modified after submission
    - Must include buyer's company ID + name
    - QR code is mandatory for official submission
    
    ### Compliance
    - Must report to MOPS (Ministry system) by 15th of next month
    - Annual audit by tax bureau
    - Keep records for 10 years

    為什麼重要

    • Claude 有了背景,不會犯「常見的 bug」
    • 減少審查時需要找的問題
    • 新人學習曲線 ÷ 2

    第四層:技術決策(省掉最多討論時間)

    ## When You Ask Claude to Build Something
    
    ### Before Implementation (Planning Phase)
    1. Claude enters Plan Mode automatically
    2. Claude reads this CLAUDE.md + design docs
    3. Claude proposes approach
    4. **YOU APPROVE** (or suggest changes)
    5. Claude implements
    
    ### Testing Strategy
    - Unit tests: Must cover edge cases
    - Integration tests: For API + database interaction
    - Manual testing: Only for UI/UX
    - Coverage target: > 85%
    
    ### Code Review Checklist
    - [ ] Logic is correct (test passes)
    - [ ] Taiwan business rules followed
    - [ ] No security holes
    - [ ] Performance acceptable
    - [ ] Error messages are clear (in Chinese)
    - [ ] Documentation updated

    為什麼重要

    • Claude 知道你的評審標準
    • 自動寫出符合預期的代碼
    • 不用反覆改

    一人公司版本的 CLAUDE.md 精簡版

    如果你覺得上面太複雜,這是最小版本(30 分鐘可寫完):

    # Taiwan Invoice System
    
    ## Stack & Language
    - TypeScript + React 18 + Node.js
    - Database: PostgreSQL
    
    ## Code Rules
    - File structure: components/ pages/ services/ __tests__/
    - Names: Components = PascalCase, functions = camelCase, constants = UPPER_CASE
    - MUST: TypeScript strict, unit tests, JSDoc, error handling
    - NEVER: console.log, hardcoded config, var, no tests
    
    ## Business Rules
    - Tax rates: 5% standard, 0% zero-rated, 0% exempt
    - Invoice format: GUN, continuous sequence, immutable after submit
    - Compliance: Report to MOPS by 15th, keep records 10 years
    
    ## When You Ask Me to Build
    1. I'll enter Plan Mode
    2. Read design doc + this file
    3. Propose approach (you approve)
    4. Implement with tests
    5. You review
    
    ## Important Decisions
    1. Tax calculation uses Strategy Pattern (easy to add new rates)
    2. Invoices immutable after submit (Taiwan law requirement)
    
    ---
    
    Done! Keep this updated as rules change.

    寫這個花了多少時間? 30-45 分鐘。

    省了多少時間? 每週 3-5 小時(因為不用重複解釋)。


    真實案例:有沒有 CLAUDE.md 的差別

    沒有 CLAUDE.md 的一人公司

    Day 1, Prompt:
    "Build invoice form with validation.
    Use React, TypeScript, follow best practices."
    
    Claude builds... but:
    - Uses var instead of const ❌
    - Only 60% test coverage ❌
    - API call has no error handling ❌
    - Component name is lowercase ❌
    
    You: "Oh no, 改了改了改了"
    時間消耗:8 小時 (1 小時寫 + 7 小時改)

    有 CLAUDE.md 的一人公司

    Day 1, CLAUDE.md 寫好,然後 Prompt:
    "Build invoice form with validation"
    
    Claude builds:
    - Automatically uses let/const ✅
    - Automatically writes unit tests ✅
    - Automatically adds error handling ✅
    - Automatically uses PascalCase ✅
    
    You: "一次到位!"
    時間消耗:2.5 小時 (30 分鐘規劃 + 2 小時實施)

    節省時間:5.5 小時 per feature。 一個月(~4 features)= 22 小時 = 3 整天!


    怎樣寫一個好的 CLAUDE.md

    ❌ 常見錯誤

    # Project Rules
    
    要遵守我們的架構。要寫好代碼。不要有 bug。
    
    Done!

    問題:太模糊,Claude 無法遵守。

    ✅ 正確方式

    # Project Rules
    
    ## Code Quality
    - MUST: TypeScript strict mode, no `any` type
    - MUST: Unit tests for all functions (Jest)
    - MUST: Error handling (try-catch or error state)
    - NEVER: console.log in production code
    - NEVER: var keyword (use let/const)
    
    ## File Naming
    - Components: PascalCase (InvoiceForm.tsx)
    - Utilities: camelCase (calculateTax.ts)
    - Tests mirror source: src/foo.ts → src/__tests__/foo.test.ts

    好處:具體、可驗證、Claude 能遵守。

    規則

    1. 具體 > 模糊
    • ❌ 「寫好代碼」
    • ✅ 「TypeScript strict mode, coverage > 85%, no console.log」
    1. 實例 > 敘述
    • ❌ 「按照公司命名慣例」
    • ✅ 「組件 = PascalCase (InvoiceForm.tsx), 函數 = camelCase (calculateTax.ts)」
    1. MUST/NEVER > 建議
    • ❌ 「考慮使用 const」
    • ✅ 「MUST use const (never var)」
    1. 定期更新 > 一次寫完就忘
    • 每月審視 1 次
    • 如果發現 Claude 經常犯某個錯誤,加入 CLAUDE.md

    一人公司老闆的 CLAUDE.md 檢查清單

    寫完了嗎?檢查一下:

    • 基本信息
    • ☐ 項目名稱
    • ☐ 技術棧
    • ☐ 主要業務邏輯
    • 代碼標準
    • ☐ 文件結構
    • ☐ 命名約定
    • ☐ TypeScript/語言設置
    • ☐ 測試要求
    • 業務規則
    • ☐ 稅務/財務規則(如有)
    • ☐ 數據有效性
    • ☐ 合規要求
    • 決策日誌
    • ☐ 架構決策 + 理由
    • ☐ 為什麼選這個技術
    • 評審標準
    • ☐ 什麼樣的代碼才算「完成」
    • ☐ 什麼是「不接受」

    如何開始

    Step 1:複製模板(1 分鐘)

    cp ~/claude-code-guide/templates/CLAUDE.md.template \
       ~/your-project/CLAUDE.md

    Step 2:填入你的內容(30 分鐘)

    打開編輯器,按照上面的框架填入:

    1. 你的技術棧
    2. 你的命名約定
    3. 你的業務規則
    4. 你的決策理由

    Step 3:提交到 Git(2 分鐘)

    git add CLAUDE.md
    git commit -m "chore: add project rules"
    git push

    Step 4:開始用(即時)

    claude
    
    user: "Add a new invoice field called customer_contact_number"
    # 不用再說「用 TypeScript」、「加測試」、「命名要駝峰」
    # Claude 自動知道

    一個月後會發生什麼

    Week 1

    • CLAUDE.md 寫好
    • 第一個功能用新規則
    • “哦,還是得改一些東西…”
    • 把發現的規則加入 CLAUDE.md

    Week 2-3

    • Claude 開始學到你的風格
    • 改動變少了
    • “不錯,大部分對了”

    Week 4

    • 新功能一次到位 90%+ 正確
    • 只需要微調
    • 驚嘆「怎麼忽然快這麼多」

    Month 2+

    • CLAUDE.md 成為寶貴資產
    • 新人/外包根據 CLAUDE.md 快速上手
    • 你的編碼風格一致,代碼可維護性 ↑

    一個常見問題:CLAUDE.md 應該多詳細

    答案:「足夠清楚讓 Claude 不猜測」

    測試方法:

    1. 寫 CLAUDE.md
    2. 給 Claude 一個簡單的 prompt
    3. 看結果
       - 如果 Claude 做對了 90%+ → 夠詳細
       - 如果還要改 → 加更多細節

    一人公司的理想狀態

    • 一份 1000-2000 字的 CLAUDE.md
    • 涵蓋 70% 的日常情況
    • 20% 用 design docs(下一篇講)
    • 10% 需要臨時 prompt

    重點回顧

    CLAUDE.md 是「一次性投資」:
    
    30 分鐘寫 CLAUDE.md
      ↓
    之後每周省 3-5 小時
      ↓
    一年省 150+ 小時
      ↓
    相當於半個全職開發者的成本!

    你如果是一人公司老闆,這是值得的投資。


    下一篇預告

    第 3 篇:設計文檔模板

    CLAUDE.md 處理「永遠不變的規則」

    那「會變的東西」(業務邏輯、UI 流程)怎麼辦?

    設計文檔

    下一篇我會告訴你:

    • 怎樣寫一份 2 小時內完成的設計文檔
    • 讓 Claude 看懂你的想法,一次實施正確
    • 實例:Invoice 功能設計文檔

    現在就做這一件事

    1. 打開編輯器
    2. 複製上面的「精簡版 CLAUDE.md」
    3. 填入你的技術棧和規則
    4. 保存為 ~/your-project/CLAUDE.md
    5. git add + commit

    花時間:30 分鐘 收益:未來每週省 3-5 小時

    下一篇見!👋

  • Claude Code 系列文 (3/5):設計文檔 — 讓 Claude 一次做對

    ⚡ 重點摘要

    • 設計文檔解決「Claude不是心靈讀者」的問題
    • 最小版本20分鐘:What+How+Edge Cases+Done When
    • 投入30分鐘,節省6小時改動,ROI 600%
    • 中等以上複雜度的功能都應該寫設計文檔

    前提:已寫好 CLAUDE.md(第 2 篇) 時間投入:20-30 分鐘設計 + 2 小時實施(vs 8 小時傳統方式) 成果:90%+ 一次正確,最多微調 1-2 處


    核心觀點

    CLAUDE.md:永遠的規則(不變)
       ↓
    設計文檔:這次功能的具體需求(會變)
       ↓
    實施:Claude 讀完兩者,一次到位

    實際效果

    傳統:
    user: "加個 PDF 匯出功能"
    claude: 實施... 但漏了 QR code、沒考慮大文件、錯誤處理不完善
    result: 改 3 次,花 8 小時
    
    ===
    
    設計優先:
    user: 先寫「PDF 匯出設計文檔」
       ├─ 輸出什麼欄位
       ├─ 格式細節
       ├─ 大文件怎麼處理
       └─ 邊界情況怎麼做
    
    claude: 讀完設計,實施功能
    result: 一次到位,花 2 小時

    為什麼設計文檔這麼關鍵

    原因 1:Claude 不是心靈讀者

    你想要:
    "PDF 應該很專業,像官方發票"
    
    Claude 理解的:
    "Generate a PDF" (可能就是基礎格式)
    
    ===
    
    如果你寫:
    "PDF 格式:
     - 頁眉:公司 logo + 發票編號
     - 內容:3 欄表格 (品項|數量|金額)
     - 頁尾:二維碼 + 簽章區域
     - 字體:14pt 標題,11pt 內容"
    
    Claude 理解的:
    正確無誤 ✅

    原因 2:邊界情況很容易漏

    你沒說的情況:
    - 如果發票超過 1 頁怎麼辦?
    - 品項名稱很長怎麼折行?
    - 金額超過 99,999,999 怎麼顯示?
    
    Claude 的猜測:
    - 默認假設只有 1 頁
    - 品項名稱截斷
    - 金額省略號或出錯
    
    ===
    
    設計文檔說清楚:
    - 多頁:自動翻頁,每頁重複頁眉
    - 長品項:自動折行到 2-3 行,調整行高
    - 大金額:科學計數法或分行顯示
    
    Claude:
    做對 ✅

    原因 3:審核快得多

    沒有設計文檔:
    你看代碼 → "嗯... 這個邏輯有點問題?"
                → 要改 → 再看一遍 → 還要改
    時間:1-2 小時審核
    
    ===
    
    有設計文檔:
    設計文檔清楚 → Claude 一次到位
    審核只需檢查「有沒有按設計文檔做」
    時間:15 分鐘審核

    一人公司的設計文檔長什麼樣

    最小版本(20 分鐘寫完)

    假設你要加「發票篩選功能」:

    # Invoice Filter Feature
    
    ## What
    用戶可以按日期、狀態、金額篩選發票列表
    
    ## How
    ### Page Flow
    1. 使用者進入「發票清單」頁面
    2. 頁面上方顯示篩選器:
       - Date range picker (from - to)
       - Status dropdown (全部 / 草稿 / 已提交 / 已申報)
       - Amount range slider (0 - 999,999)
    3. 用戶選擇條件 → 自動篩選列表(無需按搜尋按鈕)
    4. 篩選結果顯示在表格
    
    ### Data Model
    ```sql
    -- 輸入參數
    filter: {
      dateFrom: Date,
      dateTo: Date,
      status: enum ['DRAFT', 'SUBMITTED', 'FILED'],
      amountMin: number,
      amountMax: number
    }
    ```
    
    ### Edge Cases
    - 沒有搜尋結果 → 顯示「沒有符合條件的發票」
    - 篩選中 → 顯示 loading spinner
    - API 錯誤 → 顯示「載入失敗,請重試」
    
    ## Why
    - 用戶有 100+ 發票,手動找很慢
    - 會計需要按日期整理報表
    - 管理者需要看特定金額範圍的交易

    花時間:20 分鐘 代碼行數:20-30 行(因為清晰,不用試錯)

    完整版本(30 分鐘寫完)

    如果功能更複雜,加這些:

    # Invoice PDF Export Feature
    
    ## 業務背景
    台灣政府要求發票有統一格式(GUN 標準)
    用戶要匯出發票給客戶或存檔
    
    ## 用戶故事
    "作為發票系統使用者,我想點擊『匯出 PDF』按鈕,
      得到一份官方格式的 PDF,這樣我可以寄給客戶或稅務局"
    
    ## 功能範圍
    ### 必須有
    - [ ] PDF 包含所有發票欄位(發票號碼、日期、品項、金額等)
    - [ ] GUN 格式(台灣政府標準)
    - [ ] 二維碼(可掃描驗證)
    - [ ] 頁眉和頁尾
    - [ ] 多頁自動分頁
    
    ### 可以有(下個版本)
    - [ ] 批量匯出(多張發票 1 個 PDF)
    - [ ] 自訂 logo
    - [ ] 簽章區域
    
    ### 不包含
    - [ ] 自訂格式(template 系統太複雜)
    - [ ] 列印功能(瀏覽器列印已足)
    
    ## API/Data
    ### Input
    ```typescript
    POST /api/invoices/{id}/export-pdf
    
    // Response
    {
      pdf_url: "https://..../invoice_2024_001.pdf",
      generated_at: "2024-03-25T10:30:00Z"
    }
    ```
    
    ## UI/UX
    ### 按鈕位置
    - 在「發票詳情」頁面右上角
    - 按鈕文字:「匯出 PDF」
    - 點擊後:shows loading 3 秒,下載 PDF
    
    ### 錯誤情況
    - 網路錯誤 → 「無法生成 PDF,請重試」
    - 發票不完整 → 「發票資料不完整,無法匯出」
    - 檔案太大(> 10MB) → 「檔案過大,請聯絡管理員」
    
    ## 技術決策
    ### Why jsPDF instead of server-side?
    - jsPDF:快速、實時、不佔服務器資源 ✅
    - Server-side:需要 Node.js 套件、佔内存
    
    ### Why QR code?
    - Taiwan GUN requirement
    - Users can verify authenticity by scanning
    
    ## 測試 Checklist
    - [ ] PDF 內容完整(所有欄位都在)
    - [ ] 格式符合 GUN 標準(對齐、字體大小)
    - [ ] 二維碼可掃描
    - [ ] 多頁發票能正確分頁
    - [ ] 邊界情況:長品項名稱、大金額
    - [ ] 錯誤訊息清晰
    
    ## 完成條件(Acceptance Criteria)
    - [ ] 用戶點擊按鈕能下載 PDF
    - [ ] PDF 格式符合 GUN 標準
    - [ ] 二維碼正確生成
    - [ ] 網路慢時顯示 loading
    - [ ] 有錯誤時顯示清晰的訊息
    - [ ] 所有測試通過(coverage > 85%)

    花時間:30 分鐘 代碼行數:50-80 行(因為設計完整,邊界情況少)


    如何快速寫設計文檔(給一人公司老闆)

    方法 1:從 User Story 開始(最快)

    ## 功能
    允許用戶標記發票為「已審核」
    
    ## 用戶故事
    "As a manager, I want to mark invoices as reviewed,
     so I can track which invoices have been checked"
    
    ## 怎麼做
    1. 發票表格增加「審核」按鈕
    2. 點擊後標記為「已審核」,按鈕變灰
    3. 可以「取消審核」改回去
    
    ## Edge Cases
    - 多人同時審核同一張發票? → 最後一次改動獲勝
    - 已提交的發票能審核嗎? → 能,審核和提交獨立
    
    ## Done When
    - [ ] 按鈕會出現
    - [ ] 狀態能改變
    - [ ] 數據持久化
    - [ ] 網路慢時有 loading

    花時間:10-15 分鐘

    方法 2:從技術問題開始(有爭議時)

    ## 問題
    稅務計算邏輯現在在 service/taxCalculator.ts,
    很難測試,也難新增新稅種
    
    ## 提議
    用 Strategy Pattern 重構
    
    ## 對比
    ### 現狀(有問題)
    ```typescript
    if (type === 'standard') {
      tax = amount * 0.05;
    } else if (type === 'zero') {
      tax = 0;
    }
    // 很多 if,難擴展
    ```
    
    ### 改進後
    ```typescript
    const strategy = TaxStrategyFactory.get(type);
    tax = strategy.calculate(amount);
    // 新稅種只需新建 class,無需改舊代碼
    ```
    
    ## 工作
    1. 建立 TaxStrategy interface
    2. 建立 StandardTaxStrategy, ZeroTaxStrategy, ExemptTaxStrategy
    3. 建立 TaxStrategyFactory
    4. 遷移現有邏輯
    5. 寫測試
    
    ## 完成條件
    - [ ] 所有現有測試通過
    - [ ] 無新 bug
    - [ ] 代碼行數 < 現狀(因為減少 if)
    - [ ] 新稅種能在 30 分鐘內加入

    花時間:15-20 分鐘


    設計文檔和 CLAUDE.md 的區別

    項目CLAUDE.md設計文檔
    頻率一年改幾次每個功能寫一份
    內容規則、標準這次功能的細節
    例子「所有 component 用 PascalCase」「篩選器有 date picker 和 status dropdown」
    變化不變常變
    時效永遠有用功能完成後就 archive

    常見問題

    Q: 設計文檔很麻煩嗎?

    A: 不麻煩。其實省時間。

    對比:

    • ❌ 不寫設計文檔:2 小時設計(腦子裡)+ 8 小時實施 + 5 小時改 = 15 小時
    • ✅ 寫設計文檔:30 分鐘寫 + 2 小時實施 + 0.5 小時改 = 2.5 小時

    省時 6 倍。

    Q: 如果需求改了怎麼辦?

    A: 更新設計文檔,再讓 Claude 改。

    原設計:篩選器是下拉選單
    新需求:改成複選框(可選多個狀態)
    
    做法:
    1. 更新設計文檔的 UI/UX 部分
    2. Prompt: "按照新設計文檔改篩選器"
    3. Claude 改
    4. 完成

    Q: 小功能也要寫設計文檔嗎?

    A: 看複雜度

    • 簡單(邏輯 < 5 行):無需文檔,直接 prompt
    • 中等(邏輯 20-50 行):寫簡單版設計文檔(10 分鐘)
    • 複雜(邏輯 > 50 行,多頁面):寫完整版設計文檔(30 分鐘)

    一般來說:中等及以上都要寫


    實戰範例:Taiwan Invoice 設計文檔

    這是真實的設計文檔,你可以直接改成自己的:

    # Taiwan Invoice System - Design Doc
    
    ## 概述
    系統需要符合台灣官方發票格式 (GUN)
    用戶可以生成、儲存、匯出發票
    
    ## 模組 1: Invoice Data Model
    
    ### 資料結構
    ```sql
    CREATE TABLE c_invoice (
      id UUID PRIMARY KEY,
      invoice_number VARCHAR(10),  -- e.g., "001", "002"
      invoice_date DATE,
      company_name VARCHAR(255),
      company_tax_id VARCHAR(8),
      customer_name VARCHAR(255),
      customer_tax_id VARCHAR(8),
      items JSONB,  -- [{name, qty, price, amount}, ...]
      subtotal DECIMAL(12,2),
      tax_amount DECIMAL(12,2),
      total DECIMAL(12,2),
      status ENUM('DRAFT', 'SUBMITTED', 'FILED'),
      created_at TIMESTAMP,
      updated_at TIMESTAMP
    );
    ```
    
    ## 模組 2: Tax Calculation
    
    ### 規則
    - 標準稅率:5%(大部分商品)
    - 零稅率:0%(出口商品)
    - 免稅:0%(非營利組織)
    - 進項稅扣除:同月內才能計算
    
    ### 計算邏輯
    ```
    total_tax = sum(item.tax for item in items)
    where tax = item.amount * tax_rate
    
    if invoice.status == 'SUBMITTED':
      deductible_tax = tax (可抵扣)
    else:
      deductible_tax = 0 (草稿狀態不計)
    ```
    
    ## 模組 3: PDF Export
    
    ### 輸出格式
    頁面:A4 (210mm x 297mm)
    邊距:10mm
    
    頁眉:
    - 左:公司 logo (40x40mm)
    - 中:「統一發票」(20pt bold)
    - 右:發票號碼 (16pt)
    
    內容:
    - 發票日期
    - 買賣雙方資訊
    - 3 欄表格:品項、數量、金額
    - 合計 / 稅額 / 總金額
    
    頁尾:
    - QR code (25x25mm)
    - 簽章區域
    
    ## 完成條件
    - [ ] 資料模型完整
    - [ ] 稅務計算正確
    - [ ] PDF 格式符合 GUN 標準
    - [ ] 所有 edge cases 測試通過

    一人公司老闆的建議

    做法 1:檔案形式

    寫在 docs/designs/ 資料夾:

    docs/designs/
    ├── invoice-filter.md
    ├── invoice-pdf-export.md
    └── tax-calculation.md

    提交到 git,成為代碼庫的一部分。

    做法 2:更新設計文檔的時機

    • 需求改變時
    • 發現 bug 時
    • 新的 edge case 出現時

    加一句:

    ## 更新日誌
    - 2024-03-25:初版
    - 2024-03-26:加入多頁分頁需求
    - 2024-03-27:修正邊界情況 (長品項名稱)

    下一步

    現在就做

    選一個你想要的功能(不用很大),寫設計文檔:

    1. 打開編輯器

    bash touch docs/designs/[feature-name].md

    1. 按照上面的「最小版本」模板寫
    • What (是什麼)
    • How (怎麼做)
    • Edge cases (邊界情況)
    • Done when (完成條件)
    1. 花時間:15-20 分鐘
    1. 給 Claude

    “`bash claude user: “這是 [功能名稱] 的設計文檔 [貼上設計文檔]

    請按照這個設計實施” “`

    1. 對比傳統方式
    • 時間縮短 60-70%
    • 修改次數 ÷ 3
    • Bug 數量 ÷ 2

    重點回顧

    CLAUDE.md:「怎樣寫好代碼」(寫一次,永遠用)
       ↓
    設計文檔:「這次要寫什麼」(每功能一份)
       ↓
    Claude:一次實施正確 ✅

    投資回報

    • 每份設計文檔花 30 分鐘
    • 省 6 小時實施時間
    • 一年 (~50 功能) 省 300 小時 = 6 周工作量!

    下一篇預告

    第 4 篇:Hook 自動化

    有了 CLAUDE.md 和設計文檔,代碼質量大幅提升。

    但還有很多重複的手動工作:

    • 每次編輯後手動 lint
    • 每次 commit 前手動執行測試
    • 每週手動檢查依賴更新

    Hooks 自動化這些!

    下一篇會告訴你:

    • 怎樣 5 分鐘設置 3 個最重要的 Hook
    • 節省每週 5-10 小時手動工作
    • 實例:after-edit (auto-format) + before-commit (auto-test)

    現在就開始寫第一個設計文檔! 👋

  • Claude Code 系列文 (1/5):一人公司的開發穩定性秘密

    ⚡ 重點摘要

    • 一人公司最大問題:時間少,重複改動多
    • 規劃優先方法:CLAUDE.md + 設計文檔 → Claude一次做對
    • 每個功能開發時間從8-16小時縮短到2-3小時
    • 本系列5篇教你建立完整的一人公司開發系統

    寫給:一人公司老闆、獨立開發者 痛點:時間少、要求多、不能重複勞動 解決方案:用規劃優先的工作流 + Claude Code


    你的困境(認真的)

    你一個人同時是:

    • 💼 產品經理(要什麼功能)
    • 🔨 開發者(怎麼建)
    • 🧪 QA(有沒有 bug)
    • 📚 文檔編寫者(怎麼用)
    • 🚀 運維(部署和監控)

    時間分配很絕望

    • 實際寫代碼:可能只有 30%
    • 重複做同樣的決策:20%
    • 找 bug、修 bug:20%
    • 手動測試:15%
    • 其他雜事:15%

    結果

    • 一個月才能交付一個功能
    • 沒時間優化
    • 沒時間文檔
    • 夢裡都在 debug

    一般人的解決方案(都不對勁)

    ❌ 方案 1:招一個開發者

    • 成本:月薪 $2000-4000
    • 你的增加成本:70-80% (管理、協調、溝通)
    • 結果:不划算,特別是你的需求變化快

    ❌ 方案 2:外包給開發公司

    • 成本:$1000-3000 per feature
    • 問題:
    • 他們不懂你的業務邏輯
    • 一堆 bug 需要反覆修
    • 根本沒人維護
    • 改 UI 要等一周

    ❌ 方案 3:用低代碼/無代碼工具

    • 優點:快速上手
    • 缺點:
    • 超過基本功能就卡住
    • 無法擴展
    • 數據鎖定在平台
    • 月費永不停止

    ✅ 我的方案:Claude Code + 規劃優先

    這個方案的核心理念:

    少 prompt(提示詞)→ 多文檔(規劃文件)→ 穩定開發

    運作邏輯

    傳統 Claude Code 用法:
    user: "加個登入功能"
    claude: "好,現在實施..."
    結果: 80% 對,20% 要改,改 3 次才對 ❌
    
    ===
    
    我的方法:
    user: 先寫設計文檔
       ├─ 登入流程圖
       ├─ 數據模型
       ├─ API 規格
       ├─ 錯誤情況
       └─ 安全檢查點
    
    claude: 讀完設計文檔
           → 一次到位 ✅
           → 90%+ 對
           → 最多微調 1-2 次

    為什麼效果這麼好?

    1. 你花 2 小時規劃,省 8 小時改
    • Claude 少猜測 80%
    • 實施清晰,bug 少
    1. 從此不重複決策
    • 設計一次,可重用
    • 新人接手也看得懂
    • 6 個月後改需求,有據可查
    1. Claude 更聰明
    • 它讀懂需求精細度 ↑ → 代碼品質 ↑
    • 不再「我猜你想要」
    • 自動找出邊界情況
    1. 自動化率提高
    • Hooks 自動 lint + format
    • 測試自動跑
    • 手動操作 ↓ 50%

    一人公司的黃金公式

    CLAUDE.md (5 min 寫)
      ↓
    設計文檔 (20-30 min 寫)
      ↓
    Claude Code 實施 (1-2 hours)
      ↓
    驗收 (15 min)
      ↓
    上線 (5 min)
      ↓
    自動化監控 (0 min,Hook 搞定)
    
    總時間:2-3 hours per feature ✅

    vs

    傳統方式:
    實施 → 測試 → 修改 1 → 測試 → 修改 2 → ...
    總時間:8-16 hours per feature ❌

    這個系列會教你什麼

    📖 第 1 篇 (本篇):為什麼規劃優先

    📖 第 2 篇:建立你的「編碼憲法」

    • CLAUDE.md 怎麼寫
    • 一次性規則,永遠生效
    • 讓 Claude 記住你的風格和要求

    你寫一次:「所有 API 返回都要帶 error_code」
    之後:Claude 永遠自動加這個,不用提醒

    📖 第 3 篇:設計文檔模板

    • Invoice 系統設計文檔怎麼寫
    • 從業務需求到技術規格
    • 讓 Claude 能一次實施正確

    📖 第 4 篇:自動化 Hook

    • 自動格式化、自動測試、自動檢查
    • 從此沒有手動 lint 這種事
    • 節省每週 5-10 小時

    📖 第 5 篇:實戰案例 – Taiwan Invoice System

    • 完整的一人公司開發流程
    • 從零到部署,3 天內完成
    • 如何用 Plan Mode 少 prompt

    一人公司老闆應該知道的三件事

    事實 1:你的時間不是資源,是稀缺商品

    你的時間 ≠ 開發者的時間

    你 1 小時的時間價值 = 你一個小時的營收機會成本

    所以

    • ✅ 花 30 分鐘規劃(你做)
    • ❌ 不要花 8 小時反覆改(讓 Claude 做,正確率 90%+)

    事實 2:文檔是最好的投資

    一個一人公司最怕什麼?

    • 不是 bug
    • 不是需求改變
    • 是「我忘了為什麼這樣設計」

    3 個月後

    • ❌ 沒文檔:「為什麼税務計算這樣寫?誰知道… 反正改不了」
    • ✅ 有文檔:「哦,這是因為台灣稅法 §96,我記得」

    事實 3:規劃優先,自動化第二

    很多人想著「如何自動化我的工作」

    正確的順序是「如何規劃好我的工作」才能「自動化」

    類比

    • 製造業 1.0:手工 → 效率低
    • 製造業 2.0:流程化 + 自動化 → 效率高
    • 開發 1.0:隨意寫代碼 + 手動測試 → 慢
    • 開發 2.0:規劃 + 自動化 → 快

    你應該期待什麼結果

    Week 1(學習)

    • 讀完這個系列(2 小時)
    • 寫出你的 CLAUDE.md(1 小時)
    • 設置 Hook(30 分鐘)
    • 第一個功能用新方法(3 小時)

    Week 2-4(習慣)

    • 每個功能都有設計文檔(快速發現問題)
    • 自動化 lint/test(省去手動操作)
    • 改需求不再是「全部改」,而是「增量改」

    Month 2(收穫)

    • 開發速度 ×3
    • bug 率 ÷2
    • 個人壓力 ÷3
    • 有時間優化產品

    Month 3+(習慣)

    • 文檔成為資產(不是負擔)
    • 新功能開發時間可預測(不再「要多久」→「大概 2 天」)
    • 可以考慮擴招(有文檔,新人能快速上手)

    下一篇預告

    第 2 篇:CLAUDE.md – 你的編碼憲法

    我會教你怎樣用一份文檔,讓 Claude 永遠記住:

    • 你的代碼風格
    • 你的業務邏輯
    • 你的命名約定
    • 你的安全要求

    寫一次,永遠受用。


    現在就開始

    問自己三個問題:

    1. 我上週浪費了多少時間在「改 bug」上?
    • < 3 小時:你還不夠痛苦,可以緩一緩
    • 3-10 小時:現在該改了
    • \> 10 小時:你應該昨天就開始
    1. 我有沒有寫過設計文檔?
    • 沒有:你損失了 80% 的時間
    • 有,但是手寫的:轉換成模板化的吧
    1. 我願不願意花 2 小時規劃,換 8 小時省下來?
    • 願意:到第 2 篇見!
    • 不願意:你可能不是一人公司老闆該有的效率思維

    系列文快速導航

    篇章標題重點你需要做什麼
    1️⃣為什麼規劃優先理解痛點讀完,認同理念
    2️⃣CLAUDE.md 編碼憲法寫一份文檔複製模板,填入自己的規則
    3️⃣設計文檔模板學會規劃為下個功能寫設計文檔
    4️⃣Hook 自動化節省時間設置 3-5 個 Hook
    5️⃣實戰:Taiwan Invoice看完整案例套用到自己的項目

    核心觀念一句話

    「規劃優先,少 prompt;文檔優先,少反覆。」

    多花 30% 規劃時間,省 70% 改動時間。

    一人公司的職責太多,不能靠「反覆試錯」活著。

    下一篇見!👋

  • Claude Code Agent Teams:從穩定執行到自動化代碼審查的完整指南

    Claude Code Agent Teams:從穩定執行到自動化代碼審查的完整指南

    本文整合三部分內容:(1) Agent Teams 的穩定執行框架;(2) 全局代碼審查規則系統的設計與實施;(3) 自動化雙 Agent 審查機制(架構師 + PM)的完整實現方案。這是一份實踐導向的指南,涵蓋從資源評估、權限配置、到自動觸發流程的所有細節。

    第一部分:Agent Teams 的三層穩定執行框架

    1.1 評估層(Assessment)— 前置資源檢查

    每次建立 Agent Team 前,必須執行三個評估動作:

    1. 記憶體現狀:執行 free -h 或查看 Docker stats,確認可用容量
    2. 計算容量:根據模型選擇計算最大並行 agent 數(opus ~1GB、sonnet ~600MB、haiku ~400MB)
    3. 決策與確認:列出 agent 角色、模型、預估記憶體,取得用戶確認後才建立

    模型選擇口訣

    • 需要「想」 → Opus(架構決策、安全設計、業務邏輯、複雜 SQL、Code Review)
    • 需要「做」 → Sonnet(CRUD 實作、API 對接、測試撰寫、文件撰寫)
    • 需要「找」 → Haiku(檔案掃描、配置對比、API 整合)

    1.2 確認層(Confirmation)— 用戶決策前置

    建立 Team 前,必須向用戶列出清晰的角色定義和資源計劃,包括:

    • 各 agent 的角色名稱與職責
    • 指定的 AI 模型及其預估記憶體
    • 總計容量和系統可用容量
    • 並行數量和預期執行順序

    只有在用戶明確確認後,才啟動 TeamCreate 和後續任務建立。這一步防止了資源耗盡、權限誤配、以及 agent 之間通訊不暢的根本原因。

    1.3 執行層(Staged Execution)— 分階段序列化

    即使資源充足,也不應讓所有 agent 同時轟炸執行。分階段策略包括:

    1. 第 1 階段:啟動基礎設施 agent(如資源管理、環境配置)
    2. 第 2 階段:啟動 researcher agent,進行資訊搜集與分析
    3. 第 3 階段:啟動 architect agent,設計方案
    4. 第 4 階段:啟動 developer agent,進行實作
    5. 第 5 階段:啟動驗證 agent,進行測試與審查

    各階段 agent 完成任務後,主動進入「空閒」狀態並通知團隊。不進行「拉取」操作,而是由前置 agent 完成後才推進下一階段。這種設計確保:

    • 前置依賴滿足後才啟動
    • 消息傳遞清晰,無需輪詢
    • 系統記憶體壓力均勻分散
    • 故障範圍可控,易於除錯

    第二部分:全局代碼審查規則系統架構

    2.1 雙層規則設計

    代碼審查規則分為兩層,確保通用性和專案適應性的平衡:

    • 全局層~/.claude/memory/):所有項目共享的代碼品質標準(SOLID 原則、Design Pattern、代碼異味、測試規範、語言特定規範)
    • 項目層項目/.claude/code-review-rules.md):專案特定的業務邏輯規則、設計稿映射、外部驗證清單

    2.2 全局規則內容結構

    code-review-global-rules.md(SOLID、Pattern、Code Smell、Testing)

    • SOLID 五項原則的定義和違反示例
    • Design Pattern 反面示例(God Object、Feature Envy 等)
    • 代碼異味檢查清單(N+1、Magic Number、過長方法、過多參數、重複代碼、複雜邏輯)
    • 單元測試最低標準(80%+ 覆蓋、邊界情況、Mock vs Real Dependency)

    code-review-languages.md(Java、Python、JavaScript/TypeScript、SQL)

    • 命名規範(類名、方法名、變數名、常數、包名)
    • 包結構約定(分層架構:domain/service/repository/validator 等)
    • 異常處理規範
    • 語言特定工具規範(Lombok、OSGi、Type Hint、Docstring 等)

    code-review-feedback.md(架構師與 PM Agent 職責和對焦框架)

    • 架構師 Agent:SOLID 遵循度(1-5 分)、Design Pattern、Code Smell、測試覆蓋、異常處理、語言規範
    • PM Agent:功能 vs 設計稿對齐、API 返回值、邊界情況、業務邏輯、用戶體驗、外部驗證需求
    • 雙方對焦框架:架構師問「代碼設計能支持你檢查的功能嗎?」,PM 反問「這些功能需求會造成架構問題嗎?」

    code-review-process.md(自動觸發、Agent 角色、聯合報告格式)

    • 觸發點:Task marked as completed
    • Agent 角色 Prompt(初版):架構師評估、PM 評估、聯合對話
    • 聯合報告格式:分離的評估 + 統一優先級排序 (P0/P1/P2)
    • 最終判定:Pass / Needs Work / Fail

    2.3 項目層規則(台灣發票系統範例)

    項目規則分為三類:

    A. 業務邏輯規則(優先級最高)
    • 進項稅計算公式(進項稅金額 = 發票金額 × 5%,DECIMAL(19,2) 向下取整)
    • 三聯式(不含稅)vs 二聯式(含稅)的會計處理邏輯
    • 進項稅折讓的強制申報期限(當期內必須申報,無延後例外)
    • 兼營營業人的比例扣抵公式(可扣抵進項稅 = 總進項稅 × (應稅銷售額 / 總銷售額))
    • 發票號碼連續性檢查和遺失空白發票記錄
    • 發票開立日期 → 申報期間的映射(1-2月→第1期、3-4月→第2期 等,共六期)
    B. 設計稿對齐規則(優先級次之)
    • API 端點的返回格式和欄位定義
    • 邊界情況的預期響應(零金額、負數、超大金額)
    • 數據型態和範圍檢查
    C. 外部驗證清單(優先級最低,但定期更新)
    • 進項稅可扣抵期限是否仍為 10 年
    • 電子發票強制規定的生效狀態
    • 設計稿版本確認
    • 技術規範(iDempiere PO 模型、OSGi Bundle)

    第三部分:自動化雙 Agent 審查機制的實現

    3.1 TaskCompleted Hook 配置

    .claude/settings.local.json 中配置 TaskCompleted Hook,每當任務標記完成時,自動觸發架構師和 PM 兩個 agent 進行深度審查:

    {
      "hooks": {
        "TaskCompleted": [
          {
            "hooks": [
              {
                "type": "agent",
                "prompt": "Conduct comprehensive code review: (1) Architecture: SOLID principles (1-5), design patterns, code smells (P0/P1/P2), testing, exceptions. (2) Functional: spec alignment, API contracts, boundary cases, business logic (Taiwan tax rules). Provide unified P0/P1/P2 priority with Pass/Needs Work/Fail decision and file:line recommendations.",
                "model": "opus",
                "statusMessage": "Running code review on completed task...",
                "timeout": 300
              }
            ]
          }
        ]
      }
    }

    3.2 架構師 Agent 職責細節

    架構師 Agent 按以下維度進行評估,每項 1-5 分自評:

    1. SOLID 原則遵循度:檢查 S(單一職責)、O(開閉)、L(里氏替換)、I(接口隔離)、D(依賴倒轉)五項是否遵循
    2. Design Pattern 應用恰當性:是否應用了合適的設計模式,是否存在過度設計
    3. 代碼異味程度:N+1 查詢、Magic Number、過長方法(>20 行)、過多參數(>3 個)、重複代碼、複雜邏輯(圈複雜度 > 10)
    4. 測試覆蓋度:目標 80%+,是否涵蓋邊界情況(null、empty、max/min)
    5. 異常處理完整性:是否避免過寬泛的異常捕捉,異常信息是否有意義,是否吞掉異常
    6. 語言特定規範遵循度:根據 code-review-languages.md 檢查命名、包結構、工具使用規範

    輸出:各維度評分 + 具體改進建議(標記優先級 P0/P1/P2 和代碼位置)

    3.3 PM Agent 職責細節(含 QA)

    PM Agent 進行務實檢查,確保功能實現和業務邏輯正確性:

    1. 功能 vs 設計稿對齐:設計稿的所有功能點是否實現,是否有範圍蠕動
    2. API 返回值對齐:返回欄位是否與文檔一致,資料型態是否正確,必需欄位是否都有
    3. 邊界情況涵蓋:null 輸入、空集合、最大值/最小值、負數、零值是否處理
    4. 業務邏輯正確性:根據項目規則(進項稅計算、發票號碼、申報期間映射等)是否正確
    5. 用戶體驗:錯誤提示是否清楚,用戶流程是否順暢,是否有令人困惑的行為
    6. 外部驗證需求:是否需要查證業務規定(優先 C)、設計稿(優先 A)、技術規範(優先 B)

    輸出:功能層缺陷清單、QA 項目、待驗證項(註明 C/A/B 優先級)

    3.4 聯合報告與優先級統一排序

    架構師和 PM 分別完成評估後,進行深度對話:

    • 架構師問 PM:「代碼結構能支持你檢查的功能嗎?」
    • PM 反問架構師:「這些功能需求會造成架構問題嗎?」

    基於對話結果,生成聯合報告:

    • P0(Critical):N+1 查詢、安全漏洞、死鎖風險、未處理的邊界情況、違反台灣稅務規則
    • P1(Important):過長方法、重複代碼、Magic Number、缺失測試、不清晰的錯誤提示
    • P2(Nice to Have):輔助方法提取、考慮設計模式、日誌增強

    最終判定

    • Pass:P0 問題 0 個,P1 問題可接受(≤2 個或不影響核心功能)
    • ⚠️ Needs Work:P0 問題 1-3 個,或 P1 問題 >3 個,或測試覆蓋度 <70%
    • Fail:P0 問題 ≥3 個,或安全漏洞,或違反重要法規

    第四部分:審查流程與反覆迭代

    4.1 外部驗證流程

    當 PM Agent 提出待驗證項時,按優先級啟動查詢:

    優先級 C(業務邏輯)— 需人工驗證
    • 用戶透過稅務官網或法規文件進行人工查證(AI 查詢易出錯)
    • 驗證結果更新到項目規則
    • 重新審查涉及的代碼
    優先級 A(設計稿)— 查閱項目文檔
    • 查閱設計文件、API 文檔
    • 如無對應文件,提示用戶補充
    • 確認後更新 code-review-rules.md
    優先級 B(技術規範)— 查詢官方文檔
    • 查詢 iDempiere、OSGi 官方文檔
    • 標記為參考(變動機會低)

    4.2 修改與重審流程

    當報告判定為 Needs Work 或 Fail 時:

    1. 開發者查看報告,收到 P0/P1/P2 改進清單
    2. 開發者修改代碼並完成新測試
    3. 重新標記 Task 為 completed(或手動觸發 /code-review-force)
    4. 自動重審(流程回到架構師 + PM 評估)
    5. 迴圈進行,直到最終判定 Pass

    第五部分:系統集成與迭代計劃

    5.1 全局記憶結構

    所有規則和流程信息保存在用戶的全局記憶庫中:

    • ~/.claude/memory/code-review-global-rules.md — SOLID、Pattern、Code Smell、Testing
    • ~/.claude/memory/code-review-languages.md — Java、Python、JS、SQL 規範
    • ~/.claude/memory/code-review-feedback.md — 架構師/PM 職責與對焦框架
    • ~/.claude/memory/code-review-process.md — 自動觸發、報告格式、判定標準

    5.2 項目級別記憶結構

    • 項目/.claude/code-review-rules.md — 業務邏輯規則 + 設計稿映射 + 外部驗證清單
    • 項目/.claude/settings.local.json — TaskCompleted Hook 配置

    5.3 三個迭代階段

    Phase 1(現在)
    • 建立全局規則知識庫(4 個記憶文件)
    • 編寫項目層規則(code-review-rules.md)
    • 配置 TaskCompleted Hook
    • 在項目中試用審查機制
    Phase 2(2-4 週後)
    • 根據實際審查結果優化規則(哪些規則發現了 bug、哪些規則太寬泛)
    • 改進 Agent Prompt(增加上下文、更清晰的指導)
    • 補充項目層規則細節(特別是邊界情況和特殊規則)
    Phase 3(1-2 月後)
    • 考慮集成到 CI/CD(每次 PR 自動審查)
    • 累積審查報告,形成項目代碼品質歷史
    • 調整 Hook 超時和 Agent 模型選擇

    第六部分:常見問題與實踐建議

    Q1:如果審查花太長時間怎麼辦?

    A:初版 timeout 設為 300 秒。如果超時,可調整為 600 秒,或簡化 Agent Prompt 去掉某些維度。對大型代碼改動,可分成多個小 Task,每個分別審查。

    Q2:外部驗證項目誰負責查證?

    A:初版由用戶或 PM 手動查證(特別是業務邏輯 C 項)。後續可考慮集成更多自動化(如 WebSearch for C 項、文檔連接 for A 項)。

    Q3:PM Agent 如何知道設計稿的內容?

    A:初版需在 code-review-rules.md 的 B 項中維護設計稿摘要(API 返回格式、欄位定義、邊界情況)。後續可考慮直接連接設計文件或 API 文檔鏈接。

    Q4:審查報告輸出到哪裡?

    A:初版直接輸出到對話(用戶可複製保存或導出)。後續可考慮存到 Task comment、Markdown 文件或項目文檔。

    Q5:如何確保 Agent Teams 穩定運行?

    A:遵循三層框架:

    • 評估層:前置資源檢查和確認,不盲目建立 Team
    • 確認層:列出角色、模型、容量,取得用戶確認
    • 執行層:分階段序列化,避免並行轟炸,讓 agent 主動進入空閒狀態而不是被拉取

    以及定期檢查記憶體、監控 agent 通訊、設置合理的超時時間。

    結論

    穩定可信的 Agent Teams 不是靠運氣,而是靠紮實的前置規劃、清晰的資源評估、以及精心設計的執行流程。本文提供的三層框架(評估→確認→分階段執行)確保了 Team 運行的穩定性。配合全局規則庫 + 項目規則 + 自動審查機制,可以建立一套完整的代碼品質保證體系,既有通用性,也有靈活性。

    從 Phase 1 的試用開始,逐步優化規則和 Agent Prompt,經過 2-4 週的實踐,可以達到穩定的審查效果。最終目標是讓代碼審查成為自動化流程的一部分,開發者無需手動申請審查,系統自動評估和反饋,確保每個 Task 完成時都經過架構師和 PM 的雙重把關。

  • 舊系統不死,AI 讓它進化:不重寫也能持續成長

    重點摘要

    • 舊系統不是問題,缺乏 AI 輔助才是問題——AI 讓「不重寫、持續演進」成為可行選項
    • 歷史證明:超過 80% 的「重寫計畫」以失敗或兩個系統都要維護收場
    • AI 最確定的價值是讀懂舊代碼、補文件、補測試,讓團隊敢繼續開發
    • 「AI 能不能讓大規模翻新變安全」——這是尚待驗證的命題,不宜過度樂觀

    你的公司有一套跑了十年的系統。它能動,它撐起了整個業務,但沒有人敢碰它。文件不齊、邏輯散落在各處、原始開發者早就離職了。每次有人提議「重寫」,討論就會陷入沉默——因為大家心裡都知道,這條路走過很多次,沒幾次是成功的。

    AI 的出現,讓這個困境有了新的解法。但不是你想像中的那種解法。

    為什麼重寫這麼難?歷史給了殘酷的答案

    軟體界有個著名的現象叫做 Second System Effect(第二系統效應),由《人月神話》作者 Fred Brooks 提出:工程師在重寫時,往往會把所有「本來想做卻沒做」的功能都塞進去,結果新系統比舊系統更複雜、更難維護。

    但更根本的問題是:舊系統裡有隱藏的業務邏輯,它們沒有寫在文件裡,只存在於代碼的行為中——某個奇怪的判斷式、某個例外處理、某個只在特定情境才觸發的路徑。這些邏輯,是十年來無數個「為什麼這樣做?」的答案。

    重寫計畫的典型失敗模式

    • 兩個系統並行期拉太長:新舊系統同時維護,工程師精力分散,bug 在兩邊都出現
    • 上線那天發現漏了邏輯:舊系統某個角落的行為,新系統根本沒有對應
    • 商業壓力中斷重寫:計畫進行到一半,業務需求改變,只能把新舊系統黏在一起
    • 重寫後反而更慢:新架構雖然「漂亮」,但少了十年累積的效能優化細節

    這不是悲觀,這是現實。重寫不是不可能,但它的成功率遠低於大多數人的預期。在 AI 出現之前,面對舊系統,企業只有兩條路:硬撐,或者賭一把。

    AI 帶來了第三條路:輔助成長

    AI 最確定的價值,不是幫你重寫系統,而是讓「不重寫、持續演進」這件事變得可持續。

    過去,舊系統的最大問題不是代碼本身,而是「沒有人理解它」。原始開發者離職了,知識沒有傳承;文件過時了,沒有人有時間更新;要改一個功能,必須花三天理解上下文,才敢動一行代碼。

    AI 改變了這個方程式。

    AI 能為舊系統做什麼?

    挑戰 過去的困境 AI 輔助後
    理解舊代碼 要花幾天甚至幾週閱讀 AI 幾分鐘內產出架構圖和流程說明
    補充文件 沒時間寫、寫了也快過時 AI 根據現有代碼生成,每次修改後更新
    補充測試 舊系統通常 0 測試,改動沒有安全網 AI 針對現有行為補寫測試,改動有保護
    修復 bug 怕改了 A 壞了 B,只敢最小化改動 AI 追蹤影響範圍,降低連帶破壞風險
    新人上手 要跟著老人學幾個月才敢動 AI 隨時解釋任何一段代碼的邏輯和背景
    新增功能 不知道該插在哪裡,怕破壞現有邏輯 AI 建議最小侵入式的擴充點

    實際做法:AI 如何輔助舊系統成長

    第一步:讓 AI 讀懂系統,產出活的文件

    不要急著改代碼。第一件事是讓 AI 理解現有系統,然後把理解結果固化成文件。

    # 讓 AI 讀整個 codebase,產出架構說明
    # 在 Claude Code 中,直接描述你的需求:
    
    「請閱讀這個專案的所有代碼,並產出:
    1. 系統架構圖(模組與模組之間的關係)
    2. 核心業務流程說明(從使用者角度描述主要流程)
    3. 高風險區域列表(邏輯最複雜、最不敢動的地方)
    4. 技術債清單(有哪些地方明顯需要改善)」

    這份文件不是給外部人看的,是給你的團隊每天使用的工作手冊。它會隨著系統改動而更新——這一點很重要,因為過去文件之所以沒用,是因為沒有人有時間維護它。AI 讓維護文件的成本降低了 90%。

    第二步:為現有行為補測試,建立安全網

    舊系統的問題不是「代碼爛」,而是「沒有測試保護」。任何一個修改都是在沒有安全網的情況下走鋼絲。

    AI 可以閱讀現有代碼,理解它的行為,然後為這些行為寫測試——即使這些行為從來沒有文件。

    # 範例:讓 AI 為現有函式補測試
    「這個函式 calculateDiscount() 已經跑了八年,
    請分析它的所有分支條件,為每個分支寫一個測試案例,
    包括正常情況、邊界值和異常情況。
    不要改動現有邏輯,只補充測試。」

    有了測試,團隊才敢改動。改動有安全網,系統才能持續演進而不是不斷累積技術債。

    第三步:最小侵入式地新增功能

    新增功能不等於重構整個模組。AI 擅長找到「最小侵入式的擴充點」——在不動現有邏輯的前提下,把新功能插進去。

    這個原則來自 Open/Closed Principle(開放封閉原則):對擴充開放,對修改封閉。即使舊系統沒有遵循這個原則,AI 也可以建議如何在外圍包一層,讓新功能不影響舊邏輯。

    第四步:漸進式現代化,而非大爆炸式重寫

    如果真的有部分需要改善,AI 輔助的方式是:一次只動一個模組,改完之後讓它穩定跑一段時間,確認沒有問題再動下一個。

    這不是「重寫」,這是「漸進式現代化」。兩者的關鍵差異:

    重寫 漸進式現代化
    範圍 全部 一次一個模組
    風險 集中在上線日 分散,每步都可以回滾
    業務中斷 長期並行維護兩個系統 系統持續運作,局部更新
    AI 的角色 「幫我重新實作這一切」 「幫我安全地改善這一塊」

    那麼,「重寫」這條路呢?

    這是一個需要誠實面對的問題。

    過去的答案很清楚:重寫計畫成功率低,風險高,通常不是好選擇。大多數成功的案例,仔細看都是「漸進式替換」而不是「一次性重寫」。

    AI 會改變這個答案嗎?

    這是一個尚待驗證的命題。AI 確實讓理解舊系統更容易,讓知識遷移成本降低,理論上應該讓重寫的準備工作做得更完整。但「做得更完整的準備」不等於「執行時不會出問題」。隱藏的業務邏輯、時序問題、效能細節——這些在代碼裡只有在跑了幾百萬筆資料之後才會浮現。

    更誠實的說法是:

    • AI 讓「輔助成長」這條路變得可行——這是現在就可以驗證的事
    • AI 讓「重寫」變得更安全——這是有可能的,但還需要更多實際案例來驗證
    • AI 能取代「漸進式替換」的謹慎原則——不太可能,這個原則的價值在於限制風險暴露,而不是技術能力

    所以,如果有人告訴你「有了 AI,重寫就不危險了」——保持懷疑。如果有人告訴你「AI 讓你不需要擔心舊系統的技術債了」——同樣保持懷疑。

    如何判斷你的系統需要什麼?

    面對舊系統,用這個框架來判斷方向:

    優先考慮 AI 輔助成長,如果:

    • 系統仍然在提供商業價值,只是難以維護
    • 核心業務邏輯複雜,沒有人完整理解
    • 團隊規模小,無法支撐兩個系統並行
    • 業務需求變化頻繁,不能停下來等重寫完成

    可以考慮漸進式替換(不是重寫),如果:

    • 某個模組已經明顯成為瓶頸,且邊界清晰
    • 有足夠的測試保護現有行為
    • 可以部署影子流量,讓新舊模組並行驗證
    • 有明確的回滾機制

    謹慎考慮大規模重寫,只有當:

    • 現有系統在技術上已經無法繼續擴充(不只是難,而是真的不可能)
    • 有足夠的資源支撐至少 18 個月的並行期
    • 有完整的行為規格文件(或 AI 幫你產出的等效文件)
    • 組織願意接受在過渡期期間功能停滯

    結語:舊系統不是問題,缺乏支援才是

    回到最初的問題:那套跑了十年的系統,它的問題不是年齡,而是孤立。沒有人理解它,沒有測試保護它,沒有文件說明它,改動它需要承擔巨大的個人風險。

    AI 能做的,是讓這個系統不再孤立。它可以成為每個工程師的「老前輩」——隨時解釋任何一段邏輯,隨時分析改動的影響,隨時生成測試保護現有行為。

    這不是重寫的故事,這是陪伴成長的故事。

    至於重寫——如果未來真的需要,AI 會讓你準備得更充分。但那是另一個故事,而且它的結局還沒有寫完。

  • 10 年舊系統如何安全導入 AI 開發:Strangler Fig 遷移方法論

    重點摘要

    • 10 年的舊系統能跑就是最有價值的資產,不要試圖先修好再遷移
    • 核心方法論:Strangler Fig 模式 — 新軌道在旁邊長起來,舊系統自然退場
    • AI 第一件事不是寫 code,而是讀懂 10 年的系統邏輯,再動手
    • 四個階段:快照現況 → 建平行新軌 → 一次搬一個服務 → 封存舊系統

    你的系統跑了 10 年。它很髒、沒有文件、CI/CD 靠手動、密碼可能在 .env 裡或者在某個工程師的腦袋裡。但它能跑,而且在服務真實的用戶。

    現在你想引入 AI 輔助開發,想現代化整個工作流。問題來了:要從哪裡開始? 要先把舊的修乾淨,還是直接用新方法?

    錯誤的答案是:「先把舊的修好。」正確的答案是:不要動正在跑的東西,在旁邊建一條新軌道。

    為什麼「先修好再用新方法」行不通?

    這個直覺很自然,但在實際工程上幾乎都會失敗,原因有三:

    1. 無法停止開發等你修 — 業務不會暫停,新需求還是會進來,你邊修邊開發,舊問題永遠追不完
    2. 「修好」的定義會不斷移動 — 一開始說只要加 .gitignore,結果發現歷史有密碼,要 filter-repo,然後發現測試覆蓋率是零…沒有終點
    3. 你在修一個不完全理解的系統 — 10 年的系統有太多隱性知識,修的過程中很容易把「能跑的」改成「不能跑的」

    工程界有一個著名的模式專門解決這個問題,叫做 Strangler Fig(絞殺榕)模式

    Strangler Fig 模式:不砍舊樹,讓新藤蔓長過去

    絞殺榕是一種熱帶植物。它的種子落在老樹上,慢慢向下長出根,包住舊樹,最後舊樹自然退場,絞殺榕站立在原位。整個過程中,舊樹從未停止「提供支撐」,直到新系統完全就緒。

    應用到 DevOps 遷移:

    ❌ 錯誤思維:
    舊系統(停機)→ 修好 → 接新流程 → 恢復服務
    
    ✅ 正確思維(Strangler Fig):
    舊系統(持續運行,不動)
        ↓
    新軌道在旁邊建立(不影響舊系統)
        ↓
    一次搬一個服務,驗證後切換流量
        ↓
    所有服務搬完,舊系統自然退場

    關鍵洞察:能跑的系統是你最有價值的資產,不是問題的來源。遷移的目標是「讓它繼續跑,同時讓新系統在旁邊成長」,不是「讓它停下來修好再說」。

    四個階段的完整遷移方法論

    階段一:快照現況(不動任何東西)

    第一步不是改 code,不是設定 CI/CD,而是把「現在是怎麼跑起來的」完整記錄下來。這份快照是整個遷移過程的地基。

    為什麼要快照?因為在 10 年的系統裡,repo 裡的 .env 可能是舊的,文件可能是錯的,只有正在跑的進程才是真相:

    # 從正在跑的容器抽出真實的環境變數
    docker inspect <container_name> \
      --format='{{range .Config.Env}}{{println .}}{{end}}' \
      > /tmp/real-env-snapshot.txt
    
    # 或直接讀進程的環境變數
    cat /proc/$(pgrep java)/environ | tr '\0' '\n' | grep -E "DB_|API_|SECRET_"
    
    # K8s 環境
    kubectl get pods -n production -o name | while read pod; do
      echo "=== $pod ==="
      kubectl exec $pod -n production -- env 2>/dev/null
    done > /tmp/real-k8s-env-snapshot.txt

    同時盤點服務清單和依賴關係:

    # 有哪些服務在跑
    docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
    
    # 服務之間怎麼通訊
    docker network inspect bridge
    
    # 對外開放哪些 port
    ss -tlnp | grep LISTEN

    這個階段的產出是一份真實架構圖和一份真實密碼清單(妥善保管,不進任何 repo)。

    階段二:AI 讀懂你的系統

    這是大多數人忽略的步驟,也是決定 AI 協作能否成功的關鍵。

    AI 第一件事不是寫 code。

    在 AI 動手之前,它需要讀你 10 年的系統。這個過程大概需要幾天,但會產出你可能從未有過的東西:

    AI 讀完後的產出 為什麼重要
    系統架構圖 你們可能自己也沒有,新人上手和遷移規劃的基礎
    模組依賴關係 知道改哪個地方會影響哪些服務
    高風險區域標記 「這段 code 10 個人改過,有 3 個已知 bug 的修復」
    技術債清單(按影響排序) 知道先解決什麼,不是看到髒的就改
    新人上手文件 從 code 反推出來,不需要老工程師口傳

    這個階段同樣不動任何 code。AI 只是閱讀和理解。等到真正開始寫新功能時,AI 已經知道你的系統慣例是什麼、有哪些地雷不能踩。

    階段三:建立平行的新軌道

    新建一個乾淨的 repo,在旁邊建立完整的現代化工作流,舊 repo 繼續照舊運作

    舊 GitLab repo(繼續跑,不動)
         │
         │  正在服務用戶的系統
         │
    新 repo(乾淨起點)
         │
         ├─ 正確的 .gitignore(.env 全部排除)
         ├─ CI/CD pipeline(gitleaks + build + sign)
         ├─ K8s Secrets(從快照搬進來)
         └─ Branch Protection Rules

    把真實密碼從快照搬到 K8s Secrets(不是從舊 repo 搬,是從正在跑的進程抽出來):

    # 從快照建立 K8s Secrets
    kubectl create secret generic app-prod-creds \
      --from-literal=DB_PASSWORD="$(grep DB_PASSWORD /tmp/real-env-snapshot.txt | cut -d= -f2)" \
      --from-literal=SHOPEE_KEY="$(grep SHOPEE_KEY /tmp/real-env-snapshot.txt | cut -d= -f2)" \
      -n production
    
    # 建立完成後,安全刪除快照
    shred -u /tmp/real-env-snapshot.txt

    階段四:一次搬一個服務

    這是遷移的主體。原則是:每次只搬一個服務,驗證通過才搬下一個

    服務搬移的優先順序建議:

    優先順序 選擇原則 理由
    第一批 流量最小的非核心服務 風險最低,可以放心試錯
    第二批 獨立性高、依賴少的服務 不會牽一髮動全身
    最後 核心業務邏輯(訂單、付款) 等前幾批證明新流程可靠後再動

    每個服務的搬移步驟:

    1. AI 在新 repo 重寫該服務的乾淨版本(理解舊 code 後重寫,不是 copy paste)
    2. Jenkins 構建新鏡像,部署到 Staging
    3. 用影子流量驗證新舊行為一致(新舊同時收請求,比對回應)
    4. 確認無誤,切換這個服務的流量到新系統
    5. 觀察 24-48 小時
    6. 舊服務下線

    影子流量驗證(用 nginx 實現,不影響用戶):

    # nginx 配置:新舊同時收請求,比對行為
    location /api/orders {
        mirror /mirror-new;       # 複製請求到新系統
        proxy_pass http://old-api; # 用戶實際收到舊系統的回應
    }
    
    location = /mirror-new {
        internal;
        proxy_pass http://new-api;  # 新系統的回應只寫 log,不回傳用戶
    }

    AI 在整個過程中的實際角色

    理解了遷移方法論後,AI 在這個過程中的職責非常清楚:

    AI 能做(且做得很好):
      ✅ 讀 10 年的舊 code,產出架構文件
      ✅ 識別技術債,按優先順序排列
      ✅ 用「符合你們系統慣例」的方式寫新功能
      ✅ 在 feature branch 開發,開 MR,等你 review
      ✅ 補測試(補現有 code 的測試覆蓋率)
      ✅ Debug(分析 log,找根因)
      ✅ 在新服務和舊系統的接縫處寫 adapter
    
    AI 不能做(也不應該做):
      ❌ 直接 push 到 main 或 production branch
      ❌ 決定什麼時候切換流量
      ❌ 接觸任何密碼或 production secrets
      ❌ 在沒有充分理解舊系統的情況下動手

    一個典型的 AI 協作對話長這樣:

    你:「我要加一個批次出貨的功能」
    
    AI:「讓我先讀一下現有的出貨相關 code...
         我看到 OrderService.java 的 shipOrder()
         和 ShipmentRepository,還有一個舊的
         BatchJob 在 legacy/ 目錄。
    
         注意:legacy/BatchJob 有個已知的
         transaction 問題(commit a3f2c1b 的修復紀錄),
         新功能要避開。
    
         建議的實作方向是...你確認嗎?」
    
    你:「方向對,去做吧」
    
    AI:「好,我開 feature/batch-shipment,
         預計改動:
         - 新增 BatchShipmentService(核心邏輯)
         - 修改 OrderController(加 API endpoint)
         - 不動 legacy/ 目錄
         
         完成後開 MR 給你 review」

    AI 因為讀過 10 年的系統,不會做出「不符合你們慣例」的 code,也不會踩進已知的地雷。

    最常遇到的三個現實問題

    問題一:「不知道哪個 .env 是現在真正在用的」

    10 年的系統通常有多個 .env 版本,有的是舊的,有的是工程師自己改過的。以正在跑的進程為準,不要相信文件

    # 找到 Java 進程真正使用的環境變數
    cat /proc/$(pgrep java)/environ | tr '\0' '\n' | grep -E "DB_|API_|SECRET_"
    
    # 不要用
    cat .env  # 這可能是 6 個月前的版本

    問題二:「團隊還在開發,不能凍結」

    不需要凍結。舊 repo 繼續用,新 repo 並行開發。重要的 bugfix 透過 cherry-pick 同步:

    舊 repo: feature → dev → main(繼續照舊)
                  │
                  └─ cherry-pick 重要修復
                          │
    新 repo:              └─ feature → dev → main(新流程)

    問題三:「歷史 commit 有密碼怎麼辦」

    分兩步處理:

    1. 立即輪換所有洩露的密碼 — 因為 GitHub/GitLab 可能已有快取,這一步不能等
    2. 舊 repo 等到遷移完成後再 archive — 不需要現在重寫歷史,新 repo 一開始就是乾淨的

    注意:很多人以為 git rm --cached .env 就安全了,但舊 commit 裡的內容仍然可以被 git show <old-commit>:.env 讀出。唯一的技術修復是 git filter-repo,但遷移方法論讓你可以跳過這一步——因為所有新開發都在新的乾淨 repo 上進行。

    時間軸規劃

    時間 工作 風險
    第 1 週 快照現況、輪換外部 API Key、AI 開始讀系統 零(不動任何 code)
    第 2-4 週 建新 repo、CI/CD pipeline、K8s Secrets、第一個服務搬過去 低(影子流量驗證)
    第 1-3 個月 逐服務遷移,每個驗證 24-48 小時後才繼續 中(每次只影響一個服務)
    遷移完成後 舊 repo archive、完整安全強化(RBAC、Audit Log、鏡像簽名) 低(新系統已穩定)

    決策樹:你現在該從哪裡開始

    你的系統現在能跑嗎?
      │
      ├─ 能跑 → 用 Strangler Fig 模式(本文的方法)
      │           │
      │           ├─ 步驟 1:快照現況(本週就做)
      │           ├─ 步驟 2:AI 讀系統(同步進行)
      │           ├─ 步驟 3:建新軌道(第 2-4 週)
      │           └─ 步驟 4:逐服務遷移(之後)
      │
      └─ 不能跑 → 先讓它跑起來,再回到這裡

    這套方法論的本質

    Strangler Fig 模式應用在 AI 輔助開發遷移上,核心洞察只有一個:

    「10 年的技術債是過去的決策的結果,你無法在不破壞現有價值的情況下一次消除它。但你可以選擇:從今天開始,所有新的工作都用正確的方式做。」

    舊系統是你團隊的集體記憶,AI 有能力閱讀並理解這些記憶,然後用現代化的方式繼續往前走。不需要推倒重建,也不需要凍結開發去修舊債——只需要一條平行的新軌道,和耐心地一次移動一個服務。

    想了解新軌道的 CI/CD 具體設計,可以參考上一篇文章:AI 輔助開發 CI/CD 工作流:Jenkins、K8s、ISO 27001 完整設計

  • AI 輔助開發 CI/CD 工作流:Jenkins、K8s、ISO 27001 完整設計

    重點摘要

    • AI 只負責寫 code、提 PR,不碰版本決策和 Production 部署,人類保留最終控制權
    • 透過 Git tag 觸發 Jenkins,Staging 全自動部署、Production 手動 helm 執行,兩階段驗證才上線
    • 敏感資訊三層隔離:.gitignore → K8s Secrets → etcd 加密,密碼永遠不進 repo
    • 補齊 RBAC、Audit Log、鏡像簽名、Secrets Scan 四大安全缺口,達到 ISO 27001 合規

    AI 輔助開發越來越普遍,但大多數團隊面臨同一個問題:AI 寫的 code 要怎麼安全地上線? 誰決定部署時機?密碼怎麼管?如果 AI 出錯了,有什麼防護網?

    本篇文章完整說明 ONEEC OMS 系統實際採用的 AI 協作工作流設計,包含完整的 User Story、Jenkins Pipeline 架構、三環境部署策略,以及通過安全審查後補齊的 RBAC、Audit Log、鏡像簽名等安全強化配置。

    核心設計理念:人類掌控節奏,AI 加速執行

    這套工作流的核心原則只有一句話:AI 是高效能的執行者,不是決策者。具體體現在以下四點:

    • AI 負責:寫 code、建 Dockerfile、提 PR、提供 Jenkins script 和 Helm chart
    • 用戶負責:code review、創建 git tag(決定版本和部署時機)、手動 helm 部署到 Production
    • 運維負責:管理 K8s Secrets、設定 Jenkins credentials、維護集群
    • 敏感資訊:密碼、API Key、SSL 憑證永遠不進入 Git repo

    完整 User Story:從需求到上線的 10 個步驟

    以下用一個真實場景說明整個流程:場景:優化訂單 API 的查詢效能

    Step 1:AI 開發(feature branch)

    AI 從 dev 分支切出 feature branch,完成開發後推送 PR:

    # AI 執行
    git checkout dev && git pull origin dev
    git checkout -b feature/order-api-optimize
    
    # 編寫程式碼...
    
    # 本地驗證
    docker-compose up -d
    curl http://localhost:8080/api/orders?status=pending
    # ✅ 回傳正確,效能提升 30%
    
    # 提交並推送
    git add . && git commit -m "feat(order-api): optimize query performance"
    git push origin feature/order-api-optimize
    # 建立 PR → dev

    Step 2:用戶 Code Review & Merge

    用戶在 GitHub UI 審查 PR:確認邏輯正確、有測試覆蓋、無敏感資訊後 approve 並 merge 到 dev。此時沒有任何自動化觸發,代碼靜靜等待部署決策。

    Step 3:用戶創建 Staging Tag → Jenkins 自動觸發

    用戶決定要部署到測試環境時,創建一個 staging-v* tag:

    # 用戶執行
    git tag staging-v1.0.1
    git push origin staging-v1.0.1
    
    # GitHub Webhook → Jenkins 自動執行:
    # ├─ Secrets 掃描(gitleaks)
    # ├─ docker build(所有 pods)
    # ├─ cosign 簽名鏡像
    # ├─ docker push to registry
    # ├─ helm deploy to Staging K8s(使用 values-staging.yaml)
    # └─ 通知用戶:Staging v1.0.1 is live

    Step 4:用戶在 Staging 驗證

    kubectl get pods -n staging
    curl https://staging-api.example.com/api/orders?status=pending
    # ✅ 功能正常,效能優化生效
    # ✅ 錯誤率 0%
    # ✅ 回應時間 < 100ms

    Step 5:用戶創建 Production Tag → Jenkins 構建正式鏡像

    # 用戶執行(確認 Staging 無誤後)
    git tag v1.0.1
    git push origin v1.0.1
    
    # Jenkins 執行:
    # ├─ Secrets 掃描
    # ├─ docker build(所有 pods,tag 改為 v1.0.1)
    # ├─ cosign 簽名鏡像
    # ├─ docker push to registry
    # ├─ 生成 Helm values(不含敏感資訊)
    # └─ 通知用戶:Images ready, run helm command

    Step 6:用戶手動部署到 Production

    Production 部署是整個流程中唯一純手動的步驟,這是刻意設計的——確保每一次正式上線都有人類判斷:

    # 用戶在本機執行
    helm upgrade --install order-api \
      /path/to/your/prod-configs/order-api/values-prod.yaml \
      --set image.tag=v1.0.1 \
      -n production
    
    # K8s 自動從 Secrets 注入密碼、API Key
    # Kyverno 自動驗證鏡像簽名(未簽名直接拒絕)
    # Deployment 完成 ✅

    Step 7:監控確認上線成功

    kubectl get pods -n production
    curl https://api.example.com/api/orders?status=pending
    # ✅ 正式環境驗證通過,上線成功

    三個部署環境的定義與分工

    環境 用途 部署方式 配置來源 觸發者
    Dev 本地開發驗證 docker-compose up .env.dev AI(開發時)
    Staging 測試環境(K8s) Jenkins 自動部署 values-staging.yaml(在 repo) 用戶(tag 觸發)
    Production 正式環境(K8s) 手動 helm 部署 values-prod.yaml(用戶維護)+ K8s Secrets 用戶(手動執行)

    Jenkins Pipeline 完整架構

    Jenkins Pipeline 由 GitHub Webhook(tag push)觸發,整個流程分為 6 個 Stage:

    Stage 0:Secrets 掃描(安全門控)

    這是整個 Pipeline 的第一道防線,也是最重要的安全門控。使用 gitleaks 掃描 repo 中是否含有密碼、API Key 等敏感資訊,發現即中止構建並通知安全告警

    stage('Secrets Scan') {
        steps {
            sh '''
                gitleaks detect \
                  --source . \
                  --config .gitleaks.toml \
                  --exit-code 1 \
                  --report-format json \
                  --report-path gitleaks-report.json
            '''
        }
        post {
            failure {
                sh 'sh scripts/notify-security-alert.sh ${TAG_NAME} gitleaks-report.json'
                error('❌ Secrets 掃描發現敏感資訊,構建中止!')
            }
        }
    }

    Stage 1:Tag 偵測(決定部署目標)

    根據 tag 名稱判斷本次構建的部署目標:

    stage('Detect Tag') {
        steps {
            script {
                if (env.TAG_NAME =~ /^staging-v.*/) {
                    env.DEPLOYMENT_ENV = 'staging'
                } else if (env.TAG_NAME =~ /^v.*/) {
                    env.DEPLOYMENT_ENV = 'production'
                } else {
                    error("❌ 未知 tag 格式: ${env.TAG_NAME}")
                }
            }
        }
    }

    Stage 2:Build Images

    構建所有 Pod 的 Docker 鏡像。鏡像本身不含任何配置、密碼、API Key,這是配置與代碼分離的核心原則:

    #!/bin/bash
    # scripts/build-docker.sh
    TAG=$1
    
    docker build -t registry.example.com/order-api:${TAG} ./simpleec-api
    docker build -t registry.example.com/user-app:${TAG} ./user-app
    docker build -t registry.example.com/channel-job:${TAG} ./simpleec-channel-job
    # ... 所有 pods

    Stage 3:Sign Images(供應鏈安全)

    使用 cosign 為每個鏡像簽名,確保 Production 只能部署來自 Jenkins 的受信任鏡像:

    stage('Sign Images') {
        steps {
            withCredentials([file(credentialsId: 'cosign-private-key', variable: 'COSIGN_KEY')]) {
                sh 'sh scripts/sign-docker.sh ${TAG_NAME} ${COSIGN_KEY}'
            }
        }
    }
    
    # scripts/sign-docker.sh
    for IMAGE in "${IMAGES[@]}"; do
        cosign sign --key "${COSIGN_KEY}" \
          --tlog-upload=false \
          "${IMAGE}"
    done

    Stage 4:Push Images

    推送到 Docker Registry。Registry 啟用 Immutable Tags,同一個 tag 無法被覆蓋,確保版本不可篡改:

    stage('Push Images') {
        steps {
            withCredentials([usernamePassword(
                credentialsId: 'docker-registry-creds',
                usernameVariable: 'REGISTRY_USER',
                passwordVariable: 'REGISTRY_PASS'
            )]) {
                sh 'sh scripts/push-docker.sh ${TAG_NAME}'
            }
        }
    }

    Stage 5a(Staging):自動部署到 Staging K8s

    stage('Deploy to Staging') {
        when { expression { env.DEPLOYMENT_ENV == 'staging' } }
        steps {
            withCredentials([file(credentialsId: 'kubeconfig-staging', variable: 'KUBECONFIG')]) {
                sh '''
                    helm upgrade --install order-api ./k8s/helm/order-api \
                      --values ./k8s/helm/order-api/values-staging.yaml \
                      --set image.tag=${TAG_NAME} \
                      -n staging
                '''
            }
        }
    }

    Stage 5b(Production):生成 Helm Values,通知用戶手動部署

    對於 Production tag,Jenkins 不自動部署,而是生成配置檔並通知用戶手動執行:

    stage('Generate Helm Values') {
        when { expression { env.DEPLOYMENT_ENV == 'production' } }
        steps {
            sh 'sh scripts/generate-helm-values.sh ${TAG_NAME}'
            // 生成 values-v${TAG_NAME}.yaml(不含敏感資訊)
            // 通知用戶:Images ready, run helm command
        }
    }

    Helm 配置隔離:敏感資訊三層防護

    配置分為三層,層層隔離:

    第一層:values-staging.yaml(在 repo,測試配置)

    # 主機名用占位符,從 Jenkins 環境變數注入,不硬編碼內網地址
    env:
      DATABASE_HOST: "${POSTGRES_STAGING_HOST}"
      DATABASE_NAME: simpleec_test
      REDIS_HOST: "${REDIS_STAGING_HOST}"
      API_LOG_LEVEL: DEBUG

    第二層:values-prod.yaml(用戶本機維護,不進 repo)

    # 用戶的私密文件,只在本機
    env:
      DATABASE_HOST: postgres-prod.example.com
      API_LOG_LEVEL: WARN
      # ⚠️ 資料庫密碼不在這裡!從 K8s Secrets 注入
    
    envFrom:
      - secretRef:
          name: database-prod-creds  # K8s Secret(運維管理)
      - secretRef:
          name: api-keys-prod        # K8s Secret(運維管理)

    第三層:K8s Secrets + etcd 加密

    # 運維在 Production K8s 上創建
    kubectl create secret generic database-prod-creds \
      --from-literal=username=prod_user \
      --from-literal=password=<secure-password> \
      -n production
    
    # K8s 預設 Secrets 以 base64 存在 etcd(並非加密!)
    # 必須啟用 encryption at rest
    # /etc/kubernetes/encryption-config.yaml
    apiVersion: apiserver.config.k8s.io/v1
    kind: EncryptionConfiguration
    resources:
      - resources: ["secrets"]
        providers:
          - aescbc:
              keys:
                - name: key1
                  secret: <base64-encoded-32-byte-key>

    安全強化:補齊四大缺口

    原始設計經過安全審查後,發現四個必須在投產前補足的缺口:

    缺口一:K8s RBAC 未定義

    三個角色各有最小權限(文件放在 k8s/rbac/):

    角色 允許操作 明確禁止
    Jenkins SA(staging) update/patch Deployments, get Pods 讀取任何 Secrets
    用戶(production) helm 部署相關資源 讀取業務 Secrets(DB 密碼、API Key)
    運維(production) Secrets 完整管理權
    # 驗證 Jenkins SA 無法讀取 Secrets(應輸出 no)
    kubectl auth can-i get secrets \
      --as=system:serviceaccount:staging:jenkins-deployer \
      -n staging

    缺口二:K8s Audit Log 未配置

    ISO 27001 A.12.4.1 要求所有敏感操作都要有日誌。以下 Audit Policy 至少記錄 Secrets 訪問和 Deployment 變更:

    # /etc/kubernetes/audit-policy.yaml
    apiVersion: audit.k8s.io/v1
    kind: Policy
    rules:
      - level: Metadata
        resources:
          - group: ""
            resources: ["secrets"]  # 所有 Secrets 訪問都記錄
    
      - level: Request
        verbs: ["create", "update", "delete", "patch"]
        resources:
          - group: "apps"
            resources: ["deployments"]
    
      - level: None
        users: ["system:kube-proxy"]
        verbs: ["watch", "list"]

    缺口三:鏡像簽名驗證(Kyverno 準入控制)

    確保集群只能部署來自 Jenkins 簽名的鏡像,防止鏡像替換攻擊:

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: verify-image-signatures
    spec:
      validationFailureAction: Enforce  # 未簽名鏡像直接拒絕
      rules:
        - name: check-image-signature
          match:
            any:
              - resources:
                  kinds: ["Pod"]
                  namespaces: ["staging", "production"]
          verifyImages:
            - imageReferences:
                - "registry.example.com/*"
              attestors:
                - count: 1
                  entries:
                    - keys:
                        publicKeys: |-
                          -----BEGIN PUBLIC KEY-----
                          # cosign.pub 內容
                          -----END PUBLIC KEY-----

    缺口四:GitHub Branch Protection 口頭約定 → 技術強制

    分支 Required Reviews CI 必須通過 Push 限制
    main 2 人 approve ✅ jenkins-build + secrets-scan 僅 team-lead
    staging 1 人 approve ✅ jenkins-build + secrets-scan 僅 team-lead
    dev 1 人 approve 必須透過 PR(AI 不能直接 push)

    Git 分支策略與 Tag 命名規範

    整個工作流的分支拓撲如下:

    main                     # Production 對應,受嚴格保護
     └─ tag: v1.0.0, v1.0.1  # 觸發 Jenkins 構建 Production 鏡像
    
    staging                  # 測試環境,中度保護
     └─ tag: staging-v1.0.0  # 觸發 Jenkins 自動部署到 Staging K8s
    
    dev                      # 開發積累,AI 透過 PR 提交
     └─ 來源:feature/* 合入
    
    feature/*                # AI 的工作分支(每個功能一個)
     ├─ feature/user-auth
     ├─ feature/order-api
     └─ feature/channel-job-momo

    敏感資訊完整隔離架構

    存放位置 可以存什麼 絕對不能存什麼 管理者
    Git Repository 代碼、Dockerfile、values-staging.yaml、Helm chart 模板 密碼、API Key、SSL 憑證、values-prod.yaml AI + 用戶
    Docker Registry 不含配置的乾淨鏡像(cosign 簽名) 任何敏感資訊 Jenkins(push)
    K8s Secrets(etcd 加密) database-prod-creds、api-keys-prod、SSL 憑證 運維
    Jenkins Credentials GitHub token、Registry credentials、cosign key、kubeconfig 運維

    回滾策略

    Staging 環境回滾

    # 快速回滾到上一個版本
    helm rollback order-api 0 -n staging
    
    # 或指定版本
    helm upgrade order-api ./k8s/helm/order-api \
      --values ./k8s/helm/order-api/values-staging.yaml \
      --set image.tag=staging-v1.0.0 \
      -n staging

    Production 環境回滾

    # 查看部署歷史
    helm history order-api -n production
    
    # 回滾到上一個版本
    helm rollback order-api 0 -n production
    
    # 所有 tag 在 Git 可追溯
    git log --oneline --all | grep "v1.0"

    投產前安全檢查清單

    在正式上線前,以下所有項目必須確認通過:

    代碼倉庫安全

    • ✅ .gitignore 包含 .env, .env.dev, **/values-prod.yaml
    • ✅ repo 根目錄存在 .gitleaks.toml 配置文件
    • ✅ pre-commit hook 已安裝
    • ✅ git log –all — ‘*.env’ 確認歷史中無敏感文件

    Jenkins Pipeline

    • ✅ 第一個 Stage 為 Secrets Scan(gitleaks)
    • ✅ Sign Images Stage 已配置(cosign)
    • ✅ Push Images 使用 Jenkins Credentials(非明文)
    • ✅ GitHub Webhook Secret 已配置(Jenkins + GitHub 雙端)

    K8s 訪問控制

    • ✅ k8s/rbac/ 三個 RBAC 文件已 apply
    • ✅ Jenkins SA 驗證:kubectl auth can-i get secrets … → no
    • ✅ Kyverno 已安裝,鏡像簽名驗證策略已 apply
    • ✅ etcd encryption at rest 已啟用(運維確認)

    審計和監控

    • ✅ K8s Audit Log 已配置(audit-policy.yaml)
    • ✅ Audit Log 保留策略 ≥ 90 天
    • ✅ 告警規則已配置(部署失敗、Secrets 掃描失敗)

    總結:這套工作流解決了什麼問題?

    AI 輔助開發的核心挑戰不是技術,而是信任邊界:誰能做什麼?誰為每個決定負責?這套工作流的答案很清楚:

    • AI 的邊界:寫 code、提 PR、建 Docker image — 技術執行層
    • 用戶的邊界:review 代碼、創建 tag、手動部署 Production — 決策層
    • 運維的邊界:管理 Secrets、維護集群、配置 credentials — 基礎設施層
    • 自動化的邊界:Jenkins 在 tag 觸發後執行既定腳本 — 不越界,不決策

    這種分層設計讓 AI 協作既高效又安全,每一個部署都有完整的審計軌跡,每一個敏感操作都需要人類授權。