完善多赛道联调与全局产品架构

This commit is contained in:
2026-04-02 18:11:43 +08:00
parent 6964e26ec9
commit 0e28f70bad
45 changed files with 4819 additions and 282 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,8 @@ type EntrySessionSummary struct {
EventName string `json:"eventName"`
ReleaseID *string `json:"releaseId,omitempty"`
ConfigLabel *string `json:"configLabel,omitempty"`
VariantID *string `json:"variantId,omitempty"`
VariantName *string `json:"variantName,omitempty"`
RouteCode *string `json:"routeCode,omitempty"`
LaunchedAt string `json:"launchedAt"`
StartedAt *string `json:"startedAt,omitempty"`
@@ -139,10 +141,12 @@ func (s *EntryHomeService) GetEntryHome(ctx context.Context, input EntryHomeInpu
func buildEntrySessionSummary(session *postgres.Session) EntrySessionSummary {
summary := EntrySessionSummary{
ID: session.SessionPublicID,
Status: session.Status,
RouteCode: session.RouteCode,
LaunchedAt: session.LaunchedAt.Format(timeRFC3339),
ID: session.SessionPublicID,
Status: session.Status,
VariantID: session.VariantID,
VariantName: session.VariantName,
RouteCode: session.RouteCode,
LaunchedAt: session.LaunchedAt.Format(timeRFC3339),
}
if session.EventPublicID != nil {
summary.EventID = *session.EventPublicID

View File

@@ -35,6 +35,8 @@ type EventPlayResult struct {
} `json:"release,omitempty"`
ResolvedRelease *ResolvedReleaseView `json:"resolvedRelease,omitempty"`
Play struct {
AssignmentMode *string `json:"assignmentMode,omitempty"`
CourseVariants []CourseVariantView `json:"courseVariants,omitempty"`
CanLaunch bool `json:"canLaunch"`
PrimaryAction string `json:"primaryAction"`
Reason string `json:"reason"`
@@ -77,6 +79,11 @@ func (s *EventPlayService) GetEventPlay(ctx context.Context, input EventPlayInpu
result.Event.DisplayName = event.DisplayName
result.Event.Summary = event.Summary
result.Event.Status = event.Status
variantPlan := resolveVariantPlan(event.ReleasePayloadJSON)
result.Play.AssignmentMode = variantPlan.AssignmentMode
if len(variantPlan.CourseVariants) > 0 {
result.Play.CourseVariants = variantPlan.CourseVariants
}
if event.CurrentReleasePubID != nil && event.ConfigLabel != nil && event.ManifestURL != nil {
result.Release = &struct {
ID string `json:"id"`

View File

@@ -37,6 +37,7 @@ type LaunchEventInput struct {
EventPublicID string
UserID string
ReleaseID string `json:"releaseId,omitempty"`
VariantID string `json:"variantId,omitempty"`
ClientType string `json:"clientType"`
DeviceKey string `json:"deviceKey"`
}
@@ -49,6 +50,7 @@ type LaunchEventResult struct {
Launch struct {
Source string `json:"source"`
ResolvedRelease *ResolvedReleaseView `json:"resolvedRelease,omitempty"`
Variant *VariantBindingView `json:"variant,omitempty"`
Config struct {
ConfigURL string `json:"configUrl"`
ConfigLabel string `json:"configLabel"`
@@ -115,6 +117,7 @@ func (s *EventService) GetEventDetail(ctx context.Context, eventPublicID string)
func (s *EventService) LaunchEvent(ctx context.Context, input LaunchEventInput) (*LaunchEventResult, error) {
input.EventPublicID = strings.TrimSpace(input.EventPublicID)
input.ReleaseID = strings.TrimSpace(input.ReleaseID)
input.VariantID = strings.TrimSpace(input.VariantID)
input.DeviceKey = strings.TrimSpace(input.DeviceKey)
if err := validateClientType(input.ClientType); err != nil {
return nil, err
@@ -139,6 +142,24 @@ func (s *EventService) LaunchEvent(ctx context.Context, input LaunchEventInput)
if input.ReleaseID != "" && input.ReleaseID != *event.CurrentReleasePubID {
return nil, apperr.New(http.StatusConflict, "release_not_launchable", "requested release is not the current published release")
}
variantPlan := resolveVariantPlan(event.ReleasePayloadJSON)
variant, err := resolveLaunchVariant(variantPlan, input.VariantID)
if err != nil {
return nil, err
}
routeCode := event.RouteCode
var assignmentMode *string
var variantID *string
var variantName *string
if variant != nil {
resultMode := variant.AssignmentMode
assignmentMode = &resultMode
variantID = &variant.ID
variantName = &variant.Name
if variant.RouteCode != nil {
routeCode = variant.RouteCode
}
}
tx, err := s.store.Begin(ctx)
if err != nil {
@@ -163,7 +184,10 @@ func (s *EventService) LaunchEvent(ctx context.Context, input LaunchEventInput)
EventReleaseID: *event.CurrentReleaseID,
DeviceKey: input.DeviceKey,
ClientType: input.ClientType,
RouteCode: event.RouteCode,
AssignmentMode: assignmentMode,
VariantID: variantID,
VariantName: variantName,
RouteCode: routeCode,
SessionTokenHash: security.HashText(sessionToken),
SessionTokenExpiresAt: sessionTokenExpiresAt,
})
@@ -180,16 +204,17 @@ func (s *EventService) LaunchEvent(ctx context.Context, input LaunchEventInput)
result.Event.DisplayName = event.DisplayName
result.Launch.Source = LaunchSourceEventCurrentRelease
result.Launch.ResolvedRelease = buildResolvedReleaseFromEvent(event, LaunchSourceEventCurrentRelease)
result.Launch.Variant = variant
result.Launch.Config.ConfigURL = *event.ManifestURL
result.Launch.Config.ConfigLabel = *event.ConfigLabel
result.Launch.Config.ConfigChecksumSha256 = event.ManifestChecksum
result.Launch.Config.ReleaseID = *event.CurrentReleasePubID
result.Launch.Config.RouteCode = event.RouteCode
result.Launch.Config.RouteCode = routeCode
result.Launch.Business.Source = "direct-event"
result.Launch.Business.EventID = event.PublicID
result.Launch.Business.SessionID = session.SessionPublicID
result.Launch.Business.SessionToken = sessionToken
result.Launch.Business.SessionTokenExpiresAt = session.SessionTokenExpiresAt.Format(time.RFC3339)
result.Launch.Business.RouteCode = event.RouteCode
result.Launch.Business.RouteCode = routeCode
return result, nil
}

View File

@@ -26,6 +26,9 @@ type SessionResult struct {
Status string `json:"status"`
ClientType string `json:"clientType"`
DeviceKey string `json:"deviceKey"`
AssignmentMode *string `json:"assignmentMode,omitempty"`
VariantID *string `json:"variantId,omitempty"`
VariantName *string `json:"variantName,omitempty"`
RouteCode *string `json:"routeCode,omitempty"`
SessionTokenExpiresAt string `json:"sessionTokenExpiresAt"`
LaunchedAt string `json:"launchedAt"`
@@ -264,6 +267,9 @@ func buildSessionResult(session *postgres.Session) *SessionResult {
result.Session.Status = session.Status
result.Session.ClientType = session.ClientType
result.Session.DeviceKey = session.DeviceKey
result.Session.AssignmentMode = session.AssignmentMode
result.Session.VariantID = session.VariantID
result.Session.VariantName = session.VariantName
result.Session.RouteCode = session.RouteCode
result.Session.SessionTokenExpiresAt = session.SessionTokenExpiresAt.Format(time.RFC3339)
result.Session.LaunchedAt = session.LaunchedAt.Format(time.RFC3339)

View File

@@ -0,0 +1,189 @@
package service
import (
"crypto/rand"
"encoding/json"
"fmt"
"math/big"
"net/http"
"strings"
"cmr-backend/internal/apperr"
)
const (
AssignmentModeManual = "manual"
AssignmentModeRandom = "random"
AssignmentModeServerAssigned = "server-assigned"
)
type CourseVariantView struct {
ID string `json:"id"`
Name string `json:"name"`
Description *string `json:"description,omitempty"`
RouteCode *string `json:"routeCode,omitempty"`
Selectable bool `json:"selectable"`
}
type VariantBindingView struct {
ID string `json:"id"`
Name string `json:"name"`
RouteCode *string `json:"routeCode,omitempty"`
AssignmentMode string `json:"assignmentMode"`
}
type VariantPlan struct {
AssignmentMode *string
CourseVariants []CourseVariantView
}
func resolveVariantPlan(payloadJSON *string) VariantPlan {
if payloadJSON == nil || strings.TrimSpace(*payloadJSON) == "" {
return VariantPlan{}
}
var payload map[string]any
if err := json.Unmarshal([]byte(*payloadJSON), &payload); err != nil {
return VariantPlan{}
}
play, _ := payload["play"].(map[string]any)
if len(play) == 0 {
return VariantPlan{}
}
result := VariantPlan{}
if rawMode, ok := play["assignmentMode"].(string); ok {
if normalized := normalizeAssignmentMode(rawMode); normalized != nil {
result.AssignmentMode = normalized
}
}
rawVariants, _ := play["courseVariants"].([]any)
if len(rawVariants) == 0 {
return result
}
for _, raw := range rawVariants {
item, ok := raw.(map[string]any)
if !ok {
continue
}
id, _ := item["id"].(string)
name, _ := item["name"].(string)
id = strings.TrimSpace(id)
name = strings.TrimSpace(name)
if id == "" || name == "" {
continue
}
var description *string
if value, ok := item["description"].(string); ok && strings.TrimSpace(value) != "" {
trimmed := strings.TrimSpace(value)
description = &trimmed
}
var routeCode *string
if value, ok := item["routeCode"].(string); ok && strings.TrimSpace(value) != "" {
trimmed := strings.TrimSpace(value)
routeCode = &trimmed
}
selectable := true
if value, ok := item["selectable"].(bool); ok {
selectable = value
}
result.CourseVariants = append(result.CourseVariants, CourseVariantView{
ID: id,
Name: name,
Description: description,
RouteCode: routeCode,
Selectable: selectable,
})
}
return result
}
func resolveLaunchVariant(plan VariantPlan, requestedVariantID string) (*VariantBindingView, error) {
requestedVariantID = strings.TrimSpace(requestedVariantID)
if len(plan.CourseVariants) == 0 {
return nil, nil
}
mode := AssignmentModeManual
if plan.AssignmentMode != nil {
mode = *plan.AssignmentMode
}
if requestedVariantID != "" {
for _, item := range plan.CourseVariants {
if item.ID == requestedVariantID {
if !item.Selectable && mode == AssignmentModeManual {
return nil, apperr.New(http.StatusBadRequest, "variant_not_selectable", "requested variant is not selectable")
}
return &VariantBindingView{
ID: item.ID,
Name: item.Name,
RouteCode: item.RouteCode,
AssignmentMode: mode,
}, nil
}
}
return nil, apperr.New(http.StatusBadRequest, "variant_not_found", "requested variant does not exist")
}
selected, err := selectDefaultVariant(plan.CourseVariants, mode)
if err != nil {
return nil, err
}
return &VariantBindingView{
ID: selected.ID,
Name: selected.Name,
RouteCode: selected.RouteCode,
AssignmentMode: mode,
}, nil
}
func normalizeAssignmentMode(value string) *string {
switch strings.TrimSpace(value) {
case AssignmentModeManual:
mode := AssignmentModeManual
return &mode
case AssignmentModeRandom:
mode := AssignmentModeRandom
return &mode
case AssignmentModeServerAssigned:
mode := AssignmentModeServerAssigned
return &mode
default:
return nil
}
}
func selectDefaultVariant(items []CourseVariantView, mode string) (*CourseVariantView, error) {
candidates := make([]CourseVariantView, 0, len(items))
for _, item := range items {
if item.Selectable {
candidates = append(candidates, item)
}
}
if len(candidates) == 0 {
candidates = append(candidates, items...)
}
if len(candidates) == 0 {
return nil, apperr.New(http.StatusBadRequest, "variant_not_found", "course variants are empty")
}
switch mode {
case AssignmentModeRandom:
index, err := rand.Int(rand.Reader, big.NewInt(int64(len(candidates))))
if err != nil {
return nil, apperr.New(http.StatusInternalServerError, "variant_select_failed", fmt.Sprintf("failed to select random variant: %v", err))
}
selected := candidates[int(index.Int64())]
return &selected, nil
case AssignmentModeServerAssigned, AssignmentModeManual:
fallthrough
default:
selected := candidates[0]
return &selected, nil
}
}

View File

@@ -6,13 +6,16 @@ import (
)
type DemoBootstrapSummary struct {
TenantCode string `json:"tenantCode"`
ChannelCode string `json:"channelCode"`
EventID string `json:"eventId"`
ReleaseID string `json:"releaseId"`
SourceID string `json:"sourceId"`
BuildID string `json:"buildId"`
CardID string `json:"cardId"`
TenantCode string `json:"tenantCode"`
ChannelCode string `json:"channelCode"`
EventID string `json:"eventId"`
ReleaseID string `json:"releaseId"`
SourceID string `json:"sourceId"`
BuildID string `json:"buildId"`
CardID string `json:"cardId"`
VariantManualEventID string `json:"variantManualEventId"`
VariantManualRelease string `json:"variantManualReleaseId"`
VariantManualCardID string `json:"variantManualCardId"`
}
func (s *Store) EnsureDemoData(ctx context.Context) (*DemoBootstrapSummary, error) {
@@ -88,7 +91,7 @@ func (s *Store) EnsureDemoData(ctx context.Context) (*DemoBootstrapSummary, erro
$1,
1,
'Demo Config v1',
'https://oss-mbh5.colormaprun.com/gotomars/event/classic-sequential.json',
'https://oss-mbh5.colormaprun.com/gotomars/event/releases/evt_demo_001/rel_e7dd953743c5c0d2/manifest.json',
'demo-checksum-001',
'route-demo-001',
'published'
@@ -224,7 +227,7 @@ func (s *Store) EnsureDemoData(ctx context.Context) (*DemoBootstrapSummary, erro
EventReleaseID: releaseRow.ID,
AssetType: "manifest",
AssetKey: "manifest",
AssetURL: "https://oss-mbh5.colormaprun.com/gotomars/event/classic-sequential.json",
AssetURL: "https://oss-mbh5.colormaprun.com/gotomars/event/releases/evt_demo_001/rel_e7dd953743c5c0d2/manifest.json",
Checksum: &manifestChecksum,
Meta: map[string]any{"source": "release-manifest"},
},
@@ -308,17 +311,149 @@ func (s *Store) EnsureDemoData(ctx context.Context) (*DemoBootstrapSummary, erro
return nil, fmt.Errorf("ensure demo card: %w", err)
}
var manualEventID string
if err := tx.QueryRow(ctx, `
INSERT INTO events (
tenant_id, event_public_id, slug, display_name, summary, status
)
VALUES ($1, 'evt_demo_variant_manual_001', 'demo-variant-manual-run', 'Demo Variant Manual Run', 'Manual 多赛道联调活动', 'active')
ON CONFLICT (event_public_id) DO UPDATE SET
tenant_id = EXCLUDED.tenant_id,
slug = EXCLUDED.slug,
display_name = EXCLUDED.display_name,
summary = EXCLUDED.summary,
status = EXCLUDED.status
RETURNING id
`, tenantID).Scan(&manualEventID); err != nil {
return nil, fmt.Errorf("ensure variant manual demo event: %w", err)
}
var manualReleaseRow struct {
ID string
PublicID string
}
if err := tx.QueryRow(ctx, `
INSERT INTO event_releases (
release_public_id,
event_id,
release_no,
config_label,
manifest_url,
manifest_checksum_sha256,
route_code,
status,
payload_jsonb
)
VALUES (
'rel_demo_variant_manual_001',
$1,
1,
'Demo Variant Manual Config v1',
'https://oss-mbh5.colormaprun.com/gotomars/event/releases/evt_demo_001/rel_e7dd953743c5c0d2/manifest.json',
'demo-variant-checksum-001',
'route-variant-a',
'published',
$2::jsonb
)
ON CONFLICT (release_public_id) DO UPDATE SET
event_id = EXCLUDED.event_id,
config_label = EXCLUDED.config_label,
manifest_url = EXCLUDED.manifest_url,
manifest_checksum_sha256 = EXCLUDED.manifest_checksum_sha256,
route_code = EXCLUDED.route_code,
status = EXCLUDED.status,
payload_jsonb = EXCLUDED.payload_jsonb
RETURNING id, release_public_id
`, manualEventID, `{
"play": {
"assignmentMode": "manual",
"courseVariants": [
{
"id": "variant_a",
"name": "A 线",
"description": "短线体验版",
"routeCode": "route-variant-a",
"selectable": true
},
{
"id": "variant_b",
"name": "B 线",
"description": "长线挑战版",
"routeCode": "route-variant-b",
"selectable": true
}
]
}
}`).Scan(&manualReleaseRow.ID, &manualReleaseRow.PublicID); err != nil {
return nil, fmt.Errorf("ensure variant manual demo release: %w", err)
}
if _, err := tx.Exec(ctx, `
UPDATE events
SET current_release_id = $2
WHERE id = $1
`, manualEventID, manualReleaseRow.ID); err != nil {
return nil, fmt.Errorf("attach variant manual demo release: %w", err)
}
var manualCardPublicID string
if err := tx.QueryRow(ctx, `
INSERT INTO cards (
card_public_id,
tenant_id,
entry_channel_id,
card_type,
title,
subtitle,
cover_url,
event_id,
display_slot,
display_priority,
status
)
VALUES (
'card_demo_variant_manual_001',
$1,
$2,
'event',
'Demo Variant Manual Run',
'多赛道手动选择联调',
'https://oss-mbh5.colormaprun.com/gotomars/assets/demo-cover.jpg',
$3,
'home_primary',
95,
'active'
)
ON CONFLICT (card_public_id) DO UPDATE SET
tenant_id = EXCLUDED.tenant_id,
entry_channel_id = EXCLUDED.entry_channel_id,
card_type = EXCLUDED.card_type,
title = EXCLUDED.title,
subtitle = EXCLUDED.subtitle,
cover_url = EXCLUDED.cover_url,
event_id = EXCLUDED.event_id,
display_slot = EXCLUDED.display_slot,
display_priority = EXCLUDED.display_priority,
status = EXCLUDED.status
RETURNING card_public_id
`, tenantID, channelID, manualEventID).Scan(&manualCardPublicID); err != nil {
return nil, fmt.Errorf("ensure variant manual demo card: %w", err)
}
if err := tx.Commit(ctx); err != nil {
return nil, err
}
return &DemoBootstrapSummary{
TenantCode: "tenant_demo",
ChannelCode: "mini-demo",
EventID: "evt_demo_001",
ReleaseID: releaseRow.PublicID,
SourceID: source.ID,
BuildID: build.ID,
CardID: cardPublicID,
TenantCode: "tenant_demo",
ChannelCode: "mini-demo",
EventID: "evt_demo_001",
ReleaseID: releaseRow.PublicID,
SourceID: source.ID,
BuildID: build.ID,
CardID: cardPublicID,
VariantManualEventID: "evt_demo_variant_manual_001",
VariantManualRelease: manualReleaseRow.PublicID,
VariantManualCardID: manualCardPublicID,
}, nil
}

View File

@@ -22,6 +22,7 @@ type Event struct {
ManifestURL *string
ManifestChecksum *string
RouteCode *string
ReleasePayloadJSON *string
}
type EventRelease struct {
@@ -45,6 +46,9 @@ type CreateGameSessionParams struct {
EventReleaseID string
DeviceKey string
ClientType string
AssignmentMode *string
VariantID *string
VariantName *string
RouteCode *string
SessionTokenHash string
SessionTokenExpiresAt time.Time
@@ -58,6 +62,9 @@ type GameSession struct {
EventReleaseID string
DeviceKey string
ClientType string
AssignmentMode *string
VariantID *string
VariantName *string
RouteCode *string
Status string
SessionTokenExpiresAt time.Time
@@ -77,7 +84,8 @@ func (s *Store) GetEventByPublicID(ctx context.Context, eventPublicID string) (*
er.config_label,
er.manifest_url,
er.manifest_checksum_sha256,
er.route_code
er.route_code,
er.payload_jsonb::text
FROM events e
LEFT JOIN event_releases er ON er.id = e.current_release_id
WHERE e.event_public_id = $1
@@ -98,6 +106,7 @@ func (s *Store) GetEventByPublicID(ctx context.Context, eventPublicID string) (*
&event.ManifestURL,
&event.ManifestChecksum,
&event.RouteCode,
&event.ReleasePayloadJSON,
)
if errors.Is(err, pgx.ErrNoRows) {
return nil, nil
@@ -122,7 +131,8 @@ func (s *Store) GetEventByID(ctx context.Context, eventID string) (*Event, error
er.config_label,
er.manifest_url,
er.manifest_checksum_sha256,
er.route_code
er.route_code,
er.payload_jsonb::text
FROM events e
LEFT JOIN event_releases er ON er.id = e.current_release_id
WHERE e.id = $1
@@ -143,6 +153,7 @@ func (s *Store) GetEventByID(ctx context.Context, eventID string) (*Event, error
&event.ManifestURL,
&event.ManifestChecksum,
&event.RouteCode,
&event.ReleasePayloadJSON,
)
if errors.Is(err, pgx.ErrNoRows) {
return nil, nil
@@ -235,13 +246,16 @@ func (s *Store) CreateGameSession(ctx context.Context, tx Tx, params CreateGameS
event_release_id,
device_key,
client_type,
assignment_mode,
variant_id,
variant_name,
route_code,
session_token_hash,
session_token_expires_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING id, session_public_id, user_id, event_id, event_release_id, device_key, client_type, route_code, status, session_token_expires_at
`, params.SessionPublicID, params.UserID, params.EventID, params.EventReleaseID, params.DeviceKey, params.ClientType, params.RouteCode, params.SessionTokenHash, params.SessionTokenExpiresAt)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
RETURNING id, session_public_id, user_id, event_id, event_release_id, device_key, client_type, assignment_mode, variant_id, variant_name, route_code, status, session_token_expires_at
`, params.SessionPublicID, params.UserID, params.EventID, params.EventReleaseID, params.DeviceKey, params.ClientType, params.AssignmentMode, params.VariantID, params.VariantName, params.RouteCode, params.SessionTokenHash, params.SessionTokenExpiresAt)
var session GameSession
err := row.Scan(
@@ -252,6 +266,9 @@ func (s *Store) CreateGameSession(ctx context.Context, tx Tx, params CreateGameS
&session.EventReleaseID,
&session.DeviceKey,
&session.ClientType,
&session.AssignmentMode,
&session.VariantID,
&session.VariantName,
&session.RouteCode,
&session.Status,
&session.SessionTokenExpiresAt,

View File

@@ -101,6 +101,9 @@ func (s *Store) GetSessionResultByPublicID(ctx context.Context, sessionPublicID
er.manifest_checksum_sha256,
gs.device_key,
gs.client_type,
gs.assignment_mode,
gs.variant_id,
gs.variant_name,
gs.route_code,
gs.status,
gs.session_token_hash,
@@ -149,6 +152,9 @@ func (s *Store) ListSessionResultsByUserID(ctx context.Context, userID string, l
er.manifest_checksum_sha256,
gs.device_key,
gs.client_type,
gs.assignment_mode,
gs.variant_id,
gs.variant_name,
gs.route_code,
gs.status,
gs.session_token_hash,
@@ -244,6 +250,9 @@ func scanSessionResultRecord(row pgx.Row) (*SessionResultRecord, error) {
&record.ManifestChecksum,
&record.DeviceKey,
&record.ClientType,
&record.AssignmentMode,
&record.VariantID,
&record.VariantName,
&record.RouteCode,
&record.Status,
&record.SessionTokenHash,
@@ -317,6 +326,9 @@ func scanSessionResultRecordFromRows(rows pgx.Rows) (*SessionResultRecord, error
&record.ManifestChecksum,
&record.DeviceKey,
&record.ClientType,
&record.AssignmentMode,
&record.VariantID,
&record.VariantName,
&record.RouteCode,
&record.Status,
&record.SessionTokenHash,

View File

@@ -21,6 +21,9 @@ type Session struct {
ManifestChecksum *string
DeviceKey string
ClientType string
AssignmentMode *string
VariantID *string
VariantName *string
RouteCode *string
Status string
SessionTokenHash string
@@ -51,6 +54,9 @@ func (s *Store) GetSessionByPublicID(ctx context.Context, sessionPublicID string
er.manifest_checksum_sha256,
gs.device_key,
gs.client_type,
gs.assignment_mode,
gs.variant_id,
gs.variant_name,
gs.route_code,
gs.status,
gs.session_token_hash,
@@ -83,6 +89,9 @@ func (s *Store) GetSessionByPublicIDForUpdate(ctx context.Context, tx Tx, sessio
er.manifest_checksum_sha256,
gs.device_key,
gs.client_type,
gs.assignment_mode,
gs.variant_id,
gs.variant_name,
gs.route_code,
gs.status,
gs.session_token_hash,
@@ -119,6 +128,9 @@ func (s *Store) ListSessionsByUserID(ctx context.Context, userID string, limit i
er.manifest_checksum_sha256,
gs.device_key,
gs.client_type,
gs.assignment_mode,
gs.variant_id,
gs.variant_name,
gs.route_code,
gs.status,
gs.session_token_hash,
@@ -172,6 +184,9 @@ func (s *Store) ListSessionsByUserAndEvent(ctx context.Context, userID, eventID
er.manifest_checksum_sha256,
gs.device_key,
gs.client_type,
gs.assignment_mode,
gs.variant_id,
gs.variant_name,
gs.route_code,
gs.status,
gs.session_token_hash,
@@ -249,6 +264,9 @@ func scanSession(row pgx.Row) (*Session, error) {
&session.ManifestChecksum,
&session.DeviceKey,
&session.ClientType,
&session.AssignmentMode,
&session.VariantID,
&session.VariantName,
&session.RouteCode,
&session.Status,
&session.SessionTokenHash,
@@ -282,6 +300,9 @@ func scanSessionFromRows(rows pgx.Rows) (*Session, error) {
&session.ManifestChecksum,
&session.DeviceKey,
&session.ClientType,
&session.AssignmentMode,
&session.VariantID,
&session.VariantName,
&session.RouteCode,
&session.Status,
&session.SessionTokenHash,