昨天訪談出來的規格塞在同一個檔案裡,今天要把內容拆開,而拆之前得先講清楚:哪一份文件負責回答哪一種問題。
昨天讓 AI 當訪談者,問完兩輪之後產出了一份 323 行的規格,目錄長這樣:
§0 這份規格要解決的事 §5 分層
§1 名詞與狀態 §6 測試
§2 資料模型 §7 前端
§3 身分 §8 Open Questions
§4 API §9 決策來源對照
問題不在長度,而是在它把不同性質的東西混在一起。
拆的依據:spec / data-model / contracts / wireframe。
這四份的分工可以用四個問句記住:
| 文件 | 回答的問題 | 誰會拿去用 |
|---|---|---|
| spec | 這個功能要做什麼、為什麼 | 所有人 |
| data-model | 這些資料長什麼樣、彼此什麼關係 | 寫 migration、寫 query 的人 |
| contracts | 跟外面怎麼溝通(API、錯誤碼、身分) | 前端、其他模組、串接方 |
| wireframe | 使用者看到什麼、每個狀態長怎樣 | 做畫面的人 |
最後一欄比前面兩欄重要。判斷一段內容該放哪一份,最快的方法是問「誰會為了這件事打開這個檔案」——而不是問「這段話的主題是什麼」。
放 User Story、功能需求、驗收條件、還有沒決定的事。
昨天那份的 §0、§1、§8、§9 大致都屬於這一層:
有一個判準值得記:spec 裡不應該出現「怎麼實作」。
「記錄送出後唯讀」是 spec;「用 status 欄位加 CHECK 約束來擋」是 data-model。前者是需求,後者是手段,手段可以換,需求不應該跟著改。
這裡放:表、欄位、型別、可空、預設值、唯一性、索引、關聯。
而業務規則落在資料庫層的部分也放這裡。
昨天那份規格裡有這樣一條:
version_decisions FK (version_id, user_id) → version_required_confirmers
它的效果是「非名單內的人不可能留下確認紀錄」。這條約束如果是由資料庫 FK 保證,就不是靠程式碼「記得檢查」而已。
spec 和 data-model 兩份文件之間必須對得起來:spec 定義「必須成立什麼」,data-model 說明「資料層怎麼保證它」。
這一份放:API endpoint、Request / Response 格式、Error Code、認證機制。
裡面很多東西,其實不屬於任何單一功能,而是全系統共用的約定。
判斷方式還是那一句:下一個功能會不會也要用這條? 會的話它就不屬於這個功能的規格。
這裡放:畫面、狀態、每個狀態下的提示文字。
四份文件裡,只有 spec 是綁在單一功能上的,另外三份都可能被多個功能共用。
在最近負責的那個專案裡,這件事靠目錄層級解決:
| 文件 | 屬於哪一層 |
|---|---|
spec_us{N}.md |
一個 User Story |
spec.md(總覽)、data-model.md |
整個模組 |
contracts/ |
跨模組,由提供方持有 |
而用到別的模組的表時,直接在自己的 data-model.md 裡引用並註明擁有者:
## DD — <表名>(共用主檔,由 <某某> 模組定義)
誰擁有定義,誰負責維護;其他人引用,不複製。
這個系統小得多,整個系統就是一個模組,所以少了模組那層:
specs/
├── spec.md 系統總覽、六個功能的索引與優先級
├── spec_us1.md 送出產生版本 ← 昨天訪談出來的
├── spec_us2.md 確認 / 退回
├── ...
├── data-model.md 全系統的表
├── contracts/ API 契約、錯誤碼、身分機制
├── plan.md 技術背景、分層、依賴
├── tasks.md 分階段的開發任務
└── checklists/requirements.md
最後兩份不在「四件套」裡,因為它們不是規格。我會把它們分成兩種東西:規格是交給開發的合約,plan 和 tasks 是為了達成它而寫的工作文件。規格要在交付前被驗證,工作文件則可以隨著實作過程調整,這兩者的生命週期不同。
昨天那訪談結果對應到今天的文件分類:
| 原本 | 搬去哪 |
|---|---|
| §0 §1 §8 §9 | spec_us1.md |
| §2 資料模型 | data-model.md |
| §3 身分、§4 API | contracts/ |
| §5 分層 | plan.md |
| §6 測試清單 | tasks.md + checklists/ |
| §7 前端 | wireframe + plan.md(兩邊各一半) |
plan 和 tasks 不算規格。規格是交給開發的合約,那兩份是為了達成它而寫的工作文件。
明天:規格拆好了,但裡面最麻煩的一份還沒動——資料模型。訪談那輪它自己做了幾個「刻意的選擇」,其中兩個看起來像實作細節,實際上是在替業務規則把關。那些要一條一條看過。