-
Notifications
You must be signed in to change notification settings - Fork 0
Add guest auth and enforce WS token identity #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
c05b8ed
docs: 忽略后端架构文档文件
delete-cloud fe5c6af
feat(room): 实现房间阶段协议与可配置游戏规则
delete-cloud f98d44e
docs: 更新 n8n 工作流文档并重构图像生成逻辑
delete-cloud 1a064e5
Add guest auth and enforce WS token identity
delete-cloud 62f7080
Address Copilot review findings on auth and WS phase flow
delete-cloud File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -65,3 +65,4 @@ backups/ | |
|
|
||
| # Test files (local only) | ||
| backend/test2/ | ||
| backend/ARCHITECTURE.md | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| # WebSocket 房间阶段协议(投票阶段信号) | ||
|
|
||
| 目标:让前端能实时展示“投票阶段开始/结束”的倒计时,并在投票阶段禁用提交画作入口。 | ||
|
|
||
| ## 1) 房间阶段(phase) | ||
|
|
||
| 后端通过 Socket 下发的 `phase` 字段取值: | ||
| - `active`:提交/观赏阶段(允许提交画作;不一定允许投票) | ||
| - `voting`:投票阶段(不允许提交画作;允许投票/撤票) | ||
| - `gameover`:结算结束 | ||
|
|
||
| 后端落库字段:`rooms.status`。 | ||
|
|
||
| ## 2) 事件:sync:state(进入房间时全量同步) | ||
|
|
||
| 事件名:`sync:state` | ||
|
|
||
| 触发:客户端 `room:join` 后,服务端会 emit 给该 socket。 | ||
|
|
||
| Payload(camelCase,新增字段对旧前端向后兼容): | ||
| - `phase: string`(`active`/`voting`/`gameover`) | ||
| - `roomId: string` | ||
| - `totalItems: number` | ||
| - `aiCount: number` | ||
| - `turbidity: number` | ||
| - `theme: ThemeResponse` | ||
| - `items: GameItemData[]` | ||
| - `votingStartedAt?: number`(Unix 毫秒时间戳,仅 voting 期存在) | ||
| - `votingEndsAt?: number`(Unix 毫秒时间戳,仅 voting 期存在) | ||
| - `serverTime: number`(Unix 毫秒时间戳,服务端当前时间) | ||
|
|
||
| 示例(voting 中): | ||
| ```json | ||
| { | ||
| "phase": "voting", | ||
| "roomId": "ABCD12", | ||
| "totalItems": 8, | ||
| "aiCount": 2, | ||
| "turbidity": 0.4, | ||
| "votingStartedAt": 1769948000000, | ||
| "votingEndsAt": 1769948045000, | ||
| "serverTime": 1769948012345, | ||
| "theme": { "...": "..." }, | ||
| "items": [] | ||
| } | ||
| ``` | ||
|
|
||
| ## 3) 事件:phase:update(房间内广播阶段切换) | ||
|
|
||
| 事件名:`phase:update` | ||
|
|
||
| 触发:服务端在以下时机会向 `within(roomId)` 广播给同房间所有连接: | ||
| - `active -> voting`:进入投票阶段 | ||
| - `voting -> active`:投票超时且未结束游戏,重置票数并退出投票阶段 | ||
| - `* -> gameover`:胜负判定落库 gameover 后立即广播 | ||
|
|
||
| Payload(camelCase): | ||
| - `phase: string` | ||
| - `roomId: string` | ||
| - `votingStartedAt?: number`(Unix ms) | ||
| - `votingEndsAt?: number`(Unix ms) | ||
| - `serverTime: number`(Unix ms) | ||
|
|
||
| 示例(进入 voting): | ||
| ```json | ||
| { | ||
| "phase": "voting", | ||
| "roomId": "ABCD12", | ||
| "votingStartedAt": 1769948000000, | ||
| "votingEndsAt": 1769948045000, | ||
| "serverTime": 1769948000001 | ||
| } | ||
| ``` | ||
|
|
||
| 示例(退出 voting 回到 active): | ||
| ```json | ||
| { | ||
| "phase": "active", | ||
| "roomId": "ABCD12", | ||
| "serverTime": 1769948050000 | ||
| } | ||
| ``` | ||
|
|
||
| 示例(gameover): | ||
| ```json | ||
| { | ||
| "phase": "gameover", | ||
| "roomId": "ABCD12", | ||
| "serverTime": 1769948060000 | ||
| } | ||
| ``` | ||
|
|
||
| ## 4) 前端倒计时推荐算法 | ||
|
|
||
| 服务端同时提供 `votingEndsAt` 与 `serverTime`,用于抵消客户端/服务器时钟偏差。 | ||
|
|
||
| 推荐做法: | ||
| 1. 记录收到消息时的本地时间 `clientNowAtReceive = Date.now()` 与消息中的 `serverTime`。 | ||
| 2. 估算服务器与客户端的时间偏移:`offset = serverTime - clientNowAtReceive`。 | ||
| 3. 后续倒计时使用:`remainingMs = votingEndsAt - (Date.now() + offset)`。 | ||
|
|
||
| 若前端不做校时,也可直接:`remainingMs = votingEndsAt - Date.now()`(误差会更大)。 | ||
|
|
||
| ## 5) 禁提交与兼容性说明 | ||
|
|
||
| - 后端在 `voting` 阶段会拒绝 `POST /api/rooms/:room_code/drawings`(HTTP 400),因此旧前端即便未禁用按钮,也不会提交成功。 | ||
| - 新增字段/新事件均为增量:旧前端忽略未知字段/事件即可继续运行。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Room::vote_threshold的注释仍写“在线人数的 30%”,但实现已改为从Config.vote_threshold_ratio读取(默认 0.6)。建议更新注释以反映实际阈值来源/默认值,避免后续误用或调参时产生误解。There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated in 62f7080: comment now reflects config-driven ratio/min-threshold behavior for vote threshold calculation.