Skip to content

feat: implement room creation and management (Part 5) - #10

Open
Dawnstar111 wants to merge 3 commits into
QSCTech:mainfrom
Dawnstar111:feature/create_and_manage_room
Open

feat: implement room creation and management (Part 5)#10
Dawnstar111 wants to merge 3 commits into
QSCTech:mainfrom
Dawnstar111:feature/create_and_manage_room

Conversation

@Dawnstar111

@Dawnstar111 Dawnstar111 commented May 23, 2026

Copy link
Copy Markdown
Collaborator

概述

实现5组(房间创建与房间管理)全部后端 service 层功能,同时补全3组和6组依赖的 service stub,确保项目可编译运行。

5组接口

方法 路径 功能
POST /rooms 创建房间
PUT /rooms/{id} 修改房间信息(仅房主)
POST /rooms/{id}/close 关闭/解散房间(仅房主)

修改文件

文件 +行 说明
internal/api/router.go +8 X-Mock-User-ID 开发环境中间件
internal/service/room_service.go +79 5组核心逻辑 + 6组/3组临时补充实现
internal/service/user_service.go +22 3组临时补充实现 + MockUser 支持
internal/repository/room_repository.go +13 事务创建 + 成员删除 + 申请查询

5组需求逐项实现

POST /rooms - 创建房间

  • 必填字段校验: name, sport_type, campus_name, venue_name, visibility, join_mode, start_time, end_time
  • 枚举校验: visibility (public/private), join_mode (direct/approval/invite_only)
  • 时间校验: end_time > start_time
  • 容量校验: member_limit > 0(若提供)
  • 同伴码校验: tennis/badminton 需 member_limit >= 2
  • 预约状态: need_reservation=true 时自动设置 reservation_status="pending"
  • 事务保证: room + owner member 在同一个 GORM Transaction 中创建,防止脏数据
  • 状态过渡: 创建后若成员数达到 member_limit,自动 recruiting → full

PUT /rooms/{id} - 修改房间

  • 权限校验: 仅房主可修改
  • 状态校验: 仅 recruiting 状态可修改
  • 可选字段: 支持修改 name/visibility/join_mode/time/gender_rule/member_limit/organization/level_desc/description/need_reservation
  • 枚举校验: visibility 和 join_mode 修改时校验合法值
  • 时间校验: 修改后 end_time > start_time
  • 容量校验: member_limit > 0,且不能低于当前已加入人数
  • 预约状态同步: need_reservation 关闭时 reservation_status="not_required";重新开启时若原本为 not_required 则变为 pending
  • 现有预约状态保护: 若 reservation_status 已是 scheduled/submitting/success 则不覆盖

POST /rooms/{id}/close - 关闭房间

  • 权限校验: 仅房主可操作
  • 防重复: 已 cancelled 的房间不可再次关闭
  • 状态: 设置 status="cancelled"(严格遵循统一状态约定)

Review 修复明细

1. GetCurrent 固定取第一条用户 → 改为可切换

  • 修复: router.go 新增中间件,读取 X-Mock-User-ID HTTP Header 注入 context
  • GetCurrent: 检测 context 中 mock ID → 按 ID 查用户 → 找不到直接报错(不静默降级)
  • 使用方式: curl -H "X-Mock-User-ID: 3" ... 即可切换用户
  • 不影响3组: 不发送 Header 时行为不变;3组接真实登录态后可保留或删除

2. 创建房间非事务 → 改为事务

  • 修复: 新增 CreateRoomWithOwner() repository 方法
  • 原理: 使用 GORM db.Transaction() 确保 room + owner member 原子写入
  • 效果: 中间任何一步失败,全部回滚,不会留下没有 owner 的房间

3. need_reservation 和 reservation_status 不同步

  • 修复: Update 方法中 need_reservation 切换时同步更新 reservation_status
  • 规则:
    • need_reservation: true (且原状态为 not_required) → reservation_status="pending"
    • need_reservation: false → reservation_status="not_required"
    • 已有 scheduled/submitting/success 状态时不覆盖

4. 枚举字段无校验 → 增加校验

  • 修复: 新增 isValidVisibility()isValidJoinMode() 校验函数
  • 合法值:
    • visibility: public, private
    • join_mode: direct, approval, invite_only
  • 覆盖: Create 和 Update 均校验

5. member_limit 无有效性校验 → 增加校验

  • Create: member_limit > 0(若提供)
  • Update: member_limit > 0,且不能低于当前已加入成员数
  • 同伴码: tennis/badminton 创建时 member_limit >= 2

6. PR 范围超出5组 → 代码标注

  • 修复: room_service.go 和 user_service.go 中 Part 3/6 方法已添加明确注释:

@serein6174

Copy link
Copy Markdown
Collaborator

整体功能基本可以接受,本地测试通过。不过还有几个点建议继续处理或至少在后续合并前明确:

  1. X-Mock-User-ID 只能作为临时测试方案
    目前它用于在 3 组 auth 合并前方便 Postman 指定当前用户。这个可以暂时接受,但等认证模块接入后需要删除,正式环境不能允许客户端通过 header 任意指定当前用户。

  2. 不带 X-Mock-User-ID 时仍然 fallback 到第一条用户
    这个还是不合理。没有当前用户上下文时应该返回未登录/unauthenticated,而不是默认数据库第一条用户。否则漏带 header 的请求会产生错误归属。

  3. member_limit=1 创建后会立刻变成 full,导致 owner 不能 update
    创建房间时 owner 已经是 joined member,tryMarkFull 会把状态改成 full;但 Update 只允许 recruiting。这会导致房主刚创建完单人上限房间就不能改。建议至少允许 owner 修改 full 房间的基础信息,或者不要在创建后立刻锁死。

  4. buddy_code现已更正为invite_code需要同步修改,且 生成仍有碰撞风险
    现在是 ROOM%06d + UnixNano()%1000000,没有 retry。这个不一定马上出问题,但设计上不稳。建议生成失败时遇到 unique 冲突重试,或者换更可靠的随机码。

@Lucent-Snow

Copy link
Copy Markdown
Collaborator

Group 3 auth/user-profile implementation is now available in #15.

That PR adds the real context-based current-user flow:

  • X-Auth-UID -> request context via auth middleware
  • protected routes return 401 when auth is missing
  • UserService.GetCurrent resolves by auth UID instead of falling back to the first user
  • profile updates enter pending_review and create audit records

After #15 is merged, this PR should be able to drop the temporary X-Mock-User-ID middleware and the GetFirst fallback in user_service.go, then call userService.GetCurrent(ctx) against the authenticated context instead.

- Add middleware/auth.go (RequireAuth/CurrentUser/AuthByRoute)
- Replace X-Mock-User-ID with AuthByRoute in router.go
- Sync user_service.go with upstream Group 3 implementation
- Add UpdateProfileWithAudit to user_repository
- Allow owner to update room in 'full' status
- Auto-transition full→recruiting when capacity expanded
- Use crypto/rand for invite_code generation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants