diff --git a/cmd/freezer-refrigerant/api/docs.go b/cmd/freezer-refrigerant/api/docs.go index 7de8b1c..9d32cfb 100644 --- a/cmd/freezer-refrigerant/api/docs.go +++ b/cmd/freezer-refrigerant/api/docs.go @@ -154,6 +154,82 @@ const docTemplate = `{ } } }, + "/reviewDistributions": { + "post": { + "description": "Reviews Coin Distributions.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CoinDistribution" + ], + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "the type of the client calling this API. I.E. ` + "`" + `web` + "`" + `", + "name": "x_client_type", + "in": "query" + }, + { + "enum": [ + "approve", + "deny" + ], + "type": "string", + "description": "the decision for the current coin distributions", + "name": "decision", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "if not authorized", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "403": { + "description": "if not allowed", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "422": { + "description": "if syntax fails", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "504": { + "description": "if request times out", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + } + } + } + }, "/tokenomics/{userId}/extra-bonus-claims": { "post": { "description": "Claims an extra bonus for the user.", diff --git a/cmd/freezer-refrigerant/api/swagger.json b/cmd/freezer-refrigerant/api/swagger.json index a98befe..f5afe96 100644 --- a/cmd/freezer-refrigerant/api/swagger.json +++ b/cmd/freezer-refrigerant/api/swagger.json @@ -148,6 +148,82 @@ } } }, + "/reviewDistributions": { + "post": { + "description": "Reviews Coin Distributions.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CoinDistribution" + ], + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "the type of the client calling this API. I.E. `web`", + "name": "x_client_type", + "in": "query" + }, + { + "enum": [ + "approve", + "deny" + ], + "type": "string", + "description": "the decision for the current coin distributions", + "name": "decision", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "if not authorized", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "403": { + "description": "if not allowed", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "422": { + "description": "if syntax fails", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + }, + "504": { + "description": "if request times out", + "schema": { + "$ref": "#/definitions/server.ErrorResponse" + } + } + } + } + }, "/tokenomics/{userId}/extra-bonus-claims": { "post": { "description": "Claims an extra bonus for the user.", diff --git a/cmd/freezer-refrigerant/api/swagger.yaml b/cmd/freezer-refrigerant/api/swagger.yaml index 87649cf..64eb3d8 100644 --- a/cmd/freezer-refrigerant/api/swagger.yaml +++ b/cmd/freezer-refrigerant/api/swagger.yaml @@ -308,6 +308,57 @@ paths: $ref: '#/definitions/server.ErrorResponse' tags: - CoinDistribution + /reviewDistributions: + post: + consumes: + - application/json + description: Reviews Coin Distributions. + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + required: true + type: string + - description: the type of the client calling this API. I.E. `web` + in: query + name: x_client_type + type: string + - description: the decision for the current coin distributions + enum: + - approve + - deny + in: query + name: decision + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + "401": + description: if not authorized + schema: + $ref: '#/definitions/server.ErrorResponse' + "403": + description: if not allowed + schema: + $ref: '#/definitions/server.ErrorResponse' + "422": + description: if syntax fails + schema: + $ref: '#/definitions/server.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/server.ErrorResponse' + "504": + description: if request times out + schema: + $ref: '#/definitions/server.ErrorResponse' + tags: + - CoinDistribution /tokenomics/{userId}/extra-bonus-claims: post: consumes: diff --git a/cmd/freezer-refrigerant/coin_distribution.go b/cmd/freezer-refrigerant/coin_distribution.go index c2c49c1..3c92e16 100644 --- a/cmd/freezer-refrigerant/coin_distribution.go +++ b/cmd/freezer-refrigerant/coin_distribution.go @@ -15,7 +15,8 @@ import ( func (s *service) setupCoinDistributionRoutes(router *server.Router) { router. Group("/v1w"). - POST("/getCoinDistributionsForReview", server.RootHandler(s.GetCoinDistributionsForReview)) + POST("/getCoinDistributionsForReview", server.RootHandler(s.GetCoinDistributionsForReview)). + POST("/reviewDistributions", server.RootHandler(s.ReviewCoinDistributions)) } // GetCoinDistributionsForReview godoc @@ -71,3 +72,39 @@ func (s *service) GetCoinDistributionsForReview( //nolint:gocritic // . return server.OK(resp), nil } + +// ReviewCoinDistributions godoc +// +// @Schemes +// @Description Reviews Coin Distributions. +// @Tags CoinDistribution +// @Accept json +// @Produce json +// @Param Authorization header string true "Insert your access token" default(Bearer ) +// @Param x_client_type query string false "the type of the client calling this API. I.E. `web`" +// @Param decision query string true "the decision for the current coin distributions" Enums(approve,deny) +// @Success 200 "OK" +// @Failure 401 {object} server.ErrorResponse "if not authorized" +// @Failure 403 {object} server.ErrorResponse "if not allowed" +// @Failure 422 {object} server.ErrorResponse "if syntax fails" +// @Failure 500 {object} server.ErrorResponse +// @Failure 504 {object} server.ErrorResponse "if request times out" +// @Router /reviewDistributions [POST]. +func (s *service) ReviewCoinDistributions( //nolint:gocritic // . + ctx context.Context, + req *server.Request[struct { + Decision string `form:"decision" required:"true" swaggerignore:"true" enums:"approve,deny"` + }, any], +) (*server.Response[any], *server.Response[server.ErrorResponse]) { + if req.AuthenticatedUser.Role != adminRole { + return nil, server.Forbidden(errors.Errorf("insufficient role: %v, admin role required", req.AuthenticatedUser.Role)) + } + if !strings.EqualFold(req.Data.Decision, "approve") && !strings.EqualFold(req.Data.Decision, "deny") { + return nil, server.UnprocessableEntity(errors.Errorf("`decision` has to be `approve` or `deny`"), "invalid params") + } + if err := s.coinDistributionRepository.ReviewCoinDistributions(ctx, req.AuthenticatedUser.UserID, req.Data.Decision); err != nil { + return nil, server.Unexpected(errors.Wrapf(err, "failed to ReviewCoinDistributions for adminUserID:%v,decision:%v", req.AuthenticatedUser.UserID, req.Data.Decision)) //nolint:lll // . + } + + return server.OK[any](), nil +} diff --git a/coin-distribution/contract.go b/coin-distribution/contract.go index d553533..b0f073f 100644 --- a/coin-distribution/contract.go +++ b/coin-distribution/contract.go @@ -25,6 +25,7 @@ type ( io.Closer GetCoinDistributionsForReview(ctx context.Context, arg *GetCoinDistributionsForReviewArg) (*CoinDistributionsForReview, error) CheckHealth(ctx context.Context) error + ReviewCoinDistributions(ctx context.Context, reviewerUserID string, decision string) error } CoinDistributionsForReview struct { diff --git a/coin-distribution/pending_review.go b/coin-distribution/pending_review.go index 4907f01..1b7395c 100644 --- a/coin-distribution/pending_review.go +++ b/coin-distribution/pending_review.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "github.com/ice-blockchain/wintr/connectors/storage/v2" + "github.com/ice-blockchain/wintr/log" ) //nolint:funlen // . @@ -135,3 +136,9 @@ func (a *GetCoinDistributionsForReviewArg) totalsWhere() ([]string, []any) { return conditions, args } + +func (r *repository) ReviewCoinDistributions(ctx context.Context, reviewerUserID string, decision string) error { + log.Info(fmt.Sprintf("ReviewCoinDistributions(userID:`%v`, decision:`%v`)", reviewerUserID, decision)) + + return ctx.Err() +} diff --git a/go.mod b/go.mod index 79a69a8..e1d0eb0 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,6 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/gaukas/godicttls v0.0.4 // indirect github.com/georgysavva/scany/v2 v2.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.9.1 // indirect @@ -120,7 +119,7 @@ require ( github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect github.com/quic-go/quic-go v0.40.1 // indirect - github.com/refraction-networking/utls v1.5.4 // indirect + github.com/refraction-networking/utls v1.6.0 // indirect github.com/rs/zerolog v1.31.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/go.sum b/go.sum index 5e5ca62..8c295dc 100644 --- a/go.sum +++ b/go.sum @@ -104,8 +104,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk= -github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI= github.com/georgysavva/scany/v2 v2.0.0 h1:RGXqxDv4row7/FYoK8MRXAZXqoWF/NM+NP0q50k3DKU= github.com/georgysavva/scany/v2 v2.0.0/go.mod h1:sigOdh+0qb/+aOs3TVhehVT10p8qJL7K/Zhyz8vWo38= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= @@ -324,8 +322,8 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= -github.com/refraction-networking/utls v1.5.4 h1:9k6EO2b8TaOGsQ7Pl7p9w6PUhx18/ZCeT0WNTZ7Uw4o= -github.com/refraction-networking/utls v1.5.4/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw= +github.com/refraction-networking/utls v1.6.0 h1:X5vQMqVx7dY7ehxxqkFER/W6DSjy8TMqSItXm8hRDYQ= +github.com/refraction-networking/utls v1.6.0/go.mod h1:kHJ6R9DFFA0WsRgBM35iiDku4O7AqPR6y79iuzW7b10= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=