Stage 7 (wip): wire remaining ops (backend REST, FBS, gateway transcode) + real UI transport
backend: REST handlers for pass/exchange/resign/hint/evaluate/check_word/complaint/history/chat-list/nudge + new game.ListForAccount (my games) + seat display_name resolution pkg/fbs: GameActionRequest/ExchangeRequest/EvalRequest/EvalResult/CheckWordRequest/WordCheckResult/ComplaintRequest/HintResult/History/GameList/ChatList + SeatView.display_name; committed Go regenerated (flatc 23.5.26) gateway: 11 new transcode ops + backendclient methods + FB encoders ui: edge TS codegen (flatc --ts + protoc-gen-es, committed), FlatBuffers<->model codec, real connect-web transport (binary, bearer auth, Subscribe). prod bundle ~69KB gzip JS
This commit is contained in:
@@ -135,6 +135,50 @@ func (s *Store) GetGame(ctx context.Context, id uuid.UUID) (Game, error) {
|
||||
return projectGame(grow, srows)
|
||||
}
|
||||
|
||||
// ListGamesForAccount loads every game the account is seated in (active and
|
||||
// finished), newest first, each joined with its ordered seats. It backs the lobby's
|
||||
// "my games" lists.
|
||||
func (s *Store) ListGamesForAccount(ctx context.Context, accountID uuid.UUID) ([]Game, error) {
|
||||
gstmt := postgres.SELECT(table.Games.AllColumns).
|
||||
FROM(table.Games.INNER_JOIN(table.GamePlayers, table.GamePlayers.GameID.EQ(table.Games.GameID))).
|
||||
WHERE(table.GamePlayers.AccountID.EQ(postgres.UUID(accountID))).
|
||||
ORDER_BY(table.Games.UpdatedAt.DESC())
|
||||
var grows []model.Games
|
||||
if err := gstmt.QueryContext(ctx, s.db, &grows); err != nil {
|
||||
return nil, fmt.Errorf("game: list for account: %w", err)
|
||||
}
|
||||
if len(grows) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ids := make([]postgres.Expression, len(grows))
|
||||
for i, g := range grows {
|
||||
ids[i] = postgres.UUID(g.GameID)
|
||||
}
|
||||
sstmt := postgres.SELECT(table.GamePlayers.AllColumns).
|
||||
FROM(table.GamePlayers).
|
||||
WHERE(table.GamePlayers.GameID.IN(ids...)).
|
||||
ORDER_BY(table.GamePlayers.GameID.ASC(), table.GamePlayers.Seat.ASC())
|
||||
var srows []model.GamePlayers
|
||||
if err := sstmt.QueryContext(ctx, s.db, &srows); err != nil {
|
||||
return nil, fmt.Errorf("game: list seats for account: %w", err)
|
||||
}
|
||||
byGame := make(map[uuid.UUID][]model.GamePlayers, len(grows))
|
||||
for _, r := range srows {
|
||||
byGame[r.GameID] = append(byGame[r.GameID], r)
|
||||
}
|
||||
|
||||
out := make([]Game, 0, len(grows))
|
||||
for _, g := range grows {
|
||||
pg, err := projectGame(g, byGame[g.GameID])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, pg)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetJournal loads the ordered, decoded move journal for a game.
|
||||
func (s *Store) GetJournal(ctx context.Context, id uuid.UUID) ([]HistoryMove, error) {
|
||||
stmt := postgres.SELECT(table.GameMoves.AllColumns).
|
||||
|
||||
Reference in New Issue
Block a user