D-20260802-01|RoomId=不可重用的房間實例識別¶
背景與驅動力¶
既有六碼房號只有 34^6 個組合,並以非密碼學 Math.random() 產生;它同時充當房間實例識別、Gossip key、signaling scope、觀戰入口與 URL。短碼可重用使延遲訊息、舊連結與新房間落在同一 namespace,不能穩定區分兩次不同的房間生命週期。
考慮過的選項¶
- 保留六碼並增加中央租約:需要引入全域協調者,違反 P2P 房間發現設計。
- 六碼作為 canonical id、另加 generation:所有 wire 與 URL 仍需攜帶兩欄,且舊碼單獨流通時仍有歧義。
- UUID v4 作為 canonical
RoomId(採納):由 Web Crypto 產生,122 bits 隨機性,格式與驗證跨端一致。
決定¶
RoomId是 branded string,canonical wire 形式為小寫 UUID v4;生成使用crypto.randomUUID(),碰到仍存活的極低機率衝突時重生。- 每次建房都產生新
RoomId;關房後不得刻意重用。RoomId貫穿 room state、Gossip discovery/presence、match offer、signalingroom:<roomId>scope、觀戰、聊天、摘要與/room/:roomId。 - 所有不可信邊界以同一 parser fail-closed;舊
roomCode欄位與六碼值不接受、不保留相容讀取或雙寫。 matchId仍依 D-20260710-02 由 roster、startedAt、matchRules 推導;RoomId不加入比賽共識識別。- 未來若需要便於口述的邀請碼,必須建模為可輪換、可過期且與
RoomId分離的 alias;不得重新把 alias 當房間實例識別。
後果與影響¶
延遲公告、舊 URL 與歷史訊息不會因短碼重用誤指向新房;P2P 各層以單一識別鍵對齊。代價是人工輸入較長,因此目前 UI 顯示「房間 ID」並接受完整 UUID;可讀邀請 alias 留給獨立需求處理。