基于Ruby与GraphQL的线下活动状态追踪与数据建模方案咨询
核心数据建模(优先解决你最关心的问题)
首先明确:预设排期和实际运行状态必须解耦,不能共用同一张表,否则延误调整会污染原始排期数据,也不利于用户对比“原计划/实际”差异。
对应Ruby端的ActiveRecord模型设计(适配你已有的CRUD能力):
Event总活动表- 存活动基础信息:名称、时间、地点等,是所有排期的顶层关联
Stage舞台表(多舞台场景必加,单舞台可简化为常量)- 关联到所属
Event,存舞台名称
- 关联到所属
ScheduledSlot预设排期表(原始排期数据,尽量少改)- 关联:
event_id、stage_id、performer_id(关联演出者表) - 字段:
scheduled_start_at、scheduled_end_at、备注等
- 关联:
ActualSlot实际运行状态表(核心动态表)- 关联:
scheduled_slot_id - 字段:
actual_start_at(时间戳,演出实际开始时间)、actual_end_at(时间戳,演出实际结束时间,空值=正在进行) - 后端加简单事务校验:同舞台下,同一时间只能有1条
actual_end_at为空的记录,避免误操作
- 关联:
- 通知触发标记(不用单独建通知表也能实现最小需求)
- 直接在
ScheduledSlot表加两个时间戳字段:ten_min_notification_sent_at、five_min_notification_sent_at,用来标记管理员是否已经触发过对应通知,避免重复发送
- 直接在
管理员侧操作落地
所有操作都是简单的字段更新,不用复杂逻辑:
- 切换当前演出状态:
- 点击「开始XX演出」:后端创建对应
ScheduledSlot的ActualSlot记录,写入当前时间到actual_start_at;同时自动给同舞台下上一条正在进行的ActualSlot写入当前时间到actual_end_at,标记为结束 - 点击「结束当前演出」:给当前活跃的
ActualSlot写入当前时间到actual_end_at
- 点击「开始XX演出」:后端创建对应
- 触发推送通知:
- 点击「10分钟提醒」/「5分钟提醒」按钮:后端把对应
ScheduledSlot的ten_min_notification_sent_at/five_min_notification_sent_at更新为当前时间,同时触发已有的推送逻辑发送消息 - 前端按钮状态直接读后端的标记字段:如果对应时间戳不为空,按钮置灰禁止重复点击
- 点击「10分钟提醒」/「5分钟提醒」按钮:后端把对应
实时状态同步实现(适配Ruby GraphQL技术栈)
不用额外引入新的中间件,用graphql-ruby原生能力即可:
- 普通查询:写一个GraphQL Query字段
activeActualSlot(stageId: ID!),直接查询同舞台下actual_start_at非空、actual_end_at为空的ActualSlot,关联带出演出者、排期信息返回给前端 - 实时推送:用
graphql-ruby的Subscription能力(底层复用Rails自带的ActionCable即可),当ActualSlot的状态更新(开始/结束)时,触发对应舞台的Subscription推送,前端页面不用刷新就能拿到最新的当前演出状态 - 用户端展示逻辑:如果有对应的
ActualSlot就优先展示实际状态(比如“正在演出:XX乐队 已进行12分钟”),没有的话 fallback 展示ScheduledSlot的预设排期信息
简化避坑建议
- 不要为了“自动同步延误”做复杂的定时任务:你的需求里已经明确通知是管理员手动触发,状态切换也是管理员手动操作,完全不用引入额外的调度服务,减少故障点
- 预设排期一旦发布给用户看之后,尽量不要修改,所有延误调整都通过
ActualSlot体现,这样用户既能看到原始排期,也能知道当前实际的运行状态 - 不用一开始就做复杂的通知留存表,等后续需要追溯通知发送记录时再扩展即可,优先满足核心场景的落地速度
内容的提问来源于stack exchange,提问作者TLenahan14
相关产品推荐
相关产品推荐

