Files
toolbox/server/internal/store/session_store.go
T
2026-08-30 21:25:22 +08:00

82 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package store 提供会话存储接口
// 接口解耦使得可以在测试中用 mock 替换,生产用 Redis
package store
import (
"context"
"time"
)
// Session 存储的会话数据结构(不含敏感字段)
type Session struct {
ID string `json:"session_id"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}
// ParticipantInfo 参与者在全量快照中的状态
type ParticipantInfo struct {
Nickname string `json:"nickname"`
BrowserID string `json:"browser_id,omitempty"`
Submitted bool `json:"submitted"`
Match *bool `json:"match,omitempty"`
}
// SessionSnapshot Get 返回的全量快照
type SessionSnapshot struct {
SessionID string `json:"session_id"`
InitiatorHash string `json:"-"` // 发起方标准答案哈希,不对外暴露
InitiatorNickname string `json:"initiator_nickname"`
InitiatorBrowserID string `json:"initiator_browser_id,omitempty"`
InitiatorSubmitted bool `json:"initiator_submitted"`
AllowResubmit bool `json:"allow_resubmit"`
IgnoreWs bool `json:"ignore_ws"` // 是否忽略首尾空白
Participants []ParticipantInfo `json:"participants"`
ExpiresAt time.Time `json:"expires_at"`
}
// SessionStore 会话存储接口
type SessionStore interface {
// Create 原子创建会话(SET NX EX),同时记录发起方昵称和 browserId
Create(ctx context.Context, id, initiatorNickname, initiatorBrowserID string, ttl time.Duration) error
// SubmitInitiator 发起方提交标准答案(initiator_hash + initiator_nickname + 原始文本)
// 同时立即为所有已提交的参与者计算 match
SubmitInitiator(ctx context.Context, sessionID, nickname, hashHex, originalText string) error
// SubmitParticipant 参与者提交自己的文本(按 nickname 唯一标识,同时存原始文本)
// 返回:initiatorSubmitted(发起方是否已提交,是则 match 已算出)、match
SubmitParticipant(ctx context.Context, sessionID, nickname, hashHex, originalText string) (
initiatorSubmitted bool, match *bool, err error)
// JoinParticipant 参与者加入会话(只登记昵称,不提交文本)
// browserId 用于识别"同一个人",避免跨 tab 昵称冲突
JoinParticipant(ctx context.Context, sessionID, nickname, browserID string) error
// SetResubmit 设置是否允许参与者重复提交
SetResubmit(ctx context.Context, sessionID string, allow bool) error
// SetIgnoreWs 设置比对时是否忽略首尾空白(1=忽略,0=不忽略)
SetIgnoreWs(ctx context.Context, sessionID string, ignore bool) error
// GetIgnoreWs 获取当前会话的 ignore_ws 设置
GetIgnoreWs(ctx context.Context, sessionID string) (bool, error)
// RecalcMatches 按新的 ignoreWs 规则重新 trim + hash 所有已提交文本并重算 match
RecalcMatches(ctx context.Context, sessionID string, ignoreWs bool) error
// UpdateParticipantNickname 原子重命名参与者:将 participant:{old} → participant:{new}
// oldBrowserID 用于判断是否与冲突方是同一个浏览器(跳过冲突)
// 返回业务错误:ErrSessionNotFound / ErrNicknameConflict
UpdateParticipantNickname(ctx context.Context, sessionID, oldNick, newNick, oldBrowserID string) error
// RemoveParticipant 参与者离开时从 Redis 删除其所有字段(hash/text/match)
RemoveParticipant(ctx context.Context, sessionID, nickname string) error
// Get 获取会话当前状态全量快照
Get(ctx context.Context, sessionID string) (*SessionSnapshot, error)
// Delete 删除会话
Delete(ctx context.Context, sessionID string) error
}