138 lines
5.9 KiB
Go
138 lines
5.9 KiB
Go
// Package service 定义 room-service 领域服务及其持久化边界。
|
||
package service
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
"hyapp/services/room-service/internal/room/outbox"
|
||
)
|
||
|
||
// RoomMeta 对应 rooms 表中房间的持久元数据。
|
||
type RoomMeta struct {
|
||
// RoomID 是房间主键,也是恢复和 lease 路由的分区键。
|
||
RoomID string
|
||
// OwnerUserID 是房间所有者,恢复无快照房间时用于重建管理员集合。
|
||
OwnerUserID int64
|
||
// HostUserID 是主持人,恢复无快照房间时用于重建管理员集合。
|
||
HostUserID int64
|
||
// SeatCount 是初始麦位数量,只有无快照恢复时需要它重建麦位。
|
||
SeatCount int32
|
||
// Mode 是房间模式,当前作为元数据持久化。
|
||
Mode string
|
||
// Status 是房间基础状态,快照缺失时用于恢复 RoomState.Status。
|
||
Status string
|
||
// VisibleRegionID 是房间列表可见区域,0 表示 GLOBAL 兜底桶。
|
||
VisibleRegionID int64
|
||
}
|
||
|
||
// CommandRecord 对应 room_command_log 中一条成功命令。
|
||
type CommandRecord struct {
|
||
// RoomID 是命令所属房间。
|
||
RoomID string
|
||
// RoomVersion 是命令成功应用后的房间版本,恢复时按它排序回放。
|
||
RoomVersion int64
|
||
// CommandID 是幂等键,repository 必须保证同房间唯一。
|
||
CommandID string
|
||
// CommandType 是反序列化命令 payload 的分发键。
|
||
CommandType string
|
||
// Payload 是命令 JSON 序列化结果。
|
||
Payload []byte
|
||
// Replayable 标记该命令是否参与恢复回放。
|
||
Replayable bool
|
||
// CreatedAt 是命令成功落盘时间。
|
||
CreatedAt time.Time
|
||
}
|
||
|
||
// SnapshotRecord 对应 room_snapshots 中的一条最新快照。
|
||
type SnapshotRecord struct {
|
||
// RoomID 是快照所属房间。
|
||
RoomID string
|
||
// RoomVersion 是快照覆盖到的房间版本。
|
||
RoomVersion int64
|
||
// Payload 是 roomv1.RoomSnapshot 的 protobuf 序列化结果。
|
||
Payload []byte
|
||
// CreatedAt 是快照生成时间。
|
||
CreatedAt time.Time
|
||
}
|
||
|
||
// RoomListEntry 是 room_list_entries 的领域投影,只保存列表卡片所需字段。
|
||
type RoomListEntry struct {
|
||
// RoomID 是列表卡片和 JoinRoom 的跳转目标。
|
||
RoomID string
|
||
// VisibleRegionID 是列表隔离桶,查询只能按该字段过滤。
|
||
VisibleRegionID int64
|
||
// OwnerUserID 是房间所有者,用于卡片展示和运营排查。
|
||
OwnerUserID int64
|
||
// HostUserID 是当前主持人,用于卡片展示。
|
||
HostUserID int64
|
||
// Title 是卡片标题;空值由客户端或后续资料聚合兜底。
|
||
Title string
|
||
// CoverURL 是卡片封面;空值表示没有单独封面。
|
||
CoverURL string
|
||
// Mode 是房间模式,来自 RoomState/RoomMeta。
|
||
Mode string
|
||
// Status 是房间生命周期状态,列表默认只查 active。
|
||
Status string
|
||
// Heat 是房间热度,当前主要由送礼累计。
|
||
Heat int64
|
||
// OnlineCount 是 room-service 业务 presence 数量。
|
||
OnlineCount int32
|
||
// SeatCount 是麦位总数。
|
||
SeatCount int32
|
||
// OccupiedSeatCount 是当前被占用麦位数。
|
||
OccupiedSeatCount int32
|
||
// SortScore 是热门列表排序分,算法不进入 RoomState。
|
||
SortScore int64
|
||
// CreatedAtMS 是创建房间时的毫秒时间,new tab 使用它排序。
|
||
CreatedAtMS int64
|
||
// UpdatedAtMS 是投影最后更新时间。
|
||
UpdatedAtMS int64
|
||
}
|
||
|
||
// RoomListQuery 是 room-service 房间列表读模型查询条件。
|
||
type RoomListQuery struct {
|
||
// VisibleRegionID 是服务端解析出的用户区域,客户端不能伪造。
|
||
VisibleRegionID int64
|
||
// Tab 只允许 hot/new,决定排序字段。
|
||
Tab string
|
||
// Limit 是实际查询数量,service 层会限制最大值。
|
||
Limit int
|
||
// CursorSortScore 是 hot tab 的游标 score。
|
||
CursorSortScore int64
|
||
// CursorCreatedAtMS 是 new tab 的游标创建时间。
|
||
CursorCreatedAtMS int64
|
||
// CursorRoomID 是同分或同时间下的稳定翻页边界。
|
||
CursorRoomID string
|
||
}
|
||
|
||
// Repository 聚合 room-service 在首版需要的全部持久化读写。
|
||
type Repository interface {
|
||
// SaveRoomMeta 保存房间基础元数据,创建房间时必须先建立它。
|
||
SaveRoomMeta(ctx context.Context, meta RoomMeta) error
|
||
// GetRoomMeta 读取房间基础元数据,恢复无内存 Cell 的房间依赖它。
|
||
GetRoomMeta(ctx context.Context, roomID string) (RoomMeta, bool, error)
|
||
// GetCommand 读取已提交命令,用于幂等重试和 command_id 冲突判定。
|
||
GetCommand(ctx context.Context, roomID string, commandID string) (CommandRecord, bool, error)
|
||
// SaveCommand 追加成功命令日志,关键命令恢复必须依赖它。
|
||
SaveCommand(ctx context.Context, record CommandRecord) error
|
||
// ListCommandsAfter 读取快照版本之后的命令,恢复时按版本顺序回放。
|
||
ListCommandsAfter(ctx context.Context, roomID string, roomVersion int64) ([]CommandRecord, error)
|
||
// SaveSnapshot 保存最新房间快照,允许覆盖较低版本号快照但不能倒退。
|
||
SaveSnapshot(ctx context.Context, snapshot SnapshotRecord) error
|
||
// GetLatestSnapshot 读取当前最新快照,恢复时优先使用它减少回放成本。
|
||
GetLatestSnapshot(ctx context.Context, roomID string) (SnapshotRecord, bool, error)
|
||
// SaveOutbox 写入房间外事件,必须和成功命令保持同一提交语义。
|
||
SaveOutbox(ctx context.Context, records []outbox.Record) error
|
||
// ListPendingOutbox 扫描待补偿投递事件。
|
||
ListPendingOutbox(ctx context.Context, limit int) ([]outbox.Record, error)
|
||
// MarkOutboxPublished 标记事件已经投递成功。
|
||
MarkOutboxPublished(ctx context.Context, eventID string) error
|
||
// MarkOutboxFailed 记录一次投递失败并保留 pending 状态等待重试。
|
||
MarkOutboxFailed(ctx context.Context, eventID string, lastErr string) error
|
||
// UpsertRoomListEntry 写入或更新房间列表读模型;失败不应破坏 Room Cell 已提交状态。
|
||
UpsertRoomListEntry(ctx context.Context, entry RoomListEntry) error
|
||
// ListRoomListEntries 按区域和 tab 查询房间列表,不访问 Room Cell 内存。
|
||
ListRoomListEntries(ctx context.Context, query RoomListQuery) ([]RoomListEntry, error)
|
||
}
|