feat(enakgame): filter play history by game and status

GET /customer/enakgame/sessions takes optional game_id and status, so a game
reloaded mid-play finds the session it was running (status=STARTED) instead
of starting a new one and charging EnakCoin again. An invalid game_id or
status is refused.

integration-enakgame.md §4.4 now describes recovery after a reload: keep the
session_id in sessionStorage, continue a STARTED session before expires_at,
and call complete again for a COMPLETED one to get the full answer, prize
included. The mobile guide and RFC §11 mention the filters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
efrilm
2026-10-08 12:51:39 +07:00
co-authored by Claude Opus 5.5
parent b5d2cd491a
commit 52e8fe11c6
10 changed files with 129 additions and 24 deletions
+20 -4
View File
@@ -419,10 +419,26 @@ func (p *GameSessionProcessor) ListGames(ctx context.Context, customerID uuid.UU
return out, nil
}
// ListSessions returns a page of the customer's sessions, newest first.
func (p *GameSessionProcessor) ListSessions(ctx context.Context, customerID uuid.UUID, page, limit int) (*models.PaginatedResponse[models.CustomerGameSession], error) {
page, limit = enakGamePage(page, limit)
sessions, total, err := p.sessions.ListCustomerSessions(ctx, customerID, (page-1)*limit, limit)
// ListSessions returns a page of the customer's sessions, newest first, of one game
// or status when asked.
func (p *GameSessionProcessor) ListSessions(ctx context.Context, customerID uuid.UUID, q models.GameSessionListQuery) (*models.PaginatedResponse[models.CustomerGameSession], error) {
page, limit := enakGamePage(q.Page, q.Limit)
filter := repository.CustomerSessionFilter{CustomerID: customerID, Offset: (page - 1) * limit, Limit: limit}
if s := strings.TrimSpace(q.GameID); s != "" {
id, err := uuid.Parse(s)
if err != nil {
return nil, gameSessionRejected("game_id must be a UUID")
}
filter.GameID = &id
}
switch status := strings.ToUpper(strings.TrimSpace(q.Status)); status {
case "", constants.GameSessionStatusStarted, constants.GameSessionStatusCompleted,
constants.GameSessionStatusRefunded, constants.GameSessionStatusExpired:
filter.Status = status
default:
return nil, gameSessionRejected("status must be STARTED, COMPLETED, REFUNDED or EXPIRED")
}
sessions, total, err := p.sessions.ListCustomerSessions(ctx, filter)
if err != nil {
return nil, err
}