詳細(xì)設(shè)計說明書:模塊劃分、狀態(tài)機與核心接口實戰(zhàn)指南)
簡介一份面向軟件設(shè)計師、開發(fā)人員及軟件工程學(xué)習(xí)者的會議管理系統(tǒng)詳細(xì)設(shè)計說明書適用于課程設(shè)計、項目開發(fā)或文檔范式參考。說明書約78頁從概要設(shè)計入手明確編寫目的、背景與范圍隨后給出系統(tǒng)運行所需的操作系統(tǒng)、數(shù)據(jù)庫與客戶端選型并制定統(tǒng)一的系統(tǒng)模塊命名規(guī)范。核心部分為對象設(shè)計展示系統(tǒng)總體類圖結(jié)構(gòu)并逐個定義信息管理、預(yù)約管理、會議管理、人員管理、部門管理、職位管理、設(shè)備管理等關(guān)鍵類及其關(guān)系覆蓋會議管理系統(tǒng)的主要業(yè)務(wù)模塊。資源包僅含1個doc文檔大小1.9MB內(nèi)容獨立、攜帶方便。已有444人學(xué)習(xí)過這份資料適合需要借鑒完整設(shè)計文檔寫法或快速掌握系統(tǒng)架構(gòu)的讀者。通過研讀可學(xué)習(xí)規(guī)范文檔的章節(jié)組織、類圖設(shè)計方法以及環(huán)境選型與模塊劃分思路為同類系統(tǒng)設(shè)計提供直接參考。1. 會議管理系統(tǒng)詳細(xì)設(shè)計說明書先搞清這一百多頁文檔替誰在回答項目進(jìn)入詳細(xì)設(shè)計階段時團(tuán)隊桌上通常會多出一份《會議管理系統(tǒng)詳細(xì)設(shè)計說明書.doc》。這份文檔看著像文檔模板實際上決定了后面開發(fā)、測試、聯(lián)調(diào)所有人對系統(tǒng)的理解是否一致。會議管理系統(tǒng)表面是「預(yù)訂會議室 發(fā)通知 記紀(jì)要」但真正的復(fù)雜度藏在并發(fā)沖突、通知補償、決議跟蹤這些看不見的地方。詳細(xì)設(shè)計說明書的價值就是把看不見的復(fù)雜先講清楚讓開發(fā)不用靠猜寫代碼讓測試不用靠感覺設(shè)計用例讓后來接手的人不用翻一個月代碼才能看懂業(yè)務(wù)規(guī)則。這篇文章不是來介紹這份文檔的目錄結(jié)構(gòu)而是講我在做同類系統(tǒng)時這份說明書的每一章到底寫了什么、參數(shù)怎么定、坑在哪里。適合正要寫詳細(xì)設(shè)計或準(zhǔn)備評審這類文檔的工程師、項目負(fù)責(zé)人。2. 會議管理系統(tǒng)模塊怎么切從預(yù)訂到歸檔的五個邊界2.1 主鏈路梳理預(yù)訂、通知、紀(jì)要跟蹤一個都不能少會議管理系統(tǒng)的難點不在于功能多而在于模塊之間關(guān)系繁雜。剛開始拆模塊時最常見的錯誤是把「會議室預(yù)訂」和「會議管理」當(dāng)成同一件事結(jié)果做出來的系統(tǒng)里預(yù)訂單既管時間又管內(nèi)容還要管審批和通知一個表承擔(dān)了所有狀態(tài)后面改一發(fā)動全身。我經(jīng)手的幾個版本最后沉淀下來的模塊劃分是五塊會議室資源管理、會議預(yù)訂與會期管理、通知觸達(dá)、紀(jì)要歸檔、決議跟蹤。每一塊有明確的邊界和唯一職責(zé)。會議室資源管理只管會議室本身的狀態(tài)預(yù)訂模塊管時間沖突和審批通知模塊只負(fù)責(zé)觸達(dá)和重試紀(jì)要模塊管內(nèi)容的沉淀決議模塊管待辦執(zhí)行。這樣切完之后每個模塊的改動范圍清晰新增功能時不需要跨多個表來回改邏輯。模塊 | 負(fù)責(zé)什么 | 不負(fù)責(zé)什么 | 對外的關(guān)鍵接口 會議室資源管理 | 會議室的增刪改查、樓層設(shè)備、可用時段查詢 | 不判斷某個時段是否已被預(yù)訂 | 向預(yù)訂模塊提供房間狀態(tài)查詢能力 會議預(yù)訂與會期管理 | 預(yù)訂、改期、取消、審批、沖突檢測 | 不直接發(fā)通知只產(chǎn)生事件 | 向通知模塊輸出會議變更事件 通知觸達(dá) | 按模板下發(fā)會議通知、改期通知、催辦提醒 | 不存儲會議內(nèi)容不判斷參會人是否已讀 | 消費預(yù)訂模塊和決議模塊的事件 紀(jì)要歸檔 | 會上內(nèi)容記錄、附件上傳、紀(jì)要確認(rèn) | 不生成待辦事項 | 向決議模塊輸出待辦草稿 決議跟蹤 | 待辦分派、到期提醒、狀態(tài)流轉(zhuǎn)管理 | 不關(guān)心會議室資源 | 向通知模塊請求催辦提醒這五個模塊之間的依賴方向也很重要。原則上預(yù)訂模塊不能反向依賴紀(jì)要模塊紀(jì)要模塊不能依賴通知模塊內(nèi)部實現(xiàn)。說明書寫清楚依賴方向后開發(fā)并行開工時不會因為接口未定而互相等待。實際項目中我遇到過因為紀(jì)要模塊直接調(diào)了通知模塊的內(nèi)部方法導(dǎo)致通知模塊改版后紀(jì)要模塊大面積報錯這種問題靠模塊邊界是可以避免的。2.2 實體與狀態(tài)機會議室、預(yù)訂單、會議、決議誰先變狀態(tài)詳細(xì)設(shè)計說明書里最容易被寫空的部分是狀態(tài)機。很多人畫一個箭頭圖就結(jié)束了但不寫清楚每個狀態(tài)遷移的觸發(fā)條件和校驗規(guī)則開發(fā)實現(xiàn)時還是要自己編一套邏輯。會議管理系統(tǒng)涉及的實體狀態(tài)不多但每個狀態(tài)之間的遷移規(guī)則必須明確。以預(yù)訂單為例一個新提交的預(yù)訂單初始狀態(tài)是「待確認(rèn)」。管理員確認(rèn)后變?yōu)椤敢汛_認(rèn)」系統(tǒng)到達(dá)會議開始時間后自動置為「進(jìn)行中」會議結(jié)束且紀(jì)要歸檔完成后變?yōu)椤敢淹瓿伞埂U麄€生命周期里普通用戶只能取消「待確認(rèn)」或「已確認(rèn)」?fàn)顟B(tài)的預(yù)訂單對「進(jìn)行中」的會議只能提交結(jié)束申請。這些規(guī)則不寫清楚后面權(quán)限模塊就沒法設(shè)計。會議室的狀態(tài)機相對簡單可用、維護(hù)中、停用三種狀態(tài)。但要特別注意「可用」不代表「當(dāng)前時段沒人訂」可用指的是會議室本身處于可被預(yù)訂的狀態(tài)。很多新手在設(shè)計時把這兩個概念混在一起導(dǎo)致狀態(tài)既表達(dá)資源可用性又表達(dá)占用情況沖突檢測邏輯變得混亂。會議的歸檔狀態(tài)有一個容易被漏掉的約束只有紀(jì)要上傳完成且決議已拆分后會議才允許被歸檔。這意味著歸檔動作依賴紀(jì)要模塊和決議模塊的數(shù)據(jù)完整性。約束寫在說明書里之后測試可以針對這條規(guī)則專門設(shè)計用例只上傳紀(jì)要但沒有拆分決議時嘗試歸檔系統(tǒng)應(yīng)拒絕該操作。決議的狀態(tài)流轉(zhuǎn)是閉環(huán)里最容易被忽視的。決議從待認(rèn)領(lǐng)開始負(fù)責(zé)人確認(rèn)后進(jìn)入執(zhí)行中完成后提交驗證驗證通過轉(zhuǎn)已完成。但如果到期日到了還沒完成狀態(tài)要被定時任務(wù)統(tǒng)一掃描置為已逾期。這里有三個需要特別說明的參數(shù)會議結(jié)束后 24 小時內(nèi)必須上傳紀(jì)要決議的默認(rèn)執(zhí)行期限是會議結(jié)束后 7 天催辦任務(wù)每 3 天觸發(fā)一次。這幾個數(shù)字不是拍腦袋定的它們決定了許多定時任務(wù)的調(diào)度頻率和通知模塊的觸發(fā)時機寫說明書時把它們放進(jìn)「業(yè)務(wù)規(guī)則」一節(jié)比散落在文檔各處要好得多。3. 寫進(jìn)說明書的三條業(yè)務(wù)線預(yù)訂沖突、通知觸達(dá)與決議閉環(huán)3.1 會議室預(yù)訂詳細(xì)設(shè)計沖突檢測與鎖定時間參數(shù)會議室預(yù)訂是會議管理系統(tǒng)并發(fā)壓力最高的地方。多人同時搶同一個會議室時系統(tǒng)必須保證只有一個人能預(yù)訂成功。看起來簡單但實現(xiàn)時很容易因為方案選錯而翻車。我在說明書里明確要求沖突檢測必須在服務(wù)端完成不能只靠數(shù)據(jù)庫唯一索引兜底。常見做法是給會議室加一個排他時間窗口創(chuàng)建預(yù)訂單時開啟事務(wù)先鎖定該會議室在目標(biāo)時間范圍內(nèi)的記錄再執(zhí)行沖突校驗和插入。這里的核心是鎖定時機在校驗之前就加鎖而不是先查再鎖。沖突檢測涉及幾個關(guān)鍵參數(shù)這些參數(shù)直接影響用戶體驗和系統(tǒng)行為。我使用的基線是會前準(zhǔn)備時間 buffer_minutes 設(shè)為 15 分鐘最大可預(yù)訂天數(shù)為未來 30 天單次預(yù)訂最短 15 分鐘每個會議室每天最多預(yù)訂 8 次已確認(rèn)的預(yù)訂單取消時必須走審批。以下是參數(shù)表參數(shù)名稱 | 推薦值 | 使用場景與說明 buffer_minutes | 15 | 會前準(zhǔn)備時間解決前一會議拖堂造成的時間重疊問題 max_book_days_ahead | 30 | 超過該日期范圍的預(yù)訂直接拒絕減少遠(yuǎn)期變動造成的資源浪費 min_duration_minutes | 15 | 防止 5 分鐘的預(yù)訂碎片占用會議室也避免定時任務(wù)被頻繁觸發(fā) max_booking_per_room_per_day | 8 | 防止個別部門長期占用同一會議室資源分配更均衡 cancel_approve_rule | 已確認(rèn)預(yù)訂取消需審批 | 避免用戶隨意取消已確認(rèn)會議影響其他同事的日程安排提示當(dāng)會議室數(shù)量超過 50 間時預(yù)訂并發(fā)會明顯加大。此時建議在沖突檢測前加一層緩存預(yù)檢高速判斷目標(biāo)時間段是否有空閑位再走事務(wù)確認(rèn)。但緩存預(yù)檢只能用于快速拒絕不能作為最終確認(rèn)依據(jù)最終結(jié)果必須由數(shù)據(jù)庫事務(wù)決定否則可能出現(xiàn)兩邊都預(yù)訂成功的臟數(shù)據(jù)。3.2 通知觸達(dá)設(shè)計渠道降級與重試次數(shù)怎么定通知模塊看起來只是發(fā)個郵件或推送但它直接決定參會人能不能準(zhǔn)時到場。實際運營中郵件服務(wù)可能超時短信通道可能限流站內(nèi)信可能出現(xiàn)推送延遲任何一個環(huán)節(jié)出問題都要有重試和降級策略。我在詳細(xì)設(shè)計說明書中通常會定義同一會議支持站內(nèi)信、郵件、短信三種渠道。站內(nèi)信是默認(rèn)渠道只要創(chuàng)建會議就立即生成郵件在站內(nèi)信發(fā)送后延遲 5 分鐘由異步任務(wù)觸發(fā)避免瞬間并發(fā)把郵箱服務(wù)打掛短信只用于會議開始前 1 小時提醒并且僅當(dāng)會議被標(biāo)記為「重要會議」時才發(fā)送。這個設(shè)計不是功能越多越好而是成本控制短信最貴所以要限量使用。通知狀態(tài)一定要定義完整。通知記錄的狀態(tài)集合是待發(fā)送、發(fā)送中、發(fā)送成功、發(fā)送失敗。發(fā)送失敗后進(jìn)入重試隊列最多重試 3 次重試間隔分別設(shè)為 5 分鐘、10 分鐘、30 分鐘。第 3 次重試仍然失敗時狀態(tài)標(biāo)記為最終失敗系統(tǒng)不再自動重試。這里要特別區(qū)分「發(fā)送失敗」和「未讀」未讀是參會人的行為系統(tǒng)無法控制只要渠道確認(rèn)投遞成功通知任務(wù)就算完成通知詳情頁可以顯示已讀/未讀狀態(tài)但通知模塊本身不負(fù)責(zé)再次提醒。通知觸達(dá)的另外一條關(guān)鍵設(shè)計是所有通知必須在通知記錄表里留痕包括發(fā)送時間、渠道、內(nèi)容摘要、失敗原因。后續(xù)排查問題時從通知記錄表能還原整個發(fā)送鏈路而不是依賴郵件服務(wù)商的后臺日志。3.3 紀(jì)要與決議閉環(huán)誰負(fù)責(zé)、誰知會、逾期后怎么辦會議紀(jì)要和決議執(zhí)行是很多管理系統(tǒng)里的「死功能」錄了但沒人看開會時記了一大段散會后沒有動作。要讓決議閉環(huán)真正跑起來說明書里必須區(qū)分「負(fù)責(zé)人」和「知會人」兩個角色。負(fù)責(zé)人是決議的執(zhí)行責(zé)任主體系統(tǒng)給他的唯一賬號派發(fā)待辦知會人是需要了解進(jìn)展但不需要動手的人系統(tǒng)只在狀態(tài)變化時給他發(fā)送短消息。這兩個角色絕不能混用。我在項目里見過負(fù)責(zé)人和知會人混在一張表里導(dǎo)致的結(jié)果催辦郵件發(fā)給了會議室全部參會人真正該干活的人反而沒被點名。所以要單獨定義兩個字段owner_id 和 cc_ids。決議的逾期處理規(guī)則也需要明確。常用做法是決議到達(dá) due_date 仍未完成系統(tǒng)自動生成催辦任務(wù)每 3 天催一次負(fù)責(zé)人逾期超過 7 天仍未處理升級給負(fù)責(zé)人的上級主管。這個 7 天的升級閾值 escalation_days 是關(guān)鍵參數(shù)。同時配套一個定時任務(wù)的掃描頻率我的慣例是每小時跑一次狀態(tài)檢查只掃描狀態(tài)為「執(zhí)行中」且 due_date 已經(jīng)過去的決議記錄避免全表掃描消耗數(shù)據(jù)庫資源。紀(jì)要的歸檔流程也應(yīng)寫明會議結(jié)束后 24 小時內(nèi)主持人或記錄人必須上傳紀(jì)要未上傳時系統(tǒng)自動發(fā)送提醒上傳的紀(jì)要只有會議主持人可以修改其他參會人只能查看和評論。這條規(guī)則卡住了「紀(jì)要上傳后又被隨意篡改」的問題也保證了待辦拆分是基于最終紀(jì)要版本進(jìn)行的不會出現(xiàn)待辦內(nèi)容與會議結(jié)論不一致。4. 詳細(xì)設(shè)計說明書里的表結(jié)構(gòu)與接口抄作業(yè)就抄這些4.1 核心表字段清單會議室、預(yù)訂單、會議、決議怎么落庫詳細(xì)設(shè)計說明書里如果只寫邏輯模型不落物理表結(jié)構(gòu)開發(fā)設(shè)計數(shù)據(jù)庫表時還是會各有各的理解。我在說明書里會直接給出經(jīng)過反復(fù)調(diào)整的字段清單字段命名和類型盡量明確減少建模評審中的爭論。以下省略每個表都有的 created_at、updated_at 和邏輯刪除標(biāo)識字段實際建庫時按團(tuán)隊規(guī)范補齊。meeting_room 會議室表的核心字段字段名類型必填說明idbigint是主鍵room_namevarchar(64)是房間號如「A201」floorint是所在樓層capacityint是最大容納人數(shù)equipmentvarchar(255)否設(shè)備清單逗號分隔statustinyint是1 可用 / 2 維護(hù)中 / 3 停用sort_orderint否列表排序權(quán)重越小越靠前meeting_reservation 預(yù)訂單表的核心字段字段名類型必填說明idbigint是主鍵room_idbigint是會議室 ID外鍵關(guān)聯(lián) meeting_roombooker_idbigint是預(yù)訂人 IDmeeting_topicvarchar(128)是會議主題start_timedatetime是會議開始時間end_timedatetime是會議結(jié)束時間attendee_countint是參會人數(shù)statustinyint是1 待確認(rèn) / 2 已確認(rèn) / 3 已取消 / 4 已完成cancel_reasonvarchar(255)否取消原因僅在已取消狀態(tài)時寫入meeting_info 會議表的核心字段字段名類型必填說明idbigint是主鍵reservation_idbigint是關(guān)聯(lián)預(yù)訂單 IDhost_idbigint是主持人 IDtitlevarchar(128)是會議標(biāo)題默認(rèn)取預(yù)訂單主題summary_pathvarchar(255)否紀(jì)要附件保存路徑minutes_statustinyint是0 未上傳 / 1 待確認(rèn) / 2 已確認(rèn)archive_statustinyint是0 未歸檔 / 1 已歸檔meeting_resolution 決議表的核心字段字段名類型必填說明idbigint是主鍵meeting_idbigint是關(guān)聯(lián)會議 IDowner_idbigint是負(fù)責(zé)人 IDcc_idsvarchar(255)否知會人 ID逗號分隔contenttext是決議內(nèi)容due_datedatetime是完成截止時間statustinyint是1 待認(rèn)領(lǐng) / 2 執(zhí)行中 / 3 待驗證 / 4 已完成 / 5 已逾期commentvarchar(500)否完成說明狀態(tài)變?yōu)榇炞C后填寫這幾張表設(shè)計的關(guān)鍵不在字段數(shù)量而在于邊界和職責(zé)分離。預(yù)訂單只管資源占用時段和審批狀態(tài)會議表只管會議內(nèi)容和歸檔狀態(tài)決議表只管執(zhí)行閉環(huán)。三者通過外鍵關(guān)聯(lián)但狀態(tài)互不干擾。特別是在預(yù)訂單和會議之間保留 reservation_id 關(guān)聯(lián)而不是直接復(fù)制會議室名稱和預(yù)訂人姓名避免冗余字段在改期或換人后出現(xiàn)不一致。4.2 接口交互怎么描述三段式時序?qū)懬逭埱蟆⑿r炁c回執(zhí)詳細(xì)設(shè)計說明書中的接口部分不需要把每個方法簽名都列一遍但核心用例必須寫清楚「請求方提交什么、服務(wù)端校驗什么、數(shù)據(jù)最終怎么落庫」。我常用的方式是寫三段式描述既不會太抽象也不會太長。以創(chuàng)建預(yù)訂為例。第一段是請求數(shù)據(jù)前端提交 room_id、start_time、end_time、meeting_topic、attendee_count。第二段是服務(wù)端校驗邏輯先查預(yù)約時間窗是否合法再查參會人數(shù)是否超過會議室容量最后執(zhí)行沖突檢測核心 SQL 查詢范圍是以 (start_time - buffer_minutes, end_time buffer_minutes) 為區(qū)間查找狀態(tài)為「待確認(rèn)」或「已確認(rèn)」的預(yù)訂單。第三段是落庫行為無沖突后插入預(yù)訂單狀態(tài)置為待確認(rèn)同時寫入一條審批任務(wù)記錄并觸發(fā)通知事件。取消預(yù)訂的接口設(shè)計也要單獨描述這是容易出問題的地方。取消請求到達(dá)服務(wù)端后先判斷當(dāng)前時間是否晚于會議開始時間。如果會議已經(jīng)開始直接拒絕取消返回提示「會議已開始建議提交會議結(jié)束申請并上傳紀(jì)要」。如果尚未開始判斷預(yù)訂單狀態(tài)待確認(rèn)的可以直接取消已確認(rèn)的需要管理員審批。這些分支邏輯如果不寫清楚開發(fā)通常會漏掉「已開始不能取消」這條約束導(dǎo)致用戶會議開到一半還能取消。通知事件接口則按「事件驅(qū)動」的方式描述預(yù)訂模塊只在事務(wù)提交成功后向消息隊列寫入一個事件事件內(nèi)容包括 meeting_id、reservation_id、change_typecreate/cancel/reschedule。通知模塊消費事件后根據(jù)模板渲染通知內(nèi)容并調(diào)用各渠道接口。這里要特別寫明事件寫入和預(yù)訂事務(wù)是同一個事務(wù)確保預(yù)訂成功就一定有通知事件產(chǎn)生消費失敗時通知模塊負(fù)責(zé)重試不讓預(yù)訂模塊反向感知。5. 撰寫會議管理系統(tǒng)詳細(xì)設(shè)計說明書的踩坑記錄5.1 會議室狀態(tài)不一致預(yù)訂沖突檢查形同虛設(shè)現(xiàn)象系統(tǒng)上線后出現(xiàn)兩個部門訂到同一間會議室的情況沖突檢測邏輯沒有失效但數(shù)據(jù)庫里兩個訂單都成功了。原因說明書里只寫了「預(yù)訂時檢查沖突」但沒有定義加鎖范圍。開發(fā)實現(xiàn)時采用了先查后插的方式?jīng)]有加鎖事務(wù)隔離級別是 Read Committed結(jié)果并發(fā)時兩個事務(wù)都能查到「無沖突」然后都插入成功。解決將沖突檢測改為悲觀鎖方案。事務(wù)內(nèi)先對目標(biāo)會議室的主記錄執(zhí)行行級鎖定再執(zhí)行沖突查詢和插入操作同時把 buffer_minutes 納入鎖定的時間范圍。說明書里對這個規(guī)則進(jìn)行了特別標(biāo)注禁止使用裸查后插的方式處理沖突檢測。5.2 doc 文檔改到最后團(tuán)隊分不清哪份才算有效版本現(xiàn)象詳細(xì)設(shè)計說明書發(fā)給開發(fā)后開發(fā)直接在原文件上做標(biāo)注產(chǎn)品又補充了需求項目群里同時流傳多份「最新說明書」開發(fā)照著一份做測試照著另一份驗。原因doc 格式的修訂不像在線協(xié)作文檔那樣能實時統(tǒng)一團(tuán)隊里沒有指定文檔主筆變更記錄也沒有落實負(fù)責(zé)人。解決我現(xiàn)在的習(xí)慣是說明書永遠(yuǎn)只由一名主筆維護(hù)其余角色通過評審意見提交修訂需求由主筆統(tǒng)一合并。每個版本固定一個文件名格式《會議管理系統(tǒng)詳細(xì)設(shè)計說明書_vX.Y_日期.doc》版本號與日期必須同時保留避免用「最終版」「最終版2」這類無法追蹤的文件名。主筆確認(rèn)合并后舊版本只讀存檔不再修改。5.3 權(quán)限寫得太粗普通員工能取消同事的預(yù)訂現(xiàn)象上線一周內(nèi)出現(xiàn)普通員工把別人的會議預(yù)訂取消了數(shù)據(jù)庫記錄顯示取消動作來自非預(yù)訂人、非管理員。原因說明書里寫了「預(yù)訂人可取消」但沒有定義取消接口的權(quán)限校驗范圍開發(fā)實現(xiàn)時只校驗了登錄態(tài)沒有校驗操作者身份。解決在說明書中增加角色-動作權(quán)限矩陣明確列出預(yù)訂人、參會人、管理員三個角色對每類操作的可執(zhí)行性。預(yù)訂取消和改期統(tǒng)一限定為預(yù)訂人本人或管理員參會人只有查看權(quán)限審批只允許管理員操作紀(jì)要上傳權(quán)限屬于主持人或記錄人。矩陣放在所有接口設(shè)計之前作為接口實現(xiàn)的前置校驗清單。5.4 通知沒有補償重試并發(fā)一高就丟消息現(xiàn)象會議創(chuàng)建高峰時段部分參會人沒有收到會議通知郵件日志里查不到發(fā)送失敗記錄通知記錄表里也沒有對應(yīng)的消息數(shù)據(jù)。原因通知發(fā)送時只把郵件服務(wù)調(diào)用放在主流程里未將通知記錄持久化同時消息隊列出現(xiàn)瞬時阻塞時沒有被消費的消息直接丟失沒有重試補償機制。解決在通知表中增加狀態(tài)字段待發(fā)送狀態(tài)先落庫再異步逐條處理。處理失敗時更新狀態(tài)和重試次數(shù)重試次數(shù)按順序遞增整個過程由定時任務(wù)掃描兜底。通知記錄表成為唯一的數(shù)據(jù)源任何發(fā)送動作都能被追溯。5.5 決議負(fù)責(zé)人和知會人混在同一張表待辦跟蹤失控現(xiàn)象會議產(chǎn)生的決議被默認(rèn)指派給會議室預(yù)訂人而真正執(zhí)行決議的人只是參會人逾期催辦時系統(tǒng)給全部參會人群發(fā)郵件跟蹤效果極差。原因設(shè)計時把參會人等同為決議執(zhí)行人沒有區(qū)分「執(zhí)行角色」和「信息接收角色」。解決決議表單獨設(shè)置負(fù)責(zé)人 owner_id 和知會人 cc_ids 字段。創(chuàng)建決議時負(fù)責(zé)人必須手動指定系統(tǒng)不提供默認(rèn)值催辦通知只發(fā)給負(fù)責(zé)人升級通知只發(fā)給負(fù)責(zé)人的上級。會議紀(jì)要詳情頁展示負(fù)責(zé)人和知會人兩個獨立區(qū)塊知會人只能查看進(jìn)展不能操作狀態(tài)。6. 說明書交付前怎么驗證用例打點、SQL 預(yù)演和反向走查詳細(xì)設(shè)計說明書是最容易「寫時熱鬧、落地散架」的交付物。內(nèi)容寫完不算完我在交付前會做三件事來驗證說明書的質(zhì)量。第一件事是用例打點。從需求階段整理的用例清單里挑出 10 個左右最核心的用例逐個確認(rèn)它們在說明書里有沒有對應(yīng)設(shè)計。比如「預(yù)訂人修改會議時間」我要求必須同時看到三處設(shè)計沖突檢測的區(qū)間規(guī)則、權(quán)限矩陣中對改期操作的角色限制、修改成功后通知事件的重新觸發(fā)描述。任何一處缺失說明書直接退回補全不進(jìn)入評審會。第二件事是 SQL 預(yù)演。選最關(guān)鍵的查詢直接寫出來跑一遍用來暴露表結(jié)構(gòu)和索引設(shè)計的不足。比如查詢會議室最近七天的預(yù)訂記錄這個 SQL 在數(shù)據(jù)量小時毫無感覺但會議室使用半年后動輒幾千條記錄索引缺失就是預(yù)訂頁面緩慢的元兇SELECT start_time, end_time, meeting_topic, booker_id FROM meeting_reservation WHERE room_id 101 AND status 2 AND start_time NOW() ORDER BY start_time ASC;如果 (room_id, status, start_time) 沒有組合索引這條查詢會逐步變慢最后成為預(yù)訂確認(rèn)頁的黑匣子誰也不知道響應(yīng)時間為什么從 100ms 漲到 3 秒。SQL 預(yù)演就是提前把這個黑匣子揭開。第三件事是反向走查。把前端原型拿過來按頁面反推數(shù)據(jù)結(jié)構(gòu)。預(yù)訂日歷頁需要一次接口調(diào)用就拿到會議室名稱、預(yù)訂人姓名、會議主題而這些信息分散在會議室表和預(yù)訂單表里如果說明書寫接口時沒有預(yù)留聯(lián)表查詢的描述開發(fā)階段就會出現(xiàn)內(nèi)存拼接的臨時方案雖然能跑但后續(xù)每加一個字段都要改一遍。我到現(xiàn)在還記得第一次獨立負(fù)責(zé)這種系統(tǒng)時過分相信「寫完就算完成」結(jié)果集成階段被一個狀態(tài)機邊界反復(fù)折騰。后來養(yǎng)成的習(xí)慣是說明書往下發(fā)之前讓開發(fā)先做一輪挑刺式評審專門找寫得不具體、需要靠猜的地方。這個辦法幫我躲掉了不少后面要還的債也希望幫到你。本文還有配套的精品資源點擊獲取