feat/implement-and-tick-todos/main #44

Merged
admin merged 5 commits from feat/implement-and-tick-todos/main into master 2026-09-17 07:42:52 +00:00
2 changed files with 167 additions and 0 deletions
Showing only changes of commit 6e0fa92e73 - Show all commits
+57
View File
@@ -0,0 +1,57 @@
# 實作規範
改目標專案的程式碼時照這份做。這份規則只存在於本 plugin 裡,**不寫入目標專案的任何檔案**
——目標專案的 `CLAUDE.md`、`AGENTS.md` 與設定檔一律不碰。
## 先認語言,再動手
改任何一個檔案之前,先從專案檔認出這是什麼語言:
| 專案檔 | 語言 |
| --- | --- |
| `*.csproj`、`*.sln` | C# |
| `composer.json` | PHP |
| `package.json` | JavaScript/TypeScript |
| `go.mod` | Go |
| `pom.xml`、`build.gradle` | Java |
| `pyproject.toml`、`setup.py` | Python |
認出來之後,對照 `references/comment-styles.md` 取得該語言的註解格式。
**認不出來就停下來問,不要猜。** 猜錯的代價是滿檔案格式不對的註解,比沒有註解更難清理。
同一個 repo 裡有多種語言時,以**正在改的那個檔案**所屬的語言為準。
## 分層看職責,不看目錄
目錄名稱會騙人:叫 `services/` 的資料夾裡常有一半是控制層。判斷依據一律是**這段程式在做什麼**。
| 層 | 怎麼認 | 要寫什麼註解 |
| --- | --- | --- |
| 控制層 | 對外的介面:HTTP handler、CLI 進入點、事件訂閱者、對外 API | **功能註解**——這個介面在做什麼、誰會呼叫它 |
| 服務層 | 所有邏輯:判斷、計算、流程編排 | **邏輯註解**——這段邏輯在解決什麼問題,並**標註它呼叫的所有方法** |
| 存取層 | 任何碰資料來源的東西:DB、外部 API、檔案、快取、訊息佇列 | **資料源註解**——資料從哪裡來、是哪一張表/哪一支 API |
服務層要標註呼叫的方法,是為了讓 reviewer **追得到呼叫鏈**:看一個方法就知道它會往下走到哪裡,
不必逐層點開。
## 屬性一律要有用途註解
每一個屬性都寫它的用途。**屬性本身是類別時遞迴處理**——巢狀結構的每一層都要有,
不能只註解最外層然後說「詳見該類別」。
用途註解要附**真實的資料範例**,讓人知道實際格式長什麼樣(是 `2026-09-17` 還是
`2026/09/17`,是 `TWD` 還是 `NTD`)。
範例的來源有優先順序:
1. **優先從 MCP 取得**——能連到真實資料來源時,取真的值。
2. 取不到就以邏輯推理,並**明確註明「由邏輯推理、未經驗證」**。
註明這件事不能省。未經驗證的範例本身有用,但讓人誤以為它經過驗證就會出事——
有人會照著那個格式寫解析。
## 邊界
- 不改與這次待辦無關的程式碼。看到順手想修的東西,記下來、說出來,不要摸進這次的變更裡。
- 不動目標專案的設定檔、CI 設定與相依版本,除非待辦本身就是在做那件事。
- 既有程式碼的註解不符合這份規範時,**只補你改到的那些**,不要順手重寫整個檔案。
+110
View File
@@ -0,0 +1,110 @@
# 註解格式對照表
各語言的註解怎麼寫。先用 `references/coding-standards.md` 的專案檔對照認出語言,再查這裡。
規範本身(哪一層寫什麼、屬性要附真實資料範例)在 `coding-standards.md`,這份只管**格式**。
## C#
XML 文件註解,`///` 起頭。屬性用 `<summary>`,範例寫在 `<example>` 或 summary 末尾。
```csharp
/// <summary>依訂單編號取回訂單主檔。呼叫 OrderRepository.FindById。</summary>
/// <param name="orderId">訂單編號,例如 "ORD-20260917-0012"</param>
public Order GetOrder(string orderId)
/// <summary>成立時間,ISO 8601 帶時區。例:2026-09-17T14:03:00+08:00</summary>
public DateTimeOffset CreatedAt { get; set; }
```
## PHP
PHPDoc,`/** */`。屬性用 `@var`,範例接在說明後面。
```php
/**
* 依訂單編號取回訂單主檔。呼叫 OrderRepository::findById()。
*
* @param string $orderId 訂單編號,例如 "ORD-20260917-0012"
*/
public function getOrder(string $orderId): Order
/** @var string 幣別代碼,ISO 4217。例:TWD */
private string $currency;
```
## JavaScript/TypeScript
JSDoc,`/** */`。TypeScript 本身已經有型別,所以註解只寫**用途與範例**,不要複述型別。
```js
/**
* 依訂單編號取回訂單主檔。呼叫 orderRepository.findById。
* @param {string} orderId 訂單編號,例如 "ORD-20260917-0012"
*/
async function getOrder(orderId)
/** 幣別代碼,ISO 4217。例:TWD */
currency;
```
## Go
`//` 起頭,**以被註解的識別字開頭**(Go 的慣例,`go doc` 會照這個排版)。
```go
// GetOrder 依訂單編號取回訂單主檔。呼叫 orderRepo.FindByID。
func GetOrder(orderID string) (*Order, error)
type Order struct {
// Currency 是幣別代碼,ISO 4217。例:TWD
Currency string
}
```
## Java
Javadoc,`/** */`。
```java
/**
* 依訂單編號取回訂單主檔。呼叫 OrderRepository#findById。
*
* @param orderId 訂單編號,例如 "ORD-20260917-0012"
*/
public Order getOrder(String orderId)
/** 幣別代碼,ISO 4217。例:TWD */
private String currency;
```
## Python
docstring,`"""..."""`,寫在定義的**下一行**(不是上一行)。屬性用行內 `#` 或 dataclass 的 docstring。
```python
def get_order(order_id: str) -> Order:
"""依訂單編號取回訂單主檔。呼叫 OrderRepository.find_by_id。
Args:
order_id: 訂單編號,例如 "ORD-20260917-0012"
"""
@dataclass
class Order:
currency: str # 幣別代碼,ISO 4217。例:TWD
```
## 未經驗證的範例怎麼標
範例取不到真實來源時,照該語言的格式把註明寫進註解裡,**不要另起一行 TODO**:
```js
/** 幣別代碼,ISO 4217。例:TWD(由邏輯推理、未經驗證) */
```
```python
currency: str # 幣別代碼,ISO 4217。例:TWD(由邏輯推理、未經驗證)
```
這句話要留在程式碼裡,讓後面的人知道這個格式還沒有人對過。