feat: user service
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
package internalhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"galaxy/user/internal/service/adminusers"
|
||||
"galaxy/user/internal/service/shared"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type getUserByEmailRequest struct {
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type getUserByRaceNameRequest struct {
|
||||
RaceName string `json:"race_name"`
|
||||
}
|
||||
|
||||
func handleGetUserByID(useCase GetUserByIDUseCase, timeout time.Duration) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
callCtx, cancel := context.WithTimeout(c.Request.Context(), timeout)
|
||||
defer cancel()
|
||||
|
||||
result, err := useCase.Execute(callCtx, adminusers.GetUserByIDInput{
|
||||
UserID: c.Param("user_id"),
|
||||
})
|
||||
if err != nil {
|
||||
abortWithProjection(c, shared.ProjectInternalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
}
|
||||
|
||||
func handleGetUserByEmail(useCase GetUserByEmailUseCase, timeout time.Duration) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var request getUserByEmailRequest
|
||||
if err := decodeJSONRequest(c.Request, &request); err != nil {
|
||||
abortWithProjection(c, shared.ProjectInternalError(shared.InvalidRequest(err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
callCtx, cancel := context.WithTimeout(c.Request.Context(), timeout)
|
||||
defer cancel()
|
||||
|
||||
result, err := useCase.Execute(callCtx, adminusers.GetUserByEmailInput{
|
||||
Email: request.Email,
|
||||
})
|
||||
if err != nil {
|
||||
abortWithProjection(c, shared.ProjectInternalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
}
|
||||
|
||||
func handleGetUserByRaceName(useCase GetUserByRaceNameUseCase, timeout time.Duration) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var request getUserByRaceNameRequest
|
||||
if err := decodeJSONRequest(c.Request, &request); err != nil {
|
||||
abortWithProjection(c, shared.ProjectInternalError(shared.InvalidRequest(err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
callCtx, cancel := context.WithTimeout(c.Request.Context(), timeout)
|
||||
defer cancel()
|
||||
|
||||
result, err := useCase.Execute(callCtx, adminusers.GetUserByRaceNameInput{
|
||||
RaceName: request.RaceName,
|
||||
})
|
||||
if err != nil {
|
||||
abortWithProjection(c, shared.ProjectInternalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
}
|
||||
|
||||
func handleListUsers(useCase ListUsersUseCase, timeout time.Duration) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
input, err := buildListUsersInput(c)
|
||||
if err != nil {
|
||||
abortWithProjection(c, shared.ProjectInternalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
callCtx, cancel := context.WithTimeout(c.Request.Context(), timeout)
|
||||
defer cancel()
|
||||
|
||||
result, err := useCase.Execute(callCtx, input)
|
||||
if err != nil {
|
||||
abortWithProjection(c, shared.ProjectInternalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
}
|
||||
|
||||
func buildListUsersInput(c *gin.Context) (adminusers.ListUsersInput, error) {
|
||||
pageSize, err := parseOptionalPageSize(c, "page_size")
|
||||
if err != nil {
|
||||
return adminusers.ListUsersInput{}, err
|
||||
}
|
||||
pageToken, err := parseOptionalPageToken(c, "page_token")
|
||||
if err != nil {
|
||||
return adminusers.ListUsersInput{}, err
|
||||
}
|
||||
paidExpiresBefore, err := parseOptionalRFC3339Query(c, "paid_expires_before")
|
||||
if err != nil {
|
||||
return adminusers.ListUsersInput{}, err
|
||||
}
|
||||
paidExpiresAfter, err := parseOptionalRFC3339Query(c, "paid_expires_after")
|
||||
if err != nil {
|
||||
return adminusers.ListUsersInput{}, err
|
||||
}
|
||||
canLogin, err := parseOptionalBoolQuery(c, "can_login")
|
||||
if err != nil {
|
||||
return adminusers.ListUsersInput{}, err
|
||||
}
|
||||
canCreatePrivateGame, err := parseOptionalBoolQuery(c, "can_create_private_game")
|
||||
if err != nil {
|
||||
return adminusers.ListUsersInput{}, err
|
||||
}
|
||||
canJoinGame, err := parseOptionalBoolQuery(c, "can_join_game")
|
||||
if err != nil {
|
||||
return adminusers.ListUsersInput{}, err
|
||||
}
|
||||
|
||||
return adminusers.ListUsersInput{
|
||||
PageSize: pageSize,
|
||||
PageToken: pageToken,
|
||||
PaidState: c.Query("paid_state"),
|
||||
PaidExpiresBefore: paidExpiresBefore,
|
||||
PaidExpiresAfter: paidExpiresAfter,
|
||||
DeclaredCountry: c.Query("declared_country"),
|
||||
SanctionCode: c.Query("sanction_code"),
|
||||
LimitCode: c.Query("limit_code"),
|
||||
CanLogin: canLogin,
|
||||
CanCreatePrivateGame: canCreatePrivateGame,
|
||||
CanJoinGame: canJoinGame,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseOptionalPageSize(c *gin.Context, name string) (int, error) {
|
||||
raw, present := c.GetQuery(name)
|
||||
if !present {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
value, err := strconv.Atoi(strings.TrimSpace(raw))
|
||||
if err != nil || value < 1 || value > 200 {
|
||||
return 0, shared.InvalidRequest("page_size must be between 1 and 200")
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func parseOptionalPageToken(c *gin.Context, name string) (string, error) {
|
||||
raw, present := c.GetQuery(name)
|
||||
if !present {
|
||||
return "", nil
|
||||
}
|
||||
if strings.TrimSpace(raw) != raw {
|
||||
return "", shared.InvalidRequest("page_token must not contain surrounding whitespace")
|
||||
}
|
||||
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
func parseOptionalRFC3339Query(c *gin.Context, name string) (*time.Time, error) {
|
||||
raw, present := c.GetQuery(name)
|
||||
if !present {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
parsed, err := time.Parse(time.RFC3339, strings.TrimSpace(raw))
|
||||
if err != nil {
|
||||
return nil, shared.InvalidRequest(name + " must be a valid RFC 3339 timestamp")
|
||||
}
|
||||
|
||||
return &parsed, nil
|
||||
}
|
||||
|
||||
func parseOptionalBoolQuery(c *gin.Context, name string) (*bool, error) {
|
||||
raw, present := c.GetQuery(name)
|
||||
if !present {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
parsed, err := strconv.ParseBool(strings.TrimSpace(raw))
|
||||
if err != nil {
|
||||
return nil, shared.InvalidRequest(name + " must be a valid boolean")
|
||||
}
|
||||
|
||||
return &parsed, nil
|
||||
}
|
||||
Reference in New Issue
Block a user