Theme / v1.6.0

Codegraph

程式碼知識圖譜工具

實戰範例

實戰範例 001:重構 Django 複雜 URL 路由與 View 依賴圖譜

實戰演示如何利用 Codegraph 框架路由感知,在一款 Python Django 大型電商系統中安全重構訂單路由,防範 API 中斷。

實戰背景

在大型 Python Django 專案中,網址路由(URL Routing)通常採用分布式定義。各個獨立的子應用(Apps)擁有自己的 urls.py,再透過主路由 urlpatternsinclude() 進行層層嵌套。

痛點與問題描述: 我們需要重構電商後端的訂單付款接口,將原有的 GET /api/orders/<id>/pay/ 路由更名為 POST /api/orders/<id>/process-payment/,並改寫其對應的 View 視圖類別 OrderPaymentView。 由於 Django 的路由是基於正則表達式或 path 匹配的字串,傳統的 IDE 搜尋無法將「前端 AJAX 字串」與「後端的 views 實體」進行精確的強型別關聯。如果修改了後端 View 的方法,極易遺漏某個被 Django 內建模組引用的 URL 名稱(Named URLs)。因此,我們需要使用 OpenSpec 變更控制Codegraph 來進行安全路由重構。


規格定義

本次變更計畫的 ID 為 django-route-refactor。我們在 OpenSpec 規格中定義了以下驗收標準:

# 實戰範例 001:openspec/changes/django-route-refactor/specs/django-router/spec.md

## ADDED/MODIFIED Requirements

### Requirement: Payment processing route definition
系統必須(SHALL)暴露 `POST /api/orders/<id>/process-payment/` 以處理訂單付款。
- 該路由必須(SHALL)與 `OrderPaymentView``post` 方法綁定。
- 原有的 `GET /api/orders/<id>/pay/` 必須(SHALL)被廢棄。

#### Scenario: Verify Django route execution
- **WHEN** 發送 HTTP POST 請求至 `/api/orders/42/process-payment/`
- **THEN** 系統必須(SHALL)成功調用 `OrderPaymentView` 並返回 JSON 格式的支付收據。

端到端 8 輪 AI 協作紀錄

以下是 You (開發者) 與 AI 助手在實施此重構時的完整對話歷史。

── 第 1 輪:探索 Django 路由定義 ──

  • You:
    /opsx:explore "我需要重構 orders 相關的 Django 路由。請用 codegraph explore 尋找 urls.py 檔案及其內部的 urlpatterns 定義。"
  • AI:

    好的,已進入探索模式。我將呼叫 codegraph_explore 尋找專案中定義了 urls.py 的位置,以確認訂單路由的根入口。

    CG 呼叫: codegraph_explore(symbol: "urls.py")
    CG 回傳:

    • 路徑: shop/urls.py (主路由) 與 shop/orders/urls.py (訂單子路由)。

    接下來,我讀取 shop/orders/urls.py 的原始碼以檢視訂單路由配置。

    CG 呼叫: codegraph_explore(symbol: "shop/orders/urls.py")
    CG 回傳:

    • 原始碼:
      from django.urls import path
      from .views import OrderPaymentView
      
      urlpatterns = [
          path('<int:id>/pay/', OrderPaymentView.as_view(), name='order-pay'),
      ]

    分析
    訂單付款路由確實被定義為 <int:id>/pay/,並與 OrderPaymentView 視圖綁定,且命名為 'order-pay'。接下來我們需要查看 OrderPaymentView 的實作。


── 第 2 輪:查看 View 實作 ──

  • You:
    使用 codegraph explore 讀取 OrderPaymentView 的 views.py 代碼。
  • AI:

    我呼叫 codegraph_explore 檢索該 View 類別的原始碼。

    CG 呼叫: codegraph_explore(symbol: "class OrderPaymentView")
    CG 回傳:

    • 檔案路徑: shop/orders/views.py
    • 原始碼:
      from django.views import View
      from django.http import JsonResponse
      
      class OrderPaymentView(View):
          def get(self, request, id):
              # 舊的 GET 支付邏輯,安全隱患:GET 不應修改伺服器狀態
              return JsonResponse({"status": "processing", "order_id": id})

    分析
    該 View 目前僅實作了 get 方法。依據安全規範,變更伺服器狀態(進行扣款)必須改用 post 方法。因此重構方案需要將 get 重構為 post。 接下來,我們需要確認這個 order-pay URL 命名在整個系統中被哪些上游視圖或模板引用。


