實(shí)戰(zhàn)教程(八):先讓項(xiàng)目能穩(wěn)定地跑起來)
“AI 軟件開發(fā)實(shí)戰(zhàn)教程”系列第 7 篇把產(chǎn)品規(guī)劃、工程架構(gòu)和頁面設(shè)計(jì)整理成縱向開發(fā)任務(wù)、狀態(tài)看板與驗(yàn)收覆蓋矩陣讓 TDD 不會變成一堆彼此失聯(lián)的測試。到上一篇為止鄰行已經(jīng)有了三份重要事實(shí)源產(chǎn)品規(guī)劃說明首版做什么、為什么做和怎樣驗(yàn)收工程架構(gòu)說明事務(wù)、并發(fā)、權(quán)限、后臺任務(wù)和測試邊界頁面體驗(yàn)說明用戶看到什么、怎樣操作以及各種狀態(tài)如何表達(dá)?,F(xiàn)在可以開始寫代碼了嗎還差一個(gè)容易被低估的步驟把這些橫跨幾十頁的規(guī)則拆成可以獨(dú)立完成、獨(dú)立驗(yàn)證和獨(dú)立提交的任務(wù)。如果直接讓 AI“按照文檔把整個(gè)項(xiàng)目實(shí)現(xiàn)出來”常見結(jié)果是先一次性創(chuàng)建所有數(shù)據(jù)庫模型再一次性創(chuàng)建所有頁面最后補(bǔ)一些測試看板顯示功能很多實(shí)際沒有一條完整流程能運(yùn)行產(chǎn)品規(guī)劃中的邊界散落在代碼里沒人知道有沒有遺漏。這次使用dev-harness-planning生成計(jì)劃但沒有把模板填滿就算完成。計(jì)劃必須證明兩件事每個(gè)任務(wù)能產(chǎn)生一個(gè)可運(yùn)行結(jié)果所有產(chǎn)品驗(yàn)收場景都有唯一負(fù)責(zé)人。看板和任務(wù)詳情為什么要分開一個(gè)計(jì)劃文檔同時(shí)寫狀態(tài)、背景、文件、步驟、測試和風(fēng)險(xiǎn)很快就會變得難以掃描。鄰行把計(jì)劃分成三層Dashboard.md 當(dāng)前階段、任務(wù)狀態(tài)、優(yōu)先級和跳轉(zhuǎn) TaskDetails.md 每個(gè)任務(wù)的目標(biāo)、文件、TDD 步驟、驗(yàn)證和提交邊界 AcceptanceMatrix.md AC-01 到 AC-56 的負(fù)責(zé)人、證據(jù)類型和真實(shí)狀態(tài)看板只回答“現(xiàn)在做到哪里、下一項(xiàng)是什么”。任務(wù)詳情回答“這項(xiàng)工作怎樣做完”。驗(yàn)收矩陣回答“哪一條產(chǎn)品規(guī)則由誰證明”。三份文檔職責(zé)不同可以避免在多個(gè)地方復(fù)制同一大段實(shí)現(xiàn)說明。任務(wù)狀態(tài)變化時(shí)更新看板測試證據(jù)變化時(shí)更新驗(yàn)收矩陣實(shí)現(xiàn)步驟只在任務(wù)詳情維護(hù)。不按技術(shù)層拆而按用戶閉環(huán)拆一種常見拆法是任務(wù)一設(shè)計(jì)全部數(shù)據(jù)表 任務(wù)二實(shí)現(xiàn)全部后端接口 任務(wù)三實(shí)現(xiàn)全部前端頁面 任務(wù)四補(bǔ)自動(dòng)測試這種拆法對分工看起來整齊對驗(yàn)證卻很不友好。完成第一項(xiàng)以后用戶還不能做任何事完成第二項(xiàng)以后仍然沒有可用頁面到了最后才發(fā)現(xiàn)表結(jié)構(gòu)或接口不適合真實(shí)流程前面的“完成”需要大面積返工。鄰行改用縱向切片社區(qū)邀請、登錄與私密資料 → 從規(guī)則、數(shù)據(jù)庫、服務(wù)到真實(shí)注冊頁面一起完成 結(jié)構(gòu)化發(fā)布、信息大廳與詳情 → 從時(shí)間規(guī)則、發(fā)布冪等到移動(dòng)頁面一起完成 候選計(jì)算、解釋與站內(nèi)事件 → 從匹配純函數(shù)到雙方頁面一起完成 聯(lián)系方式雙向交換 → 從權(quán)限、事務(wù)、加密快照到復(fù)制降級一起完成每項(xiàng)完成后都多出一條可以實(shí)際運(yùn)行的用戶能力也能立即用瀏覽器檢查架構(gòu)和頁面設(shè)計(jì)是否真的成立。技術(shù)層仍然存在但它們服務(wù)于同一個(gè)切片而不是各自成為“已經(jīng)完成”的孤島。第一個(gè)任務(wù)不是業(yè)務(wù)功能在縱向開發(fā)以前計(jì)劃保留一個(gè)前置任務(wù) V0工程骨架與驗(yàn)證契約。它要建立Python、Django 和 PostgreSQL 的鎖定環(huán)境Web、Worker 和數(shù)據(jù)庫的本地運(yùn)行方式自定義用戶模型的第一條遷移格式、靜態(tài)檢查、單元、集成和瀏覽器測試可注入時(shí)鐘不會調(diào)用真實(shí)第三方的假提醒渠道setup、quick、test、e2e、check 等統(tǒng)一命令。V0 不是先搭一套宏大平臺。它只負(fù)責(zé)讓后面的每個(gè)任務(wù)都能以相同方式啟動(dòng)、測試和驗(yàn)收。例如產(chǎn)品大量依賴截止時(shí)刻如果沒有可注入時(shí)鐘測試就會靠真實(shí)等待或修改系統(tǒng)時(shí)間既慢又不穩(wěn)定。又例如最后一個(gè)座位依賴 PostgreSQL 行鎖如果測試環(huán)境默認(rèn)偷偷使用 SQLite測試通過也不能說明并發(fā)正確。驗(yàn)證環(huán)境本身是產(chǎn)品正確性的一部分。每個(gè)任務(wù)都先寫“怎樣失敗”任務(wù)詳情沒有只列“實(shí)現(xiàn)賬號、實(shí)現(xiàn)發(fā)布、實(shí)現(xiàn)匹配”而是為每項(xiàng)寫了 RED、GREEN、REFACTOR。以聯(lián)系方式交換為例RED 非候選、跨社區(qū)、受限賬戶、失效候選必須拒絕 重復(fù)點(diǎn)擊和并發(fā)點(diǎn)擊不能產(chǎn)生兩次交換 非參與者和頁面源碼不能看到微信號 GREEN 實(shí)現(xiàn)短事務(wù)、重新校驗(yàn)、一對一交換和加密快照 雙方同時(shí)得到對方微信號 REFACTOR 模板上下文只裝入當(dāng)前用戶有權(quán)看到的一方資料 權(quán)限判斷集中在服務(wù)不散落在頁面“先寫失敗測試”不是追求紅色輸出本身。測試必須因?yàn)槟繕?biāo)能力尚未實(shí)現(xiàn)而失敗而不是因?yàn)閷?dǎo)入路徑寫錯(cuò)、數(shù)據(jù)庫沒啟動(dòng)或測試代碼本身報(bào)錯(cuò)。確認(rèn)紅燈原因正確以后才寫最小實(shí)現(xiàn)讓它變綠。一個(gè)任務(wù)要同時(shí)擁有多個(gè)證據(jù)層次不是所有規(guī)則都適合用同一種測試。匹配時(shí)間窗口可以用純函數(shù)測試社區(qū)權(quán)限需要 HTTP 集成測試最后一個(gè)座位需要 PostgreSQL 雙連接并發(fā)復(fù)制降級需要瀏覽器微信分享和會話保持最終需要真機(jī)。因此任務(wù)詳情為每項(xiàng)規(guī)定證據(jù)層次純規(guī)則 → 時(shí)間、地點(diǎn)、狀態(tài)、提醒分類 服務(wù)和數(shù)據(jù)庫 → 冪等、授權(quán)、事務(wù)、事件一致性 HTTP → 登錄、跨社區(qū)、CSRF、表單和源碼 Playwright → 兩個(gè)用戶的完整移動(dòng)頁面流程 真實(shí)設(shè)備和外部人員 → 微信 Gate、群管理員、隱私與法律審查越接近用戶環(huán)境的測試覆蓋面越大但它不能代替更底層的精確規(guī)則測試。反過來單元測試再多也不能證明微信內(nèi)置瀏覽器真的可用。56 個(gè)驗(yàn)收場景為什么需要單獨(dú)矩陣產(chǎn)品規(guī)劃已經(jīng)寫了 56 個(gè)驗(yàn)收場景。如果只在任務(wù)描述中隨手標(biāo)幾個(gè)編號很難發(fā)現(xiàn)某一條沒人負(fù)責(zé)同一條被多個(gè)任務(wù)都認(rèn)為由對方負(fù)責(zé)人工 Gate 被寫成自動(dòng)化已通過任務(wù)完成后沒有真實(shí)測試路徑。驗(yàn)收矩陣為 AC-01 到 AC-56 每條記錄場景摘要唯一負(fù)責(zé)人計(jì)劃證據(jù)當(dāng)前真實(shí)狀態(tài)。生成以后做了機(jī)器檢查編號范圍AC-01–AC-56 總數(shù)56 順序完整是 重復(fù)0 遺漏0 當(dāng)前自動(dòng)通過0最后一行很重要。計(jì)劃覆蓋了 56 條不代表實(shí)現(xiàn)通過了 56 條。當(dāng)前狀態(tài)全部是“未實(shí)現(xiàn)”或“等待成品”這才符合項(xiàng)目事實(shí)?!皡f(xié)作任務(wù)”和“最終負(fù)責(zé)人”要分開一條驗(yàn)收往往跨多個(gè)模塊。例如 AC-24 要求第三方提醒失敗不能回滾發(fā)布、候選或交換而且一方失敗不影響另一方。候選任務(wù)會創(chuàng)建業(yè)務(wù)事件交換任務(wù)會保存交換事實(shí)提醒任務(wù)會處理發(fā)送失敗。三項(xiàng)都參與但驗(yàn)收矩陣仍把 K7 提醒任務(wù)設(shè)為最終負(fù)責(zé)人。這樣關(guān)閉任務(wù)時(shí)不會出現(xiàn)K3我已經(jīng)創(chuàng)建事件剩下不是我的問題 K4交換已經(jīng)保存提醒由別人測試 K7上游應(yīng)該已經(jīng)保證事務(wù)我只測 HTTP協(xié)作關(guān)系可以有多個(gè)最終關(guān)閉責(zé)任只能有一個(gè)。把最危險(xiǎn)的測試單獨(dú)標(biāo)出來驗(yàn)收矩陣沒有把所有場景都寫成“自動(dòng)測試”。幾類證據(jù)被明確加粗AC-27 最后一個(gè)座位必須在 PostgreSQL 做真實(shí)并發(fā)AC-23、AC-39、AC-40必須主動(dòng)掃描“不包含”敏感資料AC-31 到 AC-35只能由 iOS 和 Android 微信真機(jī)最終通過AC-39除了代碼和備份檢查還需要隱私與法律審查共同關(guān)閉。這能防止自動(dòng)化系統(tǒng)為了提高通過率用容易執(zhí)行但證據(jù)不足的測試替換真實(shí)要求。外部 Gate 也要進(jìn)看板但不能自動(dòng)完成Gate B 和 Gate C 被當(dāng)作正式任務(wù)保留G1微信成品真機(jī)驗(yàn)收 狀態(tài)等待可運(yùn)行成品 G2受控試用準(zhǔn)備 狀態(tài)等待外部人員與合規(guī)證據(jù)它們有明確輸入、步驟和通過條件卻不會在 AI 完成代碼后自動(dòng)變綠。G1 需要真實(shí) iOS、Android、微信版本和測試群G2 需要群管理員同意、地點(diǎn)確認(rèn)、七天基線、試用名單以及隱私和法律意見。計(jì)劃可以替這些工作準(zhǔn)備記錄模板不能替責(zé)任人簽字??窗宓臓顟B(tài)必須反映事實(shí)鄰行統(tǒng)一使用幾種狀態(tài) 規(guī)劃中任務(wù)定義完成代碼尚未開始 開發(fā)中當(dāng)前正在執(zhí)行而且同時(shí)只能有一個(gè)? 已完成退出條件和證據(jù)全部滿足?? 等待成品/外部任務(wù)定義清楚但缺少真實(shí)輸入 遠(yuǎn)期沒有真實(shí)數(shù)據(jù)支持現(xiàn)在進(jìn)入首版。創(chuàng)建了文件不等于任務(wù)完成測試通過一部分也不等于任務(wù)完成AI 暫時(shí)停止更不等于任務(wù)受阻。每個(gè)任務(wù)完成時(shí)必須同時(shí)更新看板狀態(tài)任務(wù)詳情中的驗(yàn)證記錄驗(yàn)收矩陣中的真實(shí)證據(jù)路徑節(jié)點(diǎn)檢查點(diǎn)本地 Git 提交。這讓第二天查看項(xiàng)目的人不必從聊天記錄猜測實(shí)際進(jìn)度。計(jì)劃也要接受自動(dòng)檢查文檔不是代碼但仍然可以做一些確定性驗(yàn)證。本次計(jì)劃檢查了Dashboard 中有 14 個(gè)任務(wù)TaskDetails 中有對應(yīng)的 14 個(gè)任務(wù)標(biāo)題驗(yàn)收矩陣恰好有 56 行編號嚴(yán)格等于 1 到 56沒有重復(fù)沒有TBD、TODO、FIXME等模板殘留Markdown 沒有明顯空白錯(cuò)誤。這不能證明任務(wù)拆分一定完美卻能消除鏈接缺失、編號漏掉和模板沒填完這類低級錯(cuò)誤。本節(jié)點(diǎn)形成的實(shí)際開發(fā)順序鄰行首版最終按這個(gè)順序推進(jìn)V0 工程骨架 → K1 社區(qū)訪問與私密資料 → K2 發(fā)布、大廳和詳情 → K3 候選與站內(nèi)事件 → K4 聯(lián)系方式交換 → K5 雙方反饋與座位 → K6 編輯、截止和狀態(tài)生命周期 → K7 外部提醒 Worker → K8 刪除、審計(jì)和社區(qū)管理 → K9 完整移動(dòng)瀏覽器驗(yàn)收 → K10 部署、恢復(fù)和試用數(shù)據(jù) → G1 微信真機(jī) → G2 受控試用準(zhǔn)備K4 完成以后登錄—詳情—交換—復(fù)制的首條成品閉環(huán)已經(jīng)存在可以開始準(zhǔn)備微信真機(jī)測試但完整 Gate B 仍等到 K9 頁面和瀏覽器質(zhì)量收束。寫在最后一個(gè)好計(jì)劃不是把所有工作都提前寫得很詳細(xì)。它應(yīng)該讓下一步足夠明確讓每條產(chǎn)品規(guī)則都有負(fù)責(zé)人讓不同證據(jù)不會互相冒充也讓遠(yuǎn)期想法不會偷偷混進(jìn)首版?,F(xiàn)在鄰行的下一步已經(jīng)非常具體執(zhí)行 V0先寫配置和健康檢查的失敗測試建立 PostgreSQL 與統(tǒng)一驗(yàn)證命令。從這一刻開始后續(xù)教程會進(jìn)入真正的 TDD 開發(fā)。文章不會只展示最后的綠色測試還會記錄第一條測試為什么失敗、最小實(shí)現(xiàn)怎樣讓它通過、重構(gòu)改變了什么、瀏覽器看到了什么以及還有哪些真實(shí) Gate 不能由 AI 關(guān)閉。本篇驗(yàn)證摘要計(jì)劃按用戶可完成的縱向流程拆分而不是按模型、頁面和接口橫向切塊每項(xiàng)任務(wù)都記錄產(chǎn)品規(guī)則、第一條失敗測試、實(shí)現(xiàn)范圍和完成門禁56 條驗(yàn)收場景分別標(biāo)注負(fù)責(zé)人、自動(dòng)證據(jù)、瀏覽器證據(jù)或人工驗(yàn)證要求PostgreSQL 并發(fā)、微信真機(jī)和真實(shí)用戶接受度不會被普通單元測試代替看板允許“部分通過”和“環(huán)境待驗(yàn)”避免任務(wù)完成被誤寫成產(chǎn)品已上線。附錄相關(guān)工具與倉庫gstack倉庫garrytan/gstack地址https://github.com/garrytan/gstackdev-harness倉庫Dev-Wiki/dev-harness地址https://github.com/Dev-Wiki/dev-harnessUI UX Pro Max Skill倉庫nextlevelbuilder/ui-ux-pro-max-skill地址https://github.com/nextlevelbuilder/ui-ux-pro-max-skill