feat: overhelm
This commit is contained in:
parent
e15242a2b8
commit
01dce42f5c
@ -1,8 +1,31 @@
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
- clean
|
||||
- build
|
||||
- deploy
|
||||
|
||||
lint:
|
||||
image: golangci/golangci-lint:v1.51-alpine
|
||||
stage: lint
|
||||
script:
|
||||
- go generate ./internal/...
|
||||
- golangci-lint version
|
||||
- golangci-lint run --disable-all --enable=vet --enable=golint ./...
|
||||
|
||||
test:
|
||||
image: golang:1.20-alpine
|
||||
stage: test
|
||||
coverage: /\(statements\)(?:\s+)?(\d+(?:\.\d+)?%)/
|
||||
script:
|
||||
- CGO_ENABLED=0 go test ./internal/... -coverprofile=coverage.out
|
||||
- go tool cover -html=coverage.out -o coverage.html
|
||||
- go tool cover -func coverage.out
|
||||
artifacts:
|
||||
expire_in: "3 days"
|
||||
paths:
|
||||
- coverage.html
|
||||
|
||||
clean-old:
|
||||
stage: clean
|
||||
image:
|
||||
|
164
.golangci.yaml
Normal file
164
.golangci.yaml
Normal file
@ -0,0 +1,164 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
skip-files:
|
||||
- \.pb\.go$
|
||||
- .pb.go
|
||||
- \.pb\.validate\.go$
|
||||
- \.pb\.gw\.go$
|
||||
- .pb.gw.go
|
||||
- \.gen\.go$
|
||||
skip-dirs:
|
||||
- mocks
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- containedctx
|
||||
- dogsled
|
||||
- dupword
|
||||
- durationcheck
|
||||
- errcheck
|
||||
- errchkjson
|
||||
- exportloopref
|
||||
- goconst
|
||||
- gocritic
|
||||
- godot
|
||||
- gofmt
|
||||
- gci
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- importas
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nakedret
|
||||
- nilerr
|
||||
- noctx
|
||||
- nolintlint
|
||||
- nosprintfhostport
|
||||
- prealloc
|
||||
- predeclared
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- thelper
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- usestdlibvars
|
||||
- whitespace
|
||||
|
||||
linters-settings:
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- (io.Closer).Close
|
||||
govet:
|
||||
check-shadowing: true
|
||||
gci:
|
||||
custom-order: false
|
||||
section-separators:
|
||||
- newLine
|
||||
sections:
|
||||
- standard # Standard section: captures all standard packages.
|
||||
- default # Default section: contains all imports that could not be matched to another section type.
|
||||
- blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled.
|
||||
- dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled.
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
# Foundation libraries
|
||||
- pkg: git.sbercloud.tech/products/paas/shared/foundation/management-server
|
||||
alias: mgmtserver
|
||||
maligned:
|
||||
suggest-new: true
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 2
|
||||
lll:
|
||||
line-length: 140
|
||||
revive:
|
||||
rules:
|
||||
# The following rules are recommended https://github.com/mgechev/revive#recommended-configuration
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
# - name: exported
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
# - name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: empty-block
|
||||
- name: superfluous-else
|
||||
- name: unused-parameter
|
||||
- name: unreachable-code
|
||||
- name: redefines-builtin-id
|
||||
#
|
||||
# Rules in addition to the recommended configuration above.
|
||||
#
|
||||
- name: bool-literal-in-expr
|
||||
- name: constant-logical-expr
|
||||
gosec:
|
||||
excludes:
|
||||
- G307 # Deferring unsafe method "Close" on type "\*os.File"
|
||||
- G108 # Profiling endpoint is automatically exposed on /debug/pprof
|
||||
gocritic:
|
||||
enabled-tags:
|
||||
- diagnostic
|
||||
- experimental
|
||||
- performance
|
||||
disabled-checks:
|
||||
- appendAssign
|
||||
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||
- evalOrder
|
||||
- ifElseChain
|
||||
- octalLiteral
|
||||
- regexpSimplify
|
||||
- sloppyReassign
|
||||
- truncateCmp
|
||||
- typeDefFirst
|
||||
- unnamedResult
|
||||
- unnecessaryDefer
|
||||
- whyNoLint
|
||||
- wrapperFunc
|
||||
- rangeValCopy
|
||||
- hugeParam
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- text: "at least one file in a package should have a package comment"
|
||||
linters:
|
||||
- stylecheck
|
||||
- text: "should have a package comment, unless it's in another file for this package"
|
||||
linters:
|
||||
- golint
|
||||
- text: "should have comment or be unexported"
|
||||
linters:
|
||||
- golint
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gosec
|
||||
- dupl
|
||||
exclude-use-default: false
|
||||
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
print-linter-name: true
|
6
.mockery.yaml
Normal file
6
.mockery.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
exported: True
|
||||
inpackage: False
|
||||
keeptree: True
|
||||
case: underscore
|
||||
with-expecter: True
|
||||
inpackage-suffix: True
|
10
Makefile
10
Makefile
@ -8,11 +8,11 @@ help: ## show this help
|
||||
|
||||
install: ## install all go dependencies
|
||||
go install \
|
||||
github.com/bufbuild/buf/cmd/buf \
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc \
|
||||
google.golang.org/protobuf/cmd/protoc-gen-go
|
||||
github.com/bufbuild/buf/cmd/buf@v1.23.1 \
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest \
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest \
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest \
|
||||
google.golang.org/protobuf/cmd/protoc-gen-go@latest
|
||||
|
||||
generate: ## generate grpc proto for golang
|
||||
buf generate --path ./proto/${SERVICE_NAME}
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: v1beta1
|
||||
version: v1
|
||||
plugins:
|
||||
- name: go
|
||||
out: internal/proto
|
||||
@ -6,7 +6,3 @@ plugins:
|
||||
out: internal/proto
|
||||
opt:
|
||||
- require_unimplemented_servers=false
|
||||
- name: grpc-gateway
|
||||
out: internal/proto
|
||||
- name: openapiv2
|
||||
out: internal/proto
|
3
buf.work.yaml
Normal file
3
buf.work.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
version: v1
|
||||
directories:
|
||||
- proto
|
5
buf.yaml
5
buf.yaml
@ -1,7 +1,4 @@
|
||||
version: v1beta1
|
||||
build:
|
||||
roots:
|
||||
- proto
|
||||
version: v1
|
||||
lint:
|
||||
use:
|
||||
- DEFAULT
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
formatter "github.com/antonfisher/nested-logrus-formatter"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/app"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/env"
|
||||
|
82
go.mod
82
go.mod
@ -5,37 +5,89 @@ go 1.20
|
||||
require (
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.1
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/sethvargo/go-envconfig v0.8.3
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.mongodb.org/mongo-driver v1.11.1
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
|
||||
google.golang.org/genproto v0.0.0-20230119192704-9d59e20e5cd1
|
||||
google.golang.org/grpc v1.52.0
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
|
||||
google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e
|
||||
google.golang.org/grpc v1.55.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/bufbuild/buf v1.23.1 // indirect
|
||||
github.com/bufbuild/connect-go v1.8.0 // indirect
|
||||
github.com/bufbuild/connect-opentelemetry-go v0.3.0 // indirect
|
||||
github.com/bufbuild/protocompile v0.5.1 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/docker/cli v24.0.2+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/docker v24.0.2+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/felixge/fgprof v0.9.3 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.8 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.0.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/glog v1.1.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/kr/pretty v0.2.1 // indirect
|
||||
github.com/google/go-containerregistry v0.15.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 // indirect
|
||||
github.com/klauspost/compress v1.16.6 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/profile v1.7.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rs/cors v1.9.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/tetratelabs/wazero v1.2.1 // indirect
|
||||
github.com/vbatts/tar-split v0.11.3 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||
golang.org/x/net v0.4.0 // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
go.opentelemetry.io/otel v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.10.0 // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/term v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
golang.org/x/tools v0.10.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
149
go.sum
149
go.sum
@ -1,25 +1,70 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ=
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA=
|
||||
github.com/bufbuild/buf v1.23.1 h1:BeMkA3+e9XTFEZPDlAI7cydFKlq24wwYiOHp8CvsRzc=
|
||||
github.com/bufbuild/buf v1.23.1/go.mod h1:ERFRzJiIjAOzUSJ3vz1zoI7XfxlBnCwZEyL+NJm4pko=
|
||||
github.com/bufbuild/connect-go v1.8.0 h1:srluNkFkZBfSfg9Qb6DrO+5nMaxix//h2ctrHZhMGKc=
|
||||
github.com/bufbuild/connect-go v1.8.0/go.mod h1:GmMJYR6orFqD0Y6ZgX8pwQ8j9baizDrIQMm1/a6LnHk=
|
||||
github.com/bufbuild/connect-opentelemetry-go v0.3.0 h1:AuZi3asTDKmjGtd2aqpyP4p5QvBFG/YEaHopViLatnk=
|
||||
github.com/bufbuild/connect-opentelemetry-go v0.3.0/go.mod h1:r1ppyTtu1EWeRodk4Q/JbyQhIWtO7eR3GoRDzjeEcNU=
|
||||
github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg=
|
||||
github.com/bufbuild/protocompile v0.5.1/go.mod h1:G5iLmavmF4NsYtpZFvE3B/zFch2GIY8+wjsYLR/lc40=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM=
|
||||
github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg=
|
||||
github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
|
||||
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
||||
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
|
||||
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@ -27,6 +72,8 @@ github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaW
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@ -34,39 +81,84 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
|
||||
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
|
||||
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 h1:1JYBfzqrWPcCclBwxFCPAou9n+q86mfnu7NAeHfte7A=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0/go.mod h1:YDZoGHuwE+ov0c8smSH49WLF3F2LaWnYYuDVd+EWrc0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co=
|
||||
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw=
|
||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
|
||||
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
|
||||
github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sethvargo/go-envconfig v0.8.3 h1:dXyUrDCJvCm3ybP7yNpiux93qoSORvuH23bdsgFfiJ0=
|
||||
github.com/sethvargo/go-envconfig v0.8.3/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
@ -79,8 +171,15 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tetratelabs/wazero v1.2.1 h1:J4X2hrGzJvt+wqltuvcSjHQ7ujQxA9gb6PeMs4qlUWs=
|
||||
github.com/tetratelabs/wazero v1.2.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
|
||||
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
|
||||
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
||||
@ -93,22 +192,42 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.mongodb.org/mongo-driver v1.11.1 h1:QP0znIRTuL0jf1oBQoAoM0C6ZJfBK4kx0Uumtv1A7w8=
|
||||
go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
|
||||
go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
|
||||
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
|
||||
go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
|
||||
go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
|
||||
go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE=
|
||||
go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4=
|
||||
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
|
||||
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -120,6 +239,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -129,6 +250,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -137,16 +260,26 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
|
||||
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@ -155,6 +288,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
|
||||
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -166,6 +301,12 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20230119192704-9d59e20e5cd1 h1:wSjSSQW7LuPdv3m1IrSN33nVxH/kID6OIKy+FMwGB2k=
|
||||
google.golang.org/genproto v0.0.0-20230119192704-9d59e20e5cd1/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||
google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw=
|
||||
google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
@ -173,15 +314,23 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
|
||||
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
|
||||
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk=
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@ -2,18 +2,27 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/initialize"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/server"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/closer"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/mongo"
|
||||
)
|
||||
|
||||
const (
|
||||
shutdownTimeout = 5 * time.Second
|
||||
)
|
||||
|
||||
func Run(config *core.Config, logger *logrus.Logger) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
closer := closer.New()
|
||||
|
||||
database, err := mongo.Connect(ctx, &mongo.ConnectDeps{
|
||||
Configuration: &config.Database.Connection,
|
||||
@ -31,7 +40,7 @@ func Run(config *core.Config, logger *logrus.Logger) {
|
||||
|
||||
services := initialize.NewServices(&initialize.ServicesDeps{
|
||||
Logger: logger,
|
||||
Respositories: repositories,
|
||||
Repositories: repositories,
|
||||
})
|
||||
|
||||
controllers := initialize.NewControllers(&initialize.ControllersDeps{
|
||||
@ -45,9 +54,18 @@ func Run(config *core.Config, logger *logrus.Logger) {
|
||||
go serverGRPC.Run(&config.GRPC)
|
||||
go serverHTTP.Run(&config.HTTP)
|
||||
|
||||
gracefulShutdown(ctx, &gracefulShutdownDeps{
|
||||
serverGRPC: serverGRPC,
|
||||
database: database.Client(),
|
||||
cancel: cancel,
|
||||
})
|
||||
closer.Add(database.Client().Disconnect)
|
||||
closer.Add(serverGRPC.Stop)
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
logger.Info("shutting down app gracefully")
|
||||
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||
|
||||
defer cancel()
|
||||
|
||||
if err := closer.Close(shutdownCtx); err != nil {
|
||||
logger.Errorf("failed to close with graceful shutdown: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/server"
|
||||
)
|
||||
|
||||
type gracefulShutdownDeps struct {
|
||||
serverGRPC *server.GRPC
|
||||
database *mongo.Client
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func gracefulShutdown(ctx context.Context, deps *gracefulShutdownDeps) {
|
||||
defer deps.serverGRPC.Stop()
|
||||
defer deps.database.Disconnect(ctx)
|
||||
defer deps.cancel()
|
||||
|
||||
quit := make(chan os.Signal, 1)
|
||||
|
||||
signal.Notify(quit, syscall.SIGTERM, syscall.SIGINT)
|
||||
|
||||
<-quit
|
||||
}
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/transfer"
|
||||
|
@ -14,14 +14,14 @@ type CommonDiscountCondition struct {
|
||||
User string `json:"user"`
|
||||
UserType string `json:"userType"`
|
||||
Coupon *string `json:"coupon"`
|
||||
PurchasesAmount float64 `json:"purchasesAmount"`
|
||||
CartPurchasesAmount float64 `json:"cartPurchasesAmount"`
|
||||
PurchasesAmount uint64 `json:"purchasesAmount"`
|
||||
CartPurchasesAmount uint64 `json:"cartPurchasesAmount"`
|
||||
}
|
||||
|
||||
type OptionalDiscounCondition struct {
|
||||
Product *string `json:"product"`
|
||||
Group *string `json:"group"`
|
||||
PriceFrom *float64 `json:"priceFrom"`
|
||||
PriceFrom *uint64 `json:"priceFrom"`
|
||||
|
||||
/* Срок использования (количество дней использования) */
|
||||
Term *uint64 `json:"term"`
|
||||
|
@ -3,7 +3,6 @@ package initialize
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/repository"
|
||||
)
|
||||
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
type ServicesDeps struct {
|
||||
Logger *logrus.Logger
|
||||
Respositories *Repositories
|
||||
Repositories *Repositories
|
||||
}
|
||||
|
||||
type Services struct {
|
||||
@ -18,7 +18,7 @@ func NewServices(deps *ServicesDeps) *Services {
|
||||
return &Services{
|
||||
DiscountService: service.NewDiscountService(&service.DiscountServiceDeps{
|
||||
Logger: deps.Logger,
|
||||
DiscountRepository: deps.Respositories.DiscountRepository,
|
||||
DiscountRepository: deps.Repositories.DiscountRepository,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -36,19 +36,19 @@ type DiscountCalculationTarget struct {
|
||||
type DiscountCondition struct {
|
||||
Period *PeriodCondition `json:"period,omitempty" bson:"period,omitempty"`
|
||||
Product *string `json:"product,omitempty" bson:"product,omitempty"`
|
||||
PriceFrom *float64 `json:"priceFrom,omitempty" bson:"priceFrom,omitempty"`
|
||||
PriceFrom *uint64 `json:"priceFrom,omitempty" bson:"priceFrom,omitempty"`
|
||||
Group *string `json:"group,omitempty" bson:"group,omitempty"`
|
||||
User *string `json:"user,omitempty" bson:"user,omitempty"`
|
||||
UserType *string `json:"userType,omitempty" bson:"userType,omitempty"`
|
||||
Coupon *string `json:"coupon,omitempty" bson:"coupon,omitempty"`
|
||||
PurchasesAmount *float64 `json:"purchasesAmount,omitempty" bson:"purchasesAmount,omitempty"`
|
||||
CartPurchasesAmount *float64 `json:"cartPurchasesAmount,omitempty" bson:"cartPurchasesAmount,omitempty"`
|
||||
PurchasesAmount *uint64 `json:"purchasesAmount,omitempty" bson:"purchasesAmount,omitempty"`
|
||||
CartPurchasesAmount *uint64 `json:"cartPurchasesAmount,omitempty" bson:"cartPurchasesAmount,omitempty"`
|
||||
|
||||
/* Срок использования (количество дней использования) */
|
||||
Term *uint64 `json:"term,omitempty" bson:"term,omitempty"`
|
||||
Term *uint64 `json:"term" bson:"term"`
|
||||
|
||||
/* Количество использований (количество попыток) */
|
||||
Usage *uint64 `json:"usage,omitempty" bson:"usage,omitempty"`
|
||||
Usage *uint64 `json:"usage" bson:"usage,omitempty"`
|
||||
}
|
||||
|
||||
type ProductTarget struct {
|
||||
@ -65,8 +65,13 @@ type PeriodCondition struct {
|
||||
type TargetScope string
|
||||
|
||||
const (
|
||||
// TargetSum тип скидки, применяющийся на финальную сформированную сумму всех товаров.
|
||||
TargetSum TargetScope = "sum"
|
||||
|
||||
// TargetGroup тип скидки, применяющийся на сумму товаров определённой группы.
|
||||
TargetGroup TargetScope = "group"
|
||||
|
||||
// TargetEach тип скидки, применяющийся на определённый товар.
|
||||
TargetEach TargetScope = "each"
|
||||
)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: discount/audit.model.proto
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: discount/discount.model.proto
|
||||
|
||||
@ -397,12 +397,12 @@ type DiscountCondition struct {
|
||||
User *string `protobuf:"bytes,2,opt,name=User,proto3,oneof" json:"User,omitempty"`
|
||||
UserType *string `protobuf:"bytes,3,opt,name=UserType,proto3,oneof" json:"UserType,omitempty"`
|
||||
Coupon *string `protobuf:"bytes,4,opt,name=Coupon,proto3,oneof" json:"Coupon,omitempty"`
|
||||
PurchasesAmount *float64 `protobuf:"fixed64,5,opt,name=PurchasesAmount,proto3,oneof" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount *float64 `protobuf:"fixed64,6,opt,name=CartPurchasesAmount,proto3,oneof" json:"CartPurchasesAmount,omitempty"`
|
||||
PurchasesAmount *uint64 `protobuf:"varint,5,opt,name=PurchasesAmount,proto3,oneof" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount *uint64 `protobuf:"varint,6,opt,name=CartPurchasesAmount,proto3,oneof" json:"CartPurchasesAmount,omitempty"`
|
||||
Product *string `protobuf:"bytes,7,opt,name=Product,proto3,oneof" json:"Product,omitempty"`
|
||||
Term *uint64 `protobuf:"varint,8,opt,name=Term,proto3,oneof" json:"Term,omitempty"`
|
||||
Usage *uint64 `protobuf:"varint,9,opt,name=Usage,proto3,oneof" json:"Usage,omitempty"`
|
||||
PriceFrom *float64 `protobuf:"fixed64,10,opt,name=PriceFrom,proto3,oneof" json:"PriceFrom,omitempty"`
|
||||
PriceFrom *uint64 `protobuf:"varint,10,opt,name=PriceFrom,proto3,oneof" json:"PriceFrom,omitempty"`
|
||||
Group *string `protobuf:"bytes,11,opt,name=Group,proto3,oneof" json:"Group,omitempty"`
|
||||
}
|
||||
|
||||
@ -466,14 +466,14 @@ func (x *DiscountCondition) GetCoupon() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *DiscountCondition) GetPurchasesAmount() float64 {
|
||||
func (x *DiscountCondition) GetPurchasesAmount() uint64 {
|
||||
if x != nil && x.PurchasesAmount != nil {
|
||||
return *x.PurchasesAmount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *DiscountCondition) GetCartPurchasesAmount() float64 {
|
||||
func (x *DiscountCondition) GetCartPurchasesAmount() uint64 {
|
||||
if x != nil && x.CartPurchasesAmount != nil {
|
||||
return *x.CartPurchasesAmount
|
||||
}
|
||||
@ -501,7 +501,7 @@ func (x *DiscountCondition) GetUsage() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *DiscountCondition) GetPriceFrom() float64 {
|
||||
func (x *DiscountCondition) GetPriceFrom() uint64 {
|
||||
if x != nil && x.PriceFrom != nil {
|
||||
return *x.PriceFrom
|
||||
}
|
||||
@ -640,8 +640,8 @@ type UserInformation struct {
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
PurchasesAmount float64 `protobuf:"fixed64,3,opt,name=PurchasesAmount,proto3" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount float64 `protobuf:"fixed64,4,opt,name=CartPurchasesAmount,proto3" json:"CartPurchasesAmount,omitempty"`
|
||||
PurchasesAmount uint64 `protobuf:"varint,3,opt,name=PurchasesAmount,proto3" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount uint64 `protobuf:"varint,4,opt,name=CartPurchasesAmount,proto3" json:"CartPurchasesAmount,omitempty"`
|
||||
}
|
||||
|
||||
func (x *UserInformation) Reset() {
|
||||
@ -690,14 +690,14 @@ func (x *UserInformation) GetType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *UserInformation) GetPurchasesAmount() float64 {
|
||||
func (x *UserInformation) GetPurchasesAmount() uint64 {
|
||||
if x != nil {
|
||||
return x.PurchasesAmount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UserInformation) GetCartPurchasesAmount() float64 {
|
||||
func (x *UserInformation) GetCartPurchasesAmount() uint64 {
|
||||
if x != nil {
|
||||
return x.CartPurchasesAmount
|
||||
}
|
||||
@ -710,7 +710,7 @@ type ProductInformation struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Price float64 `protobuf:"fixed64,2,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
Price uint64 `protobuf:"varint,2,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
Term *uint64 `protobuf:"varint,3,opt,name=Term,proto3,oneof" json:"Term,omitempty"`
|
||||
Usage *uint64 `protobuf:"varint,4,opt,name=Usage,proto3,oneof" json:"Usage,omitempty"`
|
||||
Group *string `protobuf:"bytes,5,opt,name=Group,proto3,oneof" json:"Group,omitempty"`
|
||||
@ -755,7 +755,7 @@ func (x *ProductInformation) GetID() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ProductInformation) GetPrice() float64 {
|
||||
func (x *ProductInformation) GetPrice() uint64 {
|
||||
if x != nil {
|
||||
return x.Price
|
||||
}
|
||||
@ -868,10 +868,10 @@ var file_discount_discount_model_proto_rawDesc = []byte{
|
||||
0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x06,
|
||||
0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x0f, 0x50, 0x75, 0x72,
|
||||
0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x01, 0x48, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41,
|
||||
0x28, 0x04, 0x48, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41,
|
||||
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x13, 0x43, 0x61, 0x72, 0x74,
|
||||
0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x01, 0x48, 0x05, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72,
|
||||
0x06, 0x20, 0x01, 0x28, 0x04, 0x48, 0x05, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72,
|
||||
0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12,
|
||||
0x1d, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||
0x48, 0x06, 0x52, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x88, 0x01, 0x01, 0x12, 0x17,
|
||||
@ -879,7 +879,7 @@ var file_discount_discount_model_proto_rawDesc = []byte{
|
||||
0x54, 0x65, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65,
|
||||
0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x48, 0x08, 0x52, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x88,
|
||||
0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x18,
|
||||
0x0a, 0x20, 0x01, 0x28, 0x01, 0x48, 0x09, 0x52, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x46, 0x72,
|
||||
0x0a, 0x20, 0x01, 0x28, 0x04, 0x48, 0x09, 0x52, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x46, 0x72,
|
||||
0x6f, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0b,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x0a, 0x52, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x88, 0x01, 0x01,
|
||||
0x42, 0x09, 0x0a, 0x07, 0x5f, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x5f,
|
||||
@ -909,14 +909,14 @@ var file_discount_discount_model_proto_rawDesc = []byte{
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a,
|
||||
0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65,
|
||||
0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50,
|
||||
0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x01, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61,
|
||||
0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x12, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x12,
|
||||
0x19, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x01,
|
||||
|
@ -34,6 +34,7 @@
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: discount/service.proto
|
||||
|
||||
@ -146,7 +146,7 @@ type ApplyDiscountResponse struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Price float64 `protobuf:"fixed64,1,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
Price uint64 `protobuf:"varint,1,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
AppliedDiscounts []*Discount `protobuf:"bytes,2,rep,name=AppliedDiscounts,proto3" json:"AppliedDiscounts,omitempty"`
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ func (*ApplyDiscountResponse) Descriptor() ([]byte, []int) {
|
||||
return file_discount_service_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ApplyDiscountResponse) GetPrice() float64 {
|
||||
func (x *ApplyDiscountResponse) GetPrice() uint64 {
|
||||
if x != nil {
|
||||
return x.Price
|
||||
}
|
||||
@ -307,7 +307,7 @@ var file_discount_service_proto_rawDesc = []byte{
|
||||
0x00, 0x52, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07,
|
||||
0x5f, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x22, 0x6d, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x6c, 0x79,
|
||||
0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65,
|
||||
0x64, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63,
|
||||
|
@ -681,7 +681,7 @@ func RegisterDiscountServiceHandlerServer(ctx context.Context, mux *runtime.Serv
|
||||
// RegisterDiscountServiceHandlerFromEndpoint is same as RegisterDiscountServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterDiscountServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
conn, err := grpc.DialContext(ctx, endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -341,6 +341,7 @@
|
||||
"Products": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/discountProductInformation"
|
||||
}
|
||||
},
|
||||
@ -363,6 +364,7 @@
|
||||
"AppliedDiscounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/discountDiscount"
|
||||
}
|
||||
}
|
||||
@ -445,6 +447,7 @@
|
||||
"Products": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/discountProductTarget"
|
||||
}
|
||||
},
|
||||
@ -512,6 +515,7 @@
|
||||
"Discounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/discountDiscount"
|
||||
}
|
||||
}
|
||||
@ -618,6 +622,7 @@
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,8 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc (unknown)
|
||||
// source: discount/service.proto
|
||||
|
||||
package discount
|
||||
|
||||
@ -15,6 +19,18 @@ import (
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
DiscountService_GetAllDiscounts_FullMethodName = "/discount.DiscountService/GetAllDiscounts"
|
||||
DiscountService_GetUserDiscounts_FullMethodName = "/discount.DiscountService/GetUserDiscounts"
|
||||
DiscountService_DetermineDiscounts_FullMethodName = "/discount.DiscountService/DetermineDiscounts"
|
||||
DiscountService_ApplyDiscounts_FullMethodName = "/discount.DiscountService/ApplyDiscounts"
|
||||
DiscountService_GetDiscountByID_FullMethodName = "/discount.DiscountService/GetDiscountByID"
|
||||
DiscountService_CreateDiscount_FullMethodName = "/discount.DiscountService/CreateDiscount"
|
||||
DiscountService_ReplaceDiscount_FullMethodName = "/discount.DiscountService/ReplaceDiscount"
|
||||
DiscountService_UpdateDiscount_FullMethodName = "/discount.DiscountService/UpdateDiscount"
|
||||
DiscountService_DeleteDiscount_FullMethodName = "/discount.DiscountService/DeleteDiscount"
|
||||
)
|
||||
|
||||
// DiscountServiceClient is the client API for DiscountService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
@ -40,7 +56,7 @@ func NewDiscountServiceClient(cc grpc.ClientConnInterface) DiscountServiceClient
|
||||
|
||||
func (c *discountServiceClient) GetAllDiscounts(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Discounts, error) {
|
||||
out := new(Discounts)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/GetAllDiscounts", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_GetAllDiscounts_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -49,7 +65,7 @@ func (c *discountServiceClient) GetAllDiscounts(ctx context.Context, in *emptypb
|
||||
|
||||
func (c *discountServiceClient) GetUserDiscounts(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discounts, error) {
|
||||
out := new(Discounts)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/GetUserDiscounts", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_GetUserDiscounts_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -58,7 +74,7 @@ func (c *discountServiceClient) GetUserDiscounts(ctx context.Context, in *GetDis
|
||||
|
||||
func (c *discountServiceClient) DetermineDiscounts(ctx context.Context, in *ApplyDiscountRequest, opts ...grpc.CallOption) (*Discounts, error) {
|
||||
out := new(Discounts)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/DetermineDiscounts", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_DetermineDiscounts_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -67,7 +83,7 @@ func (c *discountServiceClient) DetermineDiscounts(ctx context.Context, in *Appl
|
||||
|
||||
func (c *discountServiceClient) ApplyDiscounts(ctx context.Context, in *ApplyDiscountRequest, opts ...grpc.CallOption) (*ApplyDiscountResponse, error) {
|
||||
out := new(ApplyDiscountResponse)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/ApplyDiscounts", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_ApplyDiscounts_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -76,7 +92,7 @@ func (c *discountServiceClient) ApplyDiscounts(ctx context.Context, in *ApplyDis
|
||||
|
||||
func (c *discountServiceClient) GetDiscountByID(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discount, error) {
|
||||
out := new(Discount)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/GetDiscountByID", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_GetDiscountByID_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -85,7 +101,7 @@ func (c *discountServiceClient) GetDiscountByID(ctx context.Context, in *GetDisc
|
||||
|
||||
func (c *discountServiceClient) CreateDiscount(ctx context.Context, in *CreateDiscountRequest, opts ...grpc.CallOption) (*Discount, error) {
|
||||
out := new(Discount)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/CreateDiscount", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_CreateDiscount_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -94,7 +110,7 @@ func (c *discountServiceClient) CreateDiscount(ctx context.Context, in *CreateDi
|
||||
|
||||
func (c *discountServiceClient) ReplaceDiscount(ctx context.Context, in *DiscountOptional, opts ...grpc.CallOption) (*Discount, error) {
|
||||
out := new(Discount)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/ReplaceDiscount", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_ReplaceDiscount_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -103,7 +119,7 @@ func (c *discountServiceClient) ReplaceDiscount(ctx context.Context, in *Discoun
|
||||
|
||||
func (c *discountServiceClient) UpdateDiscount(ctx context.Context, in *DiscountOptional, opts ...grpc.CallOption) (*Discount, error) {
|
||||
out := new(Discount)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/UpdateDiscount", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_UpdateDiscount_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -112,7 +128,7 @@ func (c *discountServiceClient) UpdateDiscount(ctx context.Context, in *Discount
|
||||
|
||||
func (c *discountServiceClient) DeleteDiscount(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discount, error) {
|
||||
out := new(Discount)
|
||||
err := c.cc.Invoke(ctx, "/discount.DiscountService/DeleteDiscount", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, DiscountService_DeleteDiscount_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -187,7 +203,7 @@ func _DiscountService_GetAllDiscounts_Handler(srv interface{}, ctx context.Conte
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/GetAllDiscounts",
|
||||
FullMethod: DiscountService_GetAllDiscounts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).GetAllDiscounts(ctx, req.(*emptypb.Empty))
|
||||
@ -205,7 +221,7 @@ func _DiscountService_GetUserDiscounts_Handler(srv interface{}, ctx context.Cont
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/GetUserDiscounts",
|
||||
FullMethod: DiscountService_GetUserDiscounts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).GetUserDiscounts(ctx, req.(*GetDiscountByIDRequest))
|
||||
@ -223,7 +239,7 @@ func _DiscountService_DetermineDiscounts_Handler(srv interface{}, ctx context.Co
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/DetermineDiscounts",
|
||||
FullMethod: DiscountService_DetermineDiscounts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).DetermineDiscounts(ctx, req.(*ApplyDiscountRequest))
|
||||
@ -241,7 +257,7 @@ func _DiscountService_ApplyDiscounts_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/ApplyDiscounts",
|
||||
FullMethod: DiscountService_ApplyDiscounts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).ApplyDiscounts(ctx, req.(*ApplyDiscountRequest))
|
||||
@ -259,7 +275,7 @@ func _DiscountService_GetDiscountByID_Handler(srv interface{}, ctx context.Conte
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/GetDiscountByID",
|
||||
FullMethod: DiscountService_GetDiscountByID_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).GetDiscountByID(ctx, req.(*GetDiscountByIDRequest))
|
||||
@ -277,7 +293,7 @@ func _DiscountService_CreateDiscount_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/CreateDiscount",
|
||||
FullMethod: DiscountService_CreateDiscount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).CreateDiscount(ctx, req.(*CreateDiscountRequest))
|
||||
@ -295,7 +311,7 @@ func _DiscountService_ReplaceDiscount_Handler(srv interface{}, ctx context.Conte
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/ReplaceDiscount",
|
||||
FullMethod: DiscountService_ReplaceDiscount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).ReplaceDiscount(ctx, req.(*DiscountOptional))
|
||||
@ -313,7 +329,7 @@ func _DiscountService_UpdateDiscount_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/UpdateDiscount",
|
||||
FullMethod: DiscountService_UpdateDiscount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).UpdateDiscount(ctx, req.(*DiscountOptional))
|
||||
@ -331,7 +347,7 @@ func _DiscountService_DeleteDiscount_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/discount.DiscountService/DeleteDiscount",
|
||||
FullMethod: DiscountService_DeleteDiscount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DiscountServiceServer).DeleteDiscount(ctx, req.(*GetDiscountByIDRequest))
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.mongodb.org/mongo-driver/mongo/readconcern"
|
||||
"go.mongodb.org/mongo-driver/mongo/writeconcern"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
@ -184,7 +183,9 @@ func (receiver *DiscountRepository) UpdateMany(ctx context.Context, updates []co
|
||||
|
||||
if _, transactionError := session.WithTransaction(ctx, func(sessionContext mongo.SessionContext) (interface{}, error) {
|
||||
for _, update := range updates {
|
||||
if err := receiver.UpdateOne(sessionContext, &update); err != nil {
|
||||
updateCopy := update
|
||||
|
||||
if err := receiver.UpdateOne(sessionContext, &updateCopy); err != nil {
|
||||
receiver.logger.Errorf("failed to update <%s> in transaction on <UpdateMany> of <DiscountRepository>: %v", update.ID, err)
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
@ -60,14 +61,12 @@ func (receiver *GRPC) listen(address string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := receiver.grpc.Serve(listener); err != nil {
|
||||
return err
|
||||
return receiver.grpc.Serve(listener)
|
||||
}
|
||||
|
||||
func (receiver *GRPC) Stop(_ context.Context) error {
|
||||
receiver.grpc.GracefulStop()
|
||||
receiver.logger.Infoln("Shutting down GRPC server...")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *GRPC) Stop() {
|
||||
receiver.grpc.GracefulStop()
|
||||
receiver.logger.Infoln("Shutting down GRPC server...")
|
||||
}
|
||||
|
@ -4,18 +4,19 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
)
|
||||
|
||||
type HTTP struct {
|
||||
logger *logrus.Logger
|
||||
server *http.Server
|
||||
mux *runtime.ServeMux
|
||||
}
|
||||
|
||||
@ -23,6 +24,12 @@ func NewHTTP(logger *logrus.Logger) *HTTP {
|
||||
return &HTTP{
|
||||
logger: logger,
|
||||
mux: runtime.NewServeMux(),
|
||||
server: &http.Server{
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
ReadTimeout: 20 * time.Second,
|
||||
WriteTimeout: 20 * time.Second,
|
||||
IdleTimeout: 20 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,12 +45,19 @@ func (receiver *HTTP) Register(ctx context.Context, config *core.GRPCConfigurati
|
||||
return receiver
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Listen(address string) error {
|
||||
receiver.server.Addr = address
|
||||
receiver.server.Handler = receiver.mux
|
||||
|
||||
return receiver.server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Run(config *core.HTTPConfiguration) {
|
||||
endpoint := fmt.Sprintf(":%s", config.Port)
|
||||
|
||||
receiver.logger.Infof("HTTP server started on: <%s>", endpoint)
|
||||
|
||||
if err := http.ListenAndServe(endpoint, receiver.mux); err != nil && err != http.ErrServerClosed {
|
||||
if err := receiver.Listen(endpoint); err != nil && err != http.ErrServerClosed {
|
||||
receiver.logger.Errorf("HTTP listen error: %v", err)
|
||||
panic(err)
|
||||
}
|
||||
|
@ -4,12 +4,11 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/calculate"
|
||||
discountUtils "penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/transfer"
|
||||
)
|
||||
|
||||
@ -70,7 +69,7 @@ func (receiver *DiscountService) ApplyDiscounts(ctx context.Context, request *di
|
||||
products := transfer.ProductsProtoToCore(request.Products)
|
||||
|
||||
return &discount.ApplyDiscountResponse{
|
||||
Price: calculate.Discount(products, filteredDiscounts),
|
||||
Price: discountUtils.Calculate(products, filteredDiscounts),
|
||||
AppliedDiscounts: transfer.DiscountsModelToProto(filteredDiscounts).Discounts,
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
package calculate
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/convert"
|
||||
)
|
||||
|
||||
/*
|
||||
TODO:
|
||||
|
||||
1) Рефактор всех приватных утилит
|
||||
2) Покрытие тестами всех утилит
|
||||
3) Уточнить систему overhelm при высчитывании
|
||||
*/
|
||||
|
||||
func Discount(products []core.Product, discounts []models.Discount) float64 {
|
||||
if len(products) < 1 {
|
||||
return 0
|
||||
}
|
||||
|
||||
price := calculateProducts(products)
|
||||
|
||||
if len(discounts) < 1 {
|
||||
return price
|
||||
}
|
||||
|
||||
discountTargets := constituteDiscountTargets(divideDiscounts(discounts))
|
||||
productsMap := convert.ArrayToMap(products, func(product core.Product) string {
|
||||
return product.ID
|
||||
})
|
||||
|
||||
if eachTarget, ok := discountTargets[models.TargetEach]; ok {
|
||||
productsMap = calculateEachProduct(productsMap, eachTarget)
|
||||
price = calculateProductsMap(productsMap)
|
||||
}
|
||||
|
||||
if groupTarget, ok := discountTargets[models.TargetGroup]; ok {
|
||||
productGroups := convert.MapToMapArray(productsMap, func(product core.Product) string {
|
||||
return product.Group
|
||||
})
|
||||
|
||||
pricesGroup := calculateGroupProducts(productGroups, groupTarget)
|
||||
price = calculatePricesGroup(pricesGroup)
|
||||
}
|
||||
|
||||
if sumTarget, ok := discountTargets[models.TargetSum]; ok {
|
||||
price = price * sumTarget.Factor
|
||||
}
|
||||
|
||||
return price
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package calculate
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
)
|
||||
|
||||
func calculateProducts(products []core.Product) float64 {
|
||||
productsPrice := float64(0)
|
||||
|
||||
for _, product := range products {
|
||||
productsPrice = productsPrice + product.Price
|
||||
}
|
||||
|
||||
return productsPrice
|
||||
}
|
||||
|
||||
func calculateProductsMap(products map[string]core.Product) float64 {
|
||||
productsPrice := float64(0)
|
||||
|
||||
for _, product := range products {
|
||||
productsPrice = productsPrice + product.Price
|
||||
}
|
||||
|
||||
return productsPrice
|
||||
}
|
||||
|
||||
func calculatePricesGroup(pricesGroup map[string]float64) float64 {
|
||||
finalPrice := float64(0)
|
||||
|
||||
for _, price := range pricesGroup {
|
||||
finalPrice = finalPrice + price
|
||||
}
|
||||
|
||||
return finalPrice
|
||||
}
|
||||
|
||||
func calculateEachProduct(products map[string]core.Product, target models.DiscountCalculationTarget) map[string]core.Product {
|
||||
if target.Products == nil && target.Factor == 0 {
|
||||
return products
|
||||
}
|
||||
|
||||
if target.Products == nil {
|
||||
for key, product := range products {
|
||||
products[key] = core.Product{
|
||||
ID: key,
|
||||
Price: product.Price * target.Factor,
|
||||
}
|
||||
}
|
||||
|
||||
return products
|
||||
}
|
||||
|
||||
for _, productTarget := range target.Products {
|
||||
product, ok := products[productTarget.ID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if productTarget.Factor != 0 {
|
||||
products[product.ID] = core.Product{
|
||||
ID: product.ID,
|
||||
Price: product.Price * productTarget.Factor,
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
products[product.ID] = core.Product{
|
||||
ID: product.ID,
|
||||
Price: product.Price * target.Factor,
|
||||
}
|
||||
}
|
||||
|
||||
return products
|
||||
}
|
||||
|
||||
func calculateGroupProducts(productsGroup map[string][]core.Product, target models.DiscountCalculationTarget) map[string]float64 {
|
||||
pricesGroup := make(map[string]float64)
|
||||
|
||||
if target.TargetGroup == "" && target.Factor == 0 {
|
||||
for group, products := range productsGroup {
|
||||
pricesGroup[group] = calculateProducts(products)
|
||||
}
|
||||
|
||||
return pricesGroup
|
||||
}
|
||||
|
||||
for group, products := range productsGroup {
|
||||
pricesGroup[group] = calculateProducts(products) * target.Factor
|
||||
}
|
||||
|
||||
return pricesGroup
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package calculate
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/convert"
|
||||
)
|
||||
|
||||
func constituteDiscountTargets(dividedDiscounts map[models.TargetScope][]models.Discount) map[models.TargetScope]models.DiscountCalculationTarget {
|
||||
discountTargets := make(map[models.TargetScope]models.DiscountCalculationTarget, 3)
|
||||
|
||||
for group, discounts := range dividedDiscounts {
|
||||
switch group {
|
||||
case models.TargetEach:
|
||||
discountTargets[group] = models.DiscountCalculationTarget{
|
||||
Products: sumEachFactor(discounts),
|
||||
}
|
||||
case models.TargetGroup, models.TargetSum:
|
||||
discountTargets[group] = models.DiscountCalculationTarget{
|
||||
Factor: sumCommonFactor(discounts),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return discountTargets
|
||||
}
|
||||
|
||||
func divideDiscounts(discounts []models.Discount) map[models.TargetScope][]models.Discount {
|
||||
dividedDiscounts := make(map[models.TargetScope][]models.Discount, 3)
|
||||
|
||||
for _, discount := range discounts {
|
||||
if len(discount.Target.Products) > 0 {
|
||||
dividedDiscounts[models.TargetEach] = append(dividedDiscounts[models.TargetEach], discount)
|
||||
continue
|
||||
}
|
||||
if discount.Target.TargetScope == "" && len(discount.Target.Products) < 1 {
|
||||
dividedDiscounts[models.TargetSum] = append(dividedDiscounts[models.TargetSum], discount)
|
||||
continue
|
||||
}
|
||||
if discount.Target.TargetScope == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
dividedDiscounts[discount.Target.TargetScope] = append(dividedDiscounts[discount.Target.TargetScope], discount)
|
||||
}
|
||||
|
||||
return dividedDiscounts
|
||||
}
|
||||
|
||||
func sumCommonFactor(discounts []models.Discount) float64 {
|
||||
sum := float64(1)
|
||||
|
||||
for _, discount := range discounts {
|
||||
if discount.Target.Overhelm {
|
||||
sum = discount.Target.Factor
|
||||
break
|
||||
}
|
||||
|
||||
sum = sum * discount.Target.Factor
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
func sumEachFactor(discounts []models.Discount) []models.ProductTarget {
|
||||
productTargetsMap := make(map[string]models.ProductTarget)
|
||||
|
||||
for _, discount := range discounts {
|
||||
for _, productTarget := range discount.Target.Products {
|
||||
if productTargetsMap[productTarget.ID].Overhelm {
|
||||
continue
|
||||
}
|
||||
|
||||
if productTargetsMap[productTarget.ID].Factor > 0 {
|
||||
productTargetsMap[productTarget.ID] = models.ProductTarget{
|
||||
ID: productTarget.ID,
|
||||
Factor: productTargetsMap[productTarget.ID].Factor * productTarget.Factor,
|
||||
Overhelm: productTargetsMap[productTarget.ID].Overhelm,
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
productTargetsMap[productTarget.ID] = models.ProductTarget{
|
||||
ID: productTarget.ID,
|
||||
Factor: 1 * productTarget.Factor,
|
||||
Overhelm: productTargetsMap[productTarget.ID].Overhelm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return convert.MapToArray(productTargetsMap)
|
||||
}
|
@ -38,7 +38,7 @@ func ConstituteConditions(request *discount.ApplyDiscountRequest) (*core.Discoun
|
||||
Term: product.Term,
|
||||
Usage: product.Usage,
|
||||
}
|
||||
optionalConditionsIndex = optionalConditionsIndex + 2
|
||||
optionalConditionsIndex += 2
|
||||
}
|
||||
|
||||
return &core.DiscountConditions{
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
@ -16,17 +15,17 @@ import (
|
||||
func TestConstituteConditions(t *testing.T) {
|
||||
userID := "1"
|
||||
userType := "nkvo"
|
||||
purchasesAmount := float64(100000)
|
||||
cartPurchasesAmount := float64(5000)
|
||||
purchasesAmount := uint64(100000)
|
||||
cartPurchasesAmount := uint64(5000)
|
||||
productsGroup := "group"
|
||||
productID1 := "1"
|
||||
productID2 := "2"
|
||||
productID3 := "3"
|
||||
productID4 := "4"
|
||||
productPrice1 := float64(1000)
|
||||
productPrice2 := float64(6000)
|
||||
productPrice3 := float64(10000)
|
||||
productPrice4 := float64(4000)
|
||||
productPrice1 := uint64(1000)
|
||||
productPrice2 := uint64(6000)
|
||||
productPrice3 := uint64(10000)
|
||||
productPrice4 := uint64(4000)
|
||||
productTerm1 := uint64(14)
|
||||
productTerm2 := uint64(16)
|
||||
productUsage1 := uint64(24)
|
||||
|
144
internal/utils/discount/calculate.go
Normal file
144
internal/utils/discount/calculate.go
Normal file
@ -0,0 +1,144 @@
|
||||
package discount
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/convert"
|
||||
)
|
||||
|
||||
/*
|
||||
TODO:
|
||||
|
||||
1) Рефактор всех приватных утилит
|
||||
2) Покрытие тестами всех утилит
|
||||
*/
|
||||
|
||||
func Calculate(products []core.Product, discounts []models.Discount) uint64 {
|
||||
if len(products) < 1 {
|
||||
return 0
|
||||
}
|
||||
|
||||
price := calculateProducts(products)
|
||||
|
||||
if len(discounts) < 1 {
|
||||
return convert.FloatToUint64(price)
|
||||
}
|
||||
|
||||
discountTargetsMap := SortOverhelmingDiscounts(discounts)
|
||||
productsMap := convert.ArrayToMap(products, func(product core.Product) string {
|
||||
return product.ID
|
||||
})
|
||||
|
||||
if targetsEach, ok := discountTargetsMap[models.TargetEach]; ok {
|
||||
for _, target := range targetsEach {
|
||||
productsMap = calculateEachProductWithTarget(productsMap, target)
|
||||
}
|
||||
|
||||
price = calculateProductsMap(productsMap)
|
||||
}
|
||||
|
||||
if targetsGroup, ok := discountTargetsMap[models.TargetGroup]; ok {
|
||||
productGroups := convert.MapToMapArray(productsMap, func(product core.Product) string {
|
||||
return product.Group
|
||||
})
|
||||
|
||||
pricesGroup := calculateProductsGroup(productGroups)
|
||||
|
||||
for _, target := range targetsGroup {
|
||||
pricesGroup[target.TargetGroup] *= target.Factor
|
||||
}
|
||||
|
||||
price = calculatePricesGroupSum(pricesGroup)
|
||||
}
|
||||
|
||||
if targetsSum, ok := discountTargetsMap[models.TargetSum]; ok {
|
||||
for _, target := range targetsSum {
|
||||
price *= target.Factor
|
||||
}
|
||||
}
|
||||
|
||||
return convert.FloatToUint64(price)
|
||||
}
|
||||
|
||||
func calculateProducts(products []core.Product) float64 {
|
||||
productsPrice := float64(0)
|
||||
|
||||
for _, product := range products {
|
||||
productsPrice += product.Price
|
||||
}
|
||||
|
||||
return productsPrice
|
||||
}
|
||||
|
||||
func calculateProductsMap(products map[string]core.Product) float64 {
|
||||
productsPrice := float64(0)
|
||||
|
||||
for _, product := range products {
|
||||
productsPrice += product.Price
|
||||
}
|
||||
|
||||
return productsPrice
|
||||
}
|
||||
|
||||
func calculatePricesGroupSum(pricesGroup map[string]float64) float64 {
|
||||
finalPrice := float64(0)
|
||||
|
||||
for _, price := range pricesGroup {
|
||||
finalPrice += price
|
||||
}
|
||||
|
||||
return finalPrice
|
||||
}
|
||||
|
||||
func calculateEachProductWithTarget(products map[string]core.Product, target models.DiscountCalculationTarget) map[string]core.Product {
|
||||
if target.Products == nil && target.Factor == 0 {
|
||||
return products
|
||||
}
|
||||
|
||||
if target.Products == nil {
|
||||
for key, product := range products {
|
||||
products[key] = core.Product{
|
||||
ID: key,
|
||||
Price: product.Price * target.Factor,
|
||||
Group: product.Group,
|
||||
}
|
||||
}
|
||||
|
||||
return products
|
||||
}
|
||||
|
||||
for _, productTarget := range target.Products {
|
||||
product, ok := products[productTarget.ID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if productTarget.Factor != 0 {
|
||||
products[product.ID] = core.Product{
|
||||
ID: product.ID,
|
||||
Price: product.Price * productTarget.Factor,
|
||||
Group: product.Group,
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
products[product.ID] = core.Product{
|
||||
ID: product.ID,
|
||||
Price: product.Price * target.Factor,
|
||||
Group: product.Group,
|
||||
}
|
||||
}
|
||||
|
||||
return products
|
||||
}
|
||||
|
||||
func calculateProductsGroup(productsGroup map[string][]core.Product) map[string]float64 {
|
||||
pricesGroup := make(map[string]float64)
|
||||
|
||||
for group, products := range productsGroup {
|
||||
pricesGroup[group] = calculateProducts(products)
|
||||
}
|
||||
|
||||
return pricesGroup
|
||||
}
|
@ -1,31 +1,30 @@
|
||||
package calculate_test
|
||||
package discount_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/calculate"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/discount"
|
||||
)
|
||||
|
||||
func TestCalculate(t *testing.T) {
|
||||
t.Run("Покупка продуктов в количестве не больше 1 при отсутствии скидок", func(t *testing.T) {
|
||||
assert.Equal(t, 3.0, calculate.Discount(
|
||||
assert.Equal(t, uint64(3), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 1.0},
|
||||
{ID: "p2", Price: 2.0},
|
||||
{ID: "p1", Price: 1},
|
||||
{ID: "p2", Price: 2},
|
||||
},
|
||||
[]models.Discount{},
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Сумма корзины достигла 5к", func(t *testing.T) {
|
||||
assert.Equal(t, 4925.0, calculate.Discount(
|
||||
assert.Equal(t, uint64(4925), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 2000.0},
|
||||
{ID: "p2", Price: 3000.0},
|
||||
{ID: "p1", Price: 2000},
|
||||
{ID: "p2", Price: 3000},
|
||||
},
|
||||
[]models.Discount{
|
||||
{
|
||||
@ -36,10 +35,10 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
))
|
||||
assert.Equal(t, 4925.0, calculate.Discount(
|
||||
assert.Equal(t, uint64(4925), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 2000.0},
|
||||
{ID: "p2", Price: 3000.0},
|
||||
{ID: "p1", Price: 2000},
|
||||
{ID: "p2", Price: 3000},
|
||||
},
|
||||
[]models.Discount{
|
||||
{
|
||||
@ -52,11 +51,11 @@ func TestCalculate(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Наложение несколько скидок разного формата", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 5025.32, calculate.Discount(
|
||||
assert.Equal(t, uint64(5025), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 2000.0},
|
||||
{ID: "p2", Price: 3000.0},
|
||||
{ID: "p3", Price: 105.0},
|
||||
{ID: "p1", Price: 2000},
|
||||
{ID: "p2", Price: 3000},
|
||||
{ID: "p3", Price: 105},
|
||||
},
|
||||
[]models.Discount{
|
||||
{
|
||||
@ -71,16 +70,16 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.001)
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Наложение несколько скидок разного формата с несколькими таргетами", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 5223.89, calculate.Discount(
|
||||
assert.Equal(t, uint64(5223), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 2000.0},
|
||||
{ID: "p2", Price: 3000.0},
|
||||
{ID: "p3", Price: 105.0},
|
||||
{ID: "p4", Price: 210.0},
|
||||
{ID: "p1", Price: 2000},
|
||||
{ID: "p2", Price: 3000},
|
||||
{ID: "p3", Price: 105},
|
||||
{ID: "p4", Price: 210},
|
||||
},
|
||||
[]models.Discount{
|
||||
{
|
||||
@ -98,16 +97,16 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.001)
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Наложение несколько скидок с наличием скидки на лояльность", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 5171.66, calculate.Discount(
|
||||
assert.Equal(t, uint64(5171), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 2000.0},
|
||||
{ID: "p2", Price: 3000.0},
|
||||
{ID: "p3", Price: 105.0},
|
||||
{ID: "p4", Price: 210.0},
|
||||
{ID: "p1", Price: 2000},
|
||||
{ID: "p2", Price: 3000},
|
||||
{ID: "p3", Price: 105},
|
||||
{ID: "p4", Price: 210},
|
||||
},
|
||||
[]models.Discount{
|
||||
{
|
||||
@ -135,7 +134,7 @@ func TestCalculate(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Наложение несколько скидок на привелегии", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 422.28, calculate.Discount(
|
||||
assert.Equal(t, uint64(422), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p5", Price: 30},
|
||||
{ID: "p6", Price: 70},
|
||||
@ -164,11 +163,11 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.001)
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Наложение несколько скидок на привелегии без лояльности", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 426.55, calculate.Discount(
|
||||
assert.Equal(t, uint64(426), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p5", Price: 30},
|
||||
{ID: "p6", Price: 70},
|
||||
@ -185,11 +184,11 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.001)
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Вычисление скидки за привелегии и сервис", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 743.45, calculate.Discount(
|
||||
assert.Equal(t, uint64(743), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p5", Price: 30, Group: "dwarfener"},
|
||||
{ID: "p6", Price: 70, Group: "dwarfener"},
|
||||
@ -218,11 +217,11 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.001)
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Наложение скидок на несколько сервисов", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 2398.5, calculate.Discount(
|
||||
assert.Equal(t, uint64(2398), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 1500, Group: "templategen"},
|
||||
{ID: "p2", Price: 300, Group: "templategen"},
|
||||
@ -262,11 +261,11 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.01)
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Наложение скидок с промокодом", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 2368.68, calculate.Discount(
|
||||
assert.Equal(t, uint64(2368), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 1500, Group: "templategen"},
|
||||
{ID: "p2", Price: 300, Group: "templategen"},
|
||||
@ -287,6 +286,7 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p6", Factor: 0.5, Overhelm: true},
|
||||
@ -299,6 +299,8 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Factor: 0.99,
|
||||
Overhelm: true,
|
||||
@ -319,11 +321,11 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.01)
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("Наложение скидок по типу пользователя", func(t *testing.T) {
|
||||
assert.InEpsilon(t, 540, calculate.Discount(
|
||||
assert.Equal(t, uint64(540), discount.Calculate(
|
||||
[]core.Product{
|
||||
{ID: "p1", Price: 1500, Group: "templategen"},
|
||||
{ID: "p2", Price: 300, Group: "templategen"},
|
||||
@ -339,6 +341,6 @@ func TestCalculate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
), 0.01)
|
||||
))
|
||||
})
|
||||
}
|
147
internal/utils/discount/sort.go
Normal file
147
internal/utils/discount/sort.go
Normal file
@ -0,0 +1,147 @@
|
||||
package discount
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
)
|
||||
|
||||
func SortOverhelmingDiscounts(discounts []models.Discount) map[models.TargetScope][]models.DiscountCalculationTarget {
|
||||
dividedDiscounts := divideDiscountsByScope(discounts)
|
||||
|
||||
return map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: sortOverhelmingDiscountsEach(dividedDiscounts[models.TargetEach]),
|
||||
models.TargetGroup: sortOverhelmingDiscounts(dividedDiscounts[models.TargetGroup]),
|
||||
models.TargetSum: sortOverhelmingDiscounts(dividedDiscounts[models.TargetSum]),
|
||||
}
|
||||
}
|
||||
|
||||
func constituteOverhelmingProductTargetLayersMap(discounts []models.Discount) map[string]uint32 {
|
||||
overhelmingProductTargetLayers := make(map[string]uint32)
|
||||
|
||||
for _, discount := range discounts {
|
||||
for _, productTarget := range discount.Target.Products {
|
||||
if existingLayer, ok := overhelmingProductTargetLayers[productTarget.ID]; ok {
|
||||
if productTarget.Overhelm && existingLayer < discount.Layer {
|
||||
overhelmingProductTargetLayers[productTarget.ID] = discount.Layer
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if productTarget.Overhelm {
|
||||
overhelmingProductTargetLayers[productTarget.ID] = discount.Layer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return overhelmingProductTargetLayers
|
||||
}
|
||||
|
||||
func constituteOverhelmingDiscountLayer(discounts []models.Discount) uint32 {
|
||||
overhelmingDiscountLayer := uint32(0)
|
||||
|
||||
for _, discount := range discounts {
|
||||
if discount.Target.Overhelm && overhelmingDiscountLayer < discount.Layer {
|
||||
overhelmingDiscountLayer = discount.Layer
|
||||
}
|
||||
}
|
||||
|
||||
return overhelmingDiscountLayer
|
||||
}
|
||||
|
||||
func sortOverhelmingDiscountsEach(discounts []models.Discount) []models.DiscountCalculationTarget {
|
||||
if len(discounts) < 1 {
|
||||
return []models.DiscountCalculationTarget{}
|
||||
}
|
||||
|
||||
sortedDiscountCalculationTargetsEach := make([]models.DiscountCalculationTarget, 0, len(discounts))
|
||||
|
||||
overhelmingProductTargetLayers := constituteOverhelmingProductTargetLayersMap(discounts)
|
||||
overhelmingDiscountLayer := constituteOverhelmingDiscountLayer(discounts)
|
||||
|
||||
for _, discount := range discounts {
|
||||
if overhelmingDiscountLayer > discount.Layer {
|
||||
continue
|
||||
}
|
||||
|
||||
updatedProductTargets := make([]models.ProductTarget, 0, len(discount.Target.Products))
|
||||
|
||||
for _, productTarget := range discount.Target.Products {
|
||||
if overhelmingProductTarget, ok := overhelmingProductTargetLayers[productTarget.ID]; ok && overhelmingProductTarget > discount.Layer {
|
||||
continue
|
||||
}
|
||||
|
||||
updatedProductTargets = append(updatedProductTargets, models.ProductTarget{
|
||||
ID: productTarget.ID,
|
||||
Factor: productTarget.Factor,
|
||||
})
|
||||
}
|
||||
|
||||
sortedDiscountCalculationTargetsEach = append(sortedDiscountCalculationTargetsEach, models.DiscountCalculationTarget{
|
||||
Products: updatedProductTargets,
|
||||
Factor: discount.Target.Factor,
|
||||
TargetScope: discount.Target.TargetScope,
|
||||
TargetGroup: discount.Target.TargetGroup,
|
||||
})
|
||||
}
|
||||
|
||||
return sortedDiscountCalculationTargetsEach
|
||||
}
|
||||
|
||||
func sortOverhelmingDiscounts(discounts []models.Discount) []models.DiscountCalculationTarget {
|
||||
if len(discounts) < 1 {
|
||||
return []models.DiscountCalculationTarget{}
|
||||
}
|
||||
|
||||
sortedDiscountCalculationTargets := make([]models.DiscountCalculationTarget, 0, len(discounts))
|
||||
overhelmingDiscountLayer := constituteOverhelmingDiscountLayer(discounts)
|
||||
|
||||
for _, discount := range discounts {
|
||||
if overhelmingDiscountLayer > discount.Layer {
|
||||
continue
|
||||
}
|
||||
|
||||
sortedDiscountCalculationTargets = append(sortedDiscountCalculationTargets, models.DiscountCalculationTarget{
|
||||
Factor: discount.Target.Factor,
|
||||
TargetScope: discount.Target.TargetScope,
|
||||
TargetGroup: discount.Target.TargetGroup,
|
||||
})
|
||||
}
|
||||
|
||||
return sortedDiscountCalculationTargets
|
||||
}
|
||||
|
||||
func divideDiscountsByScope(discounts []models.Discount) map[models.TargetScope][]models.Discount {
|
||||
dividedTargets := make(map[models.TargetScope][]models.Discount, 3)
|
||||
|
||||
for _, discount := range discounts {
|
||||
if discount.Target.TargetScope == "" && len(discount.Target.Products) > 0 {
|
||||
dividedTargets[models.TargetEach] = append(dividedTargets[models.TargetEach], models.Discount{
|
||||
Layer: discount.Layer,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Products: discount.Target.Products,
|
||||
Factor: discount.Target.Factor,
|
||||
TargetScope: models.TargetEach,
|
||||
Overhelm: discount.Target.Overhelm,
|
||||
},
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if discount.Target.TargetScope == "" && len(discount.Target.Products) < 1 {
|
||||
dividedTargets[models.TargetSum] = append(dividedTargets[models.TargetSum], models.Discount{
|
||||
Layer: discount.Layer,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Factor: discount.Target.Factor,
|
||||
TargetScope: models.TargetSum,
|
||||
Overhelm: discount.Target.Overhelm,
|
||||
},
|
||||
})
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
dividedTargets[discount.Target.TargetScope] = append(dividedTargets[discount.Target.TargetScope], discount)
|
||||
}
|
||||
|
||||
return dividedTargets
|
||||
}
|
743
internal/utils/discount/sort_test.go
Normal file
743
internal/utils/discount/sort_test.go
Normal file
@ -0,0 +1,743 @@
|
||||
package discount_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/discount"
|
||||
)
|
||||
|
||||
func TestSortOverhelmingDiscounts(t *testing.T) {
|
||||
t.Run("Успешная сортировка скидок по каждому продукту при наличии перекрывающией скидки на каждый продукт и на определённый продукт", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p1", Factor: 0.93},
|
||||
{ID: "p2", Factor: 0.945},
|
||||
{ID: "p5", Factor: 0.97},
|
||||
{ID: "p7", Factor: 0.83},
|
||||
},
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.8,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p6", Factor: 0.5},
|
||||
},
|
||||
},
|
||||
},
|
||||
models.TargetGroup: {},
|
||||
models.TargetSum: {},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "1",
|
||||
Layer: 1,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Layer: 3,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p1", Factor: 0.93},
|
||||
{ID: "p2", Factor: 0.945},
|
||||
{ID: "p5", Factor: 0.97},
|
||||
{ID: "p6", Factor: 0.97},
|
||||
{ID: "p7", Factor: 0.83},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "4",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.8,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p6", Factor: 0.5, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по каждому продукту при наличии самой перекрывающей скидки", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
},
|
||||
models.TargetGroup: {},
|
||||
models.TargetSum: {},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "5",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "6",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "7",
|
||||
Layer: 3,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p1", Factor: 0.93},
|
||||
{ID: "p2", Factor: 0.945},
|
||||
{ID: "p5", Factor: 0.97},
|
||||
{ID: "p6", Factor: 0.97},
|
||||
{ID: "p7", Factor: 0.83},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "8",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.8,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p6", Factor: 0.5, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по каждому продукту при наличии скидок с одинаковым значением слоя", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91},
|
||||
},
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p1", Factor: 0.93},
|
||||
{ID: "p2", Factor: 0.945},
|
||||
{ID: "p5", Factor: 0.97},
|
||||
{ID: "p6", Factor: 0.97},
|
||||
{ID: "p7", Factor: 0.83},
|
||||
},
|
||||
},
|
||||
},
|
||||
models.TargetGroup: {},
|
||||
models.TargetSum: {},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "9",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "1",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p1", Factor: 0.93},
|
||||
{ID: "p2", Factor: 0.945},
|
||||
{ID: "p5", Factor: 0.97},
|
||||
{ID: "p6", Factor: 0.97},
|
||||
{ID: "p7", Factor: 0.83},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.8,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p6", Factor: 0.5, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по каждому продукту при наличии скидок с одинаковым значением слоя и полностью перекрывающими другие", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {
|
||||
{
|
||||
Factor: 0.92,
|
||||
TargetScope: models.TargetEach,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
{
|
||||
Factor: 0.92,
|
||||
TargetScope: models.TargetEach,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91},
|
||||
},
|
||||
},
|
||||
},
|
||||
models.TargetGroup: {},
|
||||
models.TargetSum: {},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "4",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "7",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "4",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.8,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.5, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по каждому продукту при наличии скидок, где одна полностью перекрывает продукты другой", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
{
|
||||
Factor: 0.92,
|
||||
TargetScope: models.TargetEach,
|
||||
Products: []models.ProductTarget{},
|
||||
},
|
||||
},
|
||||
models.TargetGroup: {},
|
||||
models.TargetSum: {},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "5",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "6",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.5, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по группе продуктов при наличии перекрывающих скидок", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {},
|
||||
models.TargetGroup: {
|
||||
{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
models.TargetSum: {},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "7",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Overhelm: true,
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "8",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.96,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "9",
|
||||
Layer: 3,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.91,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по группе продуктов при наличии перекрывающих скидок и разных групп", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {},
|
||||
models.TargetGroup: {
|
||||
{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
models.TargetSum: {},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "1",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Overhelm: true,
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.42,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Layer: 5,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Overhelm: true,
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "111",
|
||||
Factor: 0.9,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "4",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "111",
|
||||
Factor: 0.8,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по сумме при наличии скидки, перекрывающая все остальные", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {},
|
||||
models.TargetGroup: {},
|
||||
models.TargetSum: {
|
||||
{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "1",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Overhelm: true,
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.42,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Layer: 5,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Overhelm: true,
|
||||
Factor: 0.9,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "4",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.8,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка скидок по сумме при наличии перекрывающей скидки", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {},
|
||||
models.TargetGroup: {},
|
||||
models.TargetSum: {
|
||||
{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.92,
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.42,
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.9,
|
||||
},
|
||||
},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "1",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Overhelm: true,
|
||||
Factor: 0.42,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Layer: 5,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.9,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "4",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.8,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешная сортировка смешанных скидок при наличии перекрывающих", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
map[models.TargetScope][]models.DiscountCalculationTarget{
|
||||
models.TargetEach: {
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91},
|
||||
},
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p1", Factor: 0.93},
|
||||
{ID: "p2", Factor: 0.945},
|
||||
{ID: "p5", Factor: 0.97},
|
||||
{ID: "p6", Factor: 0.97},
|
||||
{ID: "p7", Factor: 0.83},
|
||||
},
|
||||
},
|
||||
},
|
||||
models.TargetGroup: {
|
||||
{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
models.TargetSum: {
|
||||
{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.92,
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.42,
|
||||
},
|
||||
{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.9,
|
||||
},
|
||||
},
|
||||
},
|
||||
discount.SortOverhelmingDiscounts([]models.Discount{
|
||||
{
|
||||
ID: "1",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Overhelm: true,
|
||||
Factor: 0.42,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Layer: 5,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.9,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "4",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetSum,
|
||||
Factor: 0.8,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "5",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Overhelm: true,
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.92,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "6",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "123",
|
||||
Factor: 0.42,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "7",
|
||||
Layer: 5,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
Overhelm: true,
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "111",
|
||||
Factor: 0.9,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "8",
|
||||
Layer: 2,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetGroup,
|
||||
TargetGroup: "111",
|
||||
Factor: 0.8,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "9",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p2", Factor: 0.94},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "10",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p7", Factor: 0.91, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "11",
|
||||
Layer: 6,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.92,
|
||||
Overhelm: true,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p1", Factor: 0.93},
|
||||
{ID: "p2", Factor: 0.945},
|
||||
{ID: "p5", Factor: 0.97},
|
||||
{ID: "p6", Factor: 0.97},
|
||||
{ID: "p7", Factor: 0.83},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "12",
|
||||
Layer: 4,
|
||||
Target: models.DiscountCalculationTarget{
|
||||
TargetScope: models.TargetEach,
|
||||
Factor: 0.8,
|
||||
Products: []models.ProductTarget{
|
||||
{ID: "p6", Factor: 0.5, Overhelm: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
@ -4,7 +4,6 @@ import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"golang.org/x/exp/constraints"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
)
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/expression"
|
||||
@ -52,7 +51,6 @@ func TestGetValueConditionBSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetPerionConditionBSON(t *testing.T) {
|
||||
|
||||
t.Run("Получение bson условия периода с заполненными данными", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
[]bson.M{
|
||||
|
@ -2,7 +2,6 @@ package discount
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/expression"
|
||||
@ -41,7 +40,7 @@ func ConstituteOptionalConditions(conditions *core.OptionalDiscounCondition) []b
|
||||
{"$or": expression.GetValueConditionBSON(fields.DiscountCondition.Product, defaults.GetDefaultValue(conditions.Product, ""))},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.Term, defaults.GetDefaultValue(conditions.Term, uint64(0)))},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.Usage, defaults.GetDefaultValue(conditions.Usage, uint64(0)))},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.PriceFrom, defaults.GetDefaultValue(conditions.PriceFrom, float64(0)))},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.PriceFrom, defaults.GetDefaultValue(conditions.PriceFrom, uint64(0)))},
|
||||
{"$or": expression.GetValueConditionBSON(fields.DiscountCondition.Group, defaults.GetDefaultValue(conditions.Group, ""))},
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
@ -15,11 +14,11 @@ import (
|
||||
)
|
||||
|
||||
func TestConstituteCommonConditions(t *testing.T) {
|
||||
userID := "user1"
|
||||
userType := "nkvo"
|
||||
coupon := "coupon"
|
||||
purchasesAmount := float64(10000)
|
||||
cartPurchasesAmount := float64(20000)
|
||||
userID := "user12"
|
||||
userType := "nkvo9"
|
||||
coupon := "coupon11"
|
||||
purchasesAmount := uint64(10000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
|
||||
t.Run("Формирование фильтра общих условий поиска с nil", func(t *testing.T) {
|
||||
assert.Equal(t, []bson.M{}, discount.ConstituteCommonConditions(nil))
|
||||
@ -96,11 +95,11 @@ func TestConstituteCommonConditions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConstituteOptionalConditions(t *testing.T) {
|
||||
productID := "product1"
|
||||
productID := "productgg1"
|
||||
term := uint64(14)
|
||||
usage := uint64(10)
|
||||
priceFrom := float64(13000)
|
||||
group := "group"
|
||||
priceFrom := uint64(13000)
|
||||
group := "group888"
|
||||
|
||||
t.Run("Формирование фильтра опциональных условий поиска и nil", func(t *testing.T) {
|
||||
assert.Equal(t, []bson.M{}, discount.ConstituteOptionalConditions(nil))
|
||||
@ -131,7 +130,7 @@ func TestConstituteOptionalConditions(t *testing.T) {
|
||||
{"$or": expression.GetValueConditionBSON(fields.DiscountCondition.Product, "")},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.Term, uint64(0))},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.Usage, uint64(0))},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.PriceFrom, float64(0))},
|
||||
{"$or": expression.GetAscRangeConditionBSON(fields.DiscountCondition.PriceFrom, uint64(0))},
|
||||
{"$or": expression.GetValueConditionBSON(fields.DiscountCondition.Group, "")},
|
||||
},
|
||||
discount.ConstituteOptionalConditions(&core.OptionalDiscounCondition{}),
|
||||
|
@ -2,7 +2,6 @@ package discount
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
)
|
||||
|
||||
@ -22,7 +21,8 @@ func ConditionFilter(conditions *core.DiscountConditions) *bson.M {
|
||||
}
|
||||
|
||||
for _, expression := range conditions.Optionals {
|
||||
optionalExpressions := ConstituteOptionalConditions(&expression)
|
||||
expressionCopy := expression
|
||||
optionalExpressions := ConstituteOptionalConditions(&expressionCopy)
|
||||
expressions = append(expressions, bson.M{
|
||||
"$and": append([]bson.M{}, append(commonExpressions, optionalExpressions...)...),
|
||||
})
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/expression/discount"
|
||||
@ -17,13 +16,13 @@ func TestConditionFilter(t *testing.T) {
|
||||
productID2 := "product2"
|
||||
term := uint64(14)
|
||||
usage := uint64(10)
|
||||
priceFrom := float64(13000)
|
||||
group := "group"
|
||||
priceFrom := uint64(13000)
|
||||
group := "groupopo"
|
||||
userID := "user1"
|
||||
userType := "nkvo"
|
||||
userType := "nkvo01001"
|
||||
coupon := "coupon"
|
||||
purchasesAmount := float64(10000)
|
||||
cartPurchasesAmount := float64(20000)
|
||||
purchasesAmount := uint64(10000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
|
||||
t.Run("Формирование фильтра условий поиска с пустыми условиями", func(t *testing.T) {
|
||||
assert.NotNil(t, discount.ConditionFilter(&core.DiscountConditions{}))
|
||||
|
@ -3,7 +3,6 @@ package discount
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/utils"
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
@ -16,22 +15,22 @@ import (
|
||||
|
||||
func TestGetDiscountExpression(t *testing.T) {
|
||||
id := "id1"
|
||||
name := "discount"
|
||||
name := "discount1oo"
|
||||
description := ""
|
||||
layer := uint32(3)
|
||||
deprecated := false
|
||||
user := "testUser"
|
||||
userType := "nkvo"
|
||||
coupon := "coupon1"
|
||||
product := "p1"
|
||||
priceFrom := float64(200)
|
||||
cartPurchasesAmount := float64(20000)
|
||||
purchasesAmount := float64(10000)
|
||||
user := "testUser3"
|
||||
userType := "nkvo090909"
|
||||
coupon := "coupon14"
|
||||
product := "p12"
|
||||
priceFrom := uint64(200)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
purchasesAmount := uint64(10000)
|
||||
usage := uint64(20)
|
||||
term := uint64(40)
|
||||
factor := 0.95
|
||||
targetScope := models.TargetSum
|
||||
targetGroup := "group"
|
||||
targetGroup := "groupffffff"
|
||||
overhelm := true
|
||||
condition := models.DiscountCondition{
|
||||
User: &user,
|
||||
|
@ -2,7 +2,6 @@ package discount
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/convert"
|
||||
)
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
@ -23,9 +22,9 @@ func TestGetUpdateDiscountExpression(t *testing.T) {
|
||||
userType := "nkvo"
|
||||
coupon := "coupon1"
|
||||
product := "p1"
|
||||
priceFrom := float64(200)
|
||||
cartPurchasesAmount := float64(20000)
|
||||
purchasesAmount := float64(10000)
|
||||
priceFrom := uint64(200)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
purchasesAmount := uint64(10000)
|
||||
usage := uint64(20)
|
||||
term := uint64(40)
|
||||
factor := 0.95
|
||||
|
@ -10,6 +10,7 @@ func FilterCouponDiscounts(discounts []models.Discount) ([]models.Discount, *mod
|
||||
}
|
||||
|
||||
var couponDiscount *models.Discount
|
||||
|
||||
notCouponDiscount := make([]models.Discount, 0, len(discounts))
|
||||
|
||||
for _, discount := range discounts {
|
||||
@ -19,6 +20,7 @@ func FilterCouponDiscounts(discounts []models.Discount) ([]models.Discount, *mod
|
||||
if isCouponDiscount && couponDiscount != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if isCouponDiscount && couponDiscount == nil {
|
||||
couponDiscount = ¤tDiscount
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils"
|
||||
)
|
||||
|
@ -2,7 +2,6 @@ package transfer
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
)
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/transfer"
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/transfer"
|
||||
@ -14,15 +13,15 @@ import (
|
||||
|
||||
func TestDiscountConditionProtoToModel(t *testing.T) {
|
||||
userID := "1"
|
||||
userType := "nkvo"
|
||||
coupon := "test"
|
||||
product := "product1"
|
||||
purchasesAmount := float64(20000)
|
||||
cartPurchasesAmount := float64(20000)
|
||||
userType := "nkvo11"
|
||||
coupon := "test22"
|
||||
product := "product13"
|
||||
purchasesAmount := uint64(20000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
term := uint64(20)
|
||||
usage := uint64(20)
|
||||
priceFrom := float64(20000)
|
||||
group := "testGroup"
|
||||
priceFrom := uint64(20000)
|
||||
group := "testGroupo"
|
||||
|
||||
t.Run("Перевод не до конца заполненных условий скидок с proto в модель", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
@ -86,12 +85,12 @@ func TestDiscountConditionModelToProto(t *testing.T) {
|
||||
userType := "nkvo"
|
||||
coupon := "test"
|
||||
product := "product1"
|
||||
purchasesAmount := float64(20000)
|
||||
cartPurchasesAmount := float64(20000)
|
||||
purchasesAmount := uint64(20000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
term := uint64(20)
|
||||
usage := uint64(20)
|
||||
priceFrom := float64(20000)
|
||||
group := "testGroup"
|
||||
priceFrom := uint64(20000)
|
||||
group := "testGroupbgfbgbgb"
|
||||
|
||||
t.Run("Перевод условий скидки с модели в proto", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
|
@ -6,15 +6,14 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/transfer"
|
||||
)
|
||||
|
||||
func TestDiscountsProtoToModel(t *testing.T) {
|
||||
cartPurchasesAmount := float64(20000)
|
||||
purchasesAmount := float64(20000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
purchasesAmount := uint64(20000)
|
||||
userID := string("13")
|
||||
userType := string("type")
|
||||
coupon := string("coupon1")
|
||||
@ -88,7 +87,7 @@ func TestDiscountsProtoToModel(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDiscountProtoToModel(t *testing.T) {
|
||||
cartPurchasesAmount := float64(20000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
deletedAtModel := time.Unix(1674546287, 0).UTC()
|
||||
deletedAtProto := timestamppb.Timestamp{Seconds: 1674546287}
|
||||
|
||||
@ -143,7 +142,7 @@ func TestDiscountProtoToModel(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDiscountsModelToProto(t *testing.T) {
|
||||
cartPurchasesAmount := float64(20000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
deletedAtModel := time.Unix(1674546287, 0).UTC()
|
||||
deletedAtProto := timestamppb.Timestamp{Seconds: 1674546287}
|
||||
|
||||
@ -200,7 +199,7 @@ func TestDiscountsModelToProto(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDiscountModelToProto(t *testing.T) {
|
||||
cartPurchasesAmount := float64(20000)
|
||||
cartPurchasesAmount := uint64(20000)
|
||||
|
||||
t.Run("Перевод скидки из модели в proto", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
|
@ -2,7 +2,6 @@ package transfer
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
proto "penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
)
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/transfer"
|
||||
|
@ -76,7 +76,7 @@ func ProductsProtoToCore(productInformations []*proto.ProductInformation) []core
|
||||
|
||||
products[index] = core.Product{
|
||||
ID: product.ID,
|
||||
Price: product.Price,
|
||||
Price: float64(product.Price),
|
||||
Group: receiveGroup(product),
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
|
@ -17,11 +17,11 @@ func TestContains(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "Проверка наличие строк по значению",
|
||||
inputArray: []any{"test1", "test2"},
|
||||
inputArray: []any{"test1245", "test2"},
|
||||
inputCallback: func(element any, index int, array []any) bool {
|
||||
assert.Equal(t, array, []any{"test1", "test2"})
|
||||
assert.Equal(t, array, []any{"test1245", "test2"})
|
||||
|
||||
return element == "test1"
|
||||
return element == "test1245"
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
@ -31,7 +31,7 @@ func TestContains(t *testing.T) {
|
||||
inputCallback: func(element any, index int, array []any) bool {
|
||||
assert.Equal(t, array, []any{"test1", "test2"})
|
||||
|
||||
return element == "tttt"
|
||||
return element == "fdadadfadfadf"
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
@ -108,16 +108,16 @@ func TestContains(t *testing.T) {
|
||||
{
|
||||
name: "Проверка наличие объектов по значению поля",
|
||||
inputArray: []struct{ Name string }{
|
||||
{Name: "test1"},
|
||||
{Name: "test19999"},
|
||||
{Name: "test2"},
|
||||
},
|
||||
inputCallback: func(element struct{ Name string }, index int, array []struct{ Name string }) bool {
|
||||
assert.Equal(t, array, []struct{ Name string }{
|
||||
{Name: "test1"},
|
||||
{Name: "test19999"},
|
||||
{Name: "test2"},
|
||||
})
|
||||
|
||||
return element.Name == "test1"
|
||||
return element.Name == "test19999"
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
|
@ -11,4 +11,3 @@ func Filter[T any](array []T, callback func(T, int, []T) bool) []T {
|
||||
|
||||
return filteredArray
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,13 @@ func TestFilter(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "Фильтрация массива строк по значению",
|
||||
inputArray: []any{"test1", "test2"},
|
||||
inputArray: []any{"test10130153", "test2"},
|
||||
inputCallback: func(element any, index int, array []any) bool {
|
||||
assert.Equal(t, array, []any{"test1", "test2"})
|
||||
assert.Equal(t, array, []any{"test10130153", "test2"})
|
||||
|
||||
return element == "test1"
|
||||
return element == "test10130153"
|
||||
},
|
||||
expect: []any{"test1"},
|
||||
expect: []any{"test10130153"},
|
||||
},
|
||||
{
|
||||
name: "Фильтрация массива строк по индексу",
|
||||
@ -84,19 +84,19 @@ func TestFilter(t *testing.T) {
|
||||
{
|
||||
name: "Фильтрация массива объектов по значению поля",
|
||||
inputArray: []struct{ Name string }{
|
||||
{Name: "test1"},
|
||||
{Name: "test5313131"},
|
||||
{Name: "test2"},
|
||||
},
|
||||
inputCallback: func(element struct{ Name string }, index int, array []struct{ Name string }) bool {
|
||||
assert.Equal(t, array, []struct{ Name string }{
|
||||
{Name: "test1"},
|
||||
{Name: "test5313131"},
|
||||
{Name: "test2"},
|
||||
})
|
||||
|
||||
return element.Name == "test1"
|
||||
return element.Name == "test5313131"
|
||||
},
|
||||
expect: []struct{ Name string }{
|
||||
{Name: "test1"},
|
||||
{Name: "test5313131"},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
11
pkg/array/find.go
Normal file
11
pkg/array/find.go
Normal file
@ -0,0 +1,11 @@
|
||||
package array
|
||||
|
||||
func Find[T any](array []T, callback func(T, int, []T) bool) *T {
|
||||
for index, element := range array {
|
||||
if callback(element, index, array) {
|
||||
return &element
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
32
pkg/array/find_test.go
Normal file
32
pkg/array/find_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
package array_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/array"
|
||||
)
|
||||
|
||||
func TestFind(t *testing.T) {
|
||||
t.Run("Find element in array (success)", func(t *testing.T) {
|
||||
result := "test1"
|
||||
callback := func(element string, index int, array []string) bool {
|
||||
assert.Equal(t, array, []string{"test1", "test2"})
|
||||
|
||||
return element == result
|
||||
}
|
||||
|
||||
assert.Equal(t, &result, array.Find([]string{"test1", "test2"}, callback))
|
||||
})
|
||||
|
||||
t.Run("Find element in array (failure)", func(t *testing.T) {
|
||||
result := "test"
|
||||
callback := func(element string, index int, array []string) bool {
|
||||
assert.Equal(t, array, []string{"test1", "test2"})
|
||||
|
||||
return element == result
|
||||
}
|
||||
|
||||
assert.Nil(t, array.Find([]string{"test1", "test2"}, callback))
|
||||
})
|
||||
}
|
50
pkg/closer/closer.go
Normal file
50
pkg/closer/closer.go
Normal file
@ -0,0 +1,50 @@
|
||||
package closer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Callback func(ctx context.Context) error
|
||||
|
||||
type Closer struct {
|
||||
mutex sync.Mutex
|
||||
callbacks []Callback
|
||||
}
|
||||
|
||||
func New() *Closer {
|
||||
return &Closer{}
|
||||
}
|
||||
|
||||
func (receiver *Closer) Add(callback Callback) {
|
||||
receiver.mutex.Lock()
|
||||
defer receiver.mutex.Unlock()
|
||||
|
||||
receiver.callbacks = append(receiver.callbacks, callback)
|
||||
}
|
||||
|
||||
func (receiver *Closer) Close(ctx context.Context) error {
|
||||
receiver.mutex.Lock()
|
||||
defer receiver.mutex.Unlock()
|
||||
|
||||
complete := make(chan struct{}, 1)
|
||||
|
||||
go func() {
|
||||
for index, callback := range receiver.callbacks {
|
||||
if err := callback(ctx); err != nil {
|
||||
log.Printf("[! (%d)] %v", index, err)
|
||||
}
|
||||
}
|
||||
|
||||
complete <- struct{}{}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-complete:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("shutdown cancelled: %v", ctx.Err())
|
||||
}
|
||||
}
|
74
pkg/convert/map_test.go
Normal file
74
pkg/convert/map_test.go
Normal file
@ -0,0 +1,74 @@
|
||||
package convert_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/convert"
|
||||
)
|
||||
|
||||
func TestArrayToMap(t *testing.T) {
|
||||
type Product struct {
|
||||
ID string
|
||||
Price float64
|
||||
Group string
|
||||
}
|
||||
|
||||
t.Run("Успешная конвертация массива в карту по ID", func(t *testing.T) {
|
||||
products := []Product{
|
||||
{ID: "p1", Price: 1500, Group: "templategen"},
|
||||
{ID: "p2", Price: 300, Group: "templategen"},
|
||||
{ID: "p5", Price: 30, Group: "dwarfener"},
|
||||
{ID: "p6", Price: 70, Group: "dwarfener"},
|
||||
{ID: "p7", Price: 800, Group: "dwarfener"},
|
||||
}
|
||||
|
||||
assert.Equal(t,
|
||||
map[string]Product{
|
||||
"p1": {ID: "p1", Price: 1500, Group: "templategen"},
|
||||
"p2": {ID: "p2", Price: 300, Group: "templategen"},
|
||||
"p5": {ID: "p5", Price: 30, Group: "dwarfener"},
|
||||
"p6": {ID: "p6", Price: 70, Group: "dwarfener"},
|
||||
"p7": {ID: "p7", Price: 800, Group: "dwarfener"},
|
||||
},
|
||||
convert.ArrayToMap(products, func(product Product) string {
|
||||
return product.ID
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMapToMapArray(t *testing.T) {
|
||||
type Product struct {
|
||||
ID string
|
||||
Price float64
|
||||
Group string
|
||||
}
|
||||
|
||||
t.Run("Успешная конвертация массива в карту из массивов", func(t *testing.T) {
|
||||
productsMap := map[string]Product{
|
||||
"p1": {ID: "p1", Price: 1500, Group: "templategen"},
|
||||
"p2": {ID: "p2", Price: 300, Group: "templategen"},
|
||||
"p5": {ID: "p5", Price: 30, Group: "dwarfener"},
|
||||
"p6": {ID: "p6", Price: 70, Group: "dwarfener"},
|
||||
"p7": {ID: "p7", Price: 800, Group: "dwarfener"},
|
||||
}
|
||||
|
||||
assert.EqualValues(t,
|
||||
map[string][]Product{
|
||||
"templategen": {
|
||||
{ID: "p1", Price: 1500, Group: "templategen"},
|
||||
{ID: "p2", Price: 300, Group: "templategen"},
|
||||
},
|
||||
"dwarfener": {
|
||||
{ID: "p5", Price: 30, Group: "dwarfener"},
|
||||
{ID: "p6", Price: 70, Group: "dwarfener"},
|
||||
{ID: "p7", Price: 800, Group: "dwarfener"},
|
||||
},
|
||||
},
|
||||
convert.MapToMapArray(productsMap, func(product Product) string {
|
||||
return product.Group
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
@ -50,10 +50,8 @@ func ObjectToStringMap(object interface{}, tagName string) (map[string]string, e
|
||||
mapString := make(map[string]string, len(mapObject))
|
||||
|
||||
for key, value := range mapObject {
|
||||
strKey := fmt.Sprintf("%v", key)
|
||||
strValue := fmt.Sprintf("%v", value)
|
||||
|
||||
mapString[strKey] = strValue
|
||||
mapString[key] = strValue
|
||||
}
|
||||
|
||||
return mapString, nil
|
||||
|
11
pkg/convert/uint.go
Normal file
11
pkg/convert/uint.go
Normal file
@ -0,0 +1,11 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
func FloatToUint64[T constraints.Float](number T) uint64 {
|
||||
return uint64(math.Floor(float64(number)))
|
||||
}
|
22
pkg/convert/uint_test.go
Normal file
22
pkg/convert/uint_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package convert_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/convert"
|
||||
)
|
||||
|
||||
func TestFloatToUint64(t *testing.T) {
|
||||
t.Run("Успешная конвертация float32 в uint32", func(t *testing.T) {
|
||||
assert.Equal(t, uint64(10), convert.FloatToUint64(float32(10.6)))
|
||||
})
|
||||
|
||||
t.Run("Успешная конвертация float64 в uint32", func(t *testing.T) {
|
||||
assert.Equal(t, uint64(10), convert.FloatToUint64(float64(10.6)))
|
||||
})
|
||||
|
||||
t.Run("Успешная конвертация float64 в uint32 (2)", func(t *testing.T) {
|
||||
assert.Equal(t, uint64(10), convert.FloatToUint64(float64(10)))
|
||||
})
|
||||
}
|
@ -8,7 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func TestGetDefaultValue(t *testing.T) {
|
||||
|
||||
t.Run("Стандартное значение nil", func(t *testing.T) {
|
||||
assert.Equal(t, 0, defaults.GetDefaultValue(nil, 0))
|
||||
})
|
||||
|
2
pkg/env/parse.go
vendored
2
pkg/env/parse.go
vendored
@ -9,7 +9,7 @@ import (
|
||||
envParser "github.com/sethvargo/go-envconfig"
|
||||
)
|
||||
|
||||
// Parsing default env file or env context and returns struct pointer by generic
|
||||
// Parse parsing default env file or env context and returns struct pointer by generic.
|
||||
func Parse[T interface{}](envFilePath string) (*T, error) {
|
||||
var configuration T
|
||||
|
||||
|
@ -65,7 +65,9 @@ func Connect(ctx context.Context, deps *ConnectDeps) (*mongo.Database, error) {
|
||||
|
||||
log.Printf("failed to connect to db <%s>: %s", mongoURI.String(), err.Error())
|
||||
case <-timeoutExceeded:
|
||||
return nil, fmt.Errorf("db connection <%s> failed after %d timeout", mongoURI, deps.Timeout)
|
||||
return nil, fmt.Errorf("db connection <%s> failed after %d timeout", mongoURI.String(), deps.Timeout)
|
||||
default:
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,9 @@ package mongo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
)
|
||||
|
||||
|
||||
|
||||
func Find[T any](ctx context.Context, settings *RequestSettings) ([]T, error) {
|
||||
if settings == nil {
|
||||
return []T{}, ErrEmptyArgs
|
||||
@ -13,12 +12,16 @@ func Find[T any](ctx context.Context, settings *RequestSettings) ([]T, error) {
|
||||
|
||||
results := make([]T, 0)
|
||||
|
||||
cursor, err := settings.Driver.Find(ctx, settings.Filter)
|
||||
cursor, err := settings.Driver.Find(ctx, settings.Filter, settings.Options)
|
||||
if err != nil {
|
||||
return []T{}, err
|
||||
}
|
||||
|
||||
defer cursor.Close(ctx)
|
||||
defer func() {
|
||||
if err := cursor.Close(ctx); err != nil {
|
||||
log.Printf("failed to close cursor: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
for cursor.Next(ctx) {
|
||||
result := new(T)
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/utils"
|
||||
)
|
||||
|
||||
|
@ -46,12 +46,12 @@ message DiscountCondition {
|
||||
optional string User = 2;
|
||||
optional string UserType = 3;
|
||||
optional string Coupon = 4;
|
||||
optional double PurchasesAmount = 5;
|
||||
optional double CartPurchasesAmount = 6;
|
||||
optional uint64 PurchasesAmount = 5;
|
||||
optional uint64 CartPurchasesAmount = 6;
|
||||
optional string Product = 7;
|
||||
optional uint64 Term = 8;
|
||||
optional uint64 Usage = 9;
|
||||
optional double PriceFrom = 10;
|
||||
optional uint64 PriceFrom = 10;
|
||||
optional string Group = 11;
|
||||
}
|
||||
|
||||
@ -69,13 +69,13 @@ message PeriodCondition {
|
||||
message UserInformation {
|
||||
string ID = 1;
|
||||
string Type = 2;
|
||||
double PurchasesAmount = 3;
|
||||
double CartPurchasesAmount = 4;
|
||||
uint64 PurchasesAmount = 3;
|
||||
uint64 CartPurchasesAmount = 4;
|
||||
}
|
||||
|
||||
message ProductInformation {
|
||||
string ID = 1;
|
||||
double Price = 2;
|
||||
uint64 Price = 2;
|
||||
optional uint64 Term = 3;
|
||||
optional uint64 Usage = 4;
|
||||
optional string Group = 5;
|
||||
|
@ -82,7 +82,7 @@ message ApplyDiscountRequest {
|
||||
}
|
||||
|
||||
message ApplyDiscountResponse {
|
||||
double Price = 1;
|
||||
uint64 Price = 1;
|
||||
repeated Discount AppliedDiscounts = 2;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
//go:build integration
|
||||
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
@ -9,11 +7,10 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/env"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/parse"
|
||||
)
|
||||
|
||||
func TestCreateDiscount(t *testing.T) {
|
||||
@ -24,7 +21,7 @@ func TestCreateDiscount(t *testing.T) {
|
||||
|
||||
discountClientConnection, err := grpc.Dial(
|
||||
fmt.Sprintf("%s:%s", config.GRPC.Host, config.GRPC.Port),
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
|
||||
assert.NoError(t, err)
|
||||
@ -32,7 +29,7 @@ func TestCreateDiscount(t *testing.T) {
|
||||
discountClient := discount.NewDiscountServiceClient(discountClientConnection)
|
||||
|
||||
t.Run("Создание скидки", func(t *testing.T) {
|
||||
productID := "p1"
|
||||
productID := "p1000"
|
||||
term := uint64(40)
|
||||
|
||||
createdDiscount, err := discountClient.CreateDiscount(
|
||||
@ -63,7 +60,24 @@ func TestCreateDiscount(t *testing.T) {
|
||||
isNotNil := assert.NotNil(t, findedDiscount)
|
||||
|
||||
if isNoError && isNotNil {
|
||||
assert.Equal(t, parse.Discount(createdDiscount), parse.Discount(findedDiscount))
|
||||
assert.Equal(t,
|
||||
discount.Discount{
|
||||
ID: createdDiscount.ID,
|
||||
Name: createdDiscount.Name,
|
||||
Layer: createdDiscount.Layer,
|
||||
Description: createdDiscount.Description,
|
||||
Condition: createdDiscount.Condition,
|
||||
Deprecated: createdDiscount.Deprecated,
|
||||
},
|
||||
discount.Discount{
|
||||
ID: findedDiscount.ID,
|
||||
Name: findedDiscount.Name,
|
||||
Layer: findedDiscount.Layer,
|
||||
Description: findedDiscount.Description,
|
||||
Condition: findedDiscount.Condition,
|
||||
Deprecated: findedDiscount.Deprecated,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
@ -1,5 +1,3 @@
|
||||
//go:build integration
|
||||
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
@ -9,11 +7,10 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/env"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/parse"
|
||||
)
|
||||
|
||||
func TestDeleteDiscount(t *testing.T) {
|
||||
@ -24,7 +21,7 @@ func TestDeleteDiscount(t *testing.T) {
|
||||
|
||||
discountClientConnection, err := grpc.Dial(
|
||||
fmt.Sprintf("%s:%s", config.GRPC.Host, config.GRPC.Port),
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
|
||||
assert.NoError(t, err)
|
||||
@ -63,7 +60,24 @@ func TestDeleteDiscount(t *testing.T) {
|
||||
isNotNil := assert.NotNil(t, deletedDiscount)
|
||||
|
||||
if isNoError && isNotNil {
|
||||
assert.Equal(t, parse.Discount(createdDiscount), parse.Discount(deletedDiscount))
|
||||
assert.Equal(t,
|
||||
discount.Discount{
|
||||
ID: createdDiscount.ID,
|
||||
Name: createdDiscount.Name,
|
||||
Layer: createdDiscount.Layer,
|
||||
Description: createdDiscount.Description,
|
||||
Condition: createdDiscount.Condition,
|
||||
Deprecated: createdDiscount.Deprecated,
|
||||
},
|
||||
discount.Discount{
|
||||
ID: deletedDiscount.ID,
|
||||
Name: deletedDiscount.Name,
|
||||
Layer: deletedDiscount.Layer,
|
||||
Description: deletedDiscount.Description,
|
||||
Condition: deletedDiscount.Condition,
|
||||
Deprecated: deletedDiscount.Deprecated,
|
||||
},
|
||||
)
|
||||
|
||||
findedDiscount, err := discountClient.GetDiscountByID(context.Background(), &discount.GetDiscountByIDRequest{
|
||||
ID: createdDiscount.ID,
|
@ -1,5 +1,3 @@
|
||||
//go:build integration
|
||||
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
@ -9,7 +7,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/env"
|
||||
@ -32,7 +30,7 @@ func TestApplyDiscount(t *testing.T) {
|
||||
|
||||
discountClientConnection, err := grpc.Dial(
|
||||
fmt.Sprintf("%s:%s", config.GRPC.Host, config.GRPC.Port),
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
|
||||
assert.NoError(t, err)
|
||||
@ -69,7 +67,7 @@ func TestApplyDiscount(t *testing.T) {
|
||||
utils.CleanDiscountsIDs(response.AppliedDiscounts)
|
||||
|
||||
assert.Equal(t, []*discount.Discount{data.DiscountID4}, response.AppliedDiscounts)
|
||||
assert.InEpsilon(t, 4925.0, response.Price, 0.001)
|
||||
assert.Equal(t, uint64(4925), response.Price)
|
||||
}
|
||||
})
|
||||
|
||||
@ -110,7 +108,7 @@ func TestApplyDiscount(t *testing.T) {
|
||||
utils.CleanDiscountsIDs(response.AppliedDiscounts)
|
||||
|
||||
assert.Equal(t, []*discount.Discount{data.DiscountID4, data.DiscountID22}, response.AppliedDiscounts)
|
||||
assert.InEpsilon(t, 5025.32, response.Price, 0.001)
|
||||
assert.Equal(t, uint64(5025), response.Price)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ var (
|
||||
varFalse = false
|
||||
varTrue = true
|
||||
|
||||
cartPurchasesAmounts = []float64{5000, 50000}
|
||||
purchasesAmounts = []float64{10000, 25000, 50000}
|
||||
priceFroms = []float64{1000, 5000, 2000, 6000, 500, 2500}
|
||||
cartPurchasesAmounts = []uint64{5000, 50000}
|
||||
purchasesAmounts = []uint64{10000, 25000, 50000}
|
||||
priceFroms = []uint64{1000, 5000, 2000, 6000, 500, 2500}
|
||||
|
||||
terms = []uint64{30, 90, 180}
|
||||
usages = []uint64{100, 350, 500}
|
||||
|
@ -1,5 +1,3 @@
|
||||
//go:build integration
|
||||
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
@ -9,13 +7,12 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/env"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/data"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/parse"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/utils"
|
||||
)
|
||||
|
||||
@ -27,7 +24,7 @@ func TestGetAllDiscounts(t *testing.T) {
|
||||
|
||||
discountClientConnection, err := grpc.Dial(
|
||||
fmt.Sprintf("%s:%s", config.GRPC.Host, config.GRPC.Port),
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
|
||||
assert.NoError(t, err)
|
||||
@ -42,7 +39,7 @@ func TestGetAllDiscounts(t *testing.T) {
|
||||
|
||||
if isNotNil && isNoError {
|
||||
utils.CleanDiscountsIDs(response.Discounts)
|
||||
assert.Equal(t, data.Discounts, parse.Discounts(response))
|
||||
assert.Equal(t, data.Discounts, response)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
//go:build integration
|
||||
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
@ -9,12 +7,11 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/env"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/data"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/parse"
|
||||
)
|
||||
|
||||
func TestGetDiscountByID(t *testing.T) {
|
||||
@ -25,7 +22,7 @@ func TestGetDiscountByID(t *testing.T) {
|
||||
|
||||
discountClientConnection, err := grpc.Dial(
|
||||
fmt.Sprintf("%s:%s", config.GRPC.Host, config.GRPC.Port),
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
|
||||
assert.NoError(t, err)
|
||||
@ -41,7 +38,24 @@ func TestGetDiscountByID(t *testing.T) {
|
||||
isNotNil := assert.NotNil(t, findedDiscount)
|
||||
|
||||
if isNoError && isNotNil {
|
||||
assert.Equal(t, data.DiscountID22, parse.Discount(findedDiscount))
|
||||
assert.Equal(t,
|
||||
discount.Discount{
|
||||
ID: data.DiscountID22.ID,
|
||||
Name: data.DiscountID22.Name,
|
||||
Layer: data.DiscountID22.Layer,
|
||||
Description: data.DiscountID22.Description,
|
||||
Condition: data.DiscountID22.Condition,
|
||||
Deprecated: data.DiscountID22.Deprecated,
|
||||
},
|
||||
discount.Discount{
|
||||
ID: findedDiscount.ID,
|
||||
Name: findedDiscount.Name,
|
||||
Layer: findedDiscount.Layer,
|
||||
Description: findedDiscount.Description,
|
||||
Condition: findedDiscount.Condition,
|
||||
Deprecated: findedDiscount.Deprecated,
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
//go:build integration
|
||||
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
@ -9,12 +7,11 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/env"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/data"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/parse"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/tests/integration/utils"
|
||||
)
|
||||
|
||||
@ -26,7 +23,7 @@ func TestGetUserDiscounts(t *testing.T) {
|
||||
|
||||
discountClientConnection, err := grpc.Dial(
|
||||
fmt.Sprintf("%s:%s", config.GRPC.Host, config.GRPC.Port),
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
|
||||
assert.NoError(t, err)
|
||||
@ -43,7 +40,7 @@ func TestGetUserDiscounts(t *testing.T) {
|
||||
|
||||
if isNotNil && isNoError {
|
||||
utils.CleanDiscountsIDs(response.Discounts)
|
||||
assert.Equal(t, data.User1Discounts, parse.Discounts(response))
|
||||
assert.Equal(t, data.User1Discounts, response)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
package parse
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/proto/discount"
|
||||
)
|
||||
|
||||
func Discount(discountToParse *discount.Discount) *discount.Discount {
|
||||
return &discount.Discount{
|
||||
ID: discountToParse.GetID(),
|
||||
Name: discountToParse.GetName(),
|
||||
Layer: discountToParse.GetLayer(),
|
||||
Description: discountToParse.GetDescription(),
|
||||
Condition: discountToParse.GetCondition(),
|
||||
Target: discountToParse.GetTarget(),
|
||||
Audit: discountToParse.GetAudit(),
|
||||
Deprecated: discountToParse.GetDeprecated(),
|
||||
}
|
||||
}
|
||||
|
||||
func Discounts(discountsToParse *discount.Discounts) []*discount.Discount {
|
||||
parsedDiscounts := make([]*discount.Discount, len(discountsToParse.Discounts))
|
||||
|
||||
for index, discountToParse := range discountsToParse.Discounts {
|
||||
parsedDiscounts[index] = Discount(discountToParse)
|
||||
}
|
||||
|
||||
return parsedDiscounts
|
||||
}
|
Loading…
Reference in New Issue
Block a user