── 第 3 輪:檢索 URL 命名引用 ──

  • You:
    使用 codegraph explore 檢索引用了 'order-pay' 或 reverse('order-pay') 的代碼位置。
  • AI:

    好的,我將呼叫 codegraph_explore 搜尋專案中引用了 'order-pay' 的 Inbound Callers。

    CG 呼叫: codegraph_explore(symbol: "order-pay")
    CG 回傳:

    • Inbound Callers:
      • shop/orders/templates/order_detail.html (第 34 行): {% url 'order-pay' order.id %}
      • shop/orders/tests.py (第 12 行): reverse('order-pay', args=[1])

    分析
    我們找到了兩個依賴端:

    1. HTML 模板:/shop/orders/templates/order_detail.html 中的按鈕超連結。
    2. 測試:/shop/orders/tests.py 中的 API 測試。

    我現在退出探索模式,為您建立變更計畫。


── 第 4 輪:建立提案 ──

  • You:
    /opsx:propose "將 Django 訂單支付 API 從 GET/pay 重構為 POST/process-payment,修改 View 視圖並同步更新 Named URL 與測試"
  • AI:

    好的,提案 django-route-refactor 已建立!

    • proposal.md: 說明將支付方法改為 POST 並更新路由的安全性考量。
    • specs/django-router/spec.md: 定義 HTTP POST 與 JSON 收據驗收標準。
    • tasks.md: 任務拆解:
      • 1.1 修改 shop/orders/urls.py 將路由改為 process-payment/,Named URL 改為 order-process-payment
      • 1.2 重構 views.pyOrderPaymentView 實作 post 方法。
      • 1.3 更新 HTML 模板中的 url 名稱,並將點擊事件改為發送 POST 請求。
      • 1.4 更新 tests.py 並執行測試。

    請輸入 /opsx:apply 開始實作。


── 第 5 輪:修改路由定義 (Task 1.1) ──

  • You:
    /opsx:apply
  • AI:

    Implementing: django-route-refactor (schema: spec-driven)

    正在處理任務 1.1:修改 urls.py 路由。

    我已更新了 shop/orders/urls.py,更改為:

    urlpatterns = [
        path('<int:id>/process-payment/', OrderPaymentView.as_view(), name='order-process-payment'),
    ]

    ✓ 任務 1.1 完成!已在 tasks.md 中勾選。


── 第 6 輪:重構 View 實作 (Task 1.2) ──

  • You:
    繼續任務 1.2,重構 views.py,改用 post 方法接收。
  • AI:

    Implementing: django-route-refactor

    正在處理任務 1.2:重構 views.py

    我將 OrderPaymentView 中的 get 刪除,改為 post 實作扣款邏輯:

    class OrderPaymentView(View):
        def post(self, request, id):
            # 執行付款邏輯
            return JsonResponse({"status": "success", "order_id": id, "tx_id": "tx_abc123"})

    ✓ 任務 1.2 完成!


── 第 7 輪:更新模板與測試並驗證 ──

  • You:
    繼續實作任務 1.3 與 1.4,更新 HTML 模板與測試並進行驗證。
  • AI:

    Implementing: django-route-refactor

    正在處理任務 1.3 & 1.4:模板/測試更新與全域驗證。

    1. HTML 模板:已將 order_detail.html 的按鈕更改為 AJAX POST 提交,指向 {% url 'order-process-payment' order.id %}
    2. 測試代碼:已將 tests.py 中的 self.client.get 改為 self.client.post(reverse('order-process-payment', args=[42]))
    3. 測試執行:執行 python manage.py test,測試全數通過!

    已將變更合併至主規格並歸檔。

    Archive Complete

    變更計畫已成功歸檔!


── 第 8 輪:重構價值總結 ──

  • You:
    總結本次利用 Codegraph 重構 Django 路由的優點。
  • AI:

    透過 Codegraph 的框架路由感知,我們實現了:

    • 字串依賴精確檢索:Django 模板中的 {% url 'name' %} 與 Python 的 reverse('name') 在傳統 IDE 中只是個字串。Codegraph 能感知 Named URLs,在 inboundCallers 中精確列出這兩個引用點,確保沒有任何遺漏。
    • 安全升級:將危險的 GET 修改請求重構為規範的 POST,提升了系統的安全性。