generated from PenaSide/GolangTemplate
Merge branch 'apirework' into 'staging'
Apirework See merge request pena-services/customer!50
This commit is contained in:
commit
8afc8440ef
4
Makefile
4
Makefile
@ -14,8 +14,8 @@ install: ## install all go dependencies
|
||||
|
||||
generate: ## generate grpc proto for golang
|
||||
buf generate
|
||||
oapi-codegen --config ./api/openapi/v1/api.yaml ./api/openapi/v1/openapi.yaml
|
||||
oapi-codegen --config ./api/openapi/v1/models.yaml ./api/openapi/v1/openapi.yaml
|
||||
# oapi-codegen --config ./api/openapi/v1/api.yaml ./api/openapi/v1/openapi.yaml
|
||||
# oapi-codegen --config ./api/openapi/v1/models.yaml ./api/openapi/v1/openapi.yaml
|
||||
|
||||
test: ## run all layers tests
|
||||
@make test.unit
|
||||
|
@ -4,21 +4,21 @@ JWT_AUDIENCE="pena"
|
||||
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69\n80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B\ndA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y\n+3GyaOY536H47qyXAgMBAAE=\n-----END PUBLIC KEY-----"
|
||||
|
||||
HTTP_HOST=0.0.0.0
|
||||
HTTP_PORT=8003
|
||||
HTTP_PORT=8082
|
||||
|
||||
GRPC_HOST=0.0.0.0
|
||||
GRPC_PORT=9000
|
||||
GRPC_DOMEN=customer-service:9000
|
||||
|
||||
MONGO_HOST=localhost
|
||||
MONGO_PORT=27024
|
||||
MONGO_PORT=27020
|
||||
MONGO_USER=test
|
||||
MONGO_PASSWORD=test
|
||||
MONGO_DB_NAME=admin
|
||||
MONGO_AUTH=admin
|
||||
|
||||
KAFKA_BROKERS=localhost:9092
|
||||
KAFKA_TOPIC_TARIFF=tariffs
|
||||
KAFKA_TOPIC_TARIFF=test-topic
|
||||
|
||||
AUTH_MICROSERVICE_USER_URL=http://localhost:8000/user
|
||||
HUBADMIN_MICROSERVICE_TARIFF_URL=http://localhost:8001/tariff
|
||||
@ -27,9 +27,11 @@ DISCOUNT_MICROSERVICE_GRPC_HOST=localhost:9040
|
||||
PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085
|
||||
VERIFICATION_MICROSERVICE_USER_URL=http://10.8.0.8:7035/verification
|
||||
TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
|
||||
CODEWORD_MICROSERVICE_GRPC_HOST = http://localhost:8000/user
|
||||
|
||||
API_URL=https://api.smtp.bz/v1/smtp/send
|
||||
MAIL_SENDER=noreply@mailing.pena.digital
|
||||
MAIL_API_KEY=P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev
|
||||
MAIL_AUTH_USERNAME=kotilion.95@gmail.com
|
||||
MAIL_AUTH_PASSWORD=vWwbCSg4bf0p
|
||||
MAIL_AUTH_PASSWORD=vWwbCSg4bf0p
|
||||
MAIL_ADDRESS = mail@mail.com
|
@ -1,9 +1,9 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
customer-app-staging:
|
||||
hostname: customer-service-staging
|
||||
container_name: customer-service-staging
|
||||
customer-app-stagingv1.0.0:
|
||||
hostname: customer-service-stagingv1.0.0
|
||||
container_name: customer-service-stagingv1.0.0
|
||||
image: $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||
tty: true
|
||||
environment:
|
||||
@ -45,7 +45,7 @@ services:
|
||||
- PUBLIC_KEY=$USER_PKEY
|
||||
- PRIVATE_KEY=$USER_PRIVATEKEY
|
||||
ports:
|
||||
- 10.8.0.6:8065:8065
|
||||
- 10.8.0.6:9065:9065
|
||||
- 10.8.0.6:8066:8065
|
||||
- 10.8.0.6:9066:9065
|
||||
networks:
|
||||
- default
|
||||
|
25
go.mod
25
go.mod
@ -3,15 +3,12 @@ module penahub.gitlab.yandexcloud.net/pena-services/customer
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
github.com/deepmap/oapi-codegen v1.16.2
|
||||
github.com/getkin/kin-openapi v0.123.0
|
||||
github.com/go-resty/resty/v2 v2.11.0
|
||||
github.com/gofiber/fiber/v2 v2.52.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/labstack/echo/v4 v4.11.4
|
||||
github.com/oapi-codegen/runtime v1.1.1
|
||||
github.com/pioz/faker v1.7.3
|
||||
github.com/sethvargo/go-envconfig v1.0.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
@ -21,36 +18,28 @@ require (
|
||||
go.uber.org/zap v1.27.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240221002015-b0ce06bbee7c
|
||||
google.golang.org/grpc v1.62.0
|
||||
google.golang.org/protobuf v1.32.0
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240220080149-ae9c991d3ece
|
||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240412164014-6ce70d76fedc
|
||||
google.golang.org/protobuf v1.33.0
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6
|
||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240520145524-451212248881
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.9 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/tealeg/xlsx v1.0.5 // indirect
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.7.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
@ -62,13 +51,13 @@ require (
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/crypto v0.20.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
57
go.sum
57
go.sum
@ -1,43 +1,28 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
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/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/deepmap/oapi-codegen v1.16.2 h1:xGHx0dNqYfy9gE8a7AVgVM8Sd5oF9SEgePzP+UPAUXI=
|
||||
github.com/deepmap/oapi-codegen v1.16.2/go.mod h1:rdYoEA2GE+riuZ91DvpmBX9hJbQpuY9wchXpfQ3n+ho=
|
||||
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/getkin/kin-openapi v0.123.0 h1:zIik0mRwFNLyvtXK274Q6ut+dPh6nlxBp0x7mNrPhs8=
|
||||
github.com/getkin/kin-openapi v0.123.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
|
||||
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
|
||||
github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE=
|
||||
github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE=
|
||||
github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
|
||||
github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gofiber/fiber/v2 v2.52.1 h1:1RoU2NS+b98o1L77sdl5mboGPiW+0Ypsi5oLmcYlgHI=
|
||||
github.com/gofiber/fiber/v2 v2.52.1/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@ -56,23 +41,17 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
|
||||
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
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.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
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=
|
||||
@ -83,8 +62,6 @@ github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zG
|
||||
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@ -92,21 +69,14 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
|
||||
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
|
||||
github.com/oapi-codegen/testutil v1.0.0 h1:1GI2IiMMLh2vDHr1OkNacaYU/VaApKdcmfgl4aeXAa8=
|
||||
github.com/oapi-codegen/testutil v1.0.0/go.mod h1:ttCaYbHvJtHuiyeBF0tPIX+4uhEPTeizXKx28okijLw=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
|
||||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pioz/faker v1.7.3 h1:Tez8Emuq0UN+/d6mo3a9m/9ZZ/zdfJk0c5RtRatrceM=
|
||||
github.com/pioz/faker v1.7.3/go.mod h1:xSpay5w/oz1a6+ww0M3vfpe40pSIykeUPeWEc3TvVlc=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@ -114,12 +84,12 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/sethvargo/go-envconfig v1.0.0 h1:1C66wzy4QrROf5ew4KdVw942CQDa55qmlYmw9FZxZdU=
|
||||
github.com/sethvargo/go-envconfig v1.0.0/go.mod h1:Lzc75ghUn5ucmcRGIdGQ33DKJrcjk4kihFYgSTBmjIc=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@ -137,8 +107,6 @@ github.com/twmb/franz-go/pkg/kadm v1.11.0 h1:FfeWJ0qadntFpAcQt8JzNXW4dijjytZNLrz
|
||||
github.com/twmb/franz-go/pkg/kadm v1.11.0/go.mod h1:qrhkdH+SWS3ivmbqOgHbpgVHamhaKcjH0UM+uOp0M1A=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.7.0 h1:a457IbvezYfA5UkiBvyV3zj0Is3y1i8EJgqjJYoij2E=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.7.0/go.mod h1:se9Mjdt0Nwzc9lnjJ0HyDtLyBnaBDAd7pCje47OhSyw=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
|
||||
@ -176,8 +144,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
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=
|
||||
@ -281,8 +249,8 @@ google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
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.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -292,12 +260,11 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/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=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240220080149-ae9c991d3ece h1:CsjgNNqssfa05B7iDNMyK2wWR7SZ/kglLTMAVrhGLtY=
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240220080149-ae9c991d3ece/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM=
|
||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240412164014-6ce70d76fedc h1:B9X8pOrqWPGbWZNXSJEUk/8GWeBDGQmMKgQ0F+PSliQ=
|
||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240412164014-6ce70d76fedc/go.mod h1:/DcyAjBh41IbomuDu5QzhL9flZW6lWO3ZAEbUXKobk0=
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6 h1:oV+/HNX+JPoQ3/GUx08hio7d45WpY0AMGrFs7j70QlA=
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM=
|
||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240520145524-451212248881 h1:U1/WGQdwZsmrV/ta7Uqm13Dg07IPN/5omS8gzBJYZv4=
|
||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240520145524-451212248881/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64=
|
||||
|
@ -6,19 +6,18 @@ import (
|
||||
"fmt"
|
||||
"os/signal"
|
||||
"penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.uber.org/zap"
|
||||
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/server"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/closer"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/kafka"
|
||||
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -82,6 +81,7 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
VerificationURL: &config.Service.VerificationMicroservice.URL,
|
||||
TemplategenURL: &config.Service.TemplategenMicroserviceURL.URL,
|
||||
MailClient: &config.Service.Mail,
|
||||
CodewordServiceHost: &config.Service.CodewordMicroservice,
|
||||
})
|
||||
|
||||
repositories := initialize.NewRepositories(initialize.RepositoriesDeps{
|
||||
@ -97,42 +97,50 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
Brokers: brokers,
|
||||
})
|
||||
|
||||
controllers := initialize.NewControllers(initialize.ControllersDeps{
|
||||
rpcControllers := initialize.NewRpcControllers(initialize.RpcControllersDeps{
|
||||
Logger: logger,
|
||||
Services: services,
|
||||
})
|
||||
|
||||
openapi, err := swagger.GetSwagger()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to loading openapi spec: %w", err)
|
||||
}
|
||||
|
||||
encrypt := qutils.NewEncrypt(config.Service.PubKey, config.Service.PrivKey)
|
||||
middleWare := http.NewMiddleWare(logger)
|
||||
|
||||
api := swagger.NewAPI2(logger, mongoDB, config, brokers.TariffConsumer, brokers.TariffProducer, encrypt)
|
||||
|
||||
serverHTTP, httpErr := server.NewHTTP(server.DepsHTTP{
|
||||
Logger: logger,
|
||||
Swagger: openapi,
|
||||
AuthenticationFunc: utils.NewAuthenticator(utils.NewJWT(&config.Service.JWT)),
|
||||
httpControllers := initialize.NewHttpControllers(initialize.HttpControllersDeps{
|
||||
Logger: logger,
|
||||
Encrypt: encrypt,
|
||||
Producer: brokers.TariffProducer,
|
||||
GRPC: &config.GRPC,
|
||||
Repositories: repositories,
|
||||
Clients: clients,
|
||||
MiddleWare: middleWare,
|
||||
})
|
||||
if httpErr != nil {
|
||||
return httpErr.Wrap("failed to init http server")
|
||||
}
|
||||
|
||||
serverHTTP := server.NewServer(server.ServerConfig{
|
||||
Logger: logger,
|
||||
Controllers: []server.Controller{httpControllers.CurrencyController, httpControllers.HistoryController, httpControllers.CartController, httpControllers.WalletController, httpControllers.AccountController},
|
||||
JWTConfig: &config.Service.JWT,
|
||||
})
|
||||
|
||||
serverHTTP.ListRoutes()
|
||||
|
||||
serverGRPC, grpcErr := server.NewGRPC(server.DepsGRPC{Logger: logger})
|
||||
if grpcErr != nil {
|
||||
return httpErr.Wrap("failed to init grpc server")
|
||||
return grpcErr.Wrap("failed to init grpc server")
|
||||
}
|
||||
|
||||
serverHTTP.Register(&api)
|
||||
serverGRPC.Register(controllers)
|
||||
serverGRPC.Register(rpcControllers)
|
||||
|
||||
go func() {
|
||||
if err := serverHTTP.Start(config.HTTP.Host + ":" + config.HTTP.Port); err != nil {
|
||||
logger.Error("Server startup error", zap.Error(err))
|
||||
cancel()
|
||||
}
|
||||
}()
|
||||
|
||||
go serverHTTP.Run(&config.HTTP)
|
||||
go serverGRPC.Run(&config.GRPC)
|
||||
|
||||
closer.Add(mongoDB.Client().Disconnect)
|
||||
closer.Add(serverHTTP.Stop)
|
||||
closer.Add(serverHTTP.Shutdown)
|
||||
closer.Add(serverGRPC.Stop)
|
||||
closer.Add(closer.Wrap(kafkaTariffClient.Close))
|
||||
|
||||
|
@ -17,6 +17,7 @@ type ClientsDeps struct {
|
||||
VerificationURL *models.VerificationMicroserviceURL
|
||||
TemplategenURL *models.TemplategenMicroserviceURL
|
||||
MailClient *models.MailConfiguration
|
||||
CodewordServiceHost *models.CodewordMicroserviceConfiguration
|
||||
}
|
||||
|
||||
type Clients struct {
|
||||
@ -28,6 +29,7 @@ type Clients struct {
|
||||
VerificationClient *client.VerificationClient
|
||||
TemplateClient *client.TemplateClient
|
||||
MailClient *client.MailClient
|
||||
CodewordClient *client.CodewordClient
|
||||
}
|
||||
|
||||
func NewClients(deps ClientsDeps) *Clients {
|
||||
@ -73,5 +75,9 @@ func NewClients(deps ClientsDeps) *Clients {
|
||||
FiberClient: fiber.AcquireClient(),
|
||||
MailAddress: deps.MailClient.MailAddress,
|
||||
}),
|
||||
CodewordClient: client.NewCodewordClient(client.CodewordClientDeps{
|
||||
Logger: deps.Logger,
|
||||
CodewordServiceHost: deps.CodewordServiceHost.HostGRPC,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -2,22 +2,31 @@ package initialize
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/broker/tariff"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/grpc/customer"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/grpc/payment"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/account"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/cart"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/currency"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/history"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http/wallet"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
|
||||
type ControllersDeps struct {
|
||||
type RpcControllersDeps struct {
|
||||
Logger *zap.Logger
|
||||
Services *Services
|
||||
}
|
||||
|
||||
type Controllers struct {
|
||||
type RpcControllers struct {
|
||||
PaymentController *payment.Controller
|
||||
CustomerController *customer.Controller
|
||||
}
|
||||
|
||||
func NewControllers(deps ControllersDeps) *Controllers {
|
||||
return &Controllers{
|
||||
func NewRpcControllers(deps RpcControllersDeps) *RpcControllers {
|
||||
return &RpcControllers{
|
||||
PaymentController: payment.New(payment.Deps{
|
||||
Logger: deps.Logger,
|
||||
PaymentCallbackService: deps.Services.PaymentCallbackService,
|
||||
@ -28,3 +37,69 @@ func NewControllers(deps ControllersDeps) *Controllers {
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
type HttpControllersDeps struct {
|
||||
Encrypt *qutils.Encrypt
|
||||
Producer *tariff.Producer
|
||||
GRPC *models.ConfigurationGRPC
|
||||
MiddleWare *http.MiddleWare
|
||||
Logger *zap.Logger
|
||||
Repositories *Repositories
|
||||
Clients *Clients
|
||||
}
|
||||
|
||||
type HttpController struct {
|
||||
AccountController *account.AccountController
|
||||
CartController *cart.CartController
|
||||
HistoryController *history.HistoryController
|
||||
WalletController *wallet.WalletController
|
||||
CurrencyController *currency.CurrencyController
|
||||
}
|
||||
|
||||
func NewHttpControllers(deps HttpControllersDeps) *HttpController {
|
||||
return &HttpController{
|
||||
AccountController: account.NewAccountController(account.Deps{
|
||||
MiddleWare: deps.MiddleWare,
|
||||
AccountRepo: deps.Repositories.AccountRepository,
|
||||
Logger: deps.Logger,
|
||||
Encrypt: deps.Encrypt,
|
||||
AuthClient: deps.Clients.AuthClient,
|
||||
}),
|
||||
CartController: cart.NewCartController(cart.Deps{
|
||||
MiddleWare: deps.MiddleWare,
|
||||
Logger: deps.Logger,
|
||||
AccountRepo: deps.Repositories.AccountRepository,
|
||||
HistoryRepo: deps.Repositories.HistoryRepository,
|
||||
HubAdminClient: deps.Clients.HubadminClient,
|
||||
DiscountClient: deps.Clients.DiscountClient,
|
||||
CurrencyClient: deps.Clients.CurrencyClient,
|
||||
Producer: deps.Producer,
|
||||
}),
|
||||
HistoryController: history.NewHistoryController(history.Deps{
|
||||
MiddleWare: deps.MiddleWare,
|
||||
HistoryRepo: deps.Repositories.HistoryRepository,
|
||||
AccountRepo: deps.Repositories.AccountRepository,
|
||||
VerifyClient: deps.Clients.VerificationClient,
|
||||
AuthClient: deps.Clients.AuthClient,
|
||||
TemplateClient: deps.Clients.TemplateClient,
|
||||
CodewordClient: deps.Clients.CodewordClient,
|
||||
Logger: deps.Logger,
|
||||
}),
|
||||
WalletController: wallet.NewWalletController(wallet.Deps{
|
||||
MiddleWare: deps.MiddleWare,
|
||||
AuthClient: deps.Clients.AuthClient,
|
||||
PaymentClient: deps.Clients.PaymentClient,
|
||||
GRPC: deps.GRPC,
|
||||
AccountRepo: deps.Repositories.AccountRepository,
|
||||
CurrencyClient: deps.Clients.CurrencyClient,
|
||||
VerifyClient: deps.Clients.VerificationClient,
|
||||
MailClient: deps.Clients.MailClient,
|
||||
Logger: deps.Logger,
|
||||
}),
|
||||
CurrencyController: currency.NewCurrencyController(currency.Deps{
|
||||
CurrencyRepo: deps.Repositories.CurrencyRepository,
|
||||
MiddleWare: deps.MiddleWare,
|
||||
Logger: deps.Logger,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
215
internal/interface/controller/http/account/controllers.go
Normal file
215
internal/interface/controller/http/account/controllers.go
Normal file
@ -0,0 +1,215 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"math"
|
||||
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
MiddleWare *http.MiddleWare
|
||||
AccountRepo *repository.AccountRepository
|
||||
Logger *zap.Logger
|
||||
Encrypt *qutils.Encrypt
|
||||
AuthClient *client.AuthClient
|
||||
}
|
||||
|
||||
type AccountController struct {
|
||||
middleWare *http.MiddleWare
|
||||
accountRepo *repository.AccountRepository
|
||||
logger *zap.Logger
|
||||
encrypt *qutils.Encrypt
|
||||
authClient *client.AuthClient
|
||||
}
|
||||
|
||||
func NewAccountController(deps Deps) *AccountController {
|
||||
return &AccountController{
|
||||
middleWare: deps.MiddleWare,
|
||||
accountRepo: deps.AccountRepo,
|
||||
logger: deps.Logger,
|
||||
encrypt: deps.Encrypt,
|
||||
authClient: deps.AuthClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *AccountController) DeleteAccount(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.Remove(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(account)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) ChangeAccount(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
var request models.Name
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err)
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.UpdateName(ctx.Context(), userID, &request)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(account)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) SetAccountVerificationStatus(ctx *fiber.Ctx) error {
|
||||
userID := ctx.Params("userId")
|
||||
if userID == "" {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
|
||||
}
|
||||
|
||||
var request models.SetAccountStatus
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err)
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.SetStatus(ctx.Context(), userID, request.Status)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set status on <SetVerificationStatus> of <AccountService>", zap.Error(err))
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(account)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) GetAccount(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(account)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) AddAccount(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
var er error
|
||||
|
||||
quizFrom := ctx.Cookies("quizFrom")
|
||||
quizUser := ctx.Cookies("quizUser")
|
||||
if quizUser != "" {
|
||||
quizUser, er = receiver.encrypt.DecryptStr([]byte(quizUser))
|
||||
if er != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, er)
|
||||
}
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if account != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "account exists")
|
||||
}
|
||||
|
||||
user, err := receiver.authClient.GetUser(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
account, err = receiver.accountRepo.Insert(ctx.Context(), &models.Account{
|
||||
UserID: user.ID, Wallet: models.Wallet{Currency: models.DefaultCurrency}, From: quizFrom, Partner: quizUser})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(account)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) DeleteDirectAccount(ctx *fiber.Ctx) error {
|
||||
userID := ctx.Params("userId")
|
||||
if userID == "" {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.Remove(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(account)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) GetDirectAccount(ctx *fiber.Ctx) error {
|
||||
userID := ctx.Params("userId")
|
||||
if userID == "" {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(account)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) PaginationAccounts(ctx *fiber.Ctx) error {
|
||||
pageStr := ctx.Query("page", "1")
|
||||
limitStr := ctx.Query("limit", "100")
|
||||
|
||||
page, err := strconv.ParseInt(pageStr, 10, 64)
|
||||
if err != nil || page < 1 {
|
||||
page = 1
|
||||
}
|
||||
limit, err := strconv.ParseInt(limitStr, 10, 64)
|
||||
if err != nil || limit < 1 {
|
||||
limit = models.DefaultLimit
|
||||
} else {
|
||||
limit = int64(math.Min(float64(limit), float64(models.DefaultLimit)))
|
||||
}
|
||||
|
||||
count, err := receiver.accountRepo.CountAll(ctx.Context())
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
response := models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}}
|
||||
return ctx.Status(fiber.StatusOK).JSON(response)
|
||||
}
|
||||
|
||||
totalPages := int64(math.Ceil(float64(count) / float64(limit)))
|
||||
|
||||
accounts, err := receiver.accountRepo.FindMany(ctx.Context(), page, limit)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
response := models.PaginationResponse[models.Account]{
|
||||
TotalPages: totalPages,
|
||||
Records: accounts,
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(response)
|
||||
}
|
18
internal/interface/controller/http/account/route.go
Normal file
18
internal/interface/controller/http/account/route.go
Normal file
@ -0,0 +1,18 @@
|
||||
package account
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func (receiver *AccountController) Register(router fiber.Router) {
|
||||
router.Delete("/account", receiver.DeleteAccount)
|
||||
router.Get("/account", receiver.GetAccount)
|
||||
router.Patch("/account", receiver.ChangeAccount)
|
||||
router.Post("/account", receiver.AddAccount)
|
||||
router.Delete("/account/:userId", receiver.DeleteDirectAccount)
|
||||
router.Get("/account/:userId", receiver.GetDirectAccount)
|
||||
router.Patch("/account/:userId", receiver.SetAccountVerificationStatus)
|
||||
router.Get("/accounts", receiver.PaginationAccounts)
|
||||
}
|
||||
|
||||
func (receiver *AccountController) Name() string {
|
||||
return ""
|
||||
}
|
273
internal/interface/controller/http/cart/controllers.go
Normal file
273
internal/interface/controller/http/cart/controllers.go
Normal file
@ -0,0 +1,273 @@
|
||||
package cart
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/broker/tariff"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/transfer"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
MiddleWare *http.MiddleWare
|
||||
Logger *zap.Logger
|
||||
AccountRepo *repository.AccountRepository
|
||||
HistoryRepo *repository.HistoryRepository
|
||||
HubAdminClient *client.HubadminClient
|
||||
DiscountClient *client.DiscountClient
|
||||
CurrencyClient *client.CurrencyClient
|
||||
Producer *tariff.Producer
|
||||
}
|
||||
|
||||
type CartController struct {
|
||||
middleWare *http.MiddleWare
|
||||
logger *zap.Logger
|
||||
accountRepo *repository.AccountRepository
|
||||
historyRepo *repository.HistoryRepository
|
||||
hubAdminClient *client.HubadminClient
|
||||
discountClient *client.DiscountClient
|
||||
currencyClient *client.CurrencyClient
|
||||
producer *tariff.Producer
|
||||
}
|
||||
|
||||
func NewCartController(deps Deps) *CartController {
|
||||
return &CartController{
|
||||
middleWare: deps.MiddleWare,
|
||||
logger: deps.Logger,
|
||||
accountRepo: deps.AccountRepo,
|
||||
historyRepo: deps.HistoryRepo,
|
||||
hubAdminClient: deps.HubAdminClient,
|
||||
discountClient: deps.DiscountClient,
|
||||
currencyClient: deps.CurrencyClient,
|
||||
producer: deps.Producer,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *CartController) RemoveFromCart(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
id := ctx.Query("id")
|
||||
if id == "" {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "empty item id")
|
||||
}
|
||||
|
||||
cartItems, err := receiver.accountRepo.RemoveItemFromCart(ctx.Context(), userID, id)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(cartItems)
|
||||
}
|
||||
|
||||
func (receiver *CartController) Add2cart(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
token, ok := receiver.middleWare.ExtractToken(ctx)
|
||||
if !ok || token == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
tariffID := ctx.Query("id")
|
||||
if tariffID == "" {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "empty item id")
|
||||
}
|
||||
|
||||
tariff, err := receiver.hubAdminClient.GetTariff(ctx.Context(), token, tariffID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if tariff == nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusNotFound, "tariff not found")
|
||||
}
|
||||
|
||||
cartItems, err := receiver.accountRepo.AddItemToCart(ctx.Context(), userID, tariffID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(cartItems)
|
||||
}
|
||||
|
||||
func (receiver *CartController) PayCart(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
accessToken, ok := receiver.middleWare.ExtractToken(ctx)
|
||||
if !ok || accessToken == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
receiver.logger.Info("account for pay", zap.Any("acc", account))
|
||||
|
||||
tariffs, err := receiver.hubAdminClient.GetTariffs(ctx.Context(), accessToken, account.Cart)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
receiver.logger.Info("tariffs for pay", zap.Any("acc", tariffs))
|
||||
|
||||
tariffsAmount := utils.CalculateCartPurchasesAmount(tariffs)
|
||||
|
||||
discountResponse, err := receiver.discountClient.Apply(ctx.Context(), &discount.ApplyDiscountRequest{
|
||||
UserInformation: &discount.UserInformation{
|
||||
ID: account.UserID,
|
||||
Type: string(account.Status),
|
||||
PurchasesAmount: uint64(account.Wallet.Spent),
|
||||
CartPurchasesAmount: tariffsAmount,
|
||||
},
|
||||
Products: transfer.TariffsToProductInformations(tariffs),
|
||||
Date: timestamppb.New(time.Now()),
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
receiver.logger.Info("discountResponse for pay", zap.Any("acc", discount.ApplyDiscountRequest{
|
||||
UserInformation: &discount.UserInformation{
|
||||
ID: account.UserID,
|
||||
Type: string(account.Status),
|
||||
PurchasesAmount: uint64(account.Wallet.Spent),
|
||||
CartPurchasesAmount: tariffsAmount,
|
||||
},
|
||||
Products: transfer.TariffsToProductInformations(tariffs),
|
||||
Date: timestamppb.New(time.Now()),
|
||||
}))
|
||||
|
||||
if account.Wallet.Money < int64(discountResponse.Price) {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusPaymentRequired, "insufficient funds: %d", int64(discountResponse.Price)-account.Wallet.Money)
|
||||
}
|
||||
|
||||
for _, applied := range discountResponse.AppliedDiscounts {
|
||||
if applied.Condition.User != nil && *applied.Condition.User != "" {
|
||||
_, err := receiver.discountClient.DeleteDiscount(ctx.Context(), &discount.GetDiscountByIDRequest{
|
||||
ID: applied.ID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, "failed delete discount by id:%s", applied.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithdrawAccountWalletMoney
|
||||
|
||||
request := models.WithdrawAccountWallet{
|
||||
Money: int64(discountResponse.Price),
|
||||
Account: account,
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(request.Account.Wallet.Currency) {
|
||||
request.Account.Wallet.Currency = models.InternalCurrencyKey
|
||||
}
|
||||
|
||||
var updatedAccount *models.Account
|
||||
|
||||
if request.Account.Wallet.Currency == models.InternalCurrencyKey {
|
||||
accountx, err := receiver.accountRepo.ChangeWallet(ctx.Context(), request.Account.UserID, &models.Wallet{
|
||||
Cash: request.Account.Wallet.Cash - request.Money,
|
||||
Money: request.Account.Wallet.Money - request.Money,
|
||||
Spent: request.Account.Wallet.Spent + request.Money,
|
||||
PurchasesAmount: request.Account.Wallet.PurchasesAmount,
|
||||
Currency: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
updatedAccount = accountx
|
||||
} else {
|
||||
cash, err := receiver.currencyClient.Translate(ctx.Context(), &models.TranslateCurrency{
|
||||
Money: request.Money,
|
||||
From: models.InternalCurrencyKey,
|
||||
To: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
accountx, err := receiver.accountRepo.ChangeWallet(ctx.Context(), request.Account.UserID, &models.Wallet{
|
||||
Cash: request.Account.Wallet.Cash - cash,
|
||||
Money: request.Account.Wallet.Money - request.Money,
|
||||
Spent: request.Account.Wallet.Spent + request.Money,
|
||||
PurchasesAmount: request.Account.Wallet.PurchasesAmount,
|
||||
Currency: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
updatedAccount = accountx
|
||||
}
|
||||
|
||||
if _, err := receiver.historyRepo.Insert(ctx.Context(), &models.History{
|
||||
Key: models.CustomerHistoryKeyPayCart,
|
||||
UserID: account.UserID,
|
||||
Comment: "Успешная оплата корзины",
|
||||
RawDetails: models.RawDetails{
|
||||
Tariffs: tariffs,
|
||||
Price: int64(discountResponse.Price),
|
||||
},
|
||||
}); err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
// TODO: обработать ошибки при отправке сообщений
|
||||
|
||||
sendErrors := make([]errors.Error, 0)
|
||||
waitGroup := sync.WaitGroup{}
|
||||
mutex := sync.Mutex{}
|
||||
|
||||
for _, tariff := range tariffs {
|
||||
waitGroup.Add(1)
|
||||
|
||||
go func(currentTariff models.Tariff) {
|
||||
defer waitGroup.Done()
|
||||
|
||||
if err := receiver.producer.Send(ctx.Context(), userID, ¤tTariff); err != nil {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
sendErrors = append(sendErrors, err)
|
||||
}
|
||||
}(tariff)
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
|
||||
if len(sendErrors) > 0 {
|
||||
for _, err := range sendErrors {
|
||||
receiver.logger.Error("failed to send tariffs to broker on <Pay> of <CartService>", zap.Error(err))
|
||||
}
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, "failed to send tariffs to broker")
|
||||
}
|
||||
|
||||
if _, err := receiver.accountRepo.ClearCart(ctx.Context(), account.UserID); err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
updatedAccount.Cart = []string{}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(updatedAccount)
|
||||
}
|
13
internal/interface/controller/http/cart/route.go
Normal file
13
internal/interface/controller/http/cart/route.go
Normal file
@ -0,0 +1,13 @@
|
||||
package cart
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func (receiver *CartController) Register(router fiber.Router) {
|
||||
router.Delete("/cart", receiver.RemoveFromCart)
|
||||
router.Patch("/cart", receiver.Add2cart)
|
||||
router.Post("/cart/pay", receiver.PayCart)
|
||||
}
|
||||
|
||||
func (receiver *CartController) Name() string {
|
||||
return ""
|
||||
}
|
75
internal/interface/controller/http/currency/controllers.go
Normal file
75
internal/interface/controller/http/currency/controllers.go
Normal file
@ -0,0 +1,75 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
CurrencyRepo *repository.CurrencyRepository
|
||||
MiddleWare *http.MiddleWare
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
type CurrencyController struct {
|
||||
currencyRepo *repository.CurrencyRepository
|
||||
middleWare *http.MiddleWare
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewCurrencyController(deps Deps) *CurrencyController {
|
||||
return &CurrencyController{
|
||||
currencyRepo: deps.CurrencyRepo,
|
||||
middleWare: deps.MiddleWare,
|
||||
logger: deps.Logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *CurrencyController) GetCurrencies(ctx *fiber.Ctx) error {
|
||||
currencyList, err := receiver.currencyRepo.FindCurrenciesList(ctx.Context(), models.DefaultCurrencyListName)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if err != nil && err.Type() == errors.ErrNotFound {
|
||||
return ctx.Status(fiber.StatusOK).JSON([]string{})
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(currencyList)
|
||||
}
|
||||
|
||||
func (receiver *CurrencyController) UpdateCurrencies(ctx *fiber.Ctx) error {
|
||||
var req struct {
|
||||
items []string
|
||||
}
|
||||
if err := ctx.BodyParser(&req); err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind currencies")
|
||||
}
|
||||
|
||||
currencies := req.items
|
||||
|
||||
currencyList, err := receiver.currencyRepo.ReplaceCurrencies(ctx.Context(), &models.CurrencyList{
|
||||
Name: models.DefaultCurrencyListName,
|
||||
Currencies: currencies,
|
||||
})
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if err != nil && err.Type() == errors.ErrNotFound {
|
||||
newCurrencyList, err := receiver.currencyRepo.Insert(ctx.Context(), &models.CurrencyList{
|
||||
Name: models.DefaultCurrencyListName,
|
||||
Currencies: currencies,
|
||||
})
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
return ctx.Status(fiber.StatusOK).JSON(newCurrencyList.Currencies)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(currencyList.Currencies)
|
||||
}
|
12
internal/interface/controller/http/currency/route.go
Normal file
12
internal/interface/controller/http/currency/route.go
Normal file
@ -0,0 +1,12 @@
|
||||
package currency
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func (receiver *CurrencyController) Register(router fiber.Router) {
|
||||
router.Get("/currencies", receiver.GetCurrencies)
|
||||
router.Put("/currencies", receiver.UpdateCurrencies)
|
||||
}
|
||||
|
||||
func (receiver *CurrencyController) Name() string {
|
||||
return ""
|
||||
}
|
383
internal/interface/controller/http/history/controllers.go
Normal file
383
internal/interface/controller/http/history/controllers.go
Normal file
@ -0,0 +1,383 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"math"
|
||||
"os"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
codeword_rpc "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/codeword"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/history"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
MiddleWare *http.MiddleWare
|
||||
HistoryRepo *repository.HistoryRepository
|
||||
AccountRepo *repository.AccountRepository
|
||||
VerifyClient *client.VerificationClient
|
||||
AuthClient *client.AuthClient
|
||||
TemplateClient *client.TemplateClient
|
||||
CodewordClient *client.CodewordClient
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
type HistoryController struct {
|
||||
middleWare *http.MiddleWare
|
||||
historyRepo *repository.HistoryRepository
|
||||
accountRepo *repository.AccountRepository
|
||||
verifyClient *client.VerificationClient
|
||||
authClient *client.AuthClient
|
||||
templateClient *client.TemplateClient
|
||||
codewordClient *client.CodewordClient
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewHistoryController(deps Deps) *HistoryController {
|
||||
return &HistoryController{
|
||||
middleWare: deps.MiddleWare,
|
||||
historyRepo: deps.HistoryRepo,
|
||||
authClient: deps.AuthClient,
|
||||
accountRepo: deps.AccountRepo,
|
||||
verifyClient: deps.VerifyClient,
|
||||
templateClient: deps.TemplateClient,
|
||||
codewordClient: deps.CodewordClient,
|
||||
logger: deps.Logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *HistoryController) GetHistory(ctx *fiber.Ctx) error {
|
||||
var userID string
|
||||
|
||||
pageStr := ctx.Query("page")
|
||||
limitStr := ctx.Query("limit")
|
||||
tipe := ctx.Query("type")
|
||||
accountID := ctx.Query("accountID")
|
||||
|
||||
if accountID != "" {
|
||||
userID = accountID
|
||||
} else {
|
||||
id, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || id == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
userID = id
|
||||
}
|
||||
|
||||
limit, err := strconv.ParseInt(limitStr, 10, 64)
|
||||
if err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid limit format")
|
||||
}
|
||||
|
||||
page, err := strconv.ParseInt(pageStr, 10, 64)
|
||||
if err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid page format")
|
||||
}
|
||||
|
||||
dto := &history.GetHistories{
|
||||
UserID: userID,
|
||||
Type: &tipe,
|
||||
Pagination: &models.Pagination{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
},
|
||||
}
|
||||
|
||||
count, err := receiver.historyRepo.CountAll(ctx.Context(), dto)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
returnHistories := models.PaginationResponse[models.History]{TotalPages: 0, Records: []models.History{}}
|
||||
return ctx.Status(fiber.StatusOK).JSON(returnHistories)
|
||||
}
|
||||
|
||||
totalPages := int64(math.Ceil(float64(count) / float64(dto.Pagination.Limit)))
|
||||
|
||||
histories, err := receiver.historyRepo.FindMany(ctx.Context(), dto)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
returnHistories := models.PaginationResponse[models.History]{
|
||||
TotalPages: totalPages,
|
||||
Records: histories,
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(returnHistories)
|
||||
}
|
||||
|
||||
func (receiver *HistoryController) CalculateLTV(ctx *fiber.Ctx) error {
|
||||
var req struct {
|
||||
From int64 `json:"from"`
|
||||
To int64 `json:"to"`
|
||||
}
|
||||
|
||||
if err := ctx.BodyParser(&req); err != nil {
|
||||
receiver.logger.Error("failed to bind request", zap.Error(err))
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
if req.From > req.To && req.To != 0 {
|
||||
receiver.logger.Error("From timestamp must be less than To timestamp unless To is 0")
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "From timestamp must be less than To timestamp unless To is 0")
|
||||
}
|
||||
|
||||
ltv, err := receiver.historyRepo.CalculateCustomerLTV(ctx.Context(), req.From, req.To)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to calculate LTV", zap.Error(err))
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
response := struct {
|
||||
LTV int64 `json:"LTV"`
|
||||
}{
|
||||
LTV: ltv,
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(response)
|
||||
}
|
||||
|
||||
func (receiver *HistoryController) GetRecentTariffs(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
tariffs, err := receiver.historyRepo.GetRecentTariffs(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get recent tariffs on <GetRecentTariffs> of <API2>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(tariffs)
|
||||
}
|
||||
|
||||
func (receiver *HistoryController) SendReport(ctx *fiber.Ctx) error {
|
||||
var req struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
if err := ctx.BodyParser(&req); err != nil {
|
||||
receiver.logger.Error("failed to bind request", zap.Error(err))
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
if req.Id == "" {
|
||||
receiver.logger.Error("history id is missing in <GetHistoryById> of <HistoryService>")
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "history id is missing")
|
||||
}
|
||||
|
||||
tariffs, err := receiver.historyRepo.GetHistoryByID(ctx.Context(), req.Id)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get history by id in <GetHistoryById> of <HistoryService>",
|
||||
zap.String("historyID", req.Id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if tariffs.Key != models.CustomerHistoryKeyPayCart {
|
||||
receiver.logger.Error(
|
||||
"invalid history record key",
|
||||
zap.String("historyID", req.Id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid history record key")
|
||||
}
|
||||
|
||||
historyMap, err := receiver.historyRepo.GetDocNumber(ctx.Context(), tariffs.UserID)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get history of sorting by date created in <GetDocNumber> of <HistoryService>",
|
||||
zap.String("historyID", req.Id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
token := ctx.Get("Authorization")
|
||||
fmt.Println("HEADERS", ctx.Request().Header)
|
||||
|
||||
verifuser, err := receiver.verifyClient.GetVerification(ctx.Context(), token, tariffs.UserID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get user verification on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
if !verifuser.Accepted {
|
||||
receiver.logger.Error(
|
||||
"verification not accepted",
|
||||
zap.String("userID", tariffs.UserID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "verification not accepted")
|
||||
}
|
||||
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), tariffs.UserID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
authuser, err := receiver.authClient.GetUser(ctx.Context(), tariffs.UserID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get user on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
fileContents, readerr := os.ReadFile("./report.docx")
|
||||
if readerr != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, "failed to read file")
|
||||
}
|
||||
|
||||
if account.Name.Orgname == "" {
|
||||
account.Name.Orgname = "Безымянное предприятие"
|
||||
}
|
||||
|
||||
for _, tariff := range tariffs.RawDetails.Tariffs {
|
||||
totalAmount := uint64(0)
|
||||
privilegeMeasurement := ""
|
||||
piecePrice := ""
|
||||
privilegeName := ""
|
||||
for _, privilege := range tariff.Privileges {
|
||||
totalAmount += privilege.Amount
|
||||
privilegeMeasurement = string(privilege.Type)
|
||||
piecePrice = fmt.Sprintf("%.2f", float64(privilege.Price)/100)
|
||||
privilegeName = privilege.Name
|
||||
}
|
||||
data := models.RespGeneratorService{
|
||||
DocNumber: fmt.Sprint(historyMap[req.Id] + 1),
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
OrgTaxNum: verifuser.TaxNumber,
|
||||
OrgName: account.Name.Orgname,
|
||||
Name: tariff.Name + " " + privilegeName,
|
||||
Amount: fmt.Sprint(totalAmount),
|
||||
Unit: piecePrice,
|
||||
Price: fmt.Sprintf("%.2f", float64(tariffs.RawDetails.Price)/100),
|
||||
Sum: privilegeMeasurement,
|
||||
}
|
||||
err = receiver.templateClient.SendData(ctx.Context(), data, fileContents, authuser.Login)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to send report to user on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
|
||||
type QuizLogoStat2 struct {
|
||||
Count int64 `json:"count,omitempty"`
|
||||
Items map[string]Item `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Money int64 `json:"money,omitempty"`
|
||||
Quizes map[string][2]int `json:"quizes,omitempty"`
|
||||
Regs int `json:"regs,omitempty"`
|
||||
}
|
||||
|
||||
func (receiver *HistoryController) QuizLogoStat(ctx *fiber.Ctx) error {
|
||||
var req struct {
|
||||
From *int `json:"from,omitempty"`
|
||||
Limit *int `json:"limit,omitempty"`
|
||||
Page *int `json:"page,omitempty"`
|
||||
To *int `json:"to,omitempty"`
|
||||
}
|
||||
|
||||
if err := ctx.BodyParser(&req); err != nil {
|
||||
receiver.logger.Error("failed to bind request", zap.Error(err))
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
result, err := receiver.accountRepo.QuizLogoStat(ctx.Context(), repository.QuizLogoStatDeps{
|
||||
Page: req.Page,
|
||||
Limit: req.Limit,
|
||||
From: req.From,
|
||||
To: req.To,
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, fmt.Sprint("failed getting quiz logo stat", err.Error()))
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(result)
|
||||
}
|
||||
|
||||
func (receiver *HistoryController) PromocodeLTV(ctx *fiber.Ctx) error {
|
||||
var req struct {
|
||||
From int `json:"from"`
|
||||
To int `json:"to"`
|
||||
}
|
||||
|
||||
if err := ctx.BodyParser(&req); err != nil {
|
||||
receiver.logger.Error("failed to bind request", zap.Error(err))
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
// получаем мапу вида [promoID] = []{userid,timeActivate}
|
||||
// отдаются только первые использованые на аккаунте промокоды, соответсвенно подсчет идет сугубо по ним
|
||||
// если в запросе время различается с временем активации - если меньше, то учитывается только после применения
|
||||
// если больше, то учитывается только с начала переданного from
|
||||
codewordData, err := receiver.codewordClient.GetAllPromoActivations(ctx.Context(), &codeword_rpc.Time{
|
||||
To: int64(req.To),
|
||||
From: int64(req.From),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, fmt.Sprint("failed getting codeword data", err.Error()))
|
||||
}
|
||||
|
||||
userSumMap, er := receiver.historyRepo.GetPayUsersPromoHistory(ctx.Context(), codewordData, int64(req.From), int64(req.To))
|
||||
if er != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, fmt.Sprint("failed calculate promo users paid sum", er.Error()))
|
||||
}
|
||||
|
||||
resp := make(map[string]struct {
|
||||
Regs int
|
||||
Money int64
|
||||
})
|
||||
|
||||
for promoID, data := range codewordData {
|
||||
fmt.Println("PROTOMOTO", promoID, data)
|
||||
for _, value := range data {
|
||||
|
||||
paids, ok := userSumMap[value.UserID]
|
||||
if !ok {
|
||||
paids = 0
|
||||
}
|
||||
fmt.Println("PROTOMOTO1", paids, value)
|
||||
|
||||
if value.Time >= int64(req.From) && value.Time <= int64(req.To) {
|
||||
if _, ok := resp[promoID]; !ok {
|
||||
resp[promoID] = struct {
|
||||
Regs int
|
||||
Money int64
|
||||
}{Regs: 1, Money: paids}
|
||||
continue
|
||||
}
|
||||
current := resp[promoID]
|
||||
current.Regs += 1
|
||||
current.Money += paids
|
||||
resp[promoID] = current
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(resp)
|
||||
}
|
16
internal/interface/controller/http/history/route.go
Normal file
16
internal/interface/controller/http/history/route.go
Normal file
@ -0,0 +1,16 @@
|
||||
package history
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func (receiver *HistoryController) Register(router fiber.Router) {
|
||||
router.Get("/history", receiver.GetHistory)
|
||||
router.Post("/history/ltv", receiver.CalculateLTV)
|
||||
router.Post("/promocode/ltv", receiver.PromocodeLTV)
|
||||
router.Post("/quizlogo/stat", receiver.QuizLogoStat)
|
||||
router.Get("/recent", receiver.GetRecentTariffs)
|
||||
router.Post("/sendReport", receiver.SendReport)
|
||||
}
|
||||
|
||||
func (receiver *HistoryController) Name() string {
|
||||
return ""
|
||||
}
|
55
internal/interface/controller/http/middleware.go
Normal file
55
internal/interface/controller/http/middleware.go
Normal file
@ -0,0 +1,55 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
|
||||
type MiddleWare struct {
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewMiddleWare(logger *zap.Logger) *MiddleWare {
|
||||
return &MiddleWare{
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MiddleWare) Error(ctx *fiber.Ctx, status int, message string, rest ...any) error {
|
||||
if len(rest) > 0 {
|
||||
message = fmt.Sprintf(message, rest...)
|
||||
}
|
||||
mw.logger.Error(message)
|
||||
return ctx.Status(status).JSON(models.ResponseErrorHTTP{
|
||||
StatusCode: status,
|
||||
Message: message,
|
||||
})
|
||||
}
|
||||
|
||||
func (mw *MiddleWare) ErrorOld(ctx *fiber.Ctx, err error) error {
|
||||
mw.logger.Error("error:", zap.Error(err))
|
||||
return ctx.Status(fiber.StatusInternalServerError).JSON(models.ResponseErrorHTTP{
|
||||
StatusCode: fiber.StatusInternalServerError,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
func (mw *MiddleWare) NoAuth(ctx *fiber.Ctx) error {
|
||||
return mw.Error(ctx, fiber.StatusUnauthorized, "failed to get jwt payload")
|
||||
}
|
||||
|
||||
func (mw *MiddleWare) ExtractUserID(ctx *fiber.Ctx) (string, bool) {
|
||||
id, ok := ctx.Context().UserValue(models.AuthJWTDecodedUserIDKey).(string)
|
||||
return id, ok
|
||||
}
|
||||
|
||||
func (mw *MiddleWare) ExtractToken(ctx *fiber.Ctx) (string, bool) {
|
||||
token, ok := ctx.Context().UserValue(models.AuthJWTDecodedAccessTokenKey).(string)
|
||||
return token, ok
|
||||
}
|
||||
|
||||
func (mw *MiddleWare) GetHealth(ctx *fiber.Ctx) error {
|
||||
return ctx.Status(fiber.StatusOK).SendString("OK")
|
||||
}
|
314
internal/interface/controller/http/wallet/controllers.go
Normal file
314
internal/interface/controller/http/wallet/controllers.go
Normal file
@ -0,0 +1,314 @@
|
||||
package wallet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/treasurer"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
MiddleWare *http.MiddleWare
|
||||
AuthClient *client.AuthClient
|
||||
PaymentClient *client.PaymentClient
|
||||
GRPC *models.ConfigurationGRPC
|
||||
AccountRepo *repository.AccountRepository
|
||||
CurrencyClient *client.CurrencyClient
|
||||
VerifyClient *client.VerificationClient
|
||||
MailClient *client.MailClient
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
type WalletController struct {
|
||||
middleWare *http.MiddleWare
|
||||
authClient *client.AuthClient
|
||||
paymentClient *client.PaymentClient
|
||||
grpc *models.ConfigurationGRPC
|
||||
accountRepo *repository.AccountRepository
|
||||
currencyClient *client.CurrencyClient
|
||||
verifyClient *client.VerificationClient
|
||||
mailClient *client.MailClient
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewWalletController(deps Deps) *WalletController {
|
||||
return &WalletController{
|
||||
middleWare: deps.MiddleWare,
|
||||
authClient: deps.AuthClient,
|
||||
paymentClient: deps.PaymentClient,
|
||||
grpc: deps.GRPC,
|
||||
accountRepo: deps.AccountRepo,
|
||||
currencyClient: deps.CurrencyClient,
|
||||
verifyClient: deps.VerifyClient,
|
||||
mailClient: deps.MailClient,
|
||||
logger: deps.Logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *WalletController) RequestMoney(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
var request models.GetPaymentLinkBody
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind payment link")
|
||||
}
|
||||
|
||||
if err := utils.ValidateGetPaymentLinkBody(&request); err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
link, err := receiver.GetPaymentLink(ctx.Context(), &models.GetPaymentLinkRequest{
|
||||
Body: &request,
|
||||
UserID: userID,
|
||||
ClientIP: ctx.IP(),
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(&models.GetPaymentLinkResponse{Link: link})
|
||||
}
|
||||
|
||||
func (receiver *WalletController) GetPaymentLink(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
if _, userErr := receiver.authClient.GetUser(ctx, request.UserID); userErr != nil {
|
||||
receiver.logger.Error("failed to get user on <GetPaymentLink> on <PaymentService>",
|
||||
zap.Error(userErr),
|
||||
zap.String("userID", request.UserID),
|
||||
)
|
||||
|
||||
return "", userErr
|
||||
}
|
||||
|
||||
switch request.Body.Type {
|
||||
case models.PaymentTypeBankCard:
|
||||
return receiver.GetPaymentLinkBankCard(ctx, request)
|
||||
case models.PaymentTypeYoomoney:
|
||||
return receiver.GetPaymentLinkYooMoney(ctx, request)
|
||||
case models.PaymentTypeSberPay:
|
||||
return receiver.GetPaymentLinkSberPay(ctx, request)
|
||||
case models.PaymentTypeTinkoff:
|
||||
return receiver.GetPaymentLinkTinkoff(ctx, request)
|
||||
case models.PaymentTypeSBP:
|
||||
return receiver.GetPaymentLinkSBP(ctx, request)
|
||||
case models.PaymentTypeSberB2B:
|
||||
return receiver.GetPaymentLinkB2B(ctx, request)
|
||||
}
|
||||
|
||||
return "", errors.NewWithMessage("invalid payment method type", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
func (receiver *WalletController) GetPaymentLinkBankCard(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := receiver.paymentClient.GetPaymentLinkBankCard(ctx, &treasurer.GetBankCardPaymentLinkRequest{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{receiver.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get bankcard payment link on <GetPaymentLinkBankCard> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (receiver *WalletController) GetPaymentLinkYooMoney(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := receiver.paymentClient.GetPaymentLinkYooMoney(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{receiver.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get yoomoney payment link on <GetPaymentLinkYooMoney> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (receiver *WalletController) GetPaymentLinkSberPay(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := receiver.paymentClient.GetPaymentLinkSberPay(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{receiver.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get sberpay payment link on <GetPaymentLinkSberPay> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (receiver *WalletController) GetPaymentLinkTinkoff(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := receiver.paymentClient.GetPaymentLinkTinkoff(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{receiver.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get tinkoff payment link on <GetPaymentLinkTinkoff> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (receiver *WalletController) GetPaymentLinkSBP(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := receiver.paymentClient.GetPaymentLinkSBP(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{receiver.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get sbp payment link on <GetPaymentLinkSBP> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (receiver *WalletController) GetPaymentLinkB2B(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := receiver.paymentClient.GetPaymentLinkSberbankB2B(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{receiver.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get sberbankb2b payment link on <GetPaymentLinkB2B> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (receiver *WalletController) ChangeCurrency(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
var request models.ChangeCurrency
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind currency")
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(request.Currency) {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "empty currency")
|
||||
}
|
||||
|
||||
currency := request.Currency
|
||||
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
cash, err := receiver.currencyClient.Translate(ctx.Context(), &models.TranslateCurrency{
|
||||
Money: account.Wallet.Cash,
|
||||
From: account.Wallet.Currency,
|
||||
To: currency,
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
updatedAccount, err := receiver.accountRepo.ChangeWallet(ctx.Context(), account.UserID, &models.Wallet{
|
||||
Cash: cash,
|
||||
Currency: currency,
|
||||
Money: account.Wallet.Money,
|
||||
})
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.Status(fiber.StatusOK).JSON(updatedAccount)
|
||||
}
|
||||
|
||||
func (receiver *WalletController) PostWalletRspay(ctx *fiber.Ctx) error {
|
||||
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
||||
if !ok || userID == "" {
|
||||
return receiver.middleWare.NoAuth(ctx)
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Money *float32 `json:"money,omitempty"`
|
||||
}
|
||||
|
||||
if err := ctx.BodyParser(&req); err != nil {
|
||||
receiver.logger.Error("failed to bind request", zap.Error(err))
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
user, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
if user.Status != models.AccountStatusNko && user.Status != models.AccountStatusOrg {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusForbidden, "not allowed for non organizations")
|
||||
}
|
||||
token := ctx.Get("Authorization")
|
||||
fmt.Println("HEADERS", ctx.Request().Header)
|
||||
|
||||
verification, err := receiver.verifyClient.GetVerification(ctx.Context(), token, userID)
|
||||
if err == errors.ErrNotFound {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusForbidden, "no verification data found")
|
||||
}
|
||||
|
||||
if (user.Status == models.AccountStatusOrg && len(verification.Files) != 3) ||
|
||||
(user.Status == models.AccountStatusNko && len(verification.Files) != 4) {
|
||||
return receiver.middleWare.Error(ctx, fiber.StatusForbidden, "not enough verification files")
|
||||
}
|
||||
|
||||
authData, err := receiver.authClient.GetUser(ctx.Context(), userID)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
err = receiver.mailClient.SendMessage(authData.Login, verification, *req.Money)
|
||||
if err != nil {
|
||||
return receiver.middleWare.ErrorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.SendStatus(fiber.StatusOK)
|
||||
}
|
13
internal/interface/controller/http/wallet/route.go
Normal file
13
internal/interface/controller/http/wallet/route.go
Normal file
@ -0,0 +1,13 @@
|
||||
package wallet
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func (receiver *WalletController) Register(router fiber.Router) {
|
||||
router.Patch("/wallet", receiver.ChangeCurrency)
|
||||
router.Post("/wallet", receiver.RequestMoney)
|
||||
router.Post("/wallet/rspay", receiver.PostWalletRspay)
|
||||
}
|
||||
|
||||
func (receiver *WalletController) Name() string {
|
||||
return ""
|
||||
}
|
@ -42,21 +42,6 @@ func NewAccountRepository(deps AccountRepositoryDeps) *AccountRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func NewAccountRepository2(logger *zap.Logger, mongo *mongo.Collection) AccountRepository {
|
||||
if logger == nil {
|
||||
log.Panicln("logger is nil on <NewAccountRepository>")
|
||||
}
|
||||
|
||||
if mongo == nil {
|
||||
log.Panicln("mongodb is nil on <NewAccountRepository>")
|
||||
}
|
||||
|
||||
return AccountRepository{
|
||||
logger: logger,
|
||||
mongoDB: mongo,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *AccountRepository) FindByUserID(ctx context.Context, id string) (*models.Account, errors.Error) {
|
||||
filter := bson.M{
|
||||
fields.Account.UserID: id,
|
||||
|
@ -41,21 +41,6 @@ func NewCurrencyRepository(deps CurrencyRepositoryDeps) *CurrencyRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func NewCurrencyRepository2(logger *zap.Logger, mongo *mongo.Collection) CurrencyRepository {
|
||||
if logger == nil {
|
||||
log.Panicln("logger is nil on <NewCurrencyRepository>")
|
||||
}
|
||||
|
||||
if mongo == nil {
|
||||
log.Panicln("mongodb is nil on <NewCurrencyRepository>")
|
||||
}
|
||||
|
||||
return CurrencyRepository{
|
||||
logger: logger,
|
||||
mongoDB: mongo,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *CurrencyRepository) FindCurrenciesList(ctx context.Context, name string) (*models.CurrencyList, errors.Error) {
|
||||
filter := bson.M{
|
||||
fields.Currency.Name: name,
|
||||
|
@ -45,21 +45,6 @@ func NewHistoryRepository(deps HistoryRepositoryDeps) *HistoryRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func NewHistoryRepository2(logger *zap.Logger, mongo *mongo.Collection) HistoryRepository {
|
||||
if logger == nil {
|
||||
log.Panicln("logger is nil on <NewHistoryRepository>")
|
||||
}
|
||||
|
||||
if mongo == nil {
|
||||
log.Panicln("mongodb is nil on <NewHistoryRepository>")
|
||||
}
|
||||
|
||||
return HistoryRepository{
|
||||
logger: logger,
|
||||
mongoDB: mongo,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *HistoryRepository) Insert(ctx context.Context, history *models.History) (*models.History, errors.Error) {
|
||||
result, err := receiver.mongoDB.InsertOne(ctx, history.Sanitize())
|
||||
if err != nil {
|
||||
|
@ -1,966 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"math"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
codeword_rpc "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/codeword"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/broker/tariff"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/history"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/transfer"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/echotools"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
|
||||
)
|
||||
|
||||
const defaultCurrency = "RUB" // TODO move
|
||||
|
||||
type API2 struct {
|
||||
logger *zap.Logger
|
||||
history repository.HistoryRepository
|
||||
account repository.AccountRepository
|
||||
currency repository.CurrencyRepository
|
||||
producer *tariff.Producer
|
||||
consumer *tariff.Consumer
|
||||
clients clients
|
||||
grpc models.ConfigurationGRPC
|
||||
encrypt *qutils.Encrypt
|
||||
}
|
||||
|
||||
type clients struct {
|
||||
auth *client.AuthClient
|
||||
hubadmin *client.HubadminClient
|
||||
currency *client.CurrencyClient
|
||||
discount *client.DiscountClient
|
||||
payment *client.PaymentClient
|
||||
verify *client.VerificationClient
|
||||
template *client.TemplateClient
|
||||
mail *client.MailClient
|
||||
codeword *client.CodewordClient
|
||||
}
|
||||
|
||||
var _ ServerInterface = (*API2)(nil)
|
||||
|
||||
func NewAPI2(logger *zap.Logger, db *mongo.Database, config *models.Config, consumer *tariff.Consumer, producer *tariff.Producer, encrypt *qutils.Encrypt) API2 {
|
||||
return API2{
|
||||
logger: logger,
|
||||
history: repository.NewHistoryRepository2(logger, db.Collection("histories")),
|
||||
currency: repository.NewCurrencyRepository2(logger, db.Collection("currency_lists")),
|
||||
account: repository.NewAccountRepository2(logger, db.Collection("accounts")),
|
||||
consumer: consumer,
|
||||
producer: producer,
|
||||
encrypt: encrypt,
|
||||
grpc: config.GRPC,
|
||||
clients: clients{
|
||||
auth: client.NewAuthClient(client.AuthClientDeps{Logger: logger, URLs: &config.Service.AuthMicroservice.URL}),
|
||||
hubadmin: client.NewHubadminClient(client.HubadminClientDeps{Logger: logger, URLs: &config.Service.HubadminMicroservice.URL}),
|
||||
currency: client.NewCurrencyClient(client.CurrencyClientDeps{Logger: logger, URLs: &config.Service.CurrencyMicroservice.URL}),
|
||||
discount: client.NewDiscountClient(client.DiscountClientDeps{Logger: logger, DiscountServiceHost: config.Service.DiscountMicroservice.HostGRPC}),
|
||||
payment: client.NewPaymentClient(client.PaymentClientDeps{Logger: logger, PaymentServiceHost: config.Service.PaymentMicroservice.HostGRPC}),
|
||||
verify: client.NewVerificationClient(client.VerificationClientDeps{Logger: logger, URLs: &config.Service.VerificationMicroservice.URL}),
|
||||
template: client.NewTemplateClient(client.TemplateClientDeps{Logger: logger, URLs: &config.Service.TemplategenMicroserviceURL.URL}),
|
||||
mail: client.NewMailClient(client.MailClientDeps{Logger: logger,
|
||||
ApiUrl: config.Service.Mail.ApiUrl,
|
||||
Sender: config.Service.Mail.Sender,
|
||||
Auth: &models.PlainAuth{
|
||||
Identity: config.Service.Mail.Auth.Identity,
|
||||
Username: config.Service.Mail.Auth.Username,
|
||||
Password: config.Service.Mail.Auth.Password,
|
||||
},
|
||||
ApiKey: config.Service.Mail.ApiKey,
|
||||
FiberClient: fiber.AcquireClient(),
|
||||
MailAddress: config.Service.Mail.MailAddress,
|
||||
}),
|
||||
codeword: client.NewCodewordClient(client.CodewordClientDeps{Logger: logger, CodewordServiceHost: config.Service.CodewordMicroservice.HostGRPC}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (api *API2) error(ctx echo.Context, status int, message string, rest ...any) error {
|
||||
if len(rest) > 0 {
|
||||
message = fmt.Sprintf(message, rest...)
|
||||
}
|
||||
api.logger.Error(message)
|
||||
return ctx.JSON(status, models.ResponseErrorHTTP{
|
||||
StatusCode: status,
|
||||
Message: message,
|
||||
})
|
||||
}
|
||||
|
||||
func (api *API2) errorOld(ctx echo.Context, err errors.Error) error {
|
||||
api.logger.Error("error:", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
func (api *API2) noauth(ctx echo.Context) error {
|
||||
return api.error(ctx, http.StatusUnauthorized, "failed to get jwt payload")
|
||||
}
|
||||
|
||||
// Health
|
||||
|
||||
func (api *API2) GetHealth(ctx echo.Context) error {
|
||||
return ctx.String(http.StatusOK, "OK")
|
||||
}
|
||||
|
||||
// Account
|
||||
|
||||
func (api *API2) DeleteAccount(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
account, err := api.account.Remove(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (api *API2) ChangeAccount(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
request, bindErr := echotools.Bind[models.Name](ctx)
|
||||
if bindErr != nil {
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to bind json: %w", bindErr)
|
||||
}
|
||||
|
||||
account, err := api.account.UpdateName(ctx.Request().Context(), userID, request)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (api *API2) SetAccountVerificationStatus(ctx echo.Context, userID string) error {
|
||||
request, bindErr := echotools.Bind[models.SetAccountStatus](ctx)
|
||||
if bindErr != nil {
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to bind json: %w", bindErr)
|
||||
}
|
||||
|
||||
account, err := api.account.SetStatus(ctx.Request().Context(), userID, request.Status)
|
||||
if err != nil {
|
||||
api.logger.Error("failed to set status on <SetVerificationStatus> of <AccountService>", zap.Error(err))
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (api *API2) GetAccount(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
account, err := api.account.FindByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (api *API2) AddAccount(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
var quizFrom, quizUser string
|
||||
cookie, er := ctx.Request().Cookie("quizFrom")
|
||||
if er == nil {
|
||||
quizFrom = cookie.Value
|
||||
}
|
||||
|
||||
cookie, er = ctx.Request().Cookie("quizUser")
|
||||
if er == nil {
|
||||
quizUser, er = url.QueryUnescape(cookie.Value)
|
||||
if er == nil {
|
||||
quizUser, er = api.encrypt.DecryptStr([]byte(quizUser))
|
||||
}
|
||||
}
|
||||
|
||||
account, err := api.account.FindByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if account != nil {
|
||||
return api.error(ctx, http.StatusBadRequest, "account exists")
|
||||
}
|
||||
|
||||
user, err := api.clients.auth.GetUser(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
account, err = api.account.Insert(ctx.Request().Context(), &models.Account{
|
||||
UserID: user.ID, Wallet: models.Wallet{Currency: defaultCurrency}, From: quizFrom, Partner: quizUser})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (api *API2) DeleteDirectAccount(ctx echo.Context, userID string) error {
|
||||
account, err := api.account.Remove(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (api *API2) GetDirectAccount(ctx echo.Context, userID string) error {
|
||||
account, err := api.account.FindByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (api *API2) PaginationAccounts(ctx echo.Context, params PaginationAccountsParams) error {
|
||||
if params.Page == nil || params.Limit == nil {
|
||||
return api.error(ctx, http.StatusInternalServerError, "default values missing for PaginationAccounts")
|
||||
}
|
||||
|
||||
page := int64(math.Max(float64(*params.Page), 1))
|
||||
limit := int64(math.Max(float64(*params.Limit), 1))
|
||||
limit = int64(math.Min(float64(limit), float64(models.DefaultLimit)))
|
||||
|
||||
count, err := api.account.CountAll(ctx.Request().Context())
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
response := models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}}
|
||||
return ctx.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
totalPages := int64(math.Ceil(float64(count) / float64(limit)))
|
||||
|
||||
accounts, err := api.account.FindMany(ctx.Request().Context(), page, limit)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
response := models.PaginationResponse[models.Account]{
|
||||
TotalPages: totalPages,
|
||||
Records: accounts,
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// Cart
|
||||
|
||||
func (api *API2) RemoveFromCart(ctx echo.Context, params RemoveFromCartParams) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(params.Id) {
|
||||
return api.error(ctx, http.StatusBadRequest, "empty item id")
|
||||
}
|
||||
|
||||
cartItems, err := api.account.RemoveItemFromCart(ctx.Request().Context(), userID, params.Id)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, cartItems)
|
||||
}
|
||||
|
||||
func (api *API2) Add2cart(ctx echo.Context, params Add2cartParams) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
token, ok := ctx.Get(models.AuthJWTDecodedAccessTokenKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(params.Id) {
|
||||
return api.error(ctx, http.StatusBadRequest, "empty item id")
|
||||
}
|
||||
|
||||
tariffID := params.Id
|
||||
|
||||
tariff, err := api.clients.hubadmin.GetTariff(ctx.Request().Context(), token, tariffID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if tariff == nil {
|
||||
return api.error(ctx, http.StatusNotFound, "tariff not found")
|
||||
}
|
||||
|
||||
cartItems, err := api.account.AddItemToCart(ctx.Request().Context(), userID, tariffID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, cartItems)
|
||||
}
|
||||
|
||||
func (api *API2) PayCart(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
accessToken, ok := ctx.Get(models.AuthJWTDecodedAccessTokenKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
account, err := api.account.FindByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
api.logger.Info("account for pay", zap.Any("acc", account))
|
||||
|
||||
tariffs, err := api.clients.hubadmin.GetTariffs(ctx.Request().Context(), accessToken, account.Cart)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
api.logger.Info("tariffs for pay", zap.Any("acc", tariffs))
|
||||
|
||||
tariffsAmount := utils.CalculateCartPurchasesAmount(tariffs)
|
||||
|
||||
discountResponse, err := api.clients.discount.Apply(ctx.Request().Context(), &discount.ApplyDiscountRequest{
|
||||
UserInformation: &discount.UserInformation{
|
||||
ID: account.UserID,
|
||||
Type: string(account.Status),
|
||||
PurchasesAmount: uint64(account.Wallet.Spent),
|
||||
CartPurchasesAmount: tariffsAmount,
|
||||
},
|
||||
Products: transfer.TariffsToProductInformations(tariffs),
|
||||
Date: timestamppb.New(time.Now()),
|
||||
})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
api.logger.Info("discountResponse for pay", zap.Any("acc", discount.ApplyDiscountRequest{
|
||||
UserInformation: &discount.UserInformation{
|
||||
ID: account.UserID,
|
||||
Type: string(account.Status),
|
||||
PurchasesAmount: uint64(account.Wallet.Spent),
|
||||
CartPurchasesAmount: tariffsAmount,
|
||||
},
|
||||
Products: transfer.TariffsToProductInformations(tariffs),
|
||||
Date: timestamppb.New(time.Now()),
|
||||
}))
|
||||
|
||||
if account.Wallet.Money < int64(discountResponse.Price) {
|
||||
return api.error(ctx, http.StatusPaymentRequired, "insufficient funds: %d", int64(discountResponse.Price)-account.Wallet.Money)
|
||||
}
|
||||
|
||||
for _, applied := range discountResponse.AppliedDiscounts {
|
||||
if applied.Condition.User != nil && *applied.Condition.User != "" {
|
||||
_, err := api.clients.discount.DeleteDiscount(ctx.Request().Context(), &discount.GetDiscountByIDRequest{
|
||||
ID: applied.ID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return api.error(ctx, http.StatusInternalServerError, "failed delete discount by id:%s", applied.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithdrawAccountWalletMoney
|
||||
|
||||
request := models.WithdrawAccountWallet{
|
||||
Money: int64(discountResponse.Price),
|
||||
Account: account,
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(request.Account.Wallet.Currency) {
|
||||
request.Account.Wallet.Currency = models.InternalCurrencyKey
|
||||
}
|
||||
|
||||
var updatedAccount *models.Account
|
||||
|
||||
if request.Account.Wallet.Currency == models.InternalCurrencyKey {
|
||||
accountx, err := api.account.ChangeWallet(ctx.Request().Context(), request.Account.UserID, &models.Wallet{
|
||||
Cash: request.Account.Wallet.Cash - request.Money,
|
||||
Money: request.Account.Wallet.Money - request.Money,
|
||||
Spent: request.Account.Wallet.Spent + request.Money,
|
||||
PurchasesAmount: request.Account.Wallet.PurchasesAmount,
|
||||
Currency: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
updatedAccount = accountx
|
||||
} else {
|
||||
cash, err := api.clients.currency.Translate(ctx.Request().Context(), &models.TranslateCurrency{
|
||||
Money: request.Money,
|
||||
From: models.InternalCurrencyKey,
|
||||
To: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
accountx, err := api.account.ChangeWallet(ctx.Request().Context(), request.Account.UserID, &models.Wallet{
|
||||
Cash: request.Account.Wallet.Cash - cash,
|
||||
Money: request.Account.Wallet.Money - request.Money,
|
||||
Spent: request.Account.Wallet.Spent + request.Money,
|
||||
PurchasesAmount: request.Account.Wallet.PurchasesAmount,
|
||||
Currency: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
updatedAccount = accountx
|
||||
}
|
||||
|
||||
if _, err := api.history.Insert(ctx.Request().Context(), &models.History{
|
||||
Key: models.CustomerHistoryKeyPayCart,
|
||||
UserID: account.UserID,
|
||||
Comment: "Успешная оплата корзины",
|
||||
RawDetails: models.RawDetails{
|
||||
Tariffs: tariffs,
|
||||
Price: int64(discountResponse.Price),
|
||||
},
|
||||
}); err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
// TODO: обработать ошибки при отправке сообщений
|
||||
|
||||
sendErrors := make([]errors.Error, 0)
|
||||
waitGroup := sync.WaitGroup{}
|
||||
mutex := sync.Mutex{}
|
||||
|
||||
for _, tariff := range tariffs {
|
||||
waitGroup.Add(1)
|
||||
|
||||
go func(currentTariff models.Tariff) {
|
||||
defer waitGroup.Done()
|
||||
|
||||
if err := api.producer.Send(ctx.Request().Context(), userID, ¤tTariff); err != nil {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
sendErrors = append(sendErrors, err)
|
||||
}
|
||||
}(tariff)
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
|
||||
if len(sendErrors) > 0 {
|
||||
for _, err := range sendErrors {
|
||||
api.logger.Error("failed to send tariffs to broker on <Pay> of <CartService>", zap.Error(err))
|
||||
}
|
||||
return api.error(ctx, http.StatusInternalServerError, "failed to send tariffs to broker")
|
||||
}
|
||||
|
||||
if _, err := api.account.ClearCart(ctx.Request().Context(), account.UserID); err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
updatedAccount.Cart = []string{}
|
||||
|
||||
return ctx.JSON(http.StatusOK, updatedAccount)
|
||||
}
|
||||
|
||||
// Currency
|
||||
|
||||
func (api *API2) GetCurrencies(ctx echo.Context) error {
|
||||
currencyList, err := api.currency.FindCurrenciesList(ctx.Request().Context(), models.DefaultCurrencyListName)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if err != nil && err.Type() == errors.ErrNotFound {
|
||||
return ctx.JSON(http.StatusOK, []string{})
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, currencyList)
|
||||
}
|
||||
|
||||
func (api *API2) UpdateCurrencies(ctx echo.Context) error {
|
||||
currenciesPtr, bindErr := echotools.Bind[[]string](ctx)
|
||||
if bindErr != nil {
|
||||
return api.error(ctx, http.StatusBadRequest, "faild to bind currencies")
|
||||
}
|
||||
|
||||
currencies := *currenciesPtr
|
||||
|
||||
currencyList, err := api.currency.ReplaceCurrencies(ctx.Request().Context(), &models.CurrencyList{
|
||||
Name: models.DefaultCurrencyListName,
|
||||
Currencies: currencies,
|
||||
})
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if err != nil && err.Type() == errors.ErrNotFound {
|
||||
newCurrencyList, err := api.currency.Insert(ctx.Request().Context(), &models.CurrencyList{
|
||||
Name: models.DefaultCurrencyListName,
|
||||
Currencies: currencies,
|
||||
})
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
return ctx.JSON(http.StatusOK, newCurrencyList.Currencies)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, currencyList.Currencies)
|
||||
}
|
||||
|
||||
// History
|
||||
|
||||
func (api *API2) GetHistory(ctx echo.Context, params GetHistoryParams) error {
|
||||
var userID string
|
||||
|
||||
if params.AccountID != nil && *params.AccountID != "" {
|
||||
userID = *params.AccountID
|
||||
} else {
|
||||
userID, _ = ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
}
|
||||
|
||||
dto := &history.GetHistories{
|
||||
UserID: userID,
|
||||
Type: params.Type,
|
||||
Pagination: &models.Pagination{
|
||||
Page: int64(*params.Page),
|
||||
Limit: int64(*params.Limit),
|
||||
},
|
||||
}
|
||||
|
||||
count, err := api.history.CountAll(ctx.Request().Context(), dto)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
returnHistories := models.PaginationResponse[models.History]{TotalPages: 0, Records: []models.History{}}
|
||||
return ctx.JSON(http.StatusOK, returnHistories)
|
||||
}
|
||||
|
||||
totalPages := int64(math.Ceil(float64(count) / float64(dto.Pagination.Limit)))
|
||||
|
||||
histories, err := api.history.FindMany(ctx.Request().Context(), dto)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
returnHistories := models.PaginationResponse[models.History]{
|
||||
TotalPages: totalPages,
|
||||
Records: histories,
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, returnHistories)
|
||||
}
|
||||
|
||||
// Wallet
|
||||
|
||||
func (api *API2) RequestMoney(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
request, bindErr := echotools.Bind[models.GetPaymentLinkBody](ctx)
|
||||
if bindErr != nil {
|
||||
return api.error(ctx, http.StatusBadRequest, "faild to bind payment link")
|
||||
}
|
||||
|
||||
if err := utils.ValidateGetPaymentLinkBody(request); err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
link, err := api.GetPaymentLink(ctx.Request().Context(), &models.GetPaymentLinkRequest{
|
||||
Body: request,
|
||||
UserID: userID,
|
||||
ClientIP: ctx.RealIP(),
|
||||
})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, &models.GetPaymentLinkResponse{Link: link})
|
||||
}
|
||||
|
||||
func (api *API2) ChangeCurrency(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
request, bindErr := echotools.Bind[models.ChangeCurrency](ctx)
|
||||
if bindErr != nil {
|
||||
return api.error(ctx, http.StatusBadRequest, "faild to bind currency")
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(request.Currency) {
|
||||
return api.error(ctx, http.StatusBadRequest, "empty currency")
|
||||
}
|
||||
|
||||
currency := request.Currency
|
||||
account, err := api.account.FindByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
cash, err := api.clients.currency.Translate(ctx.Request().Context(), &models.TranslateCurrency{
|
||||
Money: account.Wallet.Cash,
|
||||
From: account.Wallet.Currency,
|
||||
To: currency,
|
||||
})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
updatedAccount, err := api.account.ChangeWallet(ctx.Request().Context(), account.UserID, &models.Wallet{
|
||||
Cash: cash,
|
||||
Currency: currency,
|
||||
Money: account.Wallet.Money,
|
||||
})
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, updatedAccount)
|
||||
}
|
||||
|
||||
func (api *API2) CalculateLTV(ctx echo.Context) error {
|
||||
var req CalculateLTVJSONBody
|
||||
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
api.logger.Error("failed to bind request", zap.Error(err))
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
if req.From > req.To && req.To != 0 {
|
||||
api.logger.Error("From timestamp must be less than To timestamp unless To is 0")
|
||||
return api.error(ctx, http.StatusBadRequest, "From timestamp must be less than To timestamp unless To is 0")
|
||||
}
|
||||
|
||||
ltv, err := api.history.CalculateCustomerLTV(ctx.Request().Context(), req.From, req.To)
|
||||
if err != nil {
|
||||
api.logger.Error("failed to calculate LTV", zap.Error(err))
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
response := struct {
|
||||
LTV int64 `json:"LTV"`
|
||||
}{
|
||||
LTV: ltv,
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
func (api *API2) GetRecentTariffs(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
api.logger.Error("failed to convert jwt payload to string on <GetRecentTariffs> of <API2>")
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to convert jwt payload to string")
|
||||
}
|
||||
|
||||
if userID == "" {
|
||||
api.logger.Error("user id is missing in <GetRecentTariffs> of <API2>")
|
||||
return api.error(ctx, http.StatusBadRequest, "user id is missing")
|
||||
}
|
||||
|
||||
tariffs, err := api.history.GetRecentTariffs(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get recent tariffs on <GetRecentTariffs> of <API2>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, tariffs)
|
||||
}
|
||||
|
||||
func (api *API2) SendReport(ctx echo.Context) error {
|
||||
var req SendReportJSONBody
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
api.logger.Error("failed to bind request", zap.Error(err))
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
if req.Id == "" {
|
||||
api.logger.Error("history id is missing in <GetHistoryById> of <HistoryService>")
|
||||
return api.error(ctx, http.StatusBadRequest, "history id is missing")
|
||||
}
|
||||
|
||||
tariffs, err := api.history.GetHistoryByID(ctx.Request().Context(), req.Id)
|
||||
if err != nil {
|
||||
api.logger.Error(
|
||||
"failed to get history by id in <GetHistoryById> of <HistoryService>",
|
||||
zap.String("historyID", req.Id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if tariffs.Key != models.CustomerHistoryKeyPayCart {
|
||||
api.logger.Error(
|
||||
"invalid history record key",
|
||||
zap.String("historyID", req.Id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return api.error(ctx, http.StatusBadRequest, "invalid history record key")
|
||||
}
|
||||
|
||||
historyMap, err := api.history.GetDocNumber(ctx.Request().Context(), tariffs.UserID)
|
||||
if err != nil {
|
||||
api.logger.Error(
|
||||
"failed to get history of sorting by date created in <GetDocNumber> of <HistoryService>",
|
||||
zap.String("historyID", req.Id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
token := ctx.Request().Header.Get("Authorization")
|
||||
fmt.Println("HEADERS", ctx.Request().Header)
|
||||
|
||||
verifuser, err := api.clients.verify.GetVerification(ctx.Request().Context(), token, tariffs.UserID)
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get user verification on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
if !verifuser.Accepted {
|
||||
api.logger.Error(
|
||||
"verification not accepted",
|
||||
zap.String("userID", tariffs.UserID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return api.error(ctx, http.StatusBadRequest, "verification not accepted")
|
||||
}
|
||||
account, err := api.account.FindByUserID(ctx.Request().Context(), tariffs.UserID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
|
||||
authuser, err := api.clients.auth.GetUser(ctx.Request().Context(), tariffs.UserID)
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get user on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
fileContents, readerr := os.ReadFile("./report.docx")
|
||||
if readerr != nil {
|
||||
return api.error(ctx, http.StatusInternalServerError, "failed to read file")
|
||||
}
|
||||
|
||||
if account.Name.Orgname == "" {
|
||||
account.Name.Orgname = "Безымянное предприятие"
|
||||
}
|
||||
|
||||
for _, tariff := range tariffs.RawDetails.Tariffs {
|
||||
totalAmount := uint64(0)
|
||||
privilegeMeasurement := ""
|
||||
piecePrice := ""
|
||||
privilegeName := ""
|
||||
for _, privilege := range tariff.Privileges {
|
||||
totalAmount += privilege.Amount
|
||||
privilegeMeasurement = string(privilege.Type)
|
||||
piecePrice = fmt.Sprintf("%.2f",float64(privilege.Price)/100)
|
||||
privilegeName = privilege.Name
|
||||
}
|
||||
data := models.RespGeneratorService{
|
||||
DocNumber: fmt.Sprint(historyMap[req.Id] + 1),
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
OrgTaxNum: verifuser.TaxNumber,
|
||||
OrgName: account.Name.Orgname,
|
||||
Name: tariff.Name + " " + privilegeName,
|
||||
Amount: fmt.Sprint(totalAmount),
|
||||
Unit: piecePrice,
|
||||
Price: fmt.Sprintf("%.2f",float64(tariffs.RawDetails.Price)/100),
|
||||
Sum: privilegeMeasurement,
|
||||
}
|
||||
err = api.clients.template.SendData(ctx.Request().Context(), data, fileContents, authuser.Login)
|
||||
if err != nil {
|
||||
api.logger.Error("failed to send report to user on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.NoContent(http.StatusOK)
|
||||
}
|
||||
|
||||
func (api *API2) PostWalletRspay(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
return api.noauth(ctx)
|
||||
}
|
||||
|
||||
var req PostWalletRspayJSONBody
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
api.logger.Error("failed to bind request", zap.Error(err))
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
user, err := api.account.FindByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
if user.Status != models.AccountStatusNko && user.Status != models.AccountStatusOrg {
|
||||
return api.error(ctx, http.StatusForbidden, "not allowed for non organizations")
|
||||
}
|
||||
token := ctx.Request().Header.Get("Authorization")
|
||||
fmt.Println("HEADERS", ctx.Request().Header)
|
||||
|
||||
verification, err := api.clients.verify.GetVerification(ctx.Request().Context(), token, userID)
|
||||
if err == errors.ErrNotFound {
|
||||
return api.error(ctx, http.StatusForbidden, "no verification data found")
|
||||
}
|
||||
|
||||
if (user.Status == models.AccountStatusOrg && len(verification.Files) != 3) ||
|
||||
(user.Status == models.AccountStatusNko && len(verification.Files) != 4) {
|
||||
return api.error(ctx, http.StatusForbidden, "not enough verification files")
|
||||
}
|
||||
|
||||
authData, err := api.clients.auth.GetUser(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
err = api.clients.mail.SendMessage(authData.Login, verification, *req.Money)
|
||||
if err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.NoContent(http.StatusOK)
|
||||
}
|
||||
|
||||
type QuizLogoStat2 struct {
|
||||
Count int64 `json:"count,omitempty"`
|
||||
Items map[string]Item `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Money int64 `json:"money,omitempty"`
|
||||
Quizes map[string][2]int `json:"quizes,omitempty"`
|
||||
Regs int `json:"regs,omitempty"`
|
||||
}
|
||||
|
||||
func (api *API2) QuizLogoStat(ctx echo.Context) error {
|
||||
var req QuizLogoStatJSONRequestBody
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
api.logger.Error("failed to bind request", zap.Error(err))
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
result, err := api.account.QuizLogoStat(ctx.Request().Context(), repository.QuizLogoStatDeps{
|
||||
Page: req.Page,
|
||||
Limit: req.Limit,
|
||||
From: req.From,
|
||||
To: req.To,
|
||||
})
|
||||
if err != nil {
|
||||
return api.error(ctx, http.StatusInternalServerError, fmt.Sprint("failed getting quiz logo stat", err.Error()))
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
func (api *API2) PromocodeLTV(ctx echo.Context) error {
|
||||
var req PromocodeLTVJSONRequestBody
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
api.logger.Error("failed to bind request", zap.Error(err))
|
||||
return api.error(ctx, http.StatusBadRequest, "failed to bind request")
|
||||
}
|
||||
|
||||
// получаем мапу вида [promoID] = []{userid,timeActivate}
|
||||
// отдаются только первые использованые на аккаунте промокоды, соответсвенно подсчет идет сугубо по ним
|
||||
// если в запросе время различается с временем активации - если меньше, то учитывается только после применения
|
||||
// если больше, то учитывается только с начала переданного from
|
||||
codewordData, err := api.clients.codeword.GetAllPromoActivations(ctx.Request().Context(), &codeword_rpc.Time{
|
||||
To: int64(req.To),
|
||||
From: int64(req.From),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return api.error(ctx, http.StatusInternalServerError, fmt.Sprint("failed getting codeword data", err.Error()))
|
||||
}
|
||||
|
||||
userSumMap, er := api.history.GetPayUsersPromoHistory(ctx.Request().Context(), codewordData, int64(req.From), int64(req.To))
|
||||
if er != nil {
|
||||
return api.error(ctx, http.StatusInternalServerError, fmt.Sprint("failed clculate promo users paid sum", er.Error()))
|
||||
}
|
||||
|
||||
resp := make(map[string]struct {
|
||||
Regs int
|
||||
Money int64
|
||||
})
|
||||
|
||||
for promoID, data := range codewordData {
|
||||
fmt.Println("PROTOMOTO", promoID,data)
|
||||
for _, value := range data {
|
||||
|
||||
paids, ok := userSumMap[value.UserID]
|
||||
if !ok {
|
||||
paids = 0
|
||||
}
|
||||
fmt.Println("PROTOMOTO1", paids, value)
|
||||
|
||||
if value.Time >= int64(req.From) && value.Time <= int64(req.To) {
|
||||
if _, ok := resp[promoID]; !ok {
|
||||
resp[promoID] = struct {
|
||||
Regs int
|
||||
Money int64
|
||||
}{Regs: 1, Money: paids}
|
||||
continue
|
||||
}
|
||||
current := resp[promoID]
|
||||
current.Regs += 1
|
||||
current.Money += paids
|
||||
resp[promoID] = current
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, resp)
|
||||
}
|
@ -1,631 +0,0 @@
|
||||
// Package swagger provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.1.0 DO NOT EDIT.
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/oapi-codegen/runtime"
|
||||
)
|
||||
|
||||
// ServerInterface represents all server handlers.
|
||||
type ServerInterface interface {
|
||||
// удалить собственный аккаунт
|
||||
// (DELETE /account)
|
||||
DeleteAccount(ctx echo.Context) error
|
||||
// Получение текущего аккаунта юзера
|
||||
// (GET /account)
|
||||
GetAccount(ctx echo.Context) error
|
||||
// Отредактировать аккаунт
|
||||
// (PATCH /account)
|
||||
ChangeAccount(ctx echo.Context) error
|
||||
// Создать новый аккаунт
|
||||
// (POST /account)
|
||||
AddAccount(ctx echo.Context) error
|
||||
// Удалить аккаунт по айди
|
||||
// (DELETE /account/{userId})
|
||||
DeleteDirectAccount(ctx echo.Context, userId string) error
|
||||
// Получить аккаунт по ID пользователя системы единой авторизации
|
||||
// (GET /account/{userId})
|
||||
GetDirectAccount(ctx echo.Context, userId string) error
|
||||
// Выставление статуса верификации
|
||||
// (PATCH /account/{userId})
|
||||
SetAccountVerificationStatus(ctx echo.Context, userId string) error
|
||||
// списко аккаунтов с пагинацией
|
||||
// (GET /accounts)
|
||||
PaginationAccounts(ctx echo.Context, params PaginationAccountsParams) error
|
||||
// Удаляем из корзины тариф
|
||||
// (DELETE /cart)
|
||||
RemoveFromCart(ctx echo.Context, params RemoveFromCartParams) error
|
||||
// Добавляем в корзину тариф
|
||||
// (PATCH /cart)
|
||||
Add2cart(ctx echo.Context, params Add2cartParams) error
|
||||
// оплатить козину
|
||||
// (POST /cart/pay)
|
||||
PayCart(ctx echo.Context) error
|
||||
// получить список одобренных валют
|
||||
// (GET /currencies)
|
||||
GetCurrencies(ctx echo.Context) error
|
||||
// обновляет список одобренных валют
|
||||
// (PUT /currencies)
|
||||
UpdateCurrencies(ctx echo.Context) error
|
||||
// Получение лога событий связанных с аккаунтом
|
||||
// (GET /history)
|
||||
GetHistory(ctx echo.Context, params GetHistoryParams) error
|
||||
// Расчет среднего времени жизни платящего клиента (LTV)
|
||||
// (POST /history/ltv)
|
||||
CalculateLTV(ctx echo.Context) error
|
||||
// статистика по промокодам в разрезе регистраций и оплат
|
||||
// (POST /promocode/ltv)
|
||||
PromocodeLTV(ctx echo.Context) error
|
||||
// статистика пользователей, перешедших по логотипу в опросах
|
||||
// (POST /quizlogo/stat)
|
||||
QuizLogoStat(ctx echo.Context) error
|
||||
// Получение недавних тарифов
|
||||
// (GET /recent)
|
||||
GetRecentTariffs(ctx echo.Context) error
|
||||
// отправить акт проделанных работ на почту
|
||||
// (POST /sendReport)
|
||||
SendReport(ctx echo.Context) error
|
||||
// Изменить валюту кошелька
|
||||
// (PATCH /wallet)
|
||||
ChangeCurrency(ctx echo.Context) error
|
||||
// Запрос на получение ссылки на оплату
|
||||
// (POST /wallet)
|
||||
RequestMoney(ctx echo.Context) error
|
||||
// Обработка запроса RSPay
|
||||
// (POST /wallet/rspay)
|
||||
PostWalletRspay(ctx echo.Context) error
|
||||
}
|
||||
|
||||
// ServerInterfaceWrapper converts echo contexts to parameters.
|
||||
type ServerInterfaceWrapper struct {
|
||||
Handler ServerInterface
|
||||
}
|
||||
|
||||
// DeleteAccount converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) DeleteAccount(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.DeleteAccount(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetAccount converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetAccount(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.GetAccount(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ChangeAccount converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) ChangeAccount(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.ChangeAccount(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddAccount converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) AddAccount(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.AddAccount(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteDirectAccount converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) DeleteDirectAccount(ctx echo.Context) error {
|
||||
var err error
|
||||
// ------------- Path parameter "userId" -------------
|
||||
var userId string
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "userId", ctx.Param("userId"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter userId: %s", err))
|
||||
}
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.DeleteDirectAccount(ctx, userId)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetDirectAccount converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetDirectAccount(ctx echo.Context) error {
|
||||
var err error
|
||||
// ------------- Path parameter "userId" -------------
|
||||
var userId string
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "userId", ctx.Param("userId"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter userId: %s", err))
|
||||
}
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.GetDirectAccount(ctx, userId)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetAccountVerificationStatus converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SetAccountVerificationStatus(ctx echo.Context) error {
|
||||
var err error
|
||||
// ------------- Path parameter "userId" -------------
|
||||
var userId string
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "userId", ctx.Param("userId"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter userId: %s", err))
|
||||
}
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.SetAccountVerificationStatus(ctx, userId)
|
||||
return err
|
||||
}
|
||||
|
||||
// PaginationAccounts converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) PaginationAccounts(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params PaginationAccountsParams
|
||||
// ------------- Optional query parameter "page" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", false, false, "page", ctx.QueryParams(), ¶ms.Page)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter page: %s", err))
|
||||
}
|
||||
|
||||
// ------------- Optional query parameter "limit" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", false, false, "limit", ctx.QueryParams(), ¶ms.Limit)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter limit: %s", err))
|
||||
}
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.PaginationAccounts(ctx, params)
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveFromCart converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) RemoveFromCart(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params RemoveFromCartParams
|
||||
// ------------- Required query parameter "id" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, true, "id", ctx.QueryParams(), ¶ms.Id)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err))
|
||||
}
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.RemoveFromCart(ctx, params)
|
||||
return err
|
||||
}
|
||||
|
||||
// Add2cart converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) Add2cart(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params Add2cartParams
|
||||
// ------------- Required query parameter "id" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, true, "id", ctx.QueryParams(), ¶ms.Id)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err))
|
||||
}
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.Add2cart(ctx, params)
|
||||
return err
|
||||
}
|
||||
|
||||
// PayCart converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) PayCart(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.PayCart(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetCurrencies converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetCurrencies(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.GetCurrencies(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateCurrencies converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) UpdateCurrencies(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.UpdateCurrencies(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetHistory converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetHistory(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params GetHistoryParams
|
||||
// ------------- Optional query parameter "page" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", false, false, "page", ctx.QueryParams(), ¶ms.Page)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter page: %s", err))
|
||||
}
|
||||
|
||||
// ------------- Optional query parameter "limit" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", false, false, "limit", ctx.QueryParams(), ¶ms.Limit)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter limit: %s", err))
|
||||
}
|
||||
|
||||
// ------------- Optional query parameter "type" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", false, false, "type", ctx.QueryParams(), ¶ms.Type)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter type: %s", err))
|
||||
}
|
||||
|
||||
// ------------- Optional query parameter "accountID" -------------
|
||||
|
||||
err = runtime.BindQueryParameter("form", false, false, "accountID", ctx.QueryParams(), ¶ms.AccountID)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter accountID: %s", err))
|
||||
}
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.GetHistory(ctx, params)
|
||||
return err
|
||||
}
|
||||
|
||||
// CalculateLTV converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) CalculateLTV(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.CalculateLTV(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// PromocodeLTV converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) PromocodeLTV(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.PromocodeLTV(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// QuizLogoStat converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) QuizLogoStat(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.QuizLogoStat(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRecentTariffs converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetRecentTariffs(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.GetRecentTariffs(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// SendReport converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SendReport(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.SendReport(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ChangeCurrency converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) ChangeCurrency(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.ChangeCurrency(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// RequestMoney converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) RequestMoney(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.RequestMoney(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// PostWalletRspay converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) PostWalletRspay(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.PostWalletRspay(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// This is a simple interface which specifies echo.Route addition functions which
|
||||
// are present on both echo.Echo and echo.Group, since we want to allow using
|
||||
// either of them for path registration
|
||||
type EchoRouter interface {
|
||||
CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
}
|
||||
|
||||
// RegisterHandlers adds each server route to the EchoRouter.
|
||||
func RegisterHandlers(router EchoRouter, si ServerInterface) {
|
||||
RegisterHandlersWithBaseURL(router, si, "")
|
||||
}
|
||||
|
||||
// Registers handlers, and prepends BaseURL to the paths, so that the paths
|
||||
// can be served under a prefix.
|
||||
func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) {
|
||||
|
||||
wrapper := ServerInterfaceWrapper{
|
||||
Handler: si,
|
||||
}
|
||||
|
||||
router.DELETE(baseURL+"/account", wrapper.DeleteAccount)
|
||||
router.GET(baseURL+"/account", wrapper.GetAccount)
|
||||
router.PATCH(baseURL+"/account", wrapper.ChangeAccount)
|
||||
router.POST(baseURL+"/account", wrapper.AddAccount)
|
||||
router.DELETE(baseURL+"/account/:userId", wrapper.DeleteDirectAccount)
|
||||
router.GET(baseURL+"/account/:userId", wrapper.GetDirectAccount)
|
||||
router.PATCH(baseURL+"/account/:userId", wrapper.SetAccountVerificationStatus)
|
||||
router.GET(baseURL+"/accounts", wrapper.PaginationAccounts)
|
||||
router.DELETE(baseURL+"/cart", wrapper.RemoveFromCart)
|
||||
router.PATCH(baseURL+"/cart", wrapper.Add2cart)
|
||||
router.POST(baseURL+"/cart/pay", wrapper.PayCart)
|
||||
router.GET(baseURL+"/currencies", wrapper.GetCurrencies)
|
||||
router.PUT(baseURL+"/currencies", wrapper.UpdateCurrencies)
|
||||
router.GET(baseURL+"/history", wrapper.GetHistory)
|
||||
router.POST(baseURL+"/history/ltv", wrapper.CalculateLTV)
|
||||
router.POST(baseURL+"/promocode/ltv", wrapper.PromocodeLTV)
|
||||
router.POST(baseURL+"/quizlogo/stat", wrapper.QuizLogoStat)
|
||||
router.GET(baseURL+"/recent", wrapper.GetRecentTariffs)
|
||||
router.POST(baseURL+"/sendReport", wrapper.SendReport)
|
||||
router.PATCH(baseURL+"/wallet", wrapper.ChangeCurrency)
|
||||
router.POST(baseURL+"/wallet", wrapper.RequestMoney)
|
||||
router.POST(baseURL+"/wallet/rspay", wrapper.PostWalletRspay)
|
||||
|
||||
}
|
||||
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"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",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
// or error if failed to decode
|
||||
func decodeSpec() ([]byte, error) {
|
||||
zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, ""))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error base64 decoding spec: %w", err)
|
||||
}
|
||||
zr, err := gzip.NewReader(bytes.NewReader(zipped))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %w", err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
_, err = buf.ReadFrom(zr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %w", err)
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var rawSpec = decodeSpecCached()
|
||||
|
||||
// a naive cached of a decoded swagger spec
|
||||
func decodeSpecCached() func() ([]byte, error) {
|
||||
data, err := decodeSpec()
|
||||
return func() ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
}
|
||||
|
||||
// Constructs a synthetic filesystem for resolving external references when loading openapi specifications.
|
||||
func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) {
|
||||
res := make(map[string]func() ([]byte, error))
|
||||
if len(pathToFile) > 0 {
|
||||
res[pathToFile] = rawSpec
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// GetSwagger returns the Swagger specification corresponding to the generated code
|
||||
// in this file. The external references of Swagger specification are resolved.
|
||||
// The logic of resolving external references is tightly connected to "import-mapping" feature.
|
||||
// Externally referenced files must be embedded in the corresponding golang packages.
|
||||
// Urls can be supported but this task was out of the scope.
|
||||
func GetSwagger() (swagger *openapi3.T, err error) {
|
||||
resolvePath := PathToRawSpec("")
|
||||
|
||||
loader := openapi3.NewLoader()
|
||||
loader.IsExternalRefsAllowed = true
|
||||
loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) {
|
||||
pathToFile := url.String()
|
||||
pathToFile = path.Clean(pathToFile)
|
||||
getSpec, ok := resolvePath[pathToFile]
|
||||
if !ok {
|
||||
err1 := fmt.Errorf("path not found: %s", pathToFile)
|
||||
return nil, err1
|
||||
}
|
||||
return getSpec()
|
||||
}
|
||||
var specData []byte
|
||||
specData, err = rawSpec()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
swagger, err = loader.LoadFromData(specData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"github.com/deepmap/oapi-codegen/pkg/middleware"
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/getkin/kin-openapi/openapi3filter"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func CreateMiddleware(swagger *openapi3.T, authenticationFunc openapi3filter.AuthenticationFunc) echo.MiddlewareFunc {
|
||||
validator := middleware.OapiRequestValidatorWithOptions(swagger,
|
||||
&middleware.Options{
|
||||
Options: openapi3filter.Options{
|
||||
AuthenticationFunc: authenticationFunc,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return validator
|
||||
}
|
@ -1,299 +0,0 @@
|
||||
// Package swagger provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.1.0 DO NOT EDIT.
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
BearerScopes = "Bearer.Scopes"
|
||||
)
|
||||
|
||||
// Defines values for AccountStatus.
|
||||
const (
|
||||
Nko AccountStatus = "nko"
|
||||
No AccountStatus = "no"
|
||||
Org AccountStatus = "org"
|
||||
)
|
||||
|
||||
// Defines values for PaymentType.
|
||||
const (
|
||||
PaymentTypeAlfabank PaymentType = "alfabank"
|
||||
PaymentTypeB2bSberbank PaymentType = "b2bSberbank"
|
||||
PaymentTypeBankCard PaymentType = "bankCard"
|
||||
PaymentTypeCash PaymentType = "cash"
|
||||
PaymentTypeInstallments PaymentType = "installments"
|
||||
PaymentTypeMobile PaymentType = "mobile"
|
||||
PaymentTypeQiwi PaymentType = "qiwi"
|
||||
PaymentTypeSberbank PaymentType = "sberbank"
|
||||
PaymentTypeSbp PaymentType = "sbp"
|
||||
PaymentTypeTinkoffBank PaymentType = "tinkoffBank"
|
||||
PaymentTypeYoomoney PaymentType = "yoomoney"
|
||||
)
|
||||
|
||||
// Account defines model for Account.
|
||||
type Account struct {
|
||||
Id string `json:"_id"`
|
||||
Cart []string `json:"cart"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty"`
|
||||
IsDeleted *bool `json:"isDeleted,omitempty"`
|
||||
Name Name `json:"name"`
|
||||
Status AccountStatus `json:"status"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
UserId string `json:"userId"`
|
||||
Wallet Wallet `json:"wallet"`
|
||||
}
|
||||
|
||||
// AccountStatus defines model for AccountStatus.
|
||||
type AccountStatus string
|
||||
|
||||
// BankCard defines model for BankCard.
|
||||
type BankCard struct {
|
||||
// Cardholder Имя владельца карты
|
||||
Cardholder *string `json:"cardholder,omitempty"`
|
||||
|
||||
// Csc Код CVC2 или CVV2, 3 или 4 символа, печатается на обратной стороне карты
|
||||
Csc *string `json:"csc,omitempty"`
|
||||
|
||||
// ExpiryMonth Месяц истечения срока карты (MM)
|
||||
ExpiryMonth string `json:"expiryMonth"`
|
||||
|
||||
// ExpiryYear Год истечения срока карты (YYYY)
|
||||
ExpiryYear string `json:"expiryYear"`
|
||||
|
||||
// Number Номер карты
|
||||
Number string `json:"number"`
|
||||
}
|
||||
|
||||
// Error defines model for Error.
|
||||
type Error struct {
|
||||
Message string `json:"message"`
|
||||
StatusCode *int64 `json:"statusCode,omitempty"`
|
||||
}
|
||||
|
||||
// History defines model for History.
|
||||
type History struct {
|
||||
Comment string `json:"comment"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty"`
|
||||
Id string `json:"id"`
|
||||
IsDeleted *bool `json:"isDeleted,omitempty"`
|
||||
|
||||
// RawDetails Я пока не могу предположить, какие будут фильтры по истории, поэтому предлагаю в это поле просто класть строку с json. Ибо для каждого типа записи она своя.
|
||||
RawDetails *string `json:"rawDetails,omitempty"`
|
||||
Type string `json:"type"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
UserId string `json:"userId"`
|
||||
}
|
||||
|
||||
// Name defines model for Name.
|
||||
type Name struct {
|
||||
Firstname *string `json:"firstname,omitempty"`
|
||||
Middlename *string `json:"middlename,omitempty"`
|
||||
Orgname *string `json:"orgname,omitempty"`
|
||||
Secondname *string `json:"secondname,omitempty"`
|
||||
}
|
||||
|
||||
// PaymentType defines model for PaymentType.
|
||||
type PaymentType string
|
||||
|
||||
// PromoLtvStat defines model for PromoLtvStat.
|
||||
type PromoLtvStat struct {
|
||||
// Stats мапа ключ id промо, знчение количество регистраций и количество денег
|
||||
Stats *map[string]struct {
|
||||
// Money количество денег
|
||||
Money *int `json:"money,omitempty"`
|
||||
|
||||
// Regs количество регистраций
|
||||
Regs *int `json:"regs,omitempty"`
|
||||
} `json:"stats,omitempty"`
|
||||
}
|
||||
|
||||
// QuizLogoStat defines model for QuizLogoStat.
|
||||
type QuizLogoStat = []struct {
|
||||
// Id user id
|
||||
Id *string `json:"id,omitempty"`
|
||||
|
||||
// Money Количество денег
|
||||
Money *int `json:"money,omitempty"`
|
||||
Quizes *[]struct {
|
||||
// Money Количество денег
|
||||
Money *int `json:"money,omitempty"`
|
||||
|
||||
// Quiz qid quiz
|
||||
Quiz *string `json:"quiz,omitempty"`
|
||||
|
||||
// Regs Количество регистраций
|
||||
Regs *int `json:"regs,omitempty"`
|
||||
} `json:"quizes,omitempty"`
|
||||
|
||||
// Regs Количество регистраций
|
||||
Regs *int `json:"regs,omitempty"`
|
||||
}
|
||||
|
||||
// TariffID defines model for TariffID.
|
||||
type TariffID struct {
|
||||
ID *string `json:"ID,omitempty"`
|
||||
}
|
||||
|
||||
// Wallet defines model for Wallet.
|
||||
type Wallet struct {
|
||||
// Cash Сумма money переведённая на текущий курс
|
||||
Cash int64 `json:"cash"`
|
||||
|
||||
// Currency Текущий курс валюты
|
||||
Currency string `json:"currency"`
|
||||
|
||||
// Money Деньги на счету в копейках. Чтобы при перессчётах не возникало денег изниоткуда. фиксируемся к одной валюте, она будет внутренней, никому её не покажем
|
||||
Money int64 `json:"money"`
|
||||
|
||||
// PurchasesAmount Общая сумма денег, которые внёс пользователь
|
||||
PurchasesAmount int64 `json:"purchasesAmount"`
|
||||
|
||||
// Spent Общая сумма потраченных денег за всё время существования аккаунта
|
||||
Spent int64 `json:"spent"`
|
||||
}
|
||||
|
||||
// SetAccountVerificationStatusJSONBody defines parameters for SetAccountVerificationStatus.
|
||||
type SetAccountVerificationStatusJSONBody struct {
|
||||
Status *AccountStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// PaginationAccountsParams defines parameters for PaginationAccounts.
|
||||
type PaginationAccountsParams struct {
|
||||
// Page Номер страницы, начиная с 1
|
||||
Page *int `form:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// Limit размер страницы
|
||||
Limit *int `form:"limit,omitempty" json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// RemoveFromCartParams defines parameters for RemoveFromCart.
|
||||
type RemoveFromCartParams struct {
|
||||
Id string `form:"id" json:"id"`
|
||||
}
|
||||
|
||||
// Add2cartParams defines parameters for Add2cart.
|
||||
type Add2cartParams struct {
|
||||
Id string `form:"id" json:"id"`
|
||||
}
|
||||
|
||||
// UpdateCurrenciesJSONBody defines parameters for UpdateCurrencies.
|
||||
type UpdateCurrenciesJSONBody = []string
|
||||
|
||||
// GetHistoryParams defines parameters for GetHistory.
|
||||
type GetHistoryParams struct {
|
||||
// Page Номер страницы, начиная с 1
|
||||
Page *int `form:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// Limit Размер страницы
|
||||
Limit *int `form:"limit,omitempty" json:"limit,omitempty"`
|
||||
|
||||
// Type Тип события
|
||||
Type *string `form:"type,omitempty" json:"type,omitempty"`
|
||||
|
||||
// AccountID Идентификатор аккаунта. Если не указан, будет использоваться идентификатор из токена.
|
||||
AccountID *string `form:"accountID,omitempty" json:"accountID,omitempty"`
|
||||
}
|
||||
|
||||
// CalculateLTVJSONBody defines parameters for CalculateLTV.
|
||||
type CalculateLTVJSONBody struct {
|
||||
// From Начальная дата в формате Unix timestamp. Если 0, устанавливает начало истории.
|
||||
From int64 `json:"from"`
|
||||
|
||||
// To Конечная дата в формате Unix timestamp. Если 0, устанавливает текущее время.
|
||||
To int64 `json:"to"`
|
||||
}
|
||||
|
||||
// PromocodeLTVJSONBody defines parameters for PromocodeLTV.
|
||||
type PromocodeLTVJSONBody struct {
|
||||
// From таймштамп времени, после которого выбирать статистику
|
||||
From int `json:"from"`
|
||||
|
||||
// To таймштамп времени, до которого выбирать статистику
|
||||
To int `json:"to"`
|
||||
}
|
||||
|
||||
// QuizLogoStatJSONBody defines parameters for QuizLogoStat.
|
||||
type QuizLogoStatJSONBody struct {
|
||||
// From таймштамп времени, после которого выбирать статистику. если 0 или не передано - этого ограничения нет. нижняя граница времени
|
||||
From *int `json:"from,omitempty"`
|
||||
|
||||
// Limit лимит выборки
|
||||
Limit *int `json:"limit,omitempty"`
|
||||
|
||||
// Page страница выборки
|
||||
Page *int `json:"page,omitempty"`
|
||||
|
||||
// To таймштамп времени, до которого выбирать статистику. если 0 или не передано - этого ограничения нет. верхняя граница времени
|
||||
To *int `json:"to,omitempty"`
|
||||
}
|
||||
|
||||
// GetRecentTariffsJSONBody defines parameters for GetRecentTariffs.
|
||||
type GetRecentTariffsJSONBody struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
// SendReportJSONBody defines parameters for SendReport.
|
||||
type SendReportJSONBody struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
// ChangeCurrencyJSONBody defines parameters for ChangeCurrency.
|
||||
type ChangeCurrencyJSONBody struct {
|
||||
Currency string `json:"currency"`
|
||||
}
|
||||
|
||||
// RequestMoneyJSONBody defines parameters for RequestMoney.
|
||||
type RequestMoneyJSONBody struct {
|
||||
Amount int `json:"amount"`
|
||||
BankCard *BankCard `json:"bankCard,omitempty"`
|
||||
|
||||
// Currency ISO-4217 формат
|
||||
Currency string `json:"currency"`
|
||||
Login *string `json:"login,omitempty"`
|
||||
PhoneNumber *string `json:"phoneNumber,omitempty"`
|
||||
ReturnUrl *string `json:"returnUrl,omitempty"`
|
||||
Type PaymentType `json:"type"`
|
||||
}
|
||||
|
||||
// PostWalletRspayJSONBody defines parameters for PostWalletRspay.
|
||||
type PostWalletRspayJSONBody struct {
|
||||
Money *float32 `json:"money,omitempty"`
|
||||
}
|
||||
|
||||
// ChangeAccountJSONRequestBody defines body for ChangeAccount for application/json ContentType.
|
||||
type ChangeAccountJSONRequestBody = Name
|
||||
|
||||
// SetAccountVerificationStatusJSONRequestBody defines body for SetAccountVerificationStatus for application/json ContentType.
|
||||
type SetAccountVerificationStatusJSONRequestBody SetAccountVerificationStatusJSONBody
|
||||
|
||||
// UpdateCurrenciesJSONRequestBody defines body for UpdateCurrencies for application/json ContentType.
|
||||
type UpdateCurrenciesJSONRequestBody = UpdateCurrenciesJSONBody
|
||||
|
||||
// CalculateLTVJSONRequestBody defines body for CalculateLTV for application/json ContentType.
|
||||
type CalculateLTVJSONRequestBody CalculateLTVJSONBody
|
||||
|
||||
// PromocodeLTVJSONRequestBody defines body for PromocodeLTV for application/json ContentType.
|
||||
type PromocodeLTVJSONRequestBody PromocodeLTVJSONBody
|
||||
|
||||
// QuizLogoStatJSONRequestBody defines body for QuizLogoStat for application/json ContentType.
|
||||
type QuizLogoStatJSONRequestBody QuizLogoStatJSONBody
|
||||
|
||||
// GetRecentTariffsJSONRequestBody defines body for GetRecentTariffs for application/json ContentType.
|
||||
type GetRecentTariffsJSONRequestBody GetRecentTariffsJSONBody
|
||||
|
||||
// SendReportJSONRequestBody defines body for SendReport for application/json ContentType.
|
||||
type SendReportJSONRequestBody SendReportJSONBody
|
||||
|
||||
// ChangeCurrencyJSONRequestBody defines body for ChangeCurrency for application/json ContentType.
|
||||
type ChangeCurrencyJSONRequestBody ChangeCurrencyJSONBody
|
||||
|
||||
// RequestMoneyJSONRequestBody defines body for RequestMoney for application/json ContentType.
|
||||
type RequestMoneyJSONRequestBody RequestMoneyJSONBody
|
||||
|
||||
// PostWalletRspayJSONRequestBody defines body for PostWalletRspay for application/json ContentType.
|
||||
type PostWalletRspayJSONRequestBody PostWalletRspayJSONBody
|
@ -1,152 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/treasurer"
|
||||
)
|
||||
|
||||
func (api *API2) GetPaymentLink(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
if _, userErr := api.clients.auth.GetUser(ctx, request.UserID); userErr != nil {
|
||||
api.logger.Error("failed to get user on <GetPaymentLink> on <PaymentService>",
|
||||
zap.Error(userErr),
|
||||
zap.String("userID", request.UserID),
|
||||
)
|
||||
|
||||
return "", userErr
|
||||
}
|
||||
|
||||
switch request.Body.Type {
|
||||
case models.PaymentTypeBankCard:
|
||||
return api.GetPaymentLinkBankCard(ctx, request)
|
||||
case models.PaymentTypeYoomoney:
|
||||
return api.GetPaymentLinkYooMoney(ctx, request)
|
||||
case models.PaymentTypeSberPay:
|
||||
return api.GetPaymentLinkSberPay(ctx, request)
|
||||
case models.PaymentTypeTinkoff:
|
||||
return api.GetPaymentLinkTinkoff(ctx, request)
|
||||
case models.PaymentTypeSBP:
|
||||
return api.GetPaymentLinkSBP(ctx, request)
|
||||
case models.PaymentTypeSberB2B:
|
||||
return api.GetPaymentLinkB2B(ctx, request)
|
||||
}
|
||||
|
||||
return "", errors.NewWithMessage("invalid payment method type", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
func (api *API2) GetPaymentLinkBankCard(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := api.clients.payment.GetPaymentLinkBankCard(ctx, &treasurer.GetBankCardPaymentLinkRequest{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{api.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get bankcard payment link on <GetPaymentLinkBankCard> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (api *API2) GetPaymentLinkYooMoney(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := api.clients.payment.GetPaymentLinkYooMoney(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{api.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get yoomoney payment link on <GetPaymentLinkYooMoney> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (api *API2) GetPaymentLinkSberPay(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := api.clients.payment.GetPaymentLinkSberPay(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{api.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get sberpay payment link on <GetPaymentLinkSberPay> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (api *API2) GetPaymentLinkTinkoff(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := api.clients.payment.GetPaymentLinkTinkoff(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{api.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get tinkoff payment link on <GetPaymentLinkTinkoff> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (api *API2) GetPaymentLinkSBP(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := api.clients.payment.GetPaymentLinkSBP(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{api.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get sbp payment link on <GetPaymentLinkSBP> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func (api *API2) GetPaymentLinkB2B(ctx context.Context, request *models.GetPaymentLinkRequest) (string, errors.Error) {
|
||||
link, err := api.clients.payment.GetPaymentLinkSberbankB2B(ctx, &treasurer.GetPaymentLinkBody{
|
||||
MainSettings: &treasurer.MainPaymentSettings{
|
||||
Currency: request.Body.Currency,
|
||||
Amount: request.Body.Amount,
|
||||
UserID: request.UserID,
|
||||
ClientIP: request.ClientIP,
|
||||
CallbackHostGRPC: []string{api.grpc.Domen},
|
||||
ReturnURL: request.Body.ReturnURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
api.logger.Error("failed to get sberbankb2b payment link on <GetPaymentLinkB2B> of <PaymentService>", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
@ -31,12 +31,13 @@ type BankCard struct {
|
||||
type PaymentType string
|
||||
|
||||
const (
|
||||
PaymentTypeBankCard PaymentType = "bankCard"
|
||||
PaymentTypeTinkoff PaymentType = "tinkoffBank"
|
||||
PaymentTypeSberPay PaymentType = "sberbank"
|
||||
PaymentTypeYoomoney PaymentType = "yoomoney"
|
||||
PaymentTypeSBP PaymentType = "sbp"
|
||||
PaymentTypeSberB2B PaymentType = "b2bSberbank"
|
||||
PaymentTypeBankCard PaymentType = "bankCard"
|
||||
PaymentTypeTinkoff PaymentType = "tinkoffBank"
|
||||
PaymentTypeSberPay PaymentType = "sberbank"
|
||||
PaymentTypeYoomoney PaymentType = "yoomoney"
|
||||
PaymentTypeSBP PaymentType = "sbp"
|
||||
PaymentTypeSberB2B PaymentType = "b2bSberbank"
|
||||
DefaultCurrency = "RUB"
|
||||
)
|
||||
|
||||
type PaymentEvent struct {
|
||||
@ -45,6 +46,6 @@ type PaymentEvent struct {
|
||||
PaymentID string
|
||||
UserID string
|
||||
Currency string
|
||||
Type string
|
||||
Type string
|
||||
Amount int64
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func (receiver *GRPC) Stop(_ context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *GRPC) Register(controllers *initialize.Controllers) *GRPC {
|
||||
func (receiver *GRPC) Register(controllers *initialize.RpcControllers) *GRPC {
|
||||
payment_callback.RegisterPaymentCallbackServiceServer(receiver.grpc, controllers.PaymentController)
|
||||
customer.RegisterCustomerServiceServer(receiver.grpc, controllers.CustomerController)
|
||||
|
||||
|
@ -3,91 +3,70 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/getkin/kin-openapi/openapi3filter"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
)
|
||||
|
||||
type DepsHTTP struct {
|
||||
Logger *zap.Logger
|
||||
Swagger *openapi3.T
|
||||
AuthenticationFunc openapi3filter.AuthenticationFunc
|
||||
type ServerConfig struct {
|
||||
Logger *zap.Logger
|
||||
Controllers []Controller
|
||||
JWTConfig *models.JWTConfiguration
|
||||
}
|
||||
|
||||
type HTTP struct {
|
||||
logger *zap.Logger
|
||||
server *http.Server
|
||||
echo *echo.Echo
|
||||
type Server struct {
|
||||
Logger *zap.Logger
|
||||
Controllers []Controller
|
||||
app *fiber.App
|
||||
}
|
||||
|
||||
func NewHTTP(deps DepsHTTP) (*HTTP, errors.Error) {
|
||||
if deps.Logger == nil {
|
||||
return nil, errors.NewWithMessage("failed to init http server: logger is nil <NewHTTP>", errors.ErrInvalidArgs)
|
||||
func NewServer(config ServerConfig) *Server {
|
||||
app := fiber.New()
|
||||
|
||||
jwtUtil := utils.NewJWT(config.JWTConfig)
|
||||
app.Use(utils.NewAuthenticator(jwtUtil))
|
||||
|
||||
s := &Server{
|
||||
Logger: config.Logger,
|
||||
Controllers: config.Controllers,
|
||||
app: app,
|
||||
}
|
||||
|
||||
if deps.Swagger == nil {
|
||||
return nil, errors.NewWithMessage("failed to init http server: swagger is nil <NewHTTP>", errors.ErrInvalidArgs)
|
||||
}
|
||||
s.registerRoutes()
|
||||
|
||||
if deps.AuthenticationFunc == nil {
|
||||
return nil, errors.NewWithMessage("failed to init http server: AuthenticationFunc is nil <NewHTTP>", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
echo := echo.New()
|
||||
|
||||
echo.Use(middleware.Recover())
|
||||
echo.Use(swagger.CreateMiddleware(deps.Swagger, deps.AuthenticationFunc))
|
||||
|
||||
return &HTTP{
|
||||
echo: echo,
|
||||
logger: deps.Logger,
|
||||
server: &http.Server{
|
||||
Handler: echo,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
ReadTimeout: 20 * time.Second,
|
||||
WriteTimeout: 20 * time.Second,
|
||||
IdleTimeout: 20 * time.Second,
|
||||
},
|
||||
}, nil
|
||||
return s
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Listen(address string) error {
|
||||
receiver.server.Addr = address
|
||||
|
||||
return receiver.server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Run(config *models.ConfigurationHTTP) {
|
||||
connectionString := fmt.Sprintf("%s:%s", config.Host, config.Port)
|
||||
startServerMessage := fmt.Sprintf("starting http server on %s", connectionString)
|
||||
|
||||
receiver.logger.Info(startServerMessage)
|
||||
|
||||
if err := receiver.Listen(connectionString); err != nil && err != http.ErrServerClosed {
|
||||
receiver.logger.Error("http listen error: ", zap.Error(err))
|
||||
func (s *Server) Start(addr string) error {
|
||||
if err := s.app.Listen(addr); err != nil {
|
||||
s.Logger.Error("Failed to start server", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Stop(ctx context.Context) error {
|
||||
receiver.logger.Info("shutting down server...")
|
||||
|
||||
if err := receiver.server.Shutdown(ctx); err != nil {
|
||||
return fmt.Errorf("failed to shutdown server: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *HTTP) Register(api swagger.ServerInterface) *HTTP {
|
||||
swagger.RegisterHandlers(receiver.echo, api)
|
||||
|
||||
return receiver
|
||||
func (s *Server) Shutdown(ctx context.Context) error {
|
||||
return s.app.Shutdown()
|
||||
}
|
||||
|
||||
func (s *Server) registerRoutes() {
|
||||
for _, c := range s.Controllers {
|
||||
router := s.app.Group(c.Name())
|
||||
c.Register(router)
|
||||
}
|
||||
}
|
||||
|
||||
type Controller interface {
|
||||
Register(router fiber.Router)
|
||||
Name() string
|
||||
}
|
||||
|
||||
func (s *Server) ListRoutes() {
|
||||
fmt.Println("Registered routes:")
|
||||
for _, stack := range s.app.Stack() {
|
||||
for _, route := range stack {
|
||||
fmt.Printf("%s %s\n", route.Method, route.Path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"strings"
|
||||
|
||||
"github.com/deepmap/oapi-codegen/pkg/middleware"
|
||||
"github.com/getkin/kin-openapi/openapi3filter"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
@ -16,50 +13,40 @@ const (
|
||||
prefix = "Bearer "
|
||||
)
|
||||
|
||||
func NewAuthenticator(jwtUtil *JWT) openapi3filter.AuthenticationFunc {
|
||||
return func(ctx context.Context, input *openapi3filter.AuthenticationInput) error {
|
||||
func NewAuthenticator(jwtUtil *JWT) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
if jwtUtil == nil {
|
||||
return errors.New(
|
||||
fmt.Errorf("jwt util is nil: %w", errors.ErrInvalidArgs),
|
||||
errors.ErrInvalidArgs,
|
||||
)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, errors.ErrInvalidArgs.Error())
|
||||
}
|
||||
|
||||
return authenticate(ctx, jwtUtil, input)
|
||||
err := authenticate(jwtUtil, c)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusUnauthorized, err.Error())
|
||||
}
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func authenticate(ctx context.Context, jwtUtil *JWT, input *openapi3filter.AuthenticationInput) error {
|
||||
if input.SecuritySchemeName != "Bearer" {
|
||||
return fmt.Errorf("security scheme %s != 'Bearer'", input.SecuritySchemeName)
|
||||
}
|
||||
|
||||
// Now, we need to get the JWS from the request, to match the request expectations
|
||||
// against request contents.
|
||||
jws, err := parseJWSFromRequest(input.RequestValidationInput.Request)
|
||||
func authenticate(jwtUtil *JWT, c *fiber.Ctx) error {
|
||||
jws, err := parseJWSFromRequest(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if the JWS is valid, we have a JWT, which will contain a bunch of claims.
|
||||
userID, validateErr := jwtUtil.Validate(jws)
|
||||
if validateErr != nil {
|
||||
return validateErr
|
||||
}
|
||||
|
||||
// Set the property on the echo context so the handler is able to
|
||||
// access the claims data we generate in here.
|
||||
echoCtx := middleware.GetEchoContext(ctx)
|
||||
|
||||
echoCtx.Set(models.AuthJWTDecodedUserIDKey, userID)
|
||||
echoCtx.Set(models.AuthJWTDecodedAccessTokenKey, jws)
|
||||
c.Locals(models.AuthJWTDecodedUserIDKey, userID)
|
||||
c.Locals(models.AuthJWTDecodedAccessTokenKey, jws)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// extracts a JWS string from an Authorization: Bearer <jws> header.
|
||||
func parseJWSFromRequest(request *http.Request) (string, errors.Error) {
|
||||
header := request.Header.Get("Authorization")
|
||||
func parseJWSFromRequest(c *fiber.Ctx) (string, error) {
|
||||
header := c.Get("Authorization")
|
||||
|
||||
if header == "" || !strings.HasPrefix(header, prefix) {
|
||||
return "", errors.New(
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
|
||||
@ -37,8 +36,14 @@ func TestCalculateLTV(t *testing.T) {
|
||||
fmt.Println(from, to)
|
||||
|
||||
response, err := client.Post[interface{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/history/ltv",
|
||||
Body: swagger.CalculateLTVJSONBody{From: from, To: to},
|
||||
URL: "http://localhost:8082/history/ltv",
|
||||
Body: struct {
|
||||
From int64
|
||||
To int64
|
||||
}{
|
||||
From: from,
|
||||
To: to,
|
||||
},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if ok := assert.NoError(t, err); !ok {
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
|
||||
@ -69,9 +68,12 @@ func TestGetAccount(t *testing.T) {
|
||||
page := 0
|
||||
limit := 3
|
||||
|
||||
params := swagger.PaginationAccountsParams{
|
||||
Page: &page,
|
||||
Limit: &limit,
|
||||
params := struct {
|
||||
Page int
|
||||
Limit int
|
||||
}{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
}
|
||||
|
||||
responseGetAccount, errGetAccount := client.Get[models.PaginationResponse[models.Account], models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
|
@ -10,13 +10,19 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetAccount(t *testing.T) {
|
||||
func TestPostWalletRspay(t *testing.T) {
|
||||
jwtUtil := helpers.InitializeJWT()
|
||||
|
||||
t.Run("rspay", func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
req := struct {
|
||||
Money float32
|
||||
}{
|
||||
Money: 100,
|
||||
}
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
token, tokenErr := jwtUtil.Create("6597babdd1ba7e2dbd32d7e3")
|
||||
if isNoError := assert.NoError(t, tokenErr); !isNoError {
|
||||
@ -26,6 +32,7 @@ func TestGetAccount(t *testing.T) {
|
||||
response, err := client.Post[interface{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/wallet/rspay",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
Body: req,
|
||||
})
|
||||
if isNoError := assert.NoError(t, err); !isNoError {
|
||||
return
|
||||
|
@ -7,17 +7,24 @@ import (
|
||||
"net/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCurrencies(t *testing.T) {
|
||||
jwtUtil := helpers.InitializeJWT()
|
||||
t.Run("Получение текущих доступных курсов", func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
token, tokenErr := jwtUtil.Create("6597babdd1ba7e2dbd32d7e3")
|
||||
if isNoError := assert.NoError(t, tokenErr); !isNoError {
|
||||
return
|
||||
}
|
||||
responseGetCurrencies, errCurrencies := client.Get[[]models.CurrencyList, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/currencies",
|
||||
URL: "http://localhost:8082/currencies",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if isNoError := assert.NoError(t, errCurrencies); !isNoError {
|
||||
return
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
|
||||
@ -23,7 +22,7 @@ func TestHistoryReport(t *testing.T) {
|
||||
|
||||
response, err := client.Post[struct{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://" + "localhost:8082" + "/sendReport",
|
||||
Body: swagger.SendReportJSONBody{Id: "10002"},
|
||||
Body: struct{ Id string }{Id: "10002"},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if ok := assert.NoError(t, err); !ok {
|
||||
|
@ -2,65 +2,57 @@ package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/pioz/faker"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLogostat(t *testing.T) {
|
||||
logger, err := zap.NewProduction(zap.AddStacktrace(zap.DPanicLevel))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to init zap logger: %v", err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
mongoDB, err := mongo.Connect(ctx, &mongo.ConnectDeps{
|
||||
Configuration: &mongo.Configuration{
|
||||
Host: "localhost",
|
||||
Port: "27020",
|
||||
User: "test",
|
||||
Password: "test",
|
||||
Auth: "admin",
|
||||
DatabaseName: "admin",
|
||||
},
|
||||
Timeout: 10 * time.Second,
|
||||
})
|
||||
|
||||
repoAc := repository.NewAccountRepository2(logger, mongoDB.Collection("accounts"))
|
||||
repoHi := repository.NewHistoryRepository2(logger, mongoDB.Collection("histories"))
|
||||
InsertToDB(ctx, repoAc, repoHi)
|
||||
|
||||
api := swagger.NewAPI2(logger, mongoDB, nil, nil, nil, nil)
|
||||
|
||||
e := echo.New()
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
c := e.NewContext(req, rec)
|
||||
|
||||
requestBody := swagger.QuizLogoStatJSONRequestBody{
|
||||
From: new(int),
|
||||
Limit: new(int),
|
||||
Page: new(int),
|
||||
To: new(int),
|
||||
}
|
||||
*requestBody.From = 1713087258
|
||||
*requestBody.Limit = 10
|
||||
*requestBody.Page = 1
|
||||
*requestBody.To = 1713260058
|
||||
|
||||
c.SetRequest(c.Request().WithContext(context.WithValue(c.Request().Context(), "requestBody", requestBody)))
|
||||
|
||||
err = api.QuizLogoStat(c)
|
||||
}
|
||||
//func TestLogostat(t *testing.T) {
|
||||
// logger, err := zap.NewProduction(zap.AddStacktrace(zap.DPanicLevel))
|
||||
// if err != nil {
|
||||
// log.Fatalf("failed to init zap logger: %v", err)
|
||||
// }
|
||||
// ctx := context.Background()
|
||||
// mongoDB, err := mongo.Connect(ctx, &mongo.ConnectDeps{
|
||||
// Configuration: &mongo.Configuration{
|
||||
// Host: "localhost",
|
||||
// Port: "27020",
|
||||
// User: "test",
|
||||
// Password: "test",
|
||||
// Auth: "admin",
|
||||
// DatabaseName: "admin",
|
||||
// },
|
||||
// Timeout: 10 * time.Second,
|
||||
// })
|
||||
//
|
||||
// repoAc := repository.NewAccountRepository2(logger, mongoDB.Collection("accounts"))
|
||||
// repoHi := repository.NewHistoryRepository2(logger, mongoDB.Collection("histories"))
|
||||
// InsertToDB(ctx, repoAc, repoHi)
|
||||
//
|
||||
// api := http2.NewAPI2(logger, mongoDB, nil, nil, nil, nil)
|
||||
//
|
||||
// app := fiber.New()
|
||||
// req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
// req.Header.Set("Content-Type", "application/json")
|
||||
//
|
||||
// requestBody := struct {
|
||||
// From int
|
||||
// Limit int
|
||||
// Page int
|
||||
// To int
|
||||
// }{
|
||||
// From: 1713087258,
|
||||
// Limit: 10,
|
||||
// Page: 1,
|
||||
// To: 1713260058,
|
||||
// }
|
||||
//
|
||||
// req = req.WithContext(context.WithValue(req.Context(), "requestBody", requestBody))
|
||||
// resp := httptest.NewRecorder()
|
||||
//
|
||||
//}
|
||||
|
||||
func InsertToDB(ctx context.Context, acc repository.AccountRepository, history repository.HistoryRepository) {
|
||||
partner1 := "partner1"
|
||||
|
@ -20,6 +20,7 @@ func TestSendMessage(t *testing.T) {
|
||||
Auth: &models.PlainAuth{Username: "kotilion.95@gmail.com", Password: "vWwbCSg4bf0p"},
|
||||
FiberClient: fiber.AcquireClient(),
|
||||
Logger: zap.NewExample(),
|
||||
MailAddress: "pashamullin2001@gmail.com",
|
||||
})
|
||||
|
||||
userEmail := "test@example.com"
|
||||
|
@ -42,7 +42,10 @@ func Test_PromoLTV(t *testing.T) {
|
||||
from := int64(0)
|
||||
to := int64(1714291104)
|
||||
|
||||
historyRepo := repository.NewHistoryRepository2(logger, mdb.Collection("histories"))
|
||||
historyRepo := repository.NewHistoryRepository(repository.HistoryRepositoryDeps{
|
||||
Logger: logger,
|
||||
MongoDB: mdb.Collection("histories"),
|
||||
})
|
||||
|
||||
codewordData, err := codeword.GetAllPromoActivations(ctx, &codeword_rpc.Time{
|
||||
From: from,
|
||||
|
Loading…
Reference in New Issue
Block a user