generated from PenaSide/GolangTemplate
Merge branch 'staging'
This commit is contained in:
commit
4dcc23c946
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,4 +4,5 @@ vendor/
|
||||
.idea/
|
||||
.vscode
|
||||
.env
|
||||
main
|
||||
|
||||
|
||||
@ -14,8 +14,6 @@ deploy-to-staging:
|
||||
extends: .deploy_template
|
||||
rules:
|
||||
- if: "$CI_COMMIT_BRANCH == $STAGING_BRANCH"
|
||||
after_script:
|
||||
- ls
|
||||
|
||||
deploy-to-prod:
|
||||
rules:
|
||||
|
||||
24
Dockerfile
24
Dockerfile
@ -1,5 +1,5 @@
|
||||
# BUILD
|
||||
FROM golang:1.20.3-alpine AS build
|
||||
FROM golang:1.22.0-alpine AS build
|
||||
|
||||
# Update packages and clear cache
|
||||
RUN apk add --no-cache curl
|
||||
@ -16,30 +16,10 @@ ADD ./tools/migrate /bin/golang-migrate/
|
||||
ADD . .
|
||||
RUN git config --global url."https://buildToken:glpat-axA8ttckx3aPf_xd2Dym@penahub.gitlab.yandexcloud.net/".insteadOf "https://penahub.gitlab.yandexcloud.net/"
|
||||
# Download go depences
|
||||
RUN go mod download
|
||||
RUN go mod download
|
||||
# Build app
|
||||
RUN GOOS=linux go build -o bin ./...
|
||||
|
||||
|
||||
|
||||
# TEST
|
||||
FROM alpine:3.18.3 AS test
|
||||
|
||||
# Install packages
|
||||
RUN apk --no-cache add ca-certificates
|
||||
# Create home directory
|
||||
WORKDIR /app
|
||||
# Copy build file
|
||||
COPY --from=build /app/bin/app ./app
|
||||
# Copy migration dir
|
||||
COPY --from=build /app/migrations/test ./migrations
|
||||
# Install migrate tool
|
||||
COPY --from=build /bin/golang-migrate /usr/local/bin
|
||||
# CMD
|
||||
CMD [ "./app" ]
|
||||
|
||||
|
||||
|
||||
# PRODUCTION
|
||||
FROM alpine:3.18.3 AS production
|
||||
|
||||
|
||||
@ -16,6 +16,8 @@ tags:
|
||||
description: кошелёк
|
||||
- name: history
|
||||
description: история
|
||||
- name: statistic
|
||||
description: статистика
|
||||
|
||||
paths:
|
||||
/account:
|
||||
@ -742,6 +744,85 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/quizlogo/stat:
|
||||
post:
|
||||
tags:
|
||||
- statistic
|
||||
summary: статистика пользователей, перешедших по логотипу в опросах
|
||||
operationId: quizLogoStat
|
||||
security:
|
||||
- Bearer: [ ]
|
||||
requestBody:
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
to:
|
||||
description: таймштамп времени, до которого выбирать статистику. если 0 или не передано - этого ограничения нет. верхняя граница времени
|
||||
type: integer
|
||||
from:
|
||||
description: таймштамп времени, после которого выбирать статистику. если 0 или не передано - этого ограничения нет. нижняя граница времени
|
||||
type: integer
|
||||
page:
|
||||
description: страница выборки
|
||||
type: integer
|
||||
limit:
|
||||
description: лимит выборки
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: Успешный ответ с данными статистики
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/QuizLogoStat'
|
||||
'500':
|
||||
description: Внутренняя ошибка сервера
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/promocode/ltv:
|
||||
post:
|
||||
tags:
|
||||
- statistic
|
||||
summary: статистика по промокодам в разрезе регистраций и оплат
|
||||
operationId: promocodeLTV
|
||||
security:
|
||||
- Bearer: [ ]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
to:
|
||||
description: таймштамп времени, до которого выбирать статистику
|
||||
type: integer
|
||||
from:
|
||||
description: таймштамп времени, после которого выбирать статистику
|
||||
type: integer
|
||||
required:
|
||||
- from
|
||||
- to
|
||||
responses:
|
||||
'200':
|
||||
description: Успешный ответ с данными статистики
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PromoLtvStat'
|
||||
'500':
|
||||
description: Внутренняя ошибка сервера
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
|
||||
|
||||
components:
|
||||
schemas:
|
||||
@ -931,6 +1012,52 @@ components:
|
||||
message:
|
||||
type: string
|
||||
example: user not found
|
||||
QuizLogoStat:
|
||||
type: array
|
||||
items:
|
||||
# count:
|
||||
# type: integer
|
||||
# description: Общее количество
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: user id
|
||||
money:
|
||||
type: integer
|
||||
description: Количество денег
|
||||
regs:
|
||||
type: integer
|
||||
description: Количество регистраций
|
||||
quizes:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
quiz:
|
||||
type: string
|
||||
description: qid quiz
|
||||
regs:
|
||||
type: integer
|
||||
description: Количество регистраций
|
||||
money:
|
||||
type: integer
|
||||
description: Количество денег
|
||||
PromoLtvStat:
|
||||
type: object
|
||||
properties:
|
||||
stats:
|
||||
type: object
|
||||
description: мапа ключ id промо, знчение количество регистраций и количество денег
|
||||
additionalProperties:
|
||||
type: object
|
||||
properties:
|
||||
regs:
|
||||
type: integer
|
||||
description: количество регистраций
|
||||
money:
|
||||
type: integer
|
||||
description: количество денег
|
||||
|
||||
securitySchemes:
|
||||
Bearer: # arbitrary name for the security scheme
|
||||
|
||||
23
api/proto/codeword/promo.proto
Normal file
23
api/proto/codeword/promo.proto
Normal file
@ -0,0 +1,23 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package codeword;
|
||||
|
||||
option go_package = "./codeword_rpc";
|
||||
|
||||
message Time {
|
||||
int64 from = 1;
|
||||
int64 to = 2;
|
||||
}
|
||||
|
||||
service PromoCodeService {
|
||||
rpc GetAllPromoActivations(Time) returns (stream PromoActivationResp);
|
||||
}
|
||||
|
||||
message PromoActivationResp {
|
||||
message UserTime {
|
||||
string UserID = 1;
|
||||
int64 Time = 2;
|
||||
}
|
||||
string ID = 1;
|
||||
repeated UserTime Users = 2;
|
||||
}
|
||||
@ -32,11 +32,19 @@ services:
|
||||
- KAFKA_BROKERS=customer-redpanda:9092
|
||||
- KAFKA_TOPIC_TARIFF=tariffs
|
||||
|
||||
- AUTH_MICROSERVICE_USER_URL=http://pena-auth-service:8000/user
|
||||
- HUBADMIN_MICROSERVICE_TARIFF_URL=http://hub-admin-backend-service:8000/tariff
|
||||
- CURRENCY_MICROSERVICE_TRANSLATE_URL=http://cbrfworker-service:8000/change
|
||||
- DISCOUNT_MICROSERVICE_GRPC_HOST=discount-service:9000
|
||||
- PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085
|
||||
- AUTH_MICROSERVICE_USER_URL=http://10.6.0.11:59300/user
|
||||
- HUBADMIN_MICROSERVICE_TARIFF_URL=http://10.6.0.11:59303/tariff
|
||||
- CURRENCY_MICROSERVICE_TRANSLATE_URL=http://10.6.0.11:3131/change
|
||||
- DISCOUNT_MICROSERVICE_GRPC_HOST=10.6.0.11:9001
|
||||
- PAYMENT_MICROSERVICE_GRPC_HOST=10.6.0.11:9085
|
||||
- VERIFICATION_MICROSERVICE_USER_URL=http://10.6.0.11:7035/verification
|
||||
- TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
|
||||
- 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_ADDRESS=sells@pena.digital
|
||||
ports:
|
||||
- 8082:8000
|
||||
- 9092:9000
|
||||
|
||||
@ -31,6 +31,7 @@ services:
|
||||
- PAYMENT_MICROSERVICE_GRPC_HOST=10.8.0.8:9085
|
||||
- VERIFICATION_MICROSERVICE_USER_URL=http://10.8.0.8:7035/verification
|
||||
- TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
|
||||
- CODEWORD_MICROSERVICE_GRPC_HOST=10.8.0.8:59665
|
||||
- API_URL=https://api.smtp.bz/v1/smtp/send
|
||||
- MAIL_SENDER=noreply@noreply.pena.digital
|
||||
- MAIL_API_KEY=8tv2xcsfCMBX3TCQxzgeeEwAEYyQrPUp0ggw
|
||||
@ -42,6 +43,8 @@ services:
|
||||
- JWT_PUBLIC_KEY=$JWT_PUBLIC_KEY
|
||||
- JWT_ISSUER=pena-auth-service
|
||||
- JWT_AUDIENCE=pena
|
||||
- PUBLIC_KEY=$USER_PKEY
|
||||
- PRIVATE_KEY=$USER_PRIVATEKEY
|
||||
ports:
|
||||
- 10.8.0.8:8065:8065
|
||||
- 10.8.0.8:9065:9065
|
||||
|
||||
@ -11,27 +11,28 @@ services:
|
||||
- HTTP_PORT=8065
|
||||
|
||||
- GRPC_HOST=0.0.0.0
|
||||
- GRPC_PORT=9085
|
||||
- GRPC_DOMEN=http://customer-service:9085
|
||||
- GRPC_PORT=9065
|
||||
- GRPC_DOMEN=10.8.0.6:9065
|
||||
|
||||
- MONGO_HOST=10.6.0.11
|
||||
- MONGO_HOST=10.8.0.6
|
||||
- MONGO_PORT=27017
|
||||
- MONGO_USER=$MONGO_USER
|
||||
- MONGO_PASSWORD=$MONGO_PASSWORD
|
||||
- MONGO_DB_NAME=customer
|
||||
- MONGO_AUTH=customer
|
||||
|
||||
- KAFKA_BROKERS=10.6.0.11:9092
|
||||
- KAFKA_BROKERS=10.8.0.6:9092
|
||||
- KAFKA_TOPIC_TARIFF=tariffs
|
||||
|
||||
- AUTH_MICROSERVICE_USER_URL=http://10.6.0.11:59300/user
|
||||
- HUBADMIN_MICROSERVICE_TARIFF_URL=http://10.6.0.11:59303/tariff
|
||||
- CURRENCY_MICROSERVICE_TRANSLATE_URL=http://10.6.0.11:3131/change
|
||||
- DISCOUNT_MICROSERVICE_GRPC_HOST=10.6.0.11:9001
|
||||
- PAYMENT_MICROSERVICE_GRPC_HOST=10.6.0.11:9085
|
||||
- VERIFICATION_MICROSERVICE_USER_URL=http://10.6.0.11:7035/verification
|
||||
- AUTH_MICROSERVICE_USER_URL=http://10.8.0.6:59300/user
|
||||
- HUBADMIN_MICROSERVICE_TARIFF_URL=http://10.8.0.6:59303/tariff
|
||||
- CURRENCY_MICROSERVICE_TRANSLATE_URL=http://10.8.0.6:3131/change
|
||||
- DISCOUNT_MICROSERVICE_GRPC_HOST=10.8.0.6:9001
|
||||
- PAYMENT_MICROSERVICE_GRPC_HOST=10.8.0.6:9085
|
||||
- VERIFICATION_MICROSERVICE_USER_URL=http://10.8.0.6:7035/verification
|
||||
- TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
|
||||
- API_URL=https://api.smtp.bz/v1/smtp/send
|
||||
- CODEWORD_MICROSERVICE_GRPC_HOST=10.8.0.6:59665
|
||||
- MAIL_SENDER=noreply@mailing.pena.digital
|
||||
- MAIL_API_KEY=P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev
|
||||
- MAIL_AUTH_USERNAME=kotilion.95@gmail.com
|
||||
@ -41,8 +42,10 @@ services:
|
||||
- JWT_PUBLIC_KEY=$JWT_PUBLIC_KEY
|
||||
- JWT_ISSUER=pena-auth-service
|
||||
- JWT_AUDIENCE=pena
|
||||
- PUBLIC_KEY=$USER_PKEY
|
||||
- PRIVATE_KEY=$USER_PRIVATEKEY
|
||||
ports:
|
||||
- 8065:8065
|
||||
- 9065:9065
|
||||
- 10.8.0.6:8065:8065
|
||||
- 10.8.0.6:9065:9065
|
||||
networks:
|
||||
- default
|
||||
|
||||
68
go.mod
68
go.mod
@ -1,6 +1,6 @@
|
||||
module penahub.gitlab.yandexcloud.net/pena-services/customer
|
||||
|
||||
go 1.21
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
github.com/deepmap/oapi-codegen v1.16.2
|
||||
@ -12,121 +12,63 @@ require (
|
||||
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
|
||||
github.com/twmb/franz-go v1.16.1
|
||||
github.com/twmb/franz-go/pkg/kadm v1.11.0
|
||||
go.mongodb.org/mongo-driver v1.14.0
|
||||
go.uber.org/zap v1.27.0
|
||||
google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c
|
||||
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
|
||||
)
|
||||
|
||||
require (
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20231115204500-e097f827e652.1 // indirect
|
||||
connectrpc.com/connect v1.14.0 // indirect
|
||||
connectrpc.com/otelconnect v0.7.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/bufbuild/buf v1.29.0 // indirect
|
||||
github.com/bufbuild/protocompile v0.8.0 // indirect
|
||||
github.com/bufbuild/protovalidate-go v0.5.0 // indirect
|
||||
github.com/bufbuild/protoyaml-go v0.1.7 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.5.0 // indirect
|
||||
github.com/docker/cli v24.0.7+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker v25.0.0+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.1 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/felixge/fgprof v0.9.3 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.11 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.9 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.0.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // 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/cel-go v0.19.0 // indirect
|
||||
github.com/google/go-containerregistry v0.18.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/jdx/go-netrc v1.0.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // 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/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/profile v1.7.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rs/cors v1.10.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/cobra v1.8.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/tetratelabs/wazero v1.6.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
|
||||
github.com/valyala/fasthttp v1.52.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/vbatts/tar-split v0.11.5 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
|
||||
go.opentelemetry.io/otel v1.22.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.22.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.22.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.22.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
|
||||
golang.org/x/mod v0.14.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/term v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.17.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
268
go.sum
268
go.sum
@ -1,119 +1,43 @@
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20231115204500-e097f827e652.1 h1:u0olL4yf2p7Tl5jfsAK5keaFi+JFJuv1CDHrbiXkxkk=
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20231115204500-e097f827e652.1/go.mod h1:tiTMKD8j6Pd/D2WzREoweufjzaJKHZg35f/VGcZ2v3I=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
connectrpc.com/connect v1.14.0 h1:PDS+J7uoz5Oui2VEOMcfz6Qft7opQM9hPiKvtGC01pA=
|
||||
connectrpc.com/connect v1.14.0/go.mod h1:uoAq5bmhhn43TwhaKdGKN/bZcGtzPW1v+ngDTn5u+8s=
|
||||
connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY=
|
||||
connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||
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/bufbuild/buf v1.29.0 h1:llP6HqOcCaSGBxOfnrp/mwvcY1O/dciEOl1QaMEOB3M=
|
||||
github.com/bufbuild/buf v1.29.0/go.mod h1:UTjvPXTObvKQiGqxod32wt9zRz70TJsMpaigpbIZGuc=
|
||||
github.com/bufbuild/protocompile v0.8.0 h1:9Kp1q6OkS9L4nM3FYbr8vlJnEwtbpDPQlQOVXfR+78s=
|
||||
github.com/bufbuild/protocompile v0.8.0/go.mod h1:+Etjg4guZoAqzVk2czwEQP12yaxLJ8DxuqCJ9qHdH94=
|
||||
github.com/bufbuild/protovalidate-go v0.5.0 h1:xFery2RlLh07FQTvB7hlasKqPrDK2ug+uw6DUiuadjo=
|
||||
github.com/bufbuild/protovalidate-go v0.5.0/go.mod h1:3XAwFeJ2x9sXyPLgkxufH9sts1tQRk8fdt1AW93NiUU=
|
||||
github.com/bufbuild/protoyaml-go v0.1.7 h1:3uKIoNb/l5zrZ93u+Xzsg6cdAO06lveZE/K7UUbUQLw=
|
||||
github.com/bufbuild/protoyaml-go v0.1.7/go.mod h1:R8vE2+l49bSiIExP4VJpxOXleHE+FDzZ6HVxr3cYunw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deepmap/oapi-codegen v1.1.1 h1:6vwgopsCgvIYG6rWc+GnWakgN7oznZYj238Xta0hE9Y=
|
||||
github.com/deepmap/oapi-codegen v1.1.1/go.mod h1:dAc3+1joSEZQ6WX0WNaqZAN1J1rCX3ptKLX9bghP7Y0=
|
||||
github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s=
|
||||
github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas=
|
||||
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1xfI36MSkFg=
|
||||
github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v25.0.0+incompatible h1:g9b6wZTblhMgzOT2tspESstfw6ySZ9kdm94BLDKaZac=
|
||||
github.com/docker/docker v25.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
|
||||
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/getkin/kin-openapi v0.116.0 h1:o986hwgMzR972JzOG5j6+WTwWqllZLs1EJKMKCivs2E=
|
||||
github.com/getkin/kin-openapi v0.116.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
|
||||
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-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
|
||||
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
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.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
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.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||
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.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE=
|
||||
github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
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/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-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.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
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=
|
||||
@ -124,42 +48,20 @@ github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaW
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/cel-go v0.19.0 h1:vVgaZoHPBDd1lXCYGQOh5A06L4EtuIfmqQ/qnSXSKiU=
|
||||
github.com/google/cel-go v0.19.0/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.18.0 h1:ShE7erKNPqRh5ue6Z9DUOlk04WsnFWPO6YGr3OxnfoQ=
|
||||
github.com/google/go-containerregistry v0.18.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 h1:WzfWbQz/Ze8v6l++GGbGNFZnUShVpP/0xffCPLL+ax8=
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
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/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc=
|
||||
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
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/jdx/go-netrc v1.0.0 h1:QbLMLyCZGj0NA8glAhxUpf1zDg6cxnWgMBbjq40W0gQ=
|
||||
github.com/jdx/go-netrc v1.0.0/go.mod h1:Gh9eFQJnoTNIRHXl2j5bJXA1u84hQWJWgGh569zF3v8=
|
||||
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=
|
||||
@ -167,195 +69,105 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
|
||||
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.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
|
||||
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
|
||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/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=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=
|
||||
github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ=
|
||||
github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
|
||||
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
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.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
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/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/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.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/oapi-codegen/runtime v1.0.0 h1:P4rqFX5fMFWqRzY9M/3YF9+aPSPPB06IzP2P7oOxrWo=
|
||||
github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18B34OO356yJ/A=
|
||||
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/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
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.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
|
||||
github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
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.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
|
||||
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
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/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
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/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
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 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
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/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
|
||||
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE=
|
||||
github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
|
||||
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/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tetratelabs/wazero v1.6.0 h1:z0H1iikCdP8t+q341xqepY4EWvHEw8Es7tlqiVzlP3g=
|
||||
github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
|
||||
github.com/twmb/franz-go v1.13.6 h1:DRh06Hy3GthZuA+fQhDo+IMV+QUZHQfS2TIiWf/rCw8=
|
||||
github.com/twmb/franz-go v1.13.6/go.mod h1:jm/FtYxmhxDTN0gNSb26XaJY0irdSVcsckLiR5tQNMk=
|
||||
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
|
||||
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
|
||||
github.com/twmb/franz-go v1.16.1 h1:rpWc7fB9jd7TgmCyfxzenBI+QbgS8ZfJOUQE+tzPtbE=
|
||||
github.com/twmb/franz-go v1.16.1/go.mod h1:/pER254UPPGp/4WfGqRi+SIRGE50RSQzVubQp6+N4FA=
|
||||
github.com/twmb/franz-go/pkg/kadm v1.8.1 h1:SrzL855I7gQTGdMtOYGTHhebs7TPgPN29FPtjusqwlE=
|
||||
github.com/twmb/franz-go/pkg/kadm v1.8.1/go.mod h1:qUSM7pxoMCU1UNu5H4USE64ODcVmeG9LS96mysv1nu8=
|
||||
github.com/twmb/franz-go/pkg/kadm v1.11.0 h1:FfeWJ0qadntFpAcQt8JzNXW4dijjytZNLrzJuzzzuxA=
|
||||
github.com/twmb/franz-go/pkg/kadm v1.11.0/go.mod h1:qrhkdH+SWS3ivmbqOgHbpgVHamhaKcjH0UM+uOp0M1A=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0 h1:tbp9hxU6m8qZhQTlpGiaIJOm4BXix5lsuEZ7K00dF0s=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0/go.mod h1:SxG/xJKhgPu25SamAq0rrucfp7lbzCpEXOC+vH/ELrY=
|
||||
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 v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
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.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
|
||||
github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
|
||||
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
|
||||
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
|
||||
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
|
||||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
|
||||
go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
|
||||
go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
|
||||
go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
|
||||
go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
|
||||
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
|
||||
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
|
||||
go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
|
||||
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -363,16 +175,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
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.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
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/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
|
||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
@ -381,8 +187,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -392,15 +196,10 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -411,8 +210,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -421,27 +218,15 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@ -449,22 +234,15 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
@ -479,8 +257,6 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -490,18 +266,10 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 h1:znp6mq/drrY+6khTAlJUDNFFcDGV2ENLYKpMq8SyCds=
|
||||
google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg=
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
|
||||
google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c h1:Zmyn5CV/jxzKnF+3d+xzbomACPwLQqVpLTpyXN5uTaQ=
|
||||
google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe h1:0poefMBYvYbs7g5UkjS6HcxBPaTRAmznle9jnxYoAI8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240221002015-b0ce06bbee7c h1:9g7erC9qu44ks7UK4gDNlnk4kOxZG707xKm4jVniy6o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
@ -509,27 +277,19 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
|
||||
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
||||
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/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.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=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@ -537,7 +297,7 @@ 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-20240202120244-c4ef330cfe5d h1:gbaDt35HMDqOK84WYmDIlXMI7rstUcRqNttaT6Kx1do=
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM=
|
||||
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=
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"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 (
|
||||
@ -66,6 +67,11 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
TariffClient: kafkaTariffClient,
|
||||
})
|
||||
|
||||
err = kafkaTariffClient.Ping(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clients := initialize.NewClients(initialize.ClientsDeps{
|
||||
Logger: logger,
|
||||
AuthURL: &config.Service.AuthMicroservice.URL,
|
||||
@ -101,7 +107,9 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
return fmt.Errorf("failed to loading openapi spec: %w", err)
|
||||
}
|
||||
|
||||
api := swagger.NewAPI2(logger, mongoDB, config, brokers.TariffConsumer, brokers.TariffProducer)
|
||||
encrypt := qutils.NewEncrypt(config.Service.PubKey, config.Service.PrivKey)
|
||||
|
||||
api := swagger.NewAPI2(logger, mongoDB, config, brokers.TariffConsumer, brokers.TariffProducer, encrypt)
|
||||
|
||||
serverHTTP, httpErr := server.NewHTTP(server.DepsHTTP{
|
||||
Logger: logger,
|
||||
|
||||
@ -4,11 +4,6 @@ import (
|
||||
"go.uber.org/zap"
|
||||
"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/rest/account"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/rest/cart"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/rest/currency"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/rest/history"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/rest/wallet"
|
||||
)
|
||||
|
||||
type ControllersDeps struct {
|
||||
@ -17,38 +12,12 @@ type ControllersDeps struct {
|
||||
}
|
||||
|
||||
type Controllers struct {
|
||||
AccountController *account.Controller
|
||||
CurrencyController *currency.Controller
|
||||
CartController *cart.Controller
|
||||
HistoryController *history.Controller
|
||||
WalletController *wallet.Controller
|
||||
PaymentController *payment.Controller
|
||||
CustomerController *customer.Controller
|
||||
}
|
||||
|
||||
func NewControllers(deps ControllersDeps) *Controllers {
|
||||
return &Controllers{
|
||||
AccountController: account.New(account.Deps{
|
||||
Logger: deps.Logger,
|
||||
Service: deps.Services.AccountService,
|
||||
}),
|
||||
CurrencyController: currency.New(currency.Deps{
|
||||
Logger: deps.Logger,
|
||||
CurrencyService: deps.Services.CurrencyService,
|
||||
}),
|
||||
CartController: cart.New(cart.Deps{
|
||||
Logger: deps.Logger,
|
||||
CartService: deps.Services.CartService,
|
||||
}),
|
||||
HistoryController: history.New(history.Deps{
|
||||
Logger: deps.Logger,
|
||||
HistoryService: deps.Services.HistoryService,
|
||||
}),
|
||||
WalletController: wallet.New(wallet.Deps{
|
||||
Logger: deps.Logger,
|
||||
WalletService: deps.Services.WalletService,
|
||||
PaymentService: deps.Services.PaymentService,
|
||||
}),
|
||||
PaymentController: payment.New(payment.Deps{
|
||||
Logger: deps.Logger,
|
||||
PaymentCallbackService: deps.Services.PaymentCallbackService,
|
||||
|
||||
@ -53,11 +53,6 @@ func TestNewControllers(t *testing.T) {
|
||||
})
|
||||
|
||||
assert.NotNil(t, controllers)
|
||||
assert.NotNil(t, controllers.AccountController)
|
||||
assert.NotNil(t, controllers.CurrencyController)
|
||||
assert.NotNil(t, controllers.CartController)
|
||||
assert.NotNil(t, controllers.HistoryController)
|
||||
assert.NotNil(t, controllers.WalletController)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -3,13 +3,9 @@ package initialize
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/account"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/broker/tariff"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/callback"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/cart"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/currency"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/history"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/payment"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/wallet"
|
||||
)
|
||||
|
||||
@ -22,12 +18,8 @@ type ServicesDeps struct {
|
||||
}
|
||||
|
||||
type Services struct {
|
||||
AccountService *account.Service
|
||||
CurrencyService *currency.Service
|
||||
CartService *cart.Service
|
||||
HistoryService *history.Service
|
||||
WalletService *wallet.Service
|
||||
PaymentService *payment.Service
|
||||
PaymentCallbackService *callback.PaymentCallbackService
|
||||
TariffBrokerService *tariff.Service
|
||||
}
|
||||
@ -58,30 +50,6 @@ func NewServices(deps ServicesDeps) *Services {
|
||||
return &Services{
|
||||
WalletService: walletService,
|
||||
HistoryService: historyService,
|
||||
AccountService: account.New(account.Deps{
|
||||
Logger: deps.Logger,
|
||||
Repository: deps.Repositories.AccountRepository,
|
||||
AuthClient: deps.Clients.AuthClient,
|
||||
}),
|
||||
CurrencyService: currency.New(currency.Deps{
|
||||
Logger: deps.Logger,
|
||||
Repository: deps.Repositories.CurrencyRepository,
|
||||
}),
|
||||
CartService: cart.New(cart.Deps{
|
||||
Logger: deps.Logger,
|
||||
Repository: deps.Repositories.AccountRepository,
|
||||
HubadminClient: deps.Clients.HubadminClient,
|
||||
DiscountClient: deps.Clients.DiscountClient,
|
||||
WalletService: walletService,
|
||||
HistoryService: historyService,
|
||||
TariffBrokerService: tariffBrokerService,
|
||||
}),
|
||||
PaymentService: payment.New(payment.Deps{
|
||||
Logger: deps.Logger,
|
||||
ConfigurationGRPC: deps.ConfigurationGRPC,
|
||||
PaymentClient: deps.Clients.PaymentClient,
|
||||
AuthClient: deps.Clients.AuthClient,
|
||||
}),
|
||||
PaymentCallbackService: callback.NewPaymentCallbackService(callback.PaymentCallbackServiceDeps{
|
||||
Logger: deps.Logger,
|
||||
AccountRepository: deps.Repositories.AccountRepository,
|
||||
|
||||
@ -48,12 +48,8 @@ func TestNewServices(t *testing.T) {
|
||||
})
|
||||
|
||||
assert.NotNil(t, services)
|
||||
assert.NotNil(t, services.AccountService)
|
||||
assert.NotNil(t, services.CartService)
|
||||
assert.NotNil(t, services.CurrencyService)
|
||||
assert.NotNil(t, services.HistoryService)
|
||||
assert.NotNil(t, services.WalletService)
|
||||
assert.NotNil(t, services.PaymentService)
|
||||
assert.NotNil(t, services.PaymentCallbackService)
|
||||
assert.NotNil(t, services.TariffBrokerService)
|
||||
})
|
||||
|
||||
81
internal/interface/client/codeword.go
Normal file
81
internal/interface/client/codeword.go
Normal file
@ -0,0 +1,81 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"io"
|
||||
"log"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
codeword_rpc "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/codeword"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
|
||||
)
|
||||
|
||||
type CodewordClientDeps struct {
|
||||
Logger *zap.Logger
|
||||
CodewordServiceHost string
|
||||
}
|
||||
|
||||
type CodewordClient struct {
|
||||
logger *zap.Logger
|
||||
codewordServiceHost string
|
||||
}
|
||||
|
||||
func NewCodewordClient(deps CodewordClientDeps) *CodewordClient {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <NewCodewordClient>")
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(deps.CodewordServiceHost) {
|
||||
log.Panicln("codeword host is empty on <NewCodewordClient>")
|
||||
}
|
||||
|
||||
return &CodewordClient{
|
||||
logger: deps.Logger,
|
||||
codewordServiceHost: deps.CodewordServiceHost,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *CodewordClient) GetAllPromoActivations(ctx context.Context, req *codeword_rpc.Time) (map[string][]*codeword_rpc.PromoActivationResp_UserTime, errors.Error) {
|
||||
connection, err := grpc.Dial(receiver.codewordServiceHost, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to connect on <GetAllPromoActivations> of <CodewordClient>", zap.Error(err), zap.String("codeword host", receiver.codewordServiceHost))
|
||||
return nil, errors.New(fmt.Errorf("failed connect to codeword service: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := connection.Close(); closeErr != nil {
|
||||
receiver.logger.Error("failed to close connection on <GetAllPromoActivations> of <CodewordClient>", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
client := codeword_rpc.NewPromoCodeServiceClient(connection)
|
||||
|
||||
stream, err := client.GetAllPromoActivations(ctx, req)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed getting stats resp on <GetAllPromoActivations> of <DiscountClient>", zap.Error(err))
|
||||
return nil, errors.New(fmt.Errorf("failed getting stats resp from codeword: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
response := make(map[string][]*codeword_rpc.PromoActivationResp_UserTime)
|
||||
|
||||
for {
|
||||
activations, err := stream.Recv()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, errors.New(fmt.Errorf("failed to receive response stream in codeword rpc client: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
if activations == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
response[activations.ID] = append(response[activations.ID], activations.Users...)
|
||||
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
@ -60,3 +60,26 @@ func (receiver *DiscountClient) Apply(ctx context.Context, request *discount.App
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (receiver *DiscountClient) DeleteDiscount(ctx context.Context, request *discount.GetDiscountByIDRequest) (*discount.Discount, errors.Error) {
|
||||
connection, err := grpc.Dial(receiver.discountServiceHost, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to connect on <DeleteDiscount> of <DiscountClient>", zap.Error(err), zap.String("discount host", receiver.discountServiceHost))
|
||||
return nil, errors.New(fmt.Errorf("failed connect to discount service: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := connection.Close(); closeErr != nil {
|
||||
receiver.logger.Error("failed to close connection on <DeleteDiscount> of <DiscountClient>", zap.Error(closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
client := discount.NewDiscountServiceClient(connection)
|
||||
|
||||
response, err := client.DeleteDiscount(ctx, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to apply discounts on <DeleteDiscount> of <DiscountClient>", zap.Error(err), zap.Any("request", request))
|
||||
return nil, errors.New(fmt.Errorf("failed to delete discount by id: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ func (receiver *MailClient) SendMessage(userEmail string, verification *models.V
|
||||
return handleError(receiver.deps.Logger, "Error closing form writer", err)
|
||||
}
|
||||
|
||||
fmt.Println("SEEEEEND", receiver.deps.ApiUrl)
|
||||
fmt.Println("SEEEEEND", receiver.deps.ApiUrl)
|
||||
req := receiver.deps.FiberClient.Post(receiver.deps.ApiUrl).Body(form.Bytes()).ContentType(writer.FormDataContentType())
|
||||
if receiver.deps.ApiKey != "" {
|
||||
req.Set("Authorization", receiver.deps.ApiKey)
|
||||
|
||||
@ -42,7 +42,7 @@ func (receiver *Controller) InsertHistory(ctx context.Context, in *customer.Hist
|
||||
UserID: in.UserID,
|
||||
Comment: in.Comment,
|
||||
Key: in.Key,
|
||||
RawDetails: in.RawDetails,
|
||||
//RawDetails: in.RawDetails,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to insert history on <InsertHistory> of <HistoryController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to insert history", err)
|
||||
|
||||
@ -45,6 +45,7 @@ func (receiver *Controller) OnSuccess(ctx context.Context, in *payment_callback.
|
||||
Currency: in.Payment.Currency,
|
||||
Amount: in.Payment.Amount,
|
||||
UserID: in.Payment.UserID,
|
||||
Type: in.Payment.Type,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to send success event on <OnSuccess> of <PaymentController>", zap.Error(err))
|
||||
return nil, errors.GRPC("failed to send success event", err)
|
||||
|
||||
@ -1,166 +0,0 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"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/service/account"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/echotools"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Service *account.Service
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
logger *zap.Logger
|
||||
service *account.Service
|
||||
}
|
||||
|
||||
func New(deps Deps) *Controller {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (account controller)>")
|
||||
}
|
||||
|
||||
if deps.Service == nil {
|
||||
log.Panicln("account service is nil on <New (account controller)>")
|
||||
}
|
||||
|
||||
return &Controller{
|
||||
logger: deps.Logger,
|
||||
service: deps.Service,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Controller) GetAccount(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <GetAccount> of <AccountController>")
|
||||
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
account, err := receiver.service.GetAccountByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (receiver *Controller) GetDirectAccount(ctx echo.Context, userID string) error {
|
||||
account, err := receiver.service.GetAccountByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (receiver *Controller) GetAccounts(ctx echo.Context, params swagger.PaginationAccountsParams) error {
|
||||
response, err := receiver.service.GetAccountsList(
|
||||
ctx.Request().Context(),
|
||||
utils.DeterminePagination(params.Page, params.Limit),
|
||||
)
|
||||
if err != nil {
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
func (receiver *Controller) CreateAccount(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <CreateAccount> of <AccountController>")
|
||||
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
account, err := receiver.service.CreateAccountByUserID(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (receiver *Controller) RemoveAccount(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <RemoveAccount> of <AccountController>")
|
||||
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
account, err := receiver.service.RemoveAccount(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (receiver *Controller) RemoveDirectAccount(ctx echo.Context, userID string) error {
|
||||
account, err := receiver.service.RemoveAccount(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (receiver *Controller) SetVerificationStatus(ctx echo.Context, userID string) error {
|
||||
request, bindErr := echotools.Bind[models.SetAccountStatus](ctx)
|
||||
if bindErr != nil {
|
||||
receiver.logger.Error("failed to bind json request on <SetVerificationStatus> of <AccountController>", zap.Error(bindErr))
|
||||
return errors.HTTP(ctx, errors.New(fmt.Errorf("failed to bind json: %w", bindErr), errors.ErrInternalError))
|
||||
}
|
||||
|
||||
account, err := receiver.service.SetVerificationStatus(ctx.Request().Context(), userID, request.Status)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed set status on <SetVerificationStatus> of <AccountController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (receiver *Controller) UpdateAccountName(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <UpdateAccountName> of <AccountController>")
|
||||
return errors.HTTP(ctx, errors.New(fmt.Errorf("failed to convert jwt payload to string: %s", userID), errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
request, bindErr := echotools.Bind[models.Name](ctx)
|
||||
if bindErr != nil {
|
||||
receiver.logger.Error("failed to bind json request on <UpdateAccountName> of <AccountController>", zap.Error(bindErr))
|
||||
return errors.HTTP(ctx, errors.New(fmt.Errorf("failed to bind json: %w", bindErr), errors.ErrInternalError))
|
||||
}
|
||||
|
||||
account, err := receiver.service.UpdateAccountName(ctx.Request().Context(), userID, request)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to update account name on <UpdateAccountName> of <AccountController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
@ -1,118 +0,0 @@
|
||||
package cart
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"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/service/cart"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
CartService *cart.Service
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
logger *zap.Logger
|
||||
cartService *cart.Service
|
||||
}
|
||||
|
||||
func New(deps Deps) *Controller {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (cart controller)>")
|
||||
}
|
||||
|
||||
if deps.CartService == nil {
|
||||
log.Panicln("cart service is nil on <New (cart controller)>")
|
||||
}
|
||||
|
||||
return &Controller{
|
||||
logger: deps.Logger,
|
||||
cartService: deps.CartService,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Controller) Remove(ctx echo.Context, params swagger.RemoveFromCartParams) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <Remove> of <CartController>")
|
||||
return errors.HTTP(ctx, errors.NewWithMessage("failed to convert jwt payload to string", errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(params.Id) {
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to remove cart item from user <%s>: empty item id", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
cartItems, err := receiver.cartService.Remove(ctx.Request().Context(), userID, params.Id)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to remove item from cart on <Remove> of <CartController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, cartItems)
|
||||
}
|
||||
|
||||
func (receiver *Controller) Add(ctx echo.Context, params swagger.Add2cartParams) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <Add> of <CartController>")
|
||||
return errors.HTTP(ctx, errors.NewWithMessage("failed to convert jwt payload to string", errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
token, ok := ctx.Get(models.AuthJWTDecodedAccessTokenKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert access token payload to string on <Add> of <CartController>")
|
||||
return errors.HTTP(ctx, errors.NewWithMessage("failed to convert access token payload to string", errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(params.Id) {
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to add cart item to user <%s>: empty item id", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
cartItems, err := receiver.cartService.Add(ctx.Request().Context(), &models.AddItemToCart{
|
||||
UserID: userID,
|
||||
TariffID: params.Id,
|
||||
AccessToken: token,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to add item to cart on <Add> of <CartController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, cartItems)
|
||||
}
|
||||
|
||||
func (receiver *Controller) Pay(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <Pay> of <CartController>")
|
||||
return errors.HTTP(ctx, errors.NewWithMessage("failed to convert jwt payload to string", errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
token, ok := ctx.Get(models.AuthJWTDecodedAccessTokenKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert access token payload to string on <Pay> of <CartController>")
|
||||
return errors.HTTP(ctx, errors.NewWithMessage("failed to convert access token payload to string", errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
account, err := receiver.cartService.Pay(ctx.Request().Context(), token, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to pay cart on <Pay> of <CartController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
@ -1,82 +0,0 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/currency"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/echotools"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
CurrencyService *currency.Service
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
logger *zap.Logger
|
||||
currencyService *currency.Service
|
||||
}
|
||||
|
||||
func New(deps Deps) *Controller {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (account controller)>")
|
||||
}
|
||||
|
||||
if deps.CurrencyService == nil {
|
||||
log.Panicln("currency service is nil on <New (account controller)>")
|
||||
}
|
||||
|
||||
return &Controller{
|
||||
logger: deps.Logger,
|
||||
currencyService: deps.CurrencyService,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Controller) GetCurrencies(ctx echo.Context) error {
|
||||
currencies, err := receiver.currencyService.GetCurrencies(ctx.Request().Context())
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get currencies on <GetCurrencies> of <CurrencyController>",
|
||||
zap.Error(err),
|
||||
)
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, currencies)
|
||||
}
|
||||
|
||||
func (receiver *Controller) PutCurrencies(ctx echo.Context) error {
|
||||
currencies, bindErr := echotools.Bind[[]string](ctx)
|
||||
if bindErr != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to parse body on <PutCurrencies> of <CurrencyController>",
|
||||
zap.Error(bindErr),
|
||||
)
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to parse body: %w", bindErr),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
currenciesCopy := *currencies
|
||||
|
||||
if len(currenciesCopy) < 1 {
|
||||
currenciesCopy = make([]string, 0)
|
||||
}
|
||||
|
||||
updatedCurrencies, err := receiver.currencyService.PutCurrencies(ctx.Request().Context(), currenciesCopy)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to put currencies on <PutCurrencies> of <CurrencyController>",
|
||||
zap.Error(err),
|
||||
)
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, updatedCurrencies)
|
||||
}
|
||||
@ -1,135 +0,0 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"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/service/history"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
HistoryService *history.Service
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
logger *zap.Logger
|
||||
historyService *history.Service
|
||||
}
|
||||
|
||||
func New(deps Deps) *Controller {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (history controller)>")
|
||||
}
|
||||
|
||||
if deps.HistoryService == nil {
|
||||
log.Panicln("HistoryService is nil on <New (history controller)>")
|
||||
}
|
||||
|
||||
return &Controller{
|
||||
logger: deps.Logger,
|
||||
historyService: deps.HistoryService,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Controller) GetHistoryList(ctx echo.Context, params swagger.GetHistoryParams) error {
|
||||
var userID string
|
||||
|
||||
if params.AccountID != nil && *params.AccountID != "" {
|
||||
userID = *params.AccountID
|
||||
} else {
|
||||
userID, _ = ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
}
|
||||
|
||||
histories, err := receiver.historyService.GetHistoryList(ctx.Request().Context(), &history.GetHistories{
|
||||
Type: params.Type,
|
||||
UserID: userID,
|
||||
Pagination: &models.Pagination{
|
||||
Page: int64(*params.Page),
|
||||
Limit: int64(*params.Limit),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get histories on <GetHistoryList> of <HistoryController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, histories)
|
||||
}
|
||||
|
||||
// TODO:tests.
|
||||
func (receiver *Controller) GetRecentTariffs(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <GetRecentTariffs> of <HistoryController>")
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
tariffs, err := receiver.historyService.GetRecentTariffs(ctx.Request().Context(), userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get recent tariffs on <GetRecentTariffs> of <HistoryController>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, tariffs)
|
||||
}
|
||||
|
||||
// TODO:tests.
|
||||
func (receiver *Controller) SendReport(ctx echo.Context) error {
|
||||
historyID := ctx.Param("id")
|
||||
|
||||
err := receiver.historyService.GetHistoryByID(ctx.Request().Context(), historyID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to send report on <SendReport> of <HistoryController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.NoContent(http.StatusOK)
|
||||
}
|
||||
|
||||
// TODO:tests.
|
||||
func (receiver *Controller) CalculateLTV(ctx echo.Context) error {
|
||||
var req swagger.CalculateLTVJSONBody
|
||||
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
receiver.logger.Error("failed to bind request", zap.Error(err))
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to bind request: %s", err),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
if req.From > req.To && req.To != 0 {
|
||||
receiver.logger.Error("From timestamp must be less than To timestamp unless To is 0")
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("From timestamp must be less than To timestamp unless To is 0"),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
ltv, err := receiver.historyService.CalculateCustomerLTV(ctx.Request().Context(), req.From, req.To)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to calculate LTV", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
response := struct {
|
||||
LTV int64 `json:"LTV"`
|
||||
}{
|
||||
LTV: ltv,
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, response)
|
||||
}
|
||||
@ -1,161 +0,0 @@
|
||||
package wallet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"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/service/payment"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/wallet"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/echotools"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
WalletService *wallet.Service
|
||||
PaymentService *payment.Service
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
logger *zap.Logger
|
||||
walletService *wallet.Service
|
||||
paymentService *payment.Service
|
||||
}
|
||||
|
||||
func New(deps Deps) *Controller {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (wallet controller)>")
|
||||
}
|
||||
|
||||
if deps.WalletService == nil {
|
||||
log.Panicln("wallet service is nil on <New (wallet controller)>")
|
||||
}
|
||||
|
||||
if deps.PaymentService == nil {
|
||||
log.Panicln("payment service is nil on <New (wallet controller)>")
|
||||
}
|
||||
|
||||
return &Controller{
|
||||
logger: deps.Logger,
|
||||
walletService: deps.WalletService,
|
||||
paymentService: deps.PaymentService,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Controller) ChangeCurrency(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <ChangeCurrency> of <WallerController>")
|
||||
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
request, bindErr := echotools.Bind[models.ChangeCurrency](ctx)
|
||||
if bindErr != nil {
|
||||
receiver.logger.Error("failed to bind body on <ChangeCurrency> of <WalletController>", zap.Error(bindErr))
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to parse body on <ChangeCurrency> of <WalletController>: %w", bindErr),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
if validate.IsStringEmpty(request.Currency) {
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("empty currency key on <ChangeCurrency> of <WalletController>: %w", errors.ErrInvalidArgs),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
account, err := receiver.walletService.ChangeCurrency(ctx.Request().Context(), userID, request.Currency)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to put money on <ChangeCurrency> of <WalletController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
func (receiver *Controller) GetPaymentLink(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <GetPaymentLink> of <WallerController>")
|
||||
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
request, bindErr := echotools.Bind[models.GetPaymentLinkBody](ctx)
|
||||
if bindErr != nil {
|
||||
receiver.logger.Error("failed to bind body on <GetPaymentLink> of <WalletController>", zap.Error(bindErr))
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to parse body on <GetPaymentLink> of <WalletController>: %w", bindErr),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
if validateErr := utils.ValidateGetPaymentLinkBody(request); validateErr != nil {
|
||||
receiver.logger.Error("failed to validate body on <GetPaymentLink> of <WalletController>", zap.Error(validateErr))
|
||||
return errors.HTTP(ctx, validateErr)
|
||||
}
|
||||
|
||||
link, err := receiver.paymentService.GetPaymentLink(ctx.Request().Context(), &models.GetPaymentLinkRequest{
|
||||
Body: request,
|
||||
UserID: userID,
|
||||
ClientIP: ctx.RealIP(),
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get payment link on <GetPaymentLink> of <WalletController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, &models.GetPaymentLinkResponse{Link: link})
|
||||
}
|
||||
|
||||
func (receiver *Controller) PostWalletRspay(ctx echo.Context) error {
|
||||
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
|
||||
if !ok {
|
||||
receiver.logger.Error("failed to convert jwt payload to string on <PostWalletRspay> of <WallerController>")
|
||||
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
var req swagger.PostWalletRspayJSONBody
|
||||
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
receiver.logger.Error("failed to bind request", zap.Error(err))
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to bind request: %s", err),
|
||||
errors.ErrInvalidArgs,
|
||||
))
|
||||
}
|
||||
|
||||
token := ctx.Request().Header.Get("Authorization")
|
||||
fmt.Println("HEADERS", ctx.Request().Header)
|
||||
|
||||
if err := receiver.walletService.PostWalletRspay(ctx.Request().Context(), token, userID, req); err != nil {
|
||||
if err == errors.ErrNoAccess {
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
return errors.HTTP(ctx, errors.New(
|
||||
fmt.Errorf("failed to process rspay: %w", err),
|
||||
errors.ErrInternalError,
|
||||
))
|
||||
}
|
||||
|
||||
return ctx.NoContent(http.StatusOK)
|
||||
}
|
||||
@ -174,35 +174,6 @@ func (receiver *AccountRepository) Remove(ctx context.Context, id string) (*mode
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
func (receiver *AccountRepository) Delete(ctx context.Context, id string) (*models.Account, errors.Error) {
|
||||
account := models.Account{}
|
||||
|
||||
filter := bson.M{
|
||||
fields.Account.UserID: id,
|
||||
fields.Account.IsDeleted: false,
|
||||
}
|
||||
|
||||
if err := receiver.mongoDB.FindOneAndDelete(ctx, filter).Decode(&account); err != nil {
|
||||
receiver.logger.Error("failed delete account on <Delete> of <AccountRepository>",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
removeErr := errors.New(
|
||||
fmt.Errorf("failed to remove account with <%s> on <Delete> of <AccountRepository>: %w", id, err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
removeErr.SetType(errors.ErrNotFound)
|
||||
}
|
||||
|
||||
return nil, removeErr
|
||||
}
|
||||
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
func (receiver *AccountRepository) CountAll(ctx context.Context) (int64, errors.Error) {
|
||||
count, err := receiver.mongoDB.CountDocuments(ctx, bson.M{fields.Account.IsDeleted: false})
|
||||
if err != nil {
|
||||
@ -431,3 +402,114 @@ func (receiver *AccountRepository) UpdateName(ctx context.Context, userID string
|
||||
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
type QuizLogoStatDeps struct {
|
||||
From *int
|
||||
Limit *int
|
||||
Page *int
|
||||
To *int
|
||||
}
|
||||
|
||||
type QuizLogoStats struct {
|
||||
ID string `bson:"_id"`
|
||||
Regs int `bson:"regs"`
|
||||
Money int64 `bson:"money"`
|
||||
Quizes []Quiz `bson:"quizes"`
|
||||
}
|
||||
|
||||
type Quiz struct {
|
||||
QuizID string `bson:"quiz"`
|
||||
Regs int `bson:"regs"`
|
||||
Money int64 `bson:"money"`
|
||||
}
|
||||
|
||||
func (receiver *AccountRepository) QuizLogoStat(ctx context.Context, req QuizLogoStatDeps) ([]QuizLogoStats, error) {
|
||||
var pipeline mongo.Pipeline
|
||||
|
||||
if req.From != nil && req.To != nil {
|
||||
match := bson.D{
|
||||
{"$match", bson.D{
|
||||
{"createdAt", bson.D{{"$gte", time.Unix(int64(*req.From), 0)}}},
|
||||
{"createdAt", bson.D{{"$lte", time.Unix(int64(*req.To), 0)}}},
|
||||
{"from", bson.D{{"$exists", true}, {"$ne", ""}}},
|
||||
{"partner", bson.D{{"$exists", true}, {"$ne", ""}}},
|
||||
}},
|
||||
}
|
||||
pipeline = append(pipeline, match)
|
||||
} else {
|
||||
match := bson.D{
|
||||
{"$match", bson.D{
|
||||
{"from", bson.D{{"$exists", true}, {"$ne", ""}}},
|
||||
{"partner", bson.D{{"$exists", true}, {"$ne", ""}}},
|
||||
}},
|
||||
}
|
||||
pipeline = append(pipeline, match)
|
||||
}
|
||||
|
||||
pipeline = append(pipeline, mongo.Pipeline{
|
||||
{
|
||||
{"$lookup", bson.D{
|
||||
{"from", "histories"},
|
||||
{"localField", "userId"},
|
||||
{"foreignField", "userId"},
|
||||
{"as", "history"},
|
||||
}},
|
||||
},
|
||||
{
|
||||
{"$unwind", bson.D{
|
||||
{"path", "$history"},
|
||||
{"preserveNullAndEmptyArrays", true},
|
||||
}},
|
||||
},
|
||||
{
|
||||
{"$match", bson.D{
|
||||
{"$or", bson.A{
|
||||
bson.D{{"history", bson.D{{"$exists", false}}}},
|
||||
bson.D{{"history.key", "payment.succeeded"}},
|
||||
}},
|
||||
}},
|
||||
},
|
||||
{
|
||||
{"$group", bson.D{
|
||||
{"_id", "$userId"},
|
||||
{"partner", bson.D{{"$first", "$partner"}}},
|
||||
{"from", bson.D{{"$first", "$from"}}},
|
||||
{"sum", bson.D{{"$sum", "$history.rawDetails.price"}}},
|
||||
}},
|
||||
},
|
||||
{
|
||||
{"$group", bson.D{
|
||||
{"_id", "$from"},
|
||||
{"partner", bson.D{{"$first", "$partner"}}},
|
||||
{"regs", bson.D{{"$count", bson.D{}}}},
|
||||
{"money", bson.D{{"$sum", "$sum"}}},
|
||||
}},
|
||||
},
|
||||
{
|
||||
{"$group", bson.D{
|
||||
{"_id", "$partner"},
|
||||
{"regs", bson.D{{"$sum", "$regs"}}},
|
||||
{"money", bson.D{{"$sum", "$money"}}},
|
||||
{"quizes", bson.D{{"$push", bson.D{
|
||||
{"quiz", "$_id"},
|
||||
{"regs", "$regs"},
|
||||
{"money", "$money"},
|
||||
}}}}},
|
||||
},
|
||||
},
|
||||
}...)
|
||||
|
||||
var results []QuizLogoStats
|
||||
|
||||
cursor, err := receiver.mongoDB.Aggregate(ctx, pipeline)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
if err := cursor.All(ctx, &results); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
codeword_rpc "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/codeword"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
@ -345,3 +347,69 @@ func (receiver *HistoryRepository) CalculateCustomerLTV(ctx context.Context, fro
|
||||
averageLTV := int64(results[0].AverageLTV)
|
||||
return averageLTV, nil
|
||||
}
|
||||
|
||||
func (receiver *HistoryRepository) GetHistoryByListUsers(ctx context.Context, accounts []models.Account) (map[string][]models.History, error) {
|
||||
historyMap := make(map[string][]models.History)
|
||||
|
||||
var IDs []string
|
||||
for _, account := range accounts {
|
||||
IDs = append(IDs, account.UserID)
|
||||
}
|
||||
filter := bson.M{"userId": bson.M{"$in": IDs}}
|
||||
|
||||
cursor, err := receiver.mongoDB.Find(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
for cursor.Next(ctx) {
|
||||
var history models.History
|
||||
if err := cursor.Decode(&history); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
historyMap[history.UserID] = append(historyMap[history.UserID], history)
|
||||
}
|
||||
|
||||
if err := cursor.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return historyMap, nil
|
||||
}
|
||||
|
||||
func (receiver *HistoryRepository) GetPayUsersPromoHistory(ctx context.Context, codewordData map[string][]*codeword_rpc.PromoActivationResp_UserTime, from, to int64) (map[string]int64, error) {
|
||||
match := utils.MatchGen(codewordData, from, to)
|
||||
|
||||
pipeline := []bson.M{
|
||||
match,
|
||||
{
|
||||
"$group": bson.M{
|
||||
"_id": "$userId",
|
||||
"priceSum": bson.M{"$sum": "$rawDetails.price"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cursor, err := receiver.mongoDB.Aggregate(ctx, pipeline)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
userSum := make(map[string]int64)
|
||||
for cursor.Next(ctx) {
|
||||
var result struct {
|
||||
UserID string `bson:"_id"`
|
||||
PriceSum int64 `bson:"priceSum"`
|
||||
}
|
||||
if err := cursor.Decode(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userSum[result.UserID] = result.PriceSum
|
||||
}
|
||||
if err := cursor.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userSum, nil
|
||||
}
|
||||
|
||||
@ -5,7 +5,9 @@ import (
|
||||
"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"
|
||||
|
||||
@ -13,6 +15,7 @@ import (
|
||||
"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"
|
||||
@ -37,6 +40,7 @@ type API2 struct {
|
||||
consumer *tariff.Consumer
|
||||
clients clients
|
||||
grpc models.ConfigurationGRPC
|
||||
encrypt *qutils.Encrypt
|
||||
}
|
||||
|
||||
type clients struct {
|
||||
@ -48,11 +52,12 @@ type clients struct {
|
||||
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) API2 {
|
||||
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")),
|
||||
@ -60,6 +65,7 @@ func NewAPI2(logger *zap.Logger, db *mongo.Database, config *models.Config, cons
|
||||
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}),
|
||||
@ -81,6 +87,7 @@ func NewAPI2(logger *zap.Logger, db *mongo.Database, config *models.Config, cons
|
||||
FiberClient: fiber.AcquireClient(),
|
||||
MailAddress: config.Service.Mail.MailAddress,
|
||||
}),
|
||||
codeword: client.NewCodewordClient(client.CodewordClientDeps{Logger: logger, CodewordServiceHost: config.Service.CodewordMicroservice.HostGRPC}),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -181,6 +188,20 @@ func (api *API2) AddAccount(ctx echo.Context) error {
|
||||
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)
|
||||
@ -195,7 +216,8 @@ func (api *API2) AddAccount(ctx echo.Context) error {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
|
||||
account, err = api.account.Insert(ctx.Request().Context(), &models.Account{UserID: user.ID, Wallet: models.Wallet{Currency: defaultCurrency}})
|
||||
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)
|
||||
}
|
||||
@ -340,7 +362,7 @@ func (api *API2) PayCart(ctx echo.Context) error {
|
||||
UserInformation: &discount.UserInformation{
|
||||
ID: account.UserID,
|
||||
Type: string(account.Status),
|
||||
PurchasesAmount: uint64(account.Wallet.PurchasesAmount),
|
||||
PurchasesAmount: uint64(account.Wallet.Spent),
|
||||
CartPurchasesAmount: tariffsAmount,
|
||||
},
|
||||
Products: transfer.TariffsToProductInformations(tariffs),
|
||||
@ -365,6 +387,18 @@ func (api *API2) PayCart(ctx echo.Context) error {
|
||||
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{
|
||||
@ -415,10 +449,13 @@ func (api *API2) PayCart(ctx echo.Context) error {
|
||||
}
|
||||
|
||||
if _, err := api.history.Insert(ctx.Request().Context(), &models.History{
|
||||
Key: models.CustomerHistoryKeyPayCart,
|
||||
UserID: account.UserID,
|
||||
Comment: "Успешная оплата корзины",
|
||||
RawDetails: tariffs,
|
||||
Key: models.CustomerHistoryKeyPayCart,
|
||||
UserID: account.UserID,
|
||||
Comment: "Успешная оплата корзины",
|
||||
RawDetails: models.RawDetails{
|
||||
Tariffs: tariffs,
|
||||
Price: int64(discountResponse.Price),
|
||||
},
|
||||
}); err != nil {
|
||||
return api.errorOld(ctx, err)
|
||||
}
|
||||
@ -509,8 +546,17 @@ func (api *API2) UpdateCurrencies(ctx echo.Context) error {
|
||||
// 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{
|
||||
Type: params.Type,
|
||||
UserID: userID,
|
||||
Type: params.Type,
|
||||
Pagination: &models.Pagination{
|
||||
Page: int64(*params.Page),
|
||||
Limit: int64(*params.Limit),
|
||||
@ -849,3 +895,93 @@ func (api *API2) PostWalletRspay(ctx echo.Context) error {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@ -65,6 +65,12 @@ type ServerInterface interface {
|
||||
// Расчет среднего времени жизни платящего клиента (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
|
||||
@ -333,6 +339,28 @@ func (w *ServerInterfaceWrapper) CalculateLTV(ctx echo.Context) error {
|
||||
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
|
||||
@ -431,6 +459,8 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
||||
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)
|
||||
@ -442,83 +472,90 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"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",
|
||||
"sViZVwAA",
|
||||
"H4sIAAAAAAAC/+xce3MbR3L/KlOb/GFXViBI0dGZ/8mUL1HK9il6uVQi624JDMg9AbvQ7sIy7WIVH9ar",
|
||||
"KEuRc6m4FEs++1yV/xIQJESQBMCv0PONUt0z+56lQIqixNh3VTIIzO70zPTj14/pr42K22i6DncC35j6",
|
||||
"2vArC7xh0cfzlYrbcgL82PTcJvcCm9MPf7Sr+B/+pdVo1rkxZfyufK42Xjt3bq5S+914pXruww8nz35Y",
|
||||
"Hh83TCNYbOIIP/BsZ95YMo2K5QWpp28e9HjBTxPGrGnYAW8QPbk51BeW51mLNKfHrYBXz9PENddrWIEx",
|
||||
"ZVStgJ8J7AbXkVnldX7IR2z/gnwotbyaVfd5NHrOdevccnC4YzU4jvx7j9eMKePvxuKDGFOnMPYZjlky",
|
||||
"DT+wgpb/qtHqwK7IwUum0WpWD7vuls+9i69xvHesep0Hr6L0czlqack0PH67ZXu4aTeJsSISFKtEr1Q7",
|
||||
"Fm1GdEZG8oCTi56N6HPn/swrAdKX3iNcptNq4NyOizPcwn9dbz7xbLy2jyzn1rTlVfMSUbG86oJbr3IP",
|
||||
"/6pyv+LZzcB2HWPKgO+hL54w6MAetGELurAnHol70GawC22xLFbFumEmtvvi9fOfMfznD9e1AuRXNJM8",
|
||||
"gyFssenr0xMMerAHPTZ9/fqEyc6Gf04ysQI96EMHhkiJyWAfuuI+tMUqtKErVsUKkjlAwoawIZbplwEM",
|
||||
"YYeJFbEKQ7EMQxhAt4jw8gc6evmXTdtb/NR1ggUN3T9AF+cV9xj0aBYkqQsD6IknOC1OuZvaK/bep5++",
|
||||
"P/K8N7ilO5N/p+0afcobN27cSE86UZ7QCoDTasxp2eA5DKEPXbFctH2Xr32Uf2FGQtTbU6tLb7GO6T/2",
|
||||
"PNfLc22D+741z9PCjtLHHDdgNbflVHUrlPI37VbTT06WJ81YydhO8I+T8dO2E/B57uXWU8G3mBElOuL/",
|
||||
"2fYD11vUCJ3baHAnbUwMPMJvkVmR3UnYoA17yOtD/Bb6Yo2J+zRgckIrXidjK15DxR7SznjWnQs8sOy6",
|
||||
"r2HK/6WdkexOkt2HIWyKNQb7Yhm6sEU/78EQXkJPrIpHJnEv7EIPR2+INdgSa2KViW9Qz4hHYlUsi3V6",
|
||||
"ayheqDd60DPlIXwbHUM0BR7RJrTFYwad8PSYmrgrhw3lm3DyPWjjH+IRaSUprXioK+zPvuuUGIPvYQOH",
|
||||
"bsEeKjQk9yVs4bqQK1ahB/u43G1owz6SCD1Geq2NLNOBoXhSSsnl1zNGYHl2rebPGFM3ZwrPasYwD/px",
|
||||
"dkl3mPKLJCtUWn7gNrhXkpN+7FS5VgxP3LhnRDdtq2nsq02yGUmtafgtKeM6of9MgaO0xNdszw9C3BQv",
|
||||
"Ab6HDrRhoFtyw65W67z4GRhCB3rivu5Z15vXPPgC/89mZmbQeA2Rw14gvynj2MYftFqTV1ynejAh2j3P",
|
||||
"7c0laxF38GrIOQrAzIXoxDQC27nl1mqIVwzTuG3fsXG757g3J79ZdN2G6/BF1LzunF3Hk7MdP7Dq9QY5",
|
||||
"Aoi9/AV6qGmYxtzE3JX4aates+ijDiNd8tyG+0nwBQKs/AGi6aAPVrVqow6y6pdSAzIGiojMa61dUg09",
|
||||
"NNukFzpS3NGGd2FTY3WQc+f9Ed9EWmlTKi9CQfegBzt6W5Y7nMz7+6RkCEvsicfiPrOrSqGhpjVRCw1C",
|
||||
"9CGB1aj0MFRbo25ESJ+O4n9t2V994s674YlFblX6LKTFSi+PsIKt1U5FR/fs8Ed3u2V/pWjQk3bMc+Xf",
|
||||
"dNuuMvpFs9ACxnp23IyV9Wnf1rxXySpdvJA/BvndES1Lbt7PI0cy62r5Oj/iJ7EGfRQ3RtwgnRtcdwch",
|
||||
"hngKA1TOoYODoB9Rg3goRQk/LouVpNkfL58rj48AaE2j0vI87lR0HPizdhpGGh/1wUguQLEw/QV5WTzC",
|
||||
"s1XrWqGDX0V01ZHqYR+6sEMex90Sg/8m9LVBCA1hWbRPYgWfFU/RGRR3FRhEV3GbVBOCqL2U+KBfKX9D",
|
||||
"YL2LQBDaJYkDdxFUiWWxBl3oS7dyFzHWlnIn4/VD1wzBlwSTSD3+PkBUSQc4oPl2TKYIUeCxK54qKhWA",
|
||||
"hZc429GOsNnyKguWz/3zjTDkldnqF7AhHhIDiZWI1eLdIFg8lGBXrMu9G4ineNaEY8Uj2Cao0SbW2xOP",
|
||||
"jJEI85v8EOSQk0MSLk3KQKzjWSbObBuHdcQKbl6Htrev3iEexhpDIRL0hwnrI/eswQB5wziCjxfKR4Qq",
|
||||
"QvCR3fZwvbM6w+XzSsuzg8UrlQXekLrgI2550teeo0+/Dyn7l8+vGllb/LETcI8FC5wF7i3usDt2sEB/",
|
||||
"/km+Zor9iTU9XrO/NBkvzZfYjHo/s+YqVT4+cXbygxkDXQOKYpGXJeePqF0IgqaxhMTaTs3VH1vCfyGG",
|
||||
"6ajQC30iZpe+Tg+9ERTNDvkobXYmdpjkiDaFlCLooOezx0x8g2cHu6T1SdSQBMmvy7ANPWSTEE2IB5I7",
|
||||
"8chLhCQDUkzTyilhZ1JkhU6WWCPaEhRJz2sPSZOMA33oGabxBfd8uRnjpXKpTDC7yR2raRtTxtlSuYTm",
|
||||
"oWkFC3TAY1Ycg5auhWZT91Vg5b4MY2VYlknNBHvSBoh10hFoUSx8AbpDhvSnw3g3cq/fdB1fMtlEuSyj",
|
||||
"DU6gZNFqNut2hR4fQ58zjpuPGKGVPJJehlgTK6SMH5CS7EZ0xyecFcUl05gsjx8bcTJKpCENnkMXzzby",
|
||||
"5bdDFZESTGPqZiySN2eXZtHFazQsb5GWp1bTU647maEE24t1NAypJSL/WYhybhohH8wumcY812nE72n7",
|
||||
"lAig5QkDmsrObaNdIxvUZeIxbBMTtynisBLGAdGylBj8G+zAFvToJHqwmxoup1iLma0H24yM6i6to52x",
|
||||
"BDsxEtmCNtpXSVVHBiA2VXSlg48zqxUsuJ79FZ1ejkv/iQfvGIsmdkMx6TvBk0jC5AmQ8DOxq4wrFahf",
|
||||
"wptdsTq6oMCP2T1NotWunCyjCRIcWiAzTSuoLGhzE9uoO2EgnoTsTMkKiSdhO0QCeNi4z5vqz23lRfQK",
|
||||
"F55j3+kFy5lPKdnbLe4HH7nVxWM7K5kv0xzVD1LykVBao9xb6Ue9C7p+hZD2VrzZp1nXwwsF3XE9u4hl",
|
||||
"KOBBzIH7P4qSb7q+Tsv/FO4TalImo2YayxHhkkguTPQYVigTRmgkktuueBh5EhtiHbVxjnXPV6vvGjj4",
|
||||
"/8Uw8bESgxQdq5ZXlswIJo59LePRSwfixR9Q08n8H3pFiEMkMEDdR5N2UNmtqOAw/tuXJl4C4yFT+gMZ",
|
||||
"/KVkL+ibCSycwG05HFwAPi/YHq8k7HvT8qwGD7jn086ll3Dxgs4vs/EnhM5hqnwqDs/H/ljgtbiZOPRs",
|
||||
"KGb27XA4/O1Uwt+TghrPyTqnNVeR4R1d7P6WwuRZFbovkQZh4UNB8TcsYFnUiV9JRajiHcO0yHV1SPo3",
|
||||
"eXsllv9N4o5f4mJwXyxzyG1F3kTKV11nJCG9MKqa3jEF0A/rEBS40algFMorBa6WoScDvrE7oGS0I9az",
|
||||
"QSoZaFwlI79GIS39O0wmnuBT0iWR7jLhNgXmGDyHZ/DCZPA/+Md/QU/ckyTJSif4hZzy+Iec/F+JPOnr",
|
||||
"3LNrinWuhHVlb1cXHM0ryudZD10vmM/CLC0tvSvaScNPBIOT/HTalcN3I6yxQGZehYzp8PTWOhvRop2X",
|
||||
"Ur6bZfUhWm5KNK1RymVbmt2oRpAs9YDkrsv+gclCwofQLUpt51+fk9VL1rzt0J/nw6W8QkITlXZpmsQ6",
|
||||
"JZHaqH1VNlCssHFZQFenejZVRUXifLvFvcVYnpvWPDeS0lvlNatVD4ypcV0KJEsVkbFdQNeIJNTthh0U",
|
||||
"0FAua6h4XXCR1ipJXopS8SNJeD6NHLiBVb9kzcs3xym78VGy0kcKTeY2Xcd9JKxx0DoUhV0trzKZ3mvD",
|
||||
"puKne4Q5dwqFMax9j13TNK9f5g33C/57z21My9LnDJ/reMI+2MQcKR3/1jBpwuUbytB6Ok31a0OgMgq7",
|
||||
"IzO4sb3ZoY/SChze3UNcJdFSdnuTr415mLj2IMz4POvkkTlUMT9prKhyVNXdapeRyUFL5KkLxE1UfpWi",
|
||||
"8Rfc4QQyGIYFHtHprf0mHK8jHIkNDgUku8EHikeo38ealqxV1wew/xPaYUGzumsRCYqq05C5FtinQoFV",
|
||||
"NFNpFZgHSIvKWrz1yDTVV0Wk54oMTldMOl6HctV3KUgtRU1//LLQRaElhbZzkafpeNRrHlniCp0sHLt2",
|
||||
"5YJhGtPnLxzmetxRwVQEjdqJeq4MgEo8GOX9E87FkMryN8IyLxm9i9+V2OSwhIjMUEuzsdeoxDyzt0dz",
|
||||
"pY9rW5dOzfGi5pOx2L1XH/AJyfA1y1HVELx6KKmNlqJS2q/PcijbC/EtpCLBDi8qnUr3FP76FtxTU1Mw",
|
||||
"24P9sDponXTvkxFnVzdQiqNrpqb6YUvlCOJwCpmMXIivxOA/VPqYUsXJ+IeZKl3tJQOocdZbhjF7xRNm",
|
||||
"64hKIy5beZgXLxhvMsuQDgR4vOJ61dHjAKFkvPk4wChpjSR3wc7pAiX54iAqH9uUl9cSy6K7bOJJGKEj",
|
||||
"PYeQMxvE6CdUXqjjUhpvrB58kcSzmaIeq15p1a2Af3L1unFc0eua5za0bmabgpQoWQprboU4s8PEN7St",
|
||||
"fRl5Zdcc+0sW2A3uB1ajmRDfssnQAJK7MFAOVY/OoSsrStQkufuLpdEqtgO34FbGgEpU3xThqRqxbqK4",
|
||||
"u3SEim06AFrK7Cgy96N08mXGVxVBLFOVM11GgDaLuSN2xZeOVSUpLs3dCpFlSIMDQtDy1x2Zc34JW3Qz",
|
||||
"VSa7xDrFSWRh/QqBoy0Suz6LnAN8RorRKLt8KAVGufLkTtI+kr4qn5C+kvEbVZy7HfuuiXIqZBYGG9Lk",
|
||||
"iQfQNRmppz4L3HckJPHBiezXd+lLK+IJecPiAfRgg1B0lEOVlZqja/2/JliAGhSEPE2JJyXq0iIweBle",
|
||||
"zIl4VDyJK0dTtUjsvU+uXn+/0AI0PbfhVtwqP9gGXAqHvXkbQMpvB/rigbpSsJ9ZvpmQ1UQhdpijQ4ne",
|
||||
"oHLEdnSDXLn4dOcCNejIWn0UYrbknh8PGYfU0serbg+SidSl31GUWnzzhclLJO3wbgbde8nuhqzUPeVS",
|
||||
"rFlWWxVZRReCyULhblD0UaYMiZJtxK3F94CjWFVClv3ACmw/sCtKmm+37K/q7rw75odXs7XSnLoOfPql",
|
||||
"uRQbqnJUIKKuDUbXMiiefka1npDvHsJm5AEn6syomL8kryK+DLljM5H2bmeWoNUm0lHOw5U9Sp706AYk",
|
||||
"rQ0Xu1vwkqZq3ZLZ03QWvj3Km05eub2hUyGZFHePeC4nXf+SkrTftOYhtWa+1kbdEg4vND+gi98PoCfu",
|
||||
"KjUrPeWhbAGjrkgPQ0QLbXH3AO3p8YraPn0VzXeUHOgQ1z/UVdLQJUx1kRodWOmRRwklWVpDKdm01xld",
|
||||
"R8vf+smW7oQxpu383TIKJ+UilpdpUfJGv39syt4+xg4zs29AJkcKWUVtDkYIqOcFNeEpvRv+2oleipMc",
|
||||
"LdaVSk9kaWUO8LS7Y5og3ECZrA6Zm6xgF3pYPneql3nT9YJDpYxRhYX3rXdRkclrVlEyOex7FgX+cChi",
|
||||
"gFVNKWxEwSmX/1fmpZObdtouSCWJjyvHqWL8FSceVhnAUNwXq6nUdZoX486dRXU+P0Y3qSOj2dVc8YDh",
|
||||
"1IxzhsELQit0v4SuUyfuAGZrgdqyQWbYFKSdzdO16YW54vkYAXVVAiXdMqEy59XYe4RIlVO1TS042+I+",
|
||||
"Ss1Adb2TjeHuk7Z4JK3qdhg0fF/NHDWTUc0ZEi1c1nKdE5gskx1CR6xRV7t4bInBs2jwU9iVEWfczPuE",
|
||||
"d8U9OskhLXJF5WNJn4d7Jru3JO8rqsYQhIIGVKKwwxBxrIZvjRpKqJAQHcNjCgrthMOodCbbo08mJOUV",
|
||||
"+rB55RbBij1JtbqmF/aOkQ1oeumOoh25qIFsLVNwL3g6bhJyPFoo2ZUn1kUyhX6w2okzv+9oQbzMDCtP",
|
||||
"pp3qJpRjxZODHz8XSPJAVhikxPlXVar2o74BUB4dHcIeRPf2Q1V4kDpKqHyl5ItvWJ9h8IvKR0UdnFIq",
|
||||
"nzRLQs3ifIlqNZNJlJK/9tePEiliFTbEt+QK9aGXUe1tOWPs6pIRyyj2VH2cWGHUvQp1oSwADJsYh2PW",
|
||||
"Uk05SCUPyBAM0905IvWv6aOT01uXpZr6VPUyOh6tZUX9p+JU+AflibIubDOXaEd9EGdGbasP7FV28cof",
|
||||
"zkxOjJ9L5SNHaU5Wd+dtJ61l6as/BtwPdA80F1yHfxa1SY4fO/dhOfyfvtNe0PKca149/dRCEDT9qbEx",
|
||||
"3w54yWuNqfrgwk6rBwayE601s2ZB1Zckulmpw3oTZiKT3LSdW/pFz7vufB2XPUpTvUN6rsleiSfmtf2U",
|
||||
"bC6VqoINXds12Ev4cWLtEFpTU3yruyUSqpJeXpHoVGkMnsc8P1P9m8mUuX4g+xpepoHHpTWi/oCJ1nfl",
|
||||
"ciIjXau7VkIoVBfxAhYZKW9UwEd3pVk9O8JiIloTjcgNxw2YVa+7d3iV1VyPOa7DXG/eclRTJF/LNOG5",
|
||||
"dgnSDmCY4NcTiwq8kD3zpdclvYCkp9Rml69cCuNHiody1GW7XaRrvAxNCZtqBifWYD90hNLNJdUrIrWl",
|
||||
"eUeiSJvAQvgIKtKC4ZH/Eg9X8qB5IBHQpGo+9cBCVBWmS2Jkg77xc3Fodml26f8CAAD//9ED7UTAZAAA",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
||||
@ -1,178 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type accountController interface {
|
||||
RemoveAccount(ctx echo.Context) error
|
||||
GetAccount(ctx echo.Context) error
|
||||
CreateAccount(ctx echo.Context) error
|
||||
RemoveDirectAccount(ctx echo.Context, userID string) error
|
||||
GetDirectAccount(ctx echo.Context, userID string) error
|
||||
GetAccounts(echo.Context, PaginationAccountsParams) error
|
||||
SetVerificationStatus(ctx echo.Context, userID string) error
|
||||
UpdateAccountName(ctx echo.Context) error
|
||||
}
|
||||
|
||||
type currencyController interface {
|
||||
GetCurrencies(ctx echo.Context) error
|
||||
PutCurrencies(ctx echo.Context) error
|
||||
}
|
||||
|
||||
type cartController interface {
|
||||
Remove(echo.Context, RemoveFromCartParams) error
|
||||
Add(echo.Context, Add2cartParams) error
|
||||
Pay(echo.Context) error
|
||||
}
|
||||
|
||||
type walletController interface {
|
||||
ChangeCurrency(ctx echo.Context) error
|
||||
GetPaymentLink(ctx echo.Context) error
|
||||
PostWalletRspay(ctx echo.Context) error
|
||||
}
|
||||
|
||||
type historyController interface {
|
||||
GetHistoryList(ctx echo.Context, params GetHistoryParams) error
|
||||
GetRecentTariffs(ctx echo.Context) error
|
||||
SendReport(ctx echo.Context) error
|
||||
CalculateLTV(ctx echo.Context) error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
AccountController accountController
|
||||
CurrencyController currencyController
|
||||
CartController cartController
|
||||
WalletController walletController
|
||||
HistoryController historyController
|
||||
}
|
||||
|
||||
type API struct {
|
||||
accountController accountController
|
||||
currencyController currencyController
|
||||
cartController cartController
|
||||
walletController walletController
|
||||
historyController historyController
|
||||
}
|
||||
|
||||
func New(deps Deps) *API {
|
||||
if deps.AccountController == nil {
|
||||
log.Panicln("AccountController is nil on <New (API)>")
|
||||
}
|
||||
|
||||
if deps.CurrencyController == nil {
|
||||
log.Panicln("currencyController is nil on <New (API)>")
|
||||
}
|
||||
|
||||
if deps.CartController == nil {
|
||||
log.Panicln("cartController is nil on <New (API)>")
|
||||
}
|
||||
|
||||
if deps.WalletController == nil {
|
||||
log.Panicln("walletController is nil on <New (API)>")
|
||||
}
|
||||
|
||||
if deps.HistoryController == nil {
|
||||
log.Panicln("historyController is nil on <New (API)>")
|
||||
}
|
||||
|
||||
return &API{
|
||||
accountController: deps.AccountController,
|
||||
currencyController: deps.CurrencyController,
|
||||
cartController: deps.CartController,
|
||||
walletController: deps.WalletController,
|
||||
historyController: deps.HistoryController,
|
||||
}
|
||||
}
|
||||
|
||||
// Account
|
||||
|
||||
func (receiver *API) DeleteAccount(ctx echo.Context) error {
|
||||
return receiver.accountController.RemoveAccount(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) ChangeAccount(ctx echo.Context) error {
|
||||
return receiver.accountController.UpdateAccountName(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) SetAccountVerificationStatus(ctx echo.Context, userID string) error {
|
||||
return receiver.accountController.SetVerificationStatus(ctx, userID)
|
||||
}
|
||||
|
||||
func (receiver *API) GetAccount(ctx echo.Context) error {
|
||||
return receiver.accountController.GetAccount(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) AddAccount(ctx echo.Context) error {
|
||||
return receiver.accountController.CreateAccount(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) DeleteDirectAccount(ctx echo.Context, userID string) error {
|
||||
return receiver.accountController.RemoveDirectAccount(ctx, userID)
|
||||
}
|
||||
|
||||
func (receiver *API) GetDirectAccount(ctx echo.Context, userID string) error {
|
||||
return receiver.accountController.GetDirectAccount(ctx, userID)
|
||||
}
|
||||
|
||||
func (receiver *API) PaginationAccounts(ctx echo.Context, params PaginationAccountsParams) error {
|
||||
return receiver.accountController.GetAccounts(ctx, params)
|
||||
}
|
||||
|
||||
// Cart
|
||||
|
||||
func (receiver *API) RemoveFromCart(ctx echo.Context, params RemoveFromCartParams) error {
|
||||
return receiver.cartController.Remove(ctx, params)
|
||||
}
|
||||
|
||||
func (receiver *API) Add2cart(ctx echo.Context, params Add2cartParams) error {
|
||||
return receiver.cartController.Add(ctx, params)
|
||||
}
|
||||
|
||||
func (receiver *API) PayCart(ctx echo.Context) error {
|
||||
return receiver.cartController.Pay(ctx)
|
||||
}
|
||||
|
||||
// Currency
|
||||
|
||||
func (receiver *API) GetCurrencies(ctx echo.Context) error {
|
||||
return receiver.currencyController.GetCurrencies(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) UpdateCurrencies(ctx echo.Context) error {
|
||||
return receiver.currencyController.PutCurrencies(ctx)
|
||||
}
|
||||
|
||||
// History
|
||||
|
||||
func (receiver *API) GetHistory(ctx echo.Context, params GetHistoryParams) error {
|
||||
return receiver.historyController.GetHistoryList(ctx, params)
|
||||
}
|
||||
|
||||
func (receiver *API) GetRecentTariffs(ctx echo.Context) error {
|
||||
return receiver.historyController.GetRecentTariffs(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) SendReport(ctx echo.Context) error {
|
||||
return receiver.historyController.SendReport(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) CalculateLTV(ctx echo.Context) error {
|
||||
return receiver.historyController.CalculateLTV(ctx)
|
||||
}
|
||||
|
||||
// Wallet
|
||||
|
||||
func (receiver *API) RequestMoney(ctx echo.Context) error {
|
||||
return receiver.walletController.GetPaymentLink(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) ChangeCurrency(ctx echo.Context) error {
|
||||
return receiver.walletController.ChangeCurrency(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) PostWalletRspay(ctx echo.Context) error {
|
||||
return receiver.walletController.PostWalletRspay(ctx)
|
||||
}
|
||||
@ -100,6 +100,40 @@ type Name struct {
|
||||
// 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"`
|
||||
@ -174,6 +208,30 @@ type CalculateLTVJSONBody struct {
|
||||
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"`
|
||||
@ -219,6 +277,12 @@ 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
|
||||
|
||||
|
||||
@ -27,12 +27,10 @@ func (api *API2) GetPaymentLink(ctx context.Context, request *models.GetPaymentL
|
||||
return api.GetPaymentLinkYooMoney(ctx, request)
|
||||
case models.PaymentTypeSberPay:
|
||||
return api.GetPaymentLinkSberPay(ctx, request)
|
||||
case models.PaymentTypeSberB2B:
|
||||
return api.GetPaymentLinkSBP(ctx, request)
|
||||
case models.PaymentTypeSBP:
|
||||
return api.GetPaymentLinkSBP(ctx, request)
|
||||
case models.PaymentTypeTinkoff:
|
||||
return api.GetPaymentLinkTinkoff(ctx, request)
|
||||
case models.PaymentTypeSBP:
|
||||
return api.GetPaymentLinkSBP(ctx, request)
|
||||
}
|
||||
|
||||
return "", errors.NewWithMessage("invalid payment method type", errors.ErrInvalidArgs)
|
||||
|
||||
@ -13,6 +13,8 @@ type Account struct {
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty" bson:"deletedAt,omitempty"`
|
||||
From string `json:"from" bson:"from"`
|
||||
Partner string `json:"partner" bson:"partner"`
|
||||
}
|
||||
|
||||
func (receiver *Account) Sanitize() *Account {
|
||||
@ -25,6 +27,9 @@ func (receiver *Account) Sanitize() *Account {
|
||||
receiver.Status = DefaultAccountStatus
|
||||
receiver.CreatedAt = now
|
||||
receiver.UpdatedAt = now
|
||||
// закоментил, потому что при инзерте они всегда будут ""
|
||||
//receiver.From = ""
|
||||
//receiver.Partner = ""
|
||||
receiver.DeletedAt = nil
|
||||
receiver.Deleted = false
|
||||
|
||||
|
||||
@ -30,12 +30,15 @@ type ServiceConfiguration struct {
|
||||
HubadminMicroservice HubadminMicroserviceConfiguration
|
||||
CurrencyMicroservice CurrencyMicroserviceConfiguration
|
||||
DiscountMicroservice DiscountMicroserviceConfiguration
|
||||
CodewordMicroservice CodewordMicroserviceConfiguration
|
||||
PaymentMicroservice PaymentMicroserviceConfiguration
|
||||
VerificationMicroservice VerificationMicroserviceConfiguration
|
||||
TemplategenMicroserviceURL TemplategenMicroserviceConfiguration
|
||||
JWT JWTConfiguration
|
||||
Kafka KafkaConfiguration
|
||||
Mail MailConfiguration
|
||||
PubKey string `env:"PUBLIC_KEY"`
|
||||
PrivKey string `env:"PRIVATE_KEY"`
|
||||
}
|
||||
|
||||
type KafkaConfiguration struct {
|
||||
@ -76,6 +79,10 @@ type TemplategenMicroserviceConfiguration struct {
|
||||
URL TemplategenMicroserviceURL
|
||||
}
|
||||
|
||||
type CodewordMicroserviceConfiguration struct {
|
||||
HostGRPC string `env:"CODEWORD_MICROSERVICE_GRPC_HOST,required"`
|
||||
}
|
||||
|
||||
type PaymentMicroserviceConfiguration struct {
|
||||
HostGRPC string `env:"PAYMENT_MICROSERVICE_GRPC_HOST,required"`
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ type History struct {
|
||||
UserID string `json:"userId" bson:"userId"`
|
||||
Comment string `json:"comment" bson:"comment"`
|
||||
Key string `json:"key" bson:"key"`
|
||||
RawDetails any `json:"rawDetails" bson:"rawDetails"`
|
||||
RawDetails RawDetails `json:"rawDetails" bson:"rawDetails"`
|
||||
Deleted bool `json:"isDeleted" bson:"isDeleted"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
|
||||
@ -33,6 +33,7 @@ type ReportHistory struct {
|
||||
type RawDetails struct {
|
||||
Tariffs []Tariff `json:"tariffs" bson:"tariffs"`
|
||||
Price int64 `json:"price" bson:"price"`
|
||||
Comment string `json:"comment" bson:"comment"`
|
||||
}
|
||||
|
||||
func (receiver *History) Sanitize() *History {
|
||||
|
||||
@ -44,5 +44,6 @@ type PaymentEvent struct {
|
||||
PaymentID string
|
||||
UserID string
|
||||
Currency string
|
||||
Type string
|
||||
Amount int64
|
||||
}
|
||||
|
||||
305
internal/proto/codeword/promo.pb.go
Normal file
305
internal/proto/codeword/promo.pb.go
Normal file
@ -0,0 +1,305 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0-devel
|
||||
// protoc v3.14.0
|
||||
// source: promo.proto
|
||||
|
||||
package codeword_rpc
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Time struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
From int64 `protobuf:"varint,1,opt,name=from,proto3" json:"from,omitempty"`
|
||||
To int64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Time) Reset() {
|
||||
*x = Time{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_promo_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Time) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Time) ProtoMessage() {}
|
||||
|
||||
func (x *Time) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_promo_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Time.ProtoReflect.Descriptor instead.
|
||||
func (*Time) Descriptor() ([]byte, []int) {
|
||||
return file_promo_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Time) GetFrom() int64 {
|
||||
if x != nil {
|
||||
return x.From
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Time) GetTo() int64 {
|
||||
if x != nil {
|
||||
return x.To
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type PromoActivationResp struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Users []*PromoActivationResp_UserTime `protobuf:"bytes,2,rep,name=Users,proto3" json:"Users,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) Reset() {
|
||||
*x = PromoActivationResp{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_promo_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PromoActivationResp) ProtoMessage() {}
|
||||
|
||||
func (x *PromoActivationResp) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_promo_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PromoActivationResp.ProtoReflect.Descriptor instead.
|
||||
func (*PromoActivationResp) Descriptor() ([]byte, []int) {
|
||||
return file_promo_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) GetID() string {
|
||||
if x != nil {
|
||||
return x.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) GetUsers() []*PromoActivationResp_UserTime {
|
||||
if x != nil {
|
||||
return x.Users
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PromoActivationResp_UserTime struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UserID string `protobuf:"bytes,1,opt,name=UserID,proto3" json:"UserID,omitempty"`
|
||||
Time int64 `protobuf:"varint,2,opt,name=Time,proto3" json:"Time,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) Reset() {
|
||||
*x = PromoActivationResp_UserTime{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_promo_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PromoActivationResp_UserTime) ProtoMessage() {}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_promo_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PromoActivationResp_UserTime.ProtoReflect.Descriptor instead.
|
||||
func (*PromoActivationResp_UserTime) Descriptor() ([]byte, []int) {
|
||||
return file_promo_proto_rawDescGZIP(), []int{1, 0}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) GetUserID() string {
|
||||
if x != nil {
|
||||
return x.UserID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) GetTime() int64 {
|
||||
if x != nil {
|
||||
return x.Time
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_promo_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_promo_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63,
|
||||
0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x2a, 0x0a, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x66,
|
||||
0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x02, 0x74, 0x6f, 0x22, 0x9b, 0x01, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x41, 0x63, 0x74,
|
||||
0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x49,
|
||||
0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x3c, 0x0a, 0x05, 0x55,
|
||||
0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x64,
|
||||
0x65, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x52, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x36, 0x0a, 0x08, 0x55, 0x73, 0x65,
|
||||
0x72, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x32, 0x5d, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x53, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x50,
|
||||
0x72, 0x6f, 0x6d, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
|
||||
0x0e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x1a,
|
||||
0x1d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
|
||||
0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01,
|
||||
0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x72,
|
||||
0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_promo_proto_rawDescOnce sync.Once
|
||||
file_promo_proto_rawDescData = file_promo_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_promo_proto_rawDescGZIP() []byte {
|
||||
file_promo_proto_rawDescOnce.Do(func() {
|
||||
file_promo_proto_rawDescData = protoimpl.X.CompressGZIP(file_promo_proto_rawDescData)
|
||||
})
|
||||
return file_promo_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_promo_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_promo_proto_goTypes = []interface{}{
|
||||
(*Time)(nil), // 0: codeword.Time
|
||||
(*PromoActivationResp)(nil), // 1: codeword.PromoActivationResp
|
||||
(*PromoActivationResp_UserTime)(nil), // 2: codeword.PromoActivationResp.UserTime
|
||||
}
|
||||
var file_promo_proto_depIdxs = []int32{
|
||||
2, // 0: codeword.PromoActivationResp.Users:type_name -> codeword.PromoActivationResp.UserTime
|
||||
0, // 1: codeword.PromoCodeService.GetAllPromoActivations:input_type -> codeword.Time
|
||||
1, // 2: codeword.PromoCodeService.GetAllPromoActivations:output_type -> codeword.PromoActivationResp
|
||||
2, // [2:3] is the sub-list for method output_type
|
||||
1, // [1:2] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_promo_proto_init() }
|
||||
func file_promo_proto_init() {
|
||||
if File_promo_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_promo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Time); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_promo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PromoActivationResp); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_promo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PromoActivationResp_UserTime); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_promo_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_promo_proto_goTypes,
|
||||
DependencyIndexes: file_promo_proto_depIdxs,
|
||||
MessageInfos: file_promo_proto_msgTypes,
|
||||
}.Build()
|
||||
File_promo_proto = out.File
|
||||
file_promo_proto_rawDesc = nil
|
||||
file_promo_proto_goTypes = nil
|
||||
file_promo_proto_depIdxs = nil
|
||||
}
|
||||
128
internal/proto/codeword/promo_grpc.pb.go
Normal file
128
internal/proto/codeword/promo_grpc.pb.go
Normal file
@ -0,0 +1,128 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package codeword_rpc
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// PromoCodeServiceClient is the client API for PromoCodeService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type PromoCodeServiceClient interface {
|
||||
GetAllPromoActivations(ctx context.Context, in *Time, opts ...grpc.CallOption) (PromoCodeService_GetAllPromoActivationsClient, error)
|
||||
}
|
||||
|
||||
type promoCodeServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewPromoCodeServiceClient(cc grpc.ClientConnInterface) PromoCodeServiceClient {
|
||||
return &promoCodeServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *promoCodeServiceClient) GetAllPromoActivations(ctx context.Context, in *Time, opts ...grpc.CallOption) (PromoCodeService_GetAllPromoActivationsClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &PromoCodeService_ServiceDesc.Streams[0], "/codeword.PromoCodeService/GetAllPromoActivations", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &promoCodeServiceGetAllPromoActivationsClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type PromoCodeService_GetAllPromoActivationsClient interface {
|
||||
Recv() (*PromoActivationResp, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type promoCodeServiceGetAllPromoActivationsClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *promoCodeServiceGetAllPromoActivationsClient) Recv() (*PromoActivationResp, error) {
|
||||
m := new(PromoActivationResp)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// PromoCodeServiceServer is the server API for PromoCodeService service.
|
||||
// All implementations must embed UnimplementedPromoCodeServiceServer
|
||||
// for forward compatibility
|
||||
type PromoCodeServiceServer interface {
|
||||
GetAllPromoActivations(*Time, PromoCodeService_GetAllPromoActivationsServer) error
|
||||
mustEmbedUnimplementedPromoCodeServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedPromoCodeServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedPromoCodeServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedPromoCodeServiceServer) GetAllPromoActivations(*Time, PromoCodeService_GetAllPromoActivationsServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method GetAllPromoActivations not implemented")
|
||||
}
|
||||
func (UnimplementedPromoCodeServiceServer) mustEmbedUnimplementedPromoCodeServiceServer() {}
|
||||
|
||||
// UnsafePromoCodeServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to PromoCodeServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafePromoCodeServiceServer interface {
|
||||
mustEmbedUnimplementedPromoCodeServiceServer()
|
||||
}
|
||||
|
||||
func RegisterPromoCodeServiceServer(s grpc.ServiceRegistrar, srv PromoCodeServiceServer) {
|
||||
s.RegisterService(&PromoCodeService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _PromoCodeService_GetAllPromoActivations_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(Time)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(PromoCodeServiceServer).GetAllPromoActivations(m, &promoCodeServiceGetAllPromoActivationsServer{stream})
|
||||
}
|
||||
|
||||
type PromoCodeService_GetAllPromoActivationsServer interface {
|
||||
Send(*PromoActivationResp) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type promoCodeServiceGetAllPromoActivationsServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *promoCodeServiceGetAllPromoActivationsServer) Send(m *PromoActivationResp) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
// PromoCodeService_ServiceDesc is the grpc.ServiceDesc for PromoCodeService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var PromoCodeService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "codeword.PromoCodeService",
|
||||
HandlerType: (*PromoCodeServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "GetAllPromoActivations",
|
||||
Handler: _PromoCodeService_GetAllPromoActivations_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "promo.proto",
|
||||
}
|
||||
306
internal/proto/codeword_rpc/promo.pb.go
Normal file
306
internal/proto/codeword_rpc/promo.pb.go
Normal file
@ -0,0 +1,306 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.33.0
|
||||
// protoc (unknown)
|
||||
// source: codeword/promo.proto
|
||||
|
||||
package codeword_rpc
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Time struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
From int64 `protobuf:"varint,1,opt,name=from,proto3" json:"from,omitempty"`
|
||||
To int64 `protobuf:"varint,2,opt,name=to,proto3" json:"to,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Time) Reset() {
|
||||
*x = Time{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_codeword_promo_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Time) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Time) ProtoMessage() {}
|
||||
|
||||
func (x *Time) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_codeword_promo_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Time.ProtoReflect.Descriptor instead.
|
||||
func (*Time) Descriptor() ([]byte, []int) {
|
||||
return file_codeword_promo_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Time) GetFrom() int64 {
|
||||
if x != nil {
|
||||
return x.From
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Time) GetTo() int64 {
|
||||
if x != nil {
|
||||
return x.To
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type PromoActivationResp struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Users []*PromoActivationResp_UserTime `protobuf:"bytes,2,rep,name=Users,proto3" json:"Users,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) Reset() {
|
||||
*x = PromoActivationResp{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_codeword_promo_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PromoActivationResp) ProtoMessage() {}
|
||||
|
||||
func (x *PromoActivationResp) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_codeword_promo_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PromoActivationResp.ProtoReflect.Descriptor instead.
|
||||
func (*PromoActivationResp) Descriptor() ([]byte, []int) {
|
||||
return file_codeword_promo_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) GetID() string {
|
||||
if x != nil {
|
||||
return x.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp) GetUsers() []*PromoActivationResp_UserTime {
|
||||
if x != nil {
|
||||
return x.Users
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PromoActivationResp_UserTime struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UserID string `protobuf:"bytes,1,opt,name=UserID,proto3" json:"UserID,omitempty"`
|
||||
Time int64 `protobuf:"varint,2,opt,name=Time,proto3" json:"Time,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) Reset() {
|
||||
*x = PromoActivationResp_UserTime{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_codeword_promo_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PromoActivationResp_UserTime) ProtoMessage() {}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_codeword_promo_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PromoActivationResp_UserTime.ProtoReflect.Descriptor instead.
|
||||
func (*PromoActivationResp_UserTime) Descriptor() ([]byte, []int) {
|
||||
return file_codeword_promo_proto_rawDescGZIP(), []int{1, 0}
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) GetUserID() string {
|
||||
if x != nil {
|
||||
return x.UserID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PromoActivationResp_UserTime) GetTime() int64 {
|
||||
if x != nil {
|
||||
return x.Time
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_codeword_promo_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_codeword_promo_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x6f,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64,
|
||||
0x22, 0x2a, 0x0a, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02,
|
||||
0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x74, 0x6f, 0x22, 0x9b, 0x01, 0x0a,
|
||||
0x13, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x49, 0x44, 0x12, 0x3c, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x2e, 0x50,
|
||||
0x72, 0x6f, 0x6d, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x73, 0x70, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x05, 0x55, 0x73, 0x65,
|
||||
0x72, 0x73, 0x1a, 0x36, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x32, 0x5d, 0x0a, 0x10, 0x50, 0x72,
|
||||
0x6f, 0x6d, 0x6f, 0x43, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x49,
|
||||
0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x41, 0x63, 0x74,
|
||||
0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x77,
|
||||
0x6f, 0x72, 0x64, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x77,
|
||||
0x6f, 0x72, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x30, 0x01, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x63,
|
||||
0x6f, 0x64, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_codeword_promo_proto_rawDescOnce sync.Once
|
||||
file_codeword_promo_proto_rawDescData = file_codeword_promo_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_codeword_promo_proto_rawDescGZIP() []byte {
|
||||
file_codeword_promo_proto_rawDescOnce.Do(func() {
|
||||
file_codeword_promo_proto_rawDescData = protoimpl.X.CompressGZIP(file_codeword_promo_proto_rawDescData)
|
||||
})
|
||||
return file_codeword_promo_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_codeword_promo_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_codeword_promo_proto_goTypes = []interface{}{
|
||||
(*Time)(nil), // 0: codeword.Time
|
||||
(*PromoActivationResp)(nil), // 1: codeword.PromoActivationResp
|
||||
(*PromoActivationResp_UserTime)(nil), // 2: codeword.PromoActivationResp.UserTime
|
||||
}
|
||||
var file_codeword_promo_proto_depIdxs = []int32{
|
||||
2, // 0: codeword.PromoActivationResp.Users:type_name -> codeword.PromoActivationResp.UserTime
|
||||
0, // 1: codeword.PromoCodeService.GetAllPromoActivations:input_type -> codeword.Time
|
||||
1, // 2: codeword.PromoCodeService.GetAllPromoActivations:output_type -> codeword.PromoActivationResp
|
||||
2, // [2:3] is the sub-list for method output_type
|
||||
1, // [1:2] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_codeword_promo_proto_init() }
|
||||
func file_codeword_promo_proto_init() {
|
||||
if File_codeword_promo_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_codeword_promo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Time); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_codeword_promo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PromoActivationResp); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_codeword_promo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PromoActivationResp_UserTime); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_codeword_promo_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_codeword_promo_proto_goTypes,
|
||||
DependencyIndexes: file_codeword_promo_proto_depIdxs,
|
||||
MessageInfos: file_codeword_promo_proto_msgTypes,
|
||||
}.Build()
|
||||
File_codeword_promo_proto = out.File
|
||||
file_codeword_promo_proto_rawDesc = nil
|
||||
file_codeword_promo_proto_goTypes = nil
|
||||
file_codeword_promo_proto_depIdxs = nil
|
||||
}
|
||||
134
internal/proto/codeword_rpc/promo_grpc.pb.go
Normal file
134
internal/proto/codeword_rpc/promo_grpc.pb.go
Normal file
@ -0,0 +1,134 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc (unknown)
|
||||
// source: codeword/promo.proto
|
||||
|
||||
package codeword_rpc
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
PromoCodeService_GetAllPromoActivations_FullMethodName = "/codeword.PromoCodeService/GetAllPromoActivations"
|
||||
)
|
||||
|
||||
// PromoCodeServiceClient is the client API for PromoCodeService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type PromoCodeServiceClient interface {
|
||||
GetAllPromoActivations(ctx context.Context, in *Time, opts ...grpc.CallOption) (PromoCodeService_GetAllPromoActivationsClient, error)
|
||||
}
|
||||
|
||||
type promoCodeServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewPromoCodeServiceClient(cc grpc.ClientConnInterface) PromoCodeServiceClient {
|
||||
return &promoCodeServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *promoCodeServiceClient) GetAllPromoActivations(ctx context.Context, in *Time, opts ...grpc.CallOption) (PromoCodeService_GetAllPromoActivationsClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &PromoCodeService_ServiceDesc.Streams[0], PromoCodeService_GetAllPromoActivations_FullMethodName, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &promoCodeServiceGetAllPromoActivationsClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type PromoCodeService_GetAllPromoActivationsClient interface {
|
||||
Recv() (*PromoActivationResp, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type promoCodeServiceGetAllPromoActivationsClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *promoCodeServiceGetAllPromoActivationsClient) Recv() (*PromoActivationResp, error) {
|
||||
m := new(PromoActivationResp)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// PromoCodeServiceServer is the server API for PromoCodeService service.
|
||||
// All implementations should embed UnimplementedPromoCodeServiceServer
|
||||
// for forward compatibility
|
||||
type PromoCodeServiceServer interface {
|
||||
GetAllPromoActivations(*Time, PromoCodeService_GetAllPromoActivationsServer) error
|
||||
}
|
||||
|
||||
// UnimplementedPromoCodeServiceServer should be embedded to have forward compatible implementations.
|
||||
type UnimplementedPromoCodeServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedPromoCodeServiceServer) GetAllPromoActivations(*Time, PromoCodeService_GetAllPromoActivationsServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method GetAllPromoActivations not implemented")
|
||||
}
|
||||
|
||||
// UnsafePromoCodeServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to PromoCodeServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafePromoCodeServiceServer interface {
|
||||
mustEmbedUnimplementedPromoCodeServiceServer()
|
||||
}
|
||||
|
||||
func RegisterPromoCodeServiceServer(s grpc.ServiceRegistrar, srv PromoCodeServiceServer) {
|
||||
s.RegisterService(&PromoCodeService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _PromoCodeService_GetAllPromoActivations_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(Time)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(PromoCodeServiceServer).GetAllPromoActivations(m, &promoCodeServiceGetAllPromoActivationsServer{stream})
|
||||
}
|
||||
|
||||
type PromoCodeService_GetAllPromoActivationsServer interface {
|
||||
Send(*PromoActivationResp) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type promoCodeServiceGetAllPromoActivationsServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *promoCodeServiceGetAllPromoActivationsServer) Send(m *PromoActivationResp) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
// PromoCodeService_ServiceDesc is the grpc.ServiceDesc for PromoCodeService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var PromoCodeService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "codeword.PromoCodeService",
|
||||
HandlerType: (*PromoCodeServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "GetAllPromoActivations",
|
||||
Handler: _PromoCodeService_GetAllPromoActivations_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "codeword/promo.proto",
|
||||
}
|
||||
@ -1,239 +0,0 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
|
||||
type accountRepository interface {
|
||||
FindByUserID(ctx context.Context, id string) (*models.Account, errors.Error)
|
||||
FindMany(ctx context.Context, page, limit int64) ([]models.Account, errors.Error)
|
||||
Insert(ctx context.Context, account *models.Account) (*models.Account, errors.Error)
|
||||
Remove(ctx context.Context, id string) (*models.Account, errors.Error)
|
||||
Delete(ctx context.Context, id string) (*models.Account, errors.Error)
|
||||
CountAll(ctx context.Context) (int64, errors.Error)
|
||||
SetStatus(ctx context.Context, userID string, status models.AccountStatus) (*models.Account, errors.Error)
|
||||
UpdateName(ctx context.Context, userID string, name *models.Name) (*models.Account, errors.Error)
|
||||
}
|
||||
|
||||
const defaultCurrency = "RUB"
|
||||
|
||||
type authClient interface {
|
||||
GetUser(ctx context.Context, userID string) (*models.User, errors.Error)
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Repository accountRepository
|
||||
AuthClient authClient
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
repository accountRepository
|
||||
authClient authClient
|
||||
}
|
||||
|
||||
func New(deps Deps) *Service {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (account service)>")
|
||||
}
|
||||
|
||||
if deps.Repository == nil {
|
||||
log.Panicln("repository is nil on <New (account service)>")
|
||||
}
|
||||
|
||||
if deps.AuthClient == nil {
|
||||
log.Panicln("auth client is nil on <New (account service)>")
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
repository: deps.Repository,
|
||||
authClient: deps.AuthClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Service) GetAccountByUserID(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.FindByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get account by id on <GetAccountByUserID> of <AccountService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", userID),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) GetAccountsList(ctx context.Context, pagination *models.Pagination) (*models.PaginationResponse[models.Account], errors.Error) {
|
||||
if pagination == nil {
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("pagination is nil on <GetAccountsList> of <AccountService>: %w", errors.ErrInternalError),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
count, err := receiver.repository.CountAll(ctx)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to count accounts on <GetAccountsList> of <AccountService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
return &models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}}, nil
|
||||
}
|
||||
|
||||
totalPages := int64(math.Ceil(float64(count) / float64(pagination.Limit)))
|
||||
|
||||
accounts, err := receiver.repository.FindMany(ctx, pagination.Page, pagination.Limit)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get accounts list on <GetAccountsList> of <AccountService>",
|
||||
zap.Error(err),
|
||||
zap.Int64("page", pagination.Page),
|
||||
zap.Int64("limit", pagination.Limit),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.PaginationResponse[models.Account]{
|
||||
TotalPages: totalPages,
|
||||
Records: accounts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreateAccount(ctx context.Context, account *models.Account) (*models.Account, errors.Error) {
|
||||
findedAccount, err := receiver.GetAccountByUserID(ctx, account.UserID)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
receiver.logger.Error("failed to find account on <CreateAccount> of <AccountService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if findedAccount != nil {
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("failed to create account with <%s> on <CreateAccount> of <AccountService>: %w",
|
||||
account.UserID,
|
||||
errors.ErrConflict,
|
||||
),
|
||||
errors.ErrConflict,
|
||||
)
|
||||
}
|
||||
|
||||
createdAccount, err := receiver.repository.Insert(ctx, account)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create account on <CreateAccount> of <AccountService>",
|
||||
zap.Error(err),
|
||||
zap.Any("account", account),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return createdAccount, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreateAccountByUserID(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
||||
account, err := receiver.GetAccountByUserID(ctx, userID)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
receiver.logger.Error("failed to find account on <CreateAccountByUserID> of <AccountService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if account != nil {
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("failed to create account with <%s> on <CreateAccountByUserID> of <AccountService>: %w",
|
||||
userID,
|
||||
errors.ErrConflict,
|
||||
),
|
||||
errors.ErrConflict,
|
||||
)
|
||||
}
|
||||
|
||||
user, err := receiver.authClient.GetUser(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get user on <CreateAccountByUserID> of <AccountService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", userID),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createdAccount, err := receiver.repository.Insert(ctx, &models.Account{UserID: user.ID, Wallet: models.Wallet{Currency: defaultCurrency}})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to create account on <CreateAccountByUserID> of <AccountService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", userID),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return createdAccount, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) RemoveAccount(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.Remove(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to remove account on <RemoveAccount> of <AccountService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", userID),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) DeleteAccount(ctx context.Context, userID string) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.Delete(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to delete account on <DeleteAccount> of <AccountService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", userID),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) SetVerificationStatus(ctx context.Context, userID string, status models.AccountStatus) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.SetStatus(ctx, userID, status)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to set status on <SetVerificationStatus> of <AccountService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) UpdateAccountName(ctx context.Context, userID string, name *models.Name) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.UpdateName(ctx, userID, name)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to update account name on <UpdateAccountName> of <AccountService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
@ -2,7 +2,6 @@ package callback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@ -83,16 +82,20 @@ func (receiver *PaymentCallbackService) SuccessEvent(ctx context.Context, event
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
//go func() {
|
||||
if _, err := receiver.historyService.CreateHistory(ctx, &models.History{
|
||||
UserID: account.UserID,
|
||||
Comment: event.Message,
|
||||
Key: event.Key,
|
||||
RawDetails: fmt.Sprintf("%d%s", event.Amount, event.Currency),
|
||||
RawDetails: models.RawDetails{
|
||||
Price: event.Amount,
|
||||
Comment: event.Type + ":" + event.Currency,
|
||||
},
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to create history on <SuccessEvent> of <PaymentCallbackService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}()
|
||||
//}()
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -102,7 +105,7 @@ func (receiver *PaymentCallbackService) FailureEvent(ctx context.Context, event
|
||||
UserID: event.UserID,
|
||||
Comment: event.Message,
|
||||
Key: event.Key,
|
||||
RawDetails: fmt.Sprintf("%d%s", event.Amount, event.Currency),
|
||||
// RawDetails: fmt.Sprintf("%d%s", event.Amount, event.Currency),
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to create history on <FailureEvent> of <PaymentCallbackService>", zap.Error(err))
|
||||
return err
|
||||
|
||||
@ -1,238 +0,0 @@
|
||||
package cart
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"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/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"
|
||||
)
|
||||
|
||||
type accountRepository interface {
|
||||
FindByUserID(ctx context.Context, id string) (*models.Account, errors.Error)
|
||||
AddItemToCart(ctx context.Context, userID, itemID string) (*models.Account, errors.Error)
|
||||
RemoveItemFromCart(ctx context.Context, userID, itemID string) (*models.Account, errors.Error)
|
||||
ClearCart(ctx context.Context, userID string) (*models.Account, errors.Error)
|
||||
}
|
||||
|
||||
type hubadminClient interface {
|
||||
GetTariff(ctx context.Context, accessToken, tariffID string) (*models.Tariff, errors.Error)
|
||||
GetTariffs(ctx context.Context, accessToken string, tarriffIDs []string) ([]models.Tariff, errors.Error)
|
||||
}
|
||||
|
||||
type discountClient interface {
|
||||
Apply(context.Context, *discount.ApplyDiscountRequest) (*discount.ApplyDiscountResponse, errors.Error)
|
||||
}
|
||||
|
||||
type walletService interface {
|
||||
ReplenishAccountWallet(context.Context, *models.ReplenishAccountWallet) (*models.Account, errors.Error)
|
||||
WithdrawAccountWalletMoney(context.Context, *models.WithdrawAccountWallet) (*models.Account, errors.Error)
|
||||
}
|
||||
|
||||
type historyService interface {
|
||||
CreateHistory(ctx context.Context, history *models.History) (*models.History, errors.Error)
|
||||
}
|
||||
|
||||
type tariffBrokerService interface {
|
||||
SendMany(ctx context.Context, userID string, tariffs []models.Tariff) []errors.Error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Repository accountRepository
|
||||
HubadminClient hubadminClient
|
||||
DiscountClient discountClient
|
||||
WalletService walletService
|
||||
HistoryService historyService
|
||||
TariffBrokerService tariffBrokerService
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
repository accountRepository
|
||||
hubadminClient hubadminClient
|
||||
discountClient discountClient
|
||||
walletService walletService
|
||||
historyService historyService
|
||||
tariffBrokerService tariffBrokerService
|
||||
}
|
||||
|
||||
func New(deps Deps) *Service {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
if deps.Repository == nil {
|
||||
log.Panicln("repository is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
if deps.HubadminClient == nil {
|
||||
log.Panicln("HubadminClient is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
if deps.DiscountClient == nil {
|
||||
log.Panicln("DiscountClient is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
if deps.WalletService == nil {
|
||||
log.Panicln("WalletService is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
if deps.HistoryService == nil {
|
||||
log.Panicln("HistoryService is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
if deps.TariffBrokerService == nil {
|
||||
log.Panicln("TariffBrokerService is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
repository: deps.Repository,
|
||||
hubadminClient: deps.HubadminClient,
|
||||
discountClient: deps.DiscountClient,
|
||||
walletService: deps.WalletService,
|
||||
historyService: deps.HistoryService,
|
||||
tariffBrokerService: deps.TariffBrokerService,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Service) Remove(ctx context.Context, userID, itemID string) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.RemoveItemFromCart(ctx, userID, itemID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to remove item from cart on <Remove> of <CartService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) Add(ctx context.Context, request *models.AddItemToCart) (*models.Account, errors.Error) {
|
||||
tariff, err := receiver.hubadminClient.GetTariff(ctx, request.AccessToken, request.TariffID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get tariff on <Add> of <CartService>",
|
||||
zap.Error(err),
|
||||
zap.String("tariffID", request.TariffID),
|
||||
zap.String("accessToken", request.AccessToken),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tariff == nil {
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("failed to get tariff <%s> on <Add> of <CartService>: tariff not found", request.TariffID),
|
||||
errors.ErrNotFound,
|
||||
)
|
||||
}
|
||||
|
||||
account, err := receiver.repository.AddItemToCart(ctx, request.UserID, request.TariffID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to add item to cart on <Add> of <CartService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) Pay(ctx context.Context, accessToken string, userID string) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.FindByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to find account on <Pay> of <CartService>", zap.String("userID", userID), zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
receiver.logger.Info("account for pay", zap.Any("acc", account))
|
||||
|
||||
tariffs, err := receiver.hubadminClient.GetTariffs(ctx, accessToken, account.Cart)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get tarrifs on <Pay> of <CartService>", zap.Strings("cart", account.Cart), zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
receiver.logger.Info("tariffs for pay", zap.Any("acc", tariffs))
|
||||
|
||||
tariffsAmount := utils.CalculateCartPurchasesAmount(tariffs)
|
||||
|
||||
discountResponse, err := receiver.discountClient.Apply(ctx, &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 {
|
||||
receiver.logger.Error("failed to discount on <Pay> of <CartService>", zap.Error(err))
|
||||
return nil, 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) {
|
||||
receiver.logger.Error("insufficient funds on <Pay> of <CartService>")
|
||||
return nil, errors.New(fmt.Errorf("insufficient funds: %d", int64(discountResponse.Price)-account.Wallet.Money), errors.ErrInsufficientFunds)
|
||||
}
|
||||
|
||||
updatedAccount, err := receiver.walletService.WithdrawAccountWalletMoney(ctx, &models.WithdrawAccountWallet{
|
||||
Money: int64(discountResponse.Price),
|
||||
Account: account,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to withdraw money on <Pay> of <CartService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func(tariffs []models.Tariff) {
|
||||
if _, historyErr := receiver.historyService.CreateHistory(ctx, &models.History{
|
||||
Key: models.CustomerHistoryKeyPayCart,
|
||||
UserID: account.UserID,
|
||||
Comment: "Успешная оплата корзины",
|
||||
RawDetails: map[string]any{
|
||||
"tariffs": tariffs,
|
||||
"price": discountResponse.Price,
|
||||
},
|
||||
}); historyErr != nil {
|
||||
receiver.logger.Error("failed to insert history on <Pay> of <CartService>", zap.Error(historyErr))
|
||||
}
|
||||
}(tariffs)
|
||||
|
||||
// TODO: обработать ошибки при отправке сообщений
|
||||
|
||||
receiver.logger.Error("send to redpanda", zap.String("userID", account.UserID), zap.Any("bought tariffs", tariffs))
|
||||
|
||||
if sendErrors := receiver.tariffBrokerService.SendMany(ctx, account.UserID, tariffs); len(sendErrors) > 0 {
|
||||
for _, err := range sendErrors {
|
||||
receiver.logger.Error("failed to send tariffs to broker on <Pay> of <CartService>", zap.Error(err))
|
||||
}
|
||||
|
||||
return nil, errors.NewWithMessage("failed to send tariffs to broker", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
if _, err := receiver.repository.ClearCart(ctx, account.UserID); err != nil {
|
||||
receiver.logger.Error("failed to clear cart on <Pay> of <CartService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatedAccount.Cart = []string{}
|
||||
|
||||
return updatedAccount, nil
|
||||
}
|
||||
@ -1,93 +0,0 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
|
||||
type currencyRepository interface {
|
||||
FindCurrenciesList(ctx context.Context, name string) (*models.CurrencyList, errors.Error)
|
||||
ReplaceCurrencies(ctx context.Context, list *models.CurrencyList) (*models.CurrencyList, errors.Error)
|
||||
Insert(ctx context.Context, list *models.CurrencyList) (*models.CurrencyList, errors.Error)
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Repository currencyRepository
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
repository currencyRepository
|
||||
}
|
||||
|
||||
func New(deps Deps) *Service {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <New (currency service)>")
|
||||
}
|
||||
|
||||
if deps.Repository == nil {
|
||||
log.Panicln("repository is nil on <New (currency service)>")
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
repository: deps.Repository,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Service) GetCurrencies(ctx context.Context) ([]string, errors.Error) {
|
||||
currencyList, err := receiver.repository.FindCurrenciesList(ctx, models.DefaultCurrencyListName)
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
receiver.logger.Error(
|
||||
"failed to get currencies on <GetCurrencies> of <CurrencyService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
if err != nil && err.Type() == errors.ErrNotFound {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
return currencyList.Currencies, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) PutCurrencies(ctx context.Context, currencies []string) ([]string, errors.Error) {
|
||||
currencyList, err := receiver.repository.ReplaceCurrencies(ctx, &models.CurrencyList{
|
||||
Name: models.DefaultCurrencyListName,
|
||||
Currencies: currencies,
|
||||
})
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
receiver.logger.Error(
|
||||
"failed to put currencies on <PutCurrencies> of <CurrencyService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
if err != nil && err.Type() == errors.ErrNotFound {
|
||||
newCurrencyList, err := receiver.repository.Insert(ctx, &models.CurrencyList{
|
||||
Name: models.DefaultCurrencyListName,
|
||||
Currencies: currencies,
|
||||
})
|
||||
if err != nil && err.Type() != errors.ErrNotFound {
|
||||
receiver.logger.Error(
|
||||
"failed to insert new currency list on <PutCurrencies> of <CurrencyService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
return newCurrencyList.Currencies, nil
|
||||
}
|
||||
|
||||
return currencyList.Currencies, nil
|
||||
}
|
||||
@ -2,14 +2,9 @@ package history
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/fields"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
@ -89,44 +84,6 @@ func New(deps Deps) *Service {
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Service) GetHistoryList(ctx context.Context, dto *GetHistories) (*models.PaginationResponse[models.History], errors.Error) {
|
||||
if dto == nil {
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("pagination is nil on <GetHistoryList> of <HistoryService>: %w", errors.ErrInternalError),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
count, err := receiver.repository.CountAll(ctx, dto)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to count histories on <GetHistoryList> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
return &models.PaginationResponse[models.History]{TotalPages: 0, Records: []models.History{}}, nil
|
||||
}
|
||||
|
||||
totalPages := int64(math.Ceil(float64(count) / float64(dto.Pagination.Limit)))
|
||||
|
||||
histories, err := receiver.repository.FindMany(ctx, dto)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get historiy list on <GetHistoryList> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.PaginationResponse[models.History]{
|
||||
TotalPages: totalPages,
|
||||
Records: histories,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CreateHistory(ctx context.Context, history *models.History) (*models.History, errors.Error) {
|
||||
createdHistory, err := receiver.repository.Insert(ctx, history)
|
||||
if err != nil {
|
||||
@ -136,138 +93,3 @@ func (receiver *Service) CreateHistory(ctx context.Context, history *models.Hist
|
||||
|
||||
return createdHistory, nil
|
||||
}
|
||||
|
||||
// TODO:tests.
|
||||
func (receiver *Service) GetRecentTariffs(ctx context.Context, userID string) ([]models.TariffID, errors.Error) {
|
||||
if userID == "" {
|
||||
receiver.logger.Error("user id is missing in <GetRecentTariffs> of <HistoryService>")
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("user id is missing: %w", errors.ErrInvalidArgs),
|
||||
errors.ErrInvalidArgs,
|
||||
)
|
||||
}
|
||||
|
||||
tariffs, err := receiver.repository.GetRecentTariffs(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get recent tariffs in <GetRecentTariffs> of <HistoryService>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tariffs, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) GetHistoryByID(ctx context.Context, historyID string) errors.Error {
|
||||
if historyID == "" {
|
||||
receiver.logger.Error("history id is missing in <GetHistoryById> of <HistoryService>")
|
||||
return errors.New(
|
||||
fmt.Errorf("history id is missing: %w", errors.ErrInvalidArgs),
|
||||
errors.ErrInvalidArgs,
|
||||
)
|
||||
}
|
||||
|
||||
tariffs, err := receiver.repository.GetHistoryByID(ctx, historyID)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get history by id in <GetHistoryById> of <HistoryService>",
|
||||
zap.String("historyID", historyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
if tariffs.Key != models.CustomerHistoryKeyPayCart {
|
||||
receiver.logger.Error(
|
||||
"invalid history record key",
|
||||
zap.String("historyID", historyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
historyMap, err := receiver.repository.GetDocNumber(ctx, tariffs.UserID)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get history of sorting by date created in <GetDocNumber> of <HistoryService>",
|
||||
zap.String("historyID", historyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
verifuser, err := receiver.VerificationClient.GetVerification(ctx, 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 err
|
||||
}
|
||||
if !verifuser.Accepted {
|
||||
receiver.logger.Error(
|
||||
"verification not accepted",
|
||||
zap.String("userID", tariffs.UserID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
authuser, err := receiver.AuthClient.GetUser(ctx, 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 err
|
||||
}
|
||||
|
||||
fileContents, readerr := os.ReadFile("./report.docx")
|
||||
if readerr != nil {
|
||||
return errors.New(
|
||||
fmt.Errorf("failed to read file: %w", errors.ErrInternalError),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
for _, tariff := range tariffs.RawDetails.Tariffs {
|
||||
totalAmount := uint64(0)
|
||||
for _, privilege := range tariff.Privileges {
|
||||
totalAmount += privilege.Amount
|
||||
}
|
||||
data := models.RespGeneratorService{
|
||||
DocNumber: historyMap[historyID] + 1,
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
OrgTaxNum: verifuser.TaxNumber,
|
||||
OrgName: models.Name{Orgname: "Orgname"},
|
||||
Name: tariff.Name,
|
||||
Amount: totalAmount,
|
||||
Price: tariffs.RawDetails.Price,
|
||||
Sum: tariffs.RawDetails.Price,
|
||||
}
|
||||
err = receiver.TemlategenClient.SendData(ctx, data, fileContents, authuser.Email)
|
||||
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 err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Service) CalculateCustomerLTV(ctx context.Context, from, to int64) (int64, errors.Error) {
|
||||
ltv, err := receiver.repository.CalculateCustomerLTV(ctx, from, to)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to calculate LTV", zap.Error(err))
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ltv, nil
|
||||
}
|
||||
|
||||
@ -2,13 +2,10 @@ package wallet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"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/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
|
||||
)
|
||||
@ -119,7 +116,8 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo
|
||||
updatedAccount, changeErr := receiver.repository.ChangeWallet(ctx, request.Account.UserID, &models.Wallet{
|
||||
Cash: request.Account.Wallet.Cash + cash,
|
||||
Money: request.Account.Wallet.Money + request.Cash,
|
||||
PurchasesAmount: request.Account.Wallet.PurchasesAmount + request.Cash,
|
||||
Spent: request.Account.Wallet.Spent,
|
||||
PurchasesAmount: request.Account.Wallet.PurchasesAmount,
|
||||
Currency: request.Account.Wallet.Currency,
|
||||
LastPaymentID: request.PaymentID,
|
||||
})
|
||||
@ -134,17 +132,17 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo
|
||||
return nil, changeErr
|
||||
}
|
||||
|
||||
go func() {
|
||||
if _, historyErr := receiver.historyService.CreateHistory(ctx, &models.History{
|
||||
Key: models.CustomerHistoryKeyReplenish,
|
||||
UserID: request.Account.UserID,
|
||||
Comment: "Успешное пополнение средств (Без конвертации валюты)",
|
||||
RawDetails: fmt.Sprintf("%d%s", cash, models.InternalCurrencyKey),
|
||||
}); historyErr != nil {
|
||||
receiver.logger.Error("failed to insert history on <ReplenishAccountWallet> of <WalletService>", zap.Error(historyErr))
|
||||
}
|
||||
}()
|
||||
|
||||
// go func() {
|
||||
// if _, historyErr := receiver.historyService.CreateHistory(ctx, &models.History{
|
||||
// Key: models.CustomerHistoryKeyReplenish,
|
||||
// UserID: request.Account.UserID,
|
||||
// Comment: "Успешное пополнение средств (Без конвертации валюты)",
|
||||
// // RawDetails: fmt.Sprintf("%d%s", cash, models.InternalCurrencyKey),
|
||||
// }); historyErr != nil {
|
||||
// receiver.logger.Error("failed to insert history on <ReplenishAccountWallet> of <WalletService>", zap.Error(historyErr))
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
return updatedAccount, nil
|
||||
}
|
||||
|
||||
@ -178,154 +176,16 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
if _, historyErr := receiver.historyService.CreateHistory(ctx, &models.History{
|
||||
Key: models.CustomerHistoryKeyReplenish,
|
||||
UserID: request.Account.UserID,
|
||||
Comment: "Успешное пополнение средств (C конвертацией валюты)",
|
||||
RawDetails: fmt.Sprintf("%d%s", cash, request.Currency),
|
||||
}); historyErr != nil {
|
||||
receiver.logger.Error("failed to insert history on <ReplenishAccountWallet> of <WalletService>", zap.Error(historyErr))
|
||||
}
|
||||
}()
|
||||
// go func() {
|
||||
// if _, historyErr := receiver.historyService.CreateHistory(ctx, &models.History{
|
||||
// Key: models.CustomerHistoryKeyReplenish,
|
||||
// UserID: request.Account.UserID,
|
||||
// Comment: "Успешное пополнение средств (C конвертацией валюты)",
|
||||
// //RawDetails: fmt.Sprintf("%d%s", cash, request.Currency),
|
||||
// }); historyErr != nil {
|
||||
// receiver.logger.Error("failed to insert history on <ReplenishAccountWallet> of <WalletService>", zap.Error(historyErr))
|
||||
// }
|
||||
// }()
|
||||
|
||||
return updatedAccount, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) WithdrawAccountWalletMoney(ctx context.Context, request *models.WithdrawAccountWallet) (*models.Account, errors.Error) {
|
||||
if validate.IsStringEmpty(request.Account.Wallet.Currency) {
|
||||
request.Account.Wallet.Currency = models.InternalCurrencyKey
|
||||
}
|
||||
|
||||
if request.Account.Wallet.Currency == models.InternalCurrencyKey {
|
||||
updatedAccount, err := receiver.repository.ChangeWallet(ctx, 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 {
|
||||
receiver.logger.Error("failed to replenish wallet on <ReplenishAccountWallet> of <WalletService>",
|
||||
zap.Error(err),
|
||||
zap.String("Currency", request.Account.Wallet.Currency),
|
||||
zap.Int64("Money", request.Account.Wallet.Money-request.Money),
|
||||
zap.Int64("Cash", request.Account.Wallet.Cash+request.Money),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updatedAccount, nil
|
||||
}
|
||||
|
||||
cash, err := receiver.currencyClient.Translate(ctx, &models.TranslateCurrency{
|
||||
Money: request.Money,
|
||||
From: models.InternalCurrencyKey,
|
||||
To: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to translate money on <WithdrawAccountWalletMoney> of <WalletService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatedAccount, err := receiver.repository.ChangeWallet(ctx, 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 {
|
||||
receiver.logger.Error("failed to replenish wallet on <ReplenishAccountWallet> of <WalletService>",
|
||||
zap.Error(err),
|
||||
zap.String("Currency", request.Account.Wallet.Currency),
|
||||
zap.Int64("Money", request.Account.Wallet.Money-request.Money),
|
||||
zap.Int64("Cash", request.Account.Wallet.Cash+cash),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updatedAccount, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) ChangeCurrency(ctx context.Context, userID string, currency models.CurrencyKey) (*models.Account, errors.Error) {
|
||||
account, err := receiver.repository.FindByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to find account on <ChangeCurrency> of <WalletService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", userID),
|
||||
zap.Any("currency", currency),
|
||||
)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cash, err := receiver.currencyClient.Translate(ctx, &models.TranslateCurrency{
|
||||
Money: account.Wallet.Cash,
|
||||
From: account.Wallet.Currency,
|
||||
To: currency,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to translate currency on <ChangeCurrency> of <WalletService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatedAccount, err := receiver.repository.ChangeWallet(ctx, account.UserID, &models.Wallet{
|
||||
Cash: cash,
|
||||
Currency: currency,
|
||||
Money: account.Wallet.Money,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to update wallet on <ChangeCurrency> of <WalletService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updatedAccount, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) PostWalletRspay(ctx context.Context, token, userID string, req swagger.PostWalletRspayJSONBody) errors.Error {
|
||||
user, err := receiver.repository.FindByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user.Status != models.AccountStatusNko && user.Status != models.AccountStatusOrg {
|
||||
return errors.New(
|
||||
fmt.Errorf("not allowed for non organizations"),
|
||||
errors.ErrNoAccess,
|
||||
)
|
||||
}
|
||||
|
||||
verification, err := receiver.verificationClient.GetVerification(ctx, token, userID)
|
||||
if err == errors.ErrNotFound {
|
||||
return errors.New(
|
||||
fmt.Errorf("no verification data found"),
|
||||
errors.ErrNoAccess,
|
||||
)
|
||||
}
|
||||
|
||||
if user.Status == models.AccountStatusOrg && len(verification.Files) != 3 {
|
||||
return errors.New(
|
||||
fmt.Errorf("not enough verification files"),
|
||||
errors.ErrNoAccess,
|
||||
)
|
||||
} else if user.Status == models.AccountStatusNko && len(verification.Files) != 4 {
|
||||
return errors.New(
|
||||
fmt.Errorf("not enough verification files"),
|
||||
errors.ErrNoAccess,
|
||||
)
|
||||
}
|
||||
|
||||
authData, err := receiver.authClient.GetUser(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = receiver.mailClient.SendMessage(authData.Login, verification, *req.Money)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
34
internal/utils/promo_LTV.go
Normal file
34
internal/utils/promo_LTV.go
Normal file
@ -0,0 +1,34 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
codeword_rpc "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/codeword"
|
||||
"time"
|
||||
)
|
||||
|
||||
func MatchGen(codewordData map[string][]*codeword_rpc.PromoActivationResp_UserTime, from, to int64) bson.M {
|
||||
userActivations := make(map[string]int64)
|
||||
|
||||
for _, values := range codewordData {
|
||||
for _, activation := range values {
|
||||
userActivations[activation.UserID] = activation.Time
|
||||
}
|
||||
}
|
||||
|
||||
var conditions []bson.M
|
||||
for userID, activation := range userActivations {
|
||||
var condition bson.M
|
||||
if activation < from {
|
||||
condition = bson.M{"userId": userID, "createdAt": bson.M{"$gte": time.Unix(from, 0), "$lte": time.Unix(to, 0)}, "key": "payment.succeeded"}
|
||||
} else {
|
||||
condition = bson.M{"userId": userID, "createdAt": bson.M{"$gte": time.Unix(activation, 0), "$lte": time.Unix(to, 0)}, "key": "payment.succeeded"}
|
||||
}
|
||||
conditions = append(conditions, condition)
|
||||
}
|
||||
|
||||
match := bson.M{
|
||||
"$match": bson.M{"$or": conditions},
|
||||
}
|
||||
|
||||
return match
|
||||
}
|
||||
@ -15,9 +15,8 @@ func TariffsToProductInformations(tarrifs []models.Tariff) []*discount.ProductIn
|
||||
}
|
||||
|
||||
if tariff.Price != 0 {
|
||||
for i := range productInformations {
|
||||
productInformations[i].Price = tariff.Price
|
||||
}
|
||||
price := tariff.Price
|
||||
productInformations[len(productInformations) - 1].Usage = &price
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
@ -46,7 +45,6 @@ func makeRequest[T any, R any](url string, requestMethod func(url string) (*rest
|
||||
Error: responseBody,
|
||||
}, nil
|
||||
}
|
||||
fmt.Println("OO5OO", responseInstance.RawResponse, responseInstance.StatusCode())
|
||||
|
||||
responseBody, parseErr := parseResponse[T](responseInstance.Body(), responseInstance.RawResponse)
|
||||
if parseErr != nil {
|
||||
|
||||
@ -2,15 +2,15 @@ package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"fmt"
|
||||
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/json"
|
||||
)
|
||||
|
||||
func parseResponse[T any](body []byte, response *http.Response) (*T, error) {
|
||||
isJSONResponse := response.Header.Get("Content-Type") == "application/json"
|
||||
fmt.Println("1OOOO", response.Header.Get("Content-Type"), string(body))
|
||||
fmt.Println("1OOOO", response.Header.Get("Content-Type"), string(body))
|
||||
|
||||
if !isJSONResponse {
|
||||
responseBody, unmarshalErr := json.Unmarshal[T](body)
|
||||
|
||||
@ -25,7 +25,7 @@ func TestAddAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
responseAddAccount, errAddAccount := client.Post[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/account",
|
||||
URL: "http://localhost:8082/account",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
QueryParams: map[string]string{"id": "64e5d9830fcca0596d82c0c1"},
|
||||
})
|
||||
|
||||
@ -25,7 +25,7 @@ func TestBuyTariff(t *testing.T) {
|
||||
}
|
||||
|
||||
responseAddCart, errAddCart := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/cart",
|
||||
URL: "http://localhost:8082/cart",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
QueryParams: map[string]string{"id": "64e6105384368b75221a5c3e"},
|
||||
})
|
||||
@ -42,7 +42,7 @@ func TestBuyTariff(t *testing.T) {
|
||||
|
||||
if isUserIDValid && isCartItemValid && isCartLengthValid {
|
||||
responsePay, errPay := client.Post[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/cart/pay",
|
||||
URL: "http://localhost:8082/cart/pay",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if isNoError := assert.NoError(t, errPay); !isNoError {
|
||||
|
||||
@ -37,7 +37,7 @@ func TestCalculateLTV(t *testing.T) {
|
||||
fmt.Println(from, to)
|
||||
|
||||
response, err := client.Post[interface{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/history/ltv",
|
||||
URL: "http://localhost:8082/history/ltv",
|
||||
Body: swagger.CalculateLTVJSONBody{From: from, To: to},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
|
||||
@ -32,7 +32,7 @@ func TestChangeAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
responseChangeAccount, errChangeAccount := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/account",
|
||||
URL: "http://localhost:8082/account",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
Body: updateRequest,
|
||||
})
|
||||
@ -64,7 +64,7 @@ func TestChangeAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
responseStatusAccount, errStatusAccount := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/account/64e5d9830fcca0596d82c0c7",
|
||||
URL: "http://localhost:8082/account/64e5d9830fcca0596d82c0c7",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
Body: statusRequest,
|
||||
})
|
||||
|
||||
@ -25,7 +25,7 @@ func TestGetAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
responseGetAccount, errGetAccount := client.Get[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/account",
|
||||
URL: "http://localhost:8082/account",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if isNoError := assert.NoError(t, errGetAccount); !isNoError {
|
||||
@ -48,7 +48,7 @@ func TestGetAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
responseGetAccount, errGetAccount := client.Get[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/account/64e5d9830fcca0596d82c0c7",
|
||||
URL: "http://localhost:8082/account/64e5d9830fcca0596d82c0c7",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if isNoError := assert.NoError(t, errGetAccount); !isNoError {
|
||||
@ -75,7 +75,7 @@ func TestGetAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
responseGetAccount, errGetAccount := client.Get[models.PaginationResponse[models.Account], models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/accounts",
|
||||
URL: "http://localhost:8082/accounts",
|
||||
Body: params,
|
||||
})
|
||||
if isNoError := assert.NoError(t, errGetAccount); !isNoError {
|
||||
|
||||
@ -24,7 +24,7 @@ func TestGetRecentTariffs(t *testing.T) {
|
||||
assert.NoError(t, tokenErr)
|
||||
|
||||
responseGetRecentTariffs, errGetRecentTariffs := client.Get[[]models.TariffID, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/recent",
|
||||
URL: "http://localhost:8082/recent",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
assert.NoError(t, errGetRecentTariffs)
|
||||
|
||||
@ -24,7 +24,7 @@ func TestGetAccount(t *testing.T) {
|
||||
}
|
||||
|
||||
response, err := client.Post[interface{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/wallet/rspay",
|
||||
URL: "http://localhost:8082/wallet/rspay",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if isNoError := assert.NoError(t, err); !isNoError {
|
||||
|
||||
@ -26,7 +26,7 @@ func TestSendReport(t *testing.T) {
|
||||
assert.NoError(t, tokenErr)
|
||||
|
||||
responseSendReport, errSendReport := client.Post[interface{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/sendReport",
|
||||
URL: "http://localhost:8082/sendReport",
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
Body: map[string]interface{}{"id": historyID},
|
||||
})
|
||||
|
||||
@ -17,7 +17,7 @@ func TestCurrencies(t *testing.T) {
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
responseGetCurrencies, errCurrencies := client.Get[[]models.CurrencyList, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8000/currencies",
|
||||
URL: "http://localhost:8082/currencies",
|
||||
})
|
||||
if isNoError := assert.NoError(t, errCurrencies); !isNoError {
|
||||
return
|
||||
|
||||
@ -22,7 +22,7 @@ func TestHistoryReport(t *testing.T) {
|
||||
}
|
||||
|
||||
response, err := client.Post[struct{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://" + "localhost:8000" + "/sendReport",
|
||||
URL: "http://" + "localhost:8082" + "/sendReport",
|
||||
Body: swagger.SendReportJSONBody{Id: "10002"},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
|
||||
110
tests/integration/logostat_test.go
Normal file
110
tests/integration/logostat_test.go
Normal file
@ -0,0 +1,110 @@
|
||||
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 InsertToDB(ctx context.Context, acc repository.AccountRepository, history repository.HistoryRepository) {
|
||||
partner1 := "partner1"
|
||||
partner2 := "partner2"
|
||||
qid1 := "qid1"
|
||||
qid2 := "qid2"
|
||||
acc.Insert(ctx, &models.Account{
|
||||
ID: "1",
|
||||
UserID: partner1,
|
||||
CreatedAt: time.Now(),
|
||||
})
|
||||
acc.Insert(ctx, &models.Account{
|
||||
ID: "2",
|
||||
UserID: partner2,
|
||||
CreatedAt: time.Now(),
|
||||
})
|
||||
|
||||
for i := 1; i < 101; i++ {
|
||||
var partnerID string
|
||||
var qid string
|
||||
if i%2 == 0 {
|
||||
partnerID = partner2
|
||||
qid = qid2
|
||||
} else {
|
||||
partnerID = partner1
|
||||
qid = qid1
|
||||
}
|
||||
|
||||
acc.Insert(ctx, &models.Account{
|
||||
ID: "IDUSER" + strconv.Itoa(i),
|
||||
UserID: strconv.Itoa(i),
|
||||
CreatedAt: time.Now(),
|
||||
From: qid,
|
||||
Partner: partnerID,
|
||||
})
|
||||
|
||||
history.Insert(ctx, &models.History{
|
||||
ID: "IDHISTORY" + strconv.Itoa(i),
|
||||
UserID: strconv.Itoa(i),
|
||||
RawDetails: models.RawDetails{
|
||||
Price: int64(faker.Uint64()),
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
88
tests/integration/promo_ltv_test.go
Normal file
88
tests/integration/promo_ltv_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
||||
codeword_rpc "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/codeword"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Test_PromoLTV(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()
|
||||
|
||||
codeword := client.NewCodewordClient(client.CodewordClientDeps{
|
||||
Logger: logger,
|
||||
CodewordServiceHost: "localhost:9000",
|
||||
})
|
||||
|
||||
mdb, 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,
|
||||
})
|
||||
|
||||
from := int64(0)
|
||||
to := int64(1714291104)
|
||||
|
||||
historyRepo := repository.NewHistoryRepository2(logger, mdb.Collection("histories"))
|
||||
|
||||
codewordData, err := codeword.GetAllPromoActivations(ctx, &codeword_rpc.Time{
|
||||
From: from,
|
||||
To: to,
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
userSumMap, err := historyRepo.GetPayUsersPromoHistory(ctx, codewordData, from, to)
|
||||
assert.NoError(t, err)
|
||||
|
||||
fmt.Println("userSumMap", userSumMap)
|
||||
|
||||
resp := make(map[string]struct {
|
||||
Regs int
|
||||
Money int64
|
||||
})
|
||||
|
||||
for promoID, data := range codewordData {
|
||||
for _, value := range data {
|
||||
|
||||
paids, ok := userSumMap[value.UserID]
|
||||
if !ok {
|
||||
paids = 0
|
||||
}
|
||||
|
||||
if value.Time >= from && value.Time <= 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(resp)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user