feat: tribe change - add 2 new api endpoints (#27)
Reviewed-on: twhelp/corev3#27
This commit is contained in:
parent
4bae71da47
commit
f15b17dee0
110
api/openapi3.yml
110
api/openapi3.yml
|
@ -16,6 +16,7 @@ tags:
|
||||||
- name: players
|
- name: players
|
||||||
- name: villages
|
- name: villages
|
||||||
- name: ennoblements
|
- name: ennoblements
|
||||||
|
- name: tribe-changes
|
||||||
servers:
|
servers:
|
||||||
- url: "{scheme}://{hostname}/api"
|
- url: "{scheme}://{hostname}/api"
|
||||||
variables:
|
variables:
|
||||||
|
@ -92,7 +93,7 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- versions
|
- versions
|
||||||
- servers
|
- servers
|
||||||
description: Get server config
|
description: Get the given server's config
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -107,7 +108,7 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- versions
|
- versions
|
||||||
- servers
|
- servers
|
||||||
description: Get building info
|
description: Get the given server's building info
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -122,7 +123,7 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- versions
|
- versions
|
||||||
- servers
|
- servers
|
||||||
description: Get unit info
|
description: Get the given server's unit info
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -215,7 +216,7 @@ paths:
|
||||||
- servers
|
- servers
|
||||||
- tribes
|
- tribes
|
||||||
- players
|
- players
|
||||||
description: List tribe members
|
description: List the given tribe's members
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -272,7 +273,7 @@ paths:
|
||||||
- servers
|
- servers
|
||||||
- tribes
|
- tribes
|
||||||
- villages
|
- villages
|
||||||
description: List tribe villages
|
description: List the given tribe's villages
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -292,7 +293,7 @@ paths:
|
||||||
- servers
|
- servers
|
||||||
- players
|
- players
|
||||||
- villages
|
- villages
|
||||||
description: List player villages
|
description: List the given player's villages
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -333,7 +334,7 @@ paths:
|
||||||
- servers
|
- servers
|
||||||
- players
|
- players
|
||||||
- ennoblements
|
- ennoblements
|
||||||
description: List player ennoblements
|
description: List the given player's ennoblements
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -356,7 +357,7 @@ paths:
|
||||||
- servers
|
- servers
|
||||||
- tribes
|
- tribes
|
||||||
- ennoblements
|
- ennoblements
|
||||||
description: List tribe ennoblements
|
description: List the given tribe's ennoblements
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -379,7 +380,7 @@ paths:
|
||||||
- servers
|
- servers
|
||||||
- villages
|
- villages
|
||||||
- ennoblements
|
- ennoblements
|
||||||
description: List village ennoblements
|
description: List the given village's ennoblements
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/components/parameters/VersionCodePathParam"
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
- $ref: "#/components/parameters/ServerKeyPathParam"
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
@ -394,6 +395,52 @@ paths:
|
||||||
$ref: "#/components/responses/ListEnnoblementsResponse"
|
$ref: "#/components/responses/ListEnnoblementsResponse"
|
||||||
default:
|
default:
|
||||||
$ref: "#/components/responses/ErrorResponse"
|
$ref: "#/components/responses/ErrorResponse"
|
||||||
|
/v2/versions/{versionCode}/servers/{serverKey}/players/{playerId}/tribe-changes:
|
||||||
|
get:
|
||||||
|
operationId: listPlayerTribeChanges
|
||||||
|
tags:
|
||||||
|
- versions
|
||||||
|
- servers
|
||||||
|
- players
|
||||||
|
- tribe-changes
|
||||||
|
description: List the given player's tribe changes
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
- $ref: "#/components/parameters/PlayerIdPathParam"
|
||||||
|
- $ref: "#/components/parameters/CursorQueryParam"
|
||||||
|
- $ref: "#/components/parameters/LimitQueryParam"
|
||||||
|
- $ref: "#/components/parameters/TribeChangeSortQueryParam"
|
||||||
|
- $ref: "#/components/parameters/SinceQueryParam"
|
||||||
|
- $ref: "#/components/parameters/BeforeQueryParam"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
$ref: "#/components/responses/ListTribeChangesResponse"
|
||||||
|
default:
|
||||||
|
$ref: "#/components/responses/ErrorResponse"
|
||||||
|
/v2/versions/{versionCode}/servers/{serverKey}/tribes/{tribeId}/tribe-changes:
|
||||||
|
get:
|
||||||
|
operationId: listTribeTribeChanges
|
||||||
|
tags:
|
||||||
|
- versions
|
||||||
|
- servers
|
||||||
|
- tribes
|
||||||
|
- tribe-changes
|
||||||
|
description: List tribe membership changes
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/VersionCodePathParam"
|
||||||
|
- $ref: "#/components/parameters/ServerKeyPathParam"
|
||||||
|
- $ref: "#/components/parameters/TribeIdPathParam"
|
||||||
|
- $ref: "#/components/parameters/CursorQueryParam"
|
||||||
|
- $ref: "#/components/parameters/LimitQueryParam"
|
||||||
|
- $ref: "#/components/parameters/TribeChangeSortQueryParam"
|
||||||
|
- $ref: "#/components/parameters/SinceQueryParam"
|
||||||
|
- $ref: "#/components/parameters/BeforeQueryParam"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
$ref: "#/components/responses/ListTribeChangesResponse"
|
||||||
|
default:
|
||||||
|
$ref: "#/components/responses/ErrorResponse"
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
Error:
|
Error:
|
||||||
|
@ -1364,6 +1411,22 @@ components:
|
||||||
createdAt:
|
createdAt:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
|
TribeChange:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- player
|
||||||
|
- createdAt
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: "#/components/schemas/IntId"
|
||||||
|
player:
|
||||||
|
$ref: "#/components/schemas/PlayerMeta"
|
||||||
|
newTribe:
|
||||||
|
$ref: "#/components/schemas/TribeMeta"
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
Cursor:
|
Cursor:
|
||||||
type: object
|
type: object
|
||||||
x-go-type-skip-optional-pointer: true
|
x-go-type-skip-optional-pointer: true
|
||||||
|
@ -1512,6 +1575,20 @@ components:
|
||||||
- createdAt:ASC
|
- createdAt:ASC
|
||||||
- createdAt:DESC
|
- createdAt:DESC
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
TribeChangeSortQueryParam:
|
||||||
|
name: sort
|
||||||
|
in: query
|
||||||
|
description: Order matters!
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
default:
|
||||||
|
- createdAt:ASC
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- createdAt:ASC
|
||||||
|
- createdAt:DESC
|
||||||
|
maxItems: 1
|
||||||
SinceQueryParam:
|
SinceQueryParam:
|
||||||
name: since
|
name: since
|
||||||
in: query
|
in: query
|
||||||
|
@ -1735,6 +1812,21 @@ components:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/Ennoblement"
|
$ref: "#/components/schemas/Ennoblement"
|
||||||
|
ListTribeChangesResponse:
|
||||||
|
description: ""
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/PaginationResponse"
|
||||||
|
- type: object
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/TribeChange"
|
||||||
ErrorResponse:
|
ErrorResponse:
|
||||||
description: Default error response.
|
description: Default error response.
|
||||||
content:
|
content:
|
||||||
|
|
|
@ -111,12 +111,14 @@ var cmdServe = &cli.Command{
|
||||||
playerRepo := adapter.NewPlayerBunRepository(bunDB)
|
playerRepo := adapter.NewPlayerBunRepository(bunDB)
|
||||||
villageRepo := adapter.NewVillageBunRepository(bunDB)
|
villageRepo := adapter.NewVillageBunRepository(bunDB)
|
||||||
ennoblementRepo := adapter.NewEnnoblementBunRepository(bunDB)
|
ennoblementRepo := adapter.NewEnnoblementBunRepository(bunDB)
|
||||||
|
tribeChangeRepo := adapter.NewTribeChangeBunRepository(bunDB)
|
||||||
|
|
||||||
// services
|
// services
|
||||||
versionSvc := app.NewVersionService(versionRepo)
|
versionSvc := app.NewVersionService(versionRepo)
|
||||||
serverSvc := app.NewServerService(serverRepo, nil, nil)
|
serverSvc := app.NewServerService(serverRepo, nil, nil)
|
||||||
tribeSvc := app.NewTribeService(tribeRepo, nil, nil)
|
tribeSvc := app.NewTribeService(tribeRepo, nil, nil)
|
||||||
playerSvc := app.NewPlayerService(playerRepo, nil, nil, nil)
|
tribeChangeSvc := app.NewTribeChangeService(tribeChangeRepo)
|
||||||
|
playerSvc := app.NewPlayerService(playerRepo, tribeChangeSvc, nil, nil)
|
||||||
villageSvc := app.NewVillageService(villageRepo, nil, nil)
|
villageSvc := app.NewVillageService(villageRepo, nil, nil)
|
||||||
ennoblementSvc := app.NewEnnoblementService(ennoblementRepo, nil, nil)
|
ennoblementSvc := app.NewEnnoblementService(ennoblementRepo, nil, nil)
|
||||||
|
|
||||||
|
@ -148,6 +150,7 @@ var cmdServe = &cli.Command{
|
||||||
playerSvc,
|
playerSvc,
|
||||||
villageSvc,
|
villageSvc,
|
||||||
ennoblementSvc,
|
ennoblementSvc,
|
||||||
|
tribeChangeSvc,
|
||||||
port.WithOpenAPIConfig(oapiCfg),
|
port.WithOpenAPIConfig(oapiCfg),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -263,6 +264,23 @@ const (
|
||||||
TribeChangeSortServerKeyDESC
|
TribeChangeSortServerKeyDESC
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func newTribeChangeSortFromString(s string) (TribeChangeSort, error) {
|
||||||
|
allowed := []TribeChangeSort{
|
||||||
|
TribeChangeSortCreatedAtASC,
|
||||||
|
TribeChangeSortCreatedAtDESC,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range allowed {
|
||||||
|
if strings.EqualFold(a.String(), s) {
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, UnsupportedSortStringError{
|
||||||
|
Sort: s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IsInConflict returns true if two sorts can't be used together (e.g. TribeChangeSortIDASC and TribeChangeSortIDDESC).
|
// IsInConflict returns true if two sorts can't be used together (e.g. TribeChangeSortIDASC and TribeChangeSortIDDESC).
|
||||||
func (s TribeChangeSort) IsInConflict(s2 TribeChangeSort) bool {
|
func (s TribeChangeSort) IsInConflict(s2 TribeChangeSort) bool {
|
||||||
ss := []TribeChangeSort{s, s2}
|
ss := []TribeChangeSort{s, s2}
|
||||||
|
@ -558,6 +576,37 @@ func (params *ListTribeChangesParams) SetLimit(limit int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (params *ListTribeChangesParams) PrependSortString(sort []string) error {
|
||||||
|
if err := validateSliceLen(
|
||||||
|
sort,
|
||||||
|
tribeChangeSortMinLength,
|
||||||
|
max(tribeChangeSortMaxLength-len(params.sort), 0),
|
||||||
|
); err != nil {
|
||||||
|
return ValidationError{
|
||||||
|
Model: listTribeChangesParamsModelName,
|
||||||
|
Field: "sort",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toPrepend := make([]TribeChangeSort, 0, len(sort))
|
||||||
|
|
||||||
|
for i, s := range sort {
|
||||||
|
converted, err := newTribeChangeSortFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
return SliceElementValidationError{
|
||||||
|
Model: listTribeChangesParamsModelName,
|
||||||
|
Field: "sort",
|
||||||
|
Index: i,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toPrepend = append(toPrepend, converted)
|
||||||
|
}
|
||||||
|
|
||||||
|
return params.SetSort(append(toPrepend, params.sort...))
|
||||||
|
}
|
||||||
|
|
||||||
type ListTribeChangesResult struct {
|
type ListTribeChangesResult struct {
|
||||||
tribeChanges TribeChanges
|
tribeChanges TribeChanges
|
||||||
self TribeChangeCursor
|
self TribeChangeCursor
|
||||||
|
|
|
@ -625,6 +625,143 @@ func TestListTribeChangesParams_SetSort(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListTribeChangesParams_PrependSortString(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
defaultNewParams := func(t *testing.T) domain.ListTribeChangesParams {
|
||||||
|
t.Helper()
|
||||||
|
return domain.ListTribeChangesParams{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
sort []string
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
newParams func(t *testing.T) domain.ListTribeChangesParams
|
||||||
|
args args
|
||||||
|
expectedSort []domain.TribeChangeSort
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "OK: [createdAt:ASC]",
|
||||||
|
args: args{
|
||||||
|
sort: []string{
|
||||||
|
"createdAt:ASC",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedSort: []domain.TribeChangeSort{
|
||||||
|
domain.TribeChangeSortCreatedAtASC,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OK: [createdAt:DESC]",
|
||||||
|
args: args{
|
||||||
|
sort: []string{
|
||||||
|
"createdAt:DESC",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedSort: []domain.TribeChangeSort{
|
||||||
|
domain.TribeChangeSortCreatedAtDESC,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ERR: len(sort) < 1",
|
||||||
|
args: args{
|
||||||
|
sort: nil,
|
||||||
|
},
|
||||||
|
expectedErr: domain.ValidationError{
|
||||||
|
Model: "ListTribeChangesParams",
|
||||||
|
Field: "sort",
|
||||||
|
Err: domain.LenOutOfRangeError{
|
||||||
|
Min: 1,
|
||||||
|
Max: 3,
|
||||||
|
Current: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ERR: custom params + len(sort) > 1",
|
||||||
|
newParams: func(t *testing.T) domain.ListTribeChangesParams {
|
||||||
|
t.Helper()
|
||||||
|
params := domain.NewListTribeChangesParams()
|
||||||
|
require.NoError(t, params.SetSort([]domain.TribeChangeSort{
|
||||||
|
domain.TribeChangeSortServerKeyASC,
|
||||||
|
domain.TribeChangeSortIDASC,
|
||||||
|
}))
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
sort: []string{
|
||||||
|
"createdAt:ASC",
|
||||||
|
"createdAt:DESC",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedErr: domain.ValidationError{
|
||||||
|
Model: "ListTribeChangesParams",
|
||||||
|
Field: "sort",
|
||||||
|
Err: domain.LenOutOfRangeError{
|
||||||
|
Min: 1,
|
||||||
|
Max: 1,
|
||||||
|
Current: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ERR: unsupported sort string",
|
||||||
|
newParams: defaultNewParams,
|
||||||
|
args: args{
|
||||||
|
sort: []string{
|
||||||
|
"createdAt:",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedErr: domain.SliceElementValidationError{
|
||||||
|
Model: "ListTribeChangesParams",
|
||||||
|
Field: "sort",
|
||||||
|
Index: 0,
|
||||||
|
Err: domain.UnsupportedSortStringError{
|
||||||
|
Sort: "createdAt:",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ERR: conflict",
|
||||||
|
args: args{
|
||||||
|
sort: []string{
|
||||||
|
"createdAt:ASC",
|
||||||
|
"createdAt:DESC",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedErr: domain.ValidationError{
|
||||||
|
Model: "ListTribeChangesParams",
|
||||||
|
Field: "sort",
|
||||||
|
Err: domain.SortConflictError{
|
||||||
|
Sort: [2]string{domain.TribeChangeSortCreatedAtASC.String(), domain.TribeChangeSortCreatedAtDESC.String()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
newParams := defaultNewParams
|
||||||
|
if tt.newParams != nil {
|
||||||
|
newParams = tt.newParams
|
||||||
|
}
|
||||||
|
params := newParams(t)
|
||||||
|
|
||||||
|
require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr)
|
||||||
|
if tt.expectedErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.Equal(t, tt.expectedSort, params.Sort())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestListTribeChangesParams_SetEncodedCursor(t *testing.T) {
|
func TestListTribeChangesParams_SetEncodedCursor(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ type apiHTTPHandler struct {
|
||||||
playerSvc *app.PlayerService
|
playerSvc *app.PlayerService
|
||||||
villageSvc *app.VillageService
|
villageSvc *app.VillageService
|
||||||
ennoblementSvc *app.EnnoblementService
|
ennoblementSvc *app.EnnoblementService
|
||||||
|
tribeChangeSvc *app.TribeChangeService
|
||||||
errorRenderer apiErrorRenderer
|
errorRenderer apiErrorRenderer
|
||||||
openAPISchema func() (*openapi3.T, error)
|
openAPISchema func() (*openapi3.T, error)
|
||||||
}
|
}
|
||||||
|
@ -36,6 +37,7 @@ func NewAPIHTTPHandler(
|
||||||
playerSvc *app.PlayerService,
|
playerSvc *app.PlayerService,
|
||||||
villageSvc *app.VillageService,
|
villageSvc *app.VillageService,
|
||||||
ennoblementSvc *app.EnnoblementService,
|
ennoblementSvc *app.EnnoblementService,
|
||||||
|
tribeChangeSvc *app.TribeChangeService,
|
||||||
opts ...APIHTTPHandlerOption,
|
opts ...APIHTTPHandlerOption,
|
||||||
) http.Handler {
|
) http.Handler {
|
||||||
cfg := newAPIHTTPHandlerConfig(opts...)
|
cfg := newAPIHTTPHandlerConfig(opts...)
|
||||||
|
@ -47,6 +49,7 @@ func NewAPIHTTPHandler(
|
||||||
playerSvc: playerSvc,
|
playerSvc: playerSvc,
|
||||||
villageSvc: villageSvc,
|
villageSvc: villageSvc,
|
||||||
ennoblementSvc: ennoblementSvc,
|
ennoblementSvc: ennoblementSvc,
|
||||||
|
tribeChangeSvc: tribeChangeSvc,
|
||||||
openAPISchema: sync.OnceValues(func() (*openapi3.T, error) {
|
openAPISchema: sync.OnceValues(func() (*openapi3.T, error) {
|
||||||
return getOpenAPISchema(cfg.openAPI)
|
return getOpenAPISchema(cfg.openAPI)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -173,7 +173,7 @@ func TestListEnnoblements(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OK: after",
|
name: "OK: before",
|
||||||
reqModifier: func(t *testing.T, req *http.Request) {
|
reqModifier: func(t *testing.T, req *http.Request) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
@ -820,7 +820,7 @@ func TestListPlayerEnnoblements(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OK: after",
|
name: "OK: before",
|
||||||
reqModifier: func(t *testing.T, req *http.Request) {
|
reqModifier: func(t *testing.T, req *http.Request) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
@ -1520,7 +1520,7 @@ func TestListTribeEnnoblements(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OK: after",
|
name: "OK: before",
|
||||||
reqModifier: func(t *testing.T, req *http.Request) {
|
reqModifier: func(t *testing.T, req *http.Request) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
@ -2212,7 +2212,7 @@ func TestListVillageEnnoblements(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OK: after",
|
name: "OK: before",
|
||||||
reqModifier: func(t *testing.T, req *http.Request) {
|
reqModifier: func(t *testing.T, req *http.Request) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ func newAPIHTTPHandler(tb testing.TB, opts ...func(cfg *apiHTTPHandlerConfig)) h
|
||||||
playerRepo := adapter.NewPlayerBunRepository(bunDB)
|
playerRepo := adapter.NewPlayerBunRepository(bunDB)
|
||||||
villageRepo := adapter.NewVillageBunRepository(bunDB)
|
villageRepo := adapter.NewVillageBunRepository(bunDB)
|
||||||
ennoblementRepo := adapter.NewEnnoblementBunRepository(bunDB)
|
ennoblementRepo := adapter.NewEnnoblementBunRepository(bunDB)
|
||||||
|
tribeChangeRepo := adapter.NewTribeChangeBunRepository(bunDB)
|
||||||
|
|
||||||
return port.NewAPIHTTPHandler(
|
return port.NewAPIHTTPHandler(
|
||||||
app.NewVersionService(versionRepo),
|
app.NewVersionService(versionRepo),
|
||||||
|
@ -47,6 +48,7 @@ func newAPIHTTPHandler(tb testing.TB, opts ...func(cfg *apiHTTPHandlerConfig)) h
|
||||||
app.NewPlayerService(playerRepo, nil, nil, nil),
|
app.NewPlayerService(playerRepo, nil, nil, nil),
|
||||||
app.NewVillageService(villageRepo, nil, nil),
|
app.NewVillageService(villageRepo, nil, nil),
|
||||||
app.NewEnnoblementService(ennoblementRepo, nil, nil),
|
app.NewEnnoblementService(ennoblementRepo, nil, nil),
|
||||||
|
app.NewTribeChangeService(tribeChangeRepo),
|
||||||
cfg.options...,
|
cfg.options...,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
192
internal/port/handler_http_api_tribe_change.go
Normal file
192
internal/port/handler_http_api_tribe_change.go
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
package port
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||||
|
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:gocyclo
|
||||||
|
func (h *apiHTTPHandler) ListPlayerTribeChanges(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
_ apimodel.VersionCodePathParam,
|
||||||
|
serverKey apimodel.ServerKeyPathParam,
|
||||||
|
playerID apimodel.PlayerIdPathParam,
|
||||||
|
params apimodel.ListPlayerTribeChangesParams,
|
||||||
|
) {
|
||||||
|
domainParams := domain.NewListTribeChangesParams()
|
||||||
|
|
||||||
|
if err := domainParams.SetSort([]domain.TribeChangeSort{domain.TribeChangeSortIDASC}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := domainParams.SetPlayerIDs([]int{playerID}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Sort != nil {
|
||||||
|
if err := domainParams.PrependSortString(*params.Sort); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := domainParams.PrependSortString([]string{domain.TribeChangeSortCreatedAtASC.String()}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Before != nil {
|
||||||
|
if err := domainParams.SetBefore(domain.NullTime{
|
||||||
|
V: *params.Before,
|
||||||
|
Valid: true,
|
||||||
|
}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Since != nil {
|
||||||
|
if err := domainParams.SetSince(domain.NullTime{
|
||||||
|
V: *params.Since,
|
||||||
|
Valid: true,
|
||||||
|
}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Limit != nil {
|
||||||
|
if err := domainParams.SetLimit(*params.Limit); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Cursor != nil {
|
||||||
|
if err := domainParams.SetEncodedCursor(*params.Cursor); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.tribeChangeSvc.ListWithRelations(r.Context(), domainParams)
|
||||||
|
if err != nil {
|
||||||
|
h.errorRenderer.render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
renderJSON(w, r, http.StatusOK, apimodel.NewListTribeChangesResponse(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:gocyclo
|
||||||
|
func (h *apiHTTPHandler) ListTribeTribeChanges(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
_ apimodel.VersionCodePathParam,
|
||||||
|
serverKey apimodel.ServerKeyPathParam,
|
||||||
|
tribeID apimodel.TribeIdPathParam,
|
||||||
|
params apimodel.ListTribeTribeChangesParams,
|
||||||
|
) {
|
||||||
|
domainParams := domain.NewListTribeChangesParams()
|
||||||
|
|
||||||
|
if err := domainParams.SetSort([]domain.TribeChangeSort{domain.TribeChangeSortIDASC}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := domainParams.SetTribeIDs([]int{tribeID}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Sort != nil {
|
||||||
|
if err := domainParams.PrependSortString(*params.Sort); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := domainParams.PrependSortString([]string{domain.TribeChangeSortCreatedAtASC.String()}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Before != nil {
|
||||||
|
if err := domainParams.SetBefore(domain.NullTime{
|
||||||
|
V: *params.Before,
|
||||||
|
Valid: true,
|
||||||
|
}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Since != nil {
|
||||||
|
if err := domainParams.SetSince(domain.NullTime{
|
||||||
|
V: *params.Since,
|
||||||
|
Valid: true,
|
||||||
|
}); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Limit != nil {
|
||||||
|
if err := domainParams.SetLimit(*params.Limit); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Cursor != nil {
|
||||||
|
if err := domainParams.SetEncodedCursor(*params.Cursor); err != nil {
|
||||||
|
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.tribeChangeSvc.ListWithRelations(r.Context(), domainParams)
|
||||||
|
if err != nil {
|
||||||
|
h.errorRenderer.render(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
renderJSON(w, r, http.StatusOK, apimodel.NewListTribeChangesResponse(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatListTribeChangesErrorPath(segments []domain.ErrorPathSegment) []string {
|
||||||
|
if segments[0].Model != "ListTribeChangesParams" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch segments[0].Field {
|
||||||
|
case "cursor":
|
||||||
|
return []string{"$query", "cursor"}
|
||||||
|
case "limit":
|
||||||
|
return []string{"$query", "limit"}
|
||||||
|
case "sort":
|
||||||
|
path := []string{"$query", "sort"}
|
||||||
|
if segments[0].Index >= 0 {
|
||||||
|
path = append(path, strconv.Itoa(segments[0].Index))
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
1488
internal/port/handler_http_api_tribe_change_test.go
Normal file
1488
internal/port/handler_http_api_tribe_change_test.go
Normal file
File diff suppressed because it is too large
Load Diff
33
internal/port/internal/apimodel/tribe_change.go
Normal file
33
internal/port/internal/apimodel/tribe_change.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package apimodel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTribeChange(withRelations domain.TribeChangeWithRelations) TribeChange {
|
||||||
|
tc := withRelations.TribeChange()
|
||||||
|
return TribeChange{
|
||||||
|
CreatedAt: tc.CreatedAt(),
|
||||||
|
Id: tc.ID(),
|
||||||
|
NewTribe: NewNullTribeMeta(withRelations.NewTribe()),
|
||||||
|
Player: NewPlayerMeta(withRelations.Player().WithRelations(withRelations.OldTribe())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewListTribeChangesResponse(res domain.ListTribeChangesWithRelationsResult) ListTribeChangesResponse {
|
||||||
|
tcs := res.TribeChanges()
|
||||||
|
|
||||||
|
resp := ListTribeChangesResponse{
|
||||||
|
Data: make([]TribeChange, 0, len(tcs)),
|
||||||
|
Cursor: Cursor{
|
||||||
|
Next: res.Next().Encode(),
|
||||||
|
Self: res.Self().Encode(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tcs {
|
||||||
|
resp.Data = append(resp.Data, NewTribeChange(tc))
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user