feat(enakgame): weekly leaderboard
GET /customer/enakgame/leaderboard ranks the customers of an organization by the EnakCoin they won from games in one week, Monday to Sunday in Asia/Jakarta. Only completed, unflagged sessions count, by the week they started; entry cost is not subtracted. Equal totals rank by who reached theirs first, so no two customers share a rank. Optional date (any day of the week, this week by default), game_id and limit (10, at most 100). The response holds the top ranks and, under me, the customer asking wherever they rank. Other customers are shown by a masked name: the first word whole, the others by their first letter; a word with a digit keeps only its first character. The EnakGame web game shows it: integration-enakgame.md §10 (checklist now §11) and RFC §11. The DB test needs TEST_DATABASE_URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c43baa53e1
commit
3af16a1fbc
@@ -74,6 +74,7 @@ type EnakGameCustomerService interface {
|
||||
CompleteSession(ctx context.Context, customerID, sessionID uuid.UUID, in models.GameSessionCompleteInput) *contract.Response
|
||||
ListSessions(ctx context.Context, customerID uuid.UUID, q models.GameSessionListQuery) *contract.Response
|
||||
GetSession(ctx context.Context, customerID, sessionID uuid.UUID) *contract.Response
|
||||
Leaderboard(ctx context.Context, customerID uuid.UUID, q models.EnakGameLeaderboardQuery) *contract.Response
|
||||
|
||||
ListVouchers(ctx context.Context, customerID uuid.UUID) *contract.Response
|
||||
RedeemVoucher(ctx context.Context, customerID, voucherID uuid.UUID, req *contract.RedeemVoucherRequest, idempotencyKey string, info models.CustomerPinRequestInfo) *contract.Response
|
||||
@@ -381,6 +382,11 @@ func (s *EnakGameCustomerServiceImpl) GetSession(ctx context.Context, customerID
|
||||
return respond(ctx, session, err)
|
||||
}
|
||||
|
||||
func (s *EnakGameCustomerServiceImpl) Leaderboard(ctx context.Context, customerID uuid.UUID, q models.EnakGameLeaderboardQuery) *contract.Response {
|
||||
board, err := s.sessions.Leaderboard(ctx, customerID, q)
|
||||
return respond(ctx, board, err)
|
||||
}
|
||||
|
||||
// decodeStrict reads a JSON body into v, refusing unknown fields and trailing data.
|
||||
// It returns the error response, or nil when the body fits.
|
||||
func decodeStrict(body []byte, v any) *contract.Response {
|
||||
|
||||
Reference in New Issue
Block a user