From c4f7c33c0381a136cf88fde6fbe48329ede119b3 Mon Sep 17 00:00:00 2001 From: Pavel Date: Sun, 3 Mar 2024 23:18:42 +0300 Subject: [PATCH] test bp --- .env | 65 - blueprint.yaml | 8 +- cmd/codeword/main.go | 32 - cmd/main.go | 38 + database.puml | 48 + deployment/local/docker-compose.yaml | 28 - deployment/staging/docker-compose.yaml | 0 deployment/test/docker-compose.yaml | 0 go.mod | 2 +- go.sum | 2 + internal/adapters/client/auth.go | 66 - internal/adapters/client/mail.go | 84 -- internal/app/app.go | 147 +-- .../promocode/promocode_controller.go | 206 --- internal/controller/promocode/route.go | 18 - .../recovery/recovery_controller.go | 134 -- internal/controller/recovery/route.go | 14 - internal/controllers/promocode.go | 135 ++ internal/controllers/recover.go | 87 ++ internal/controllers/stats.go | 45 + internal/errors/errors.go | 3 - internal/initialize/clients.go | 30 - internal/initialize/config.go | 53 - internal/initialize/encrypt.go | 13 - internal/initialize/grpc.go | 26 - internal/initialize/kafka.go | 27 - internal/initialize/mongo.go | 50 - internal/initialize/redis.go | 21 - internal/kafka/tariff/producer.go | 56 - internal/models/activatereq.go | 8 + internal/models/activateresp.go | 6 + internal/models/auth.go | 14 - internal/models/bonus.go | 81 +- internal/models/createfastlinkreq.go | 6 + internal/models/createfastlinkresp.go | 6 + internal/models/deps.go | 15 - internal/models/discount.go | 12 + internal/models/editpromocodereq.go | 16 + internal/models/filter.go | 8 + internal/models/getpromocodeslistreq.go | 10 + internal/models/getpromocodeslistresp.go | 8 + internal/models/privilege.go | 8 + internal/models/promocode.go | 28 + internal/models/promocodereq.go | 18 + internal/models/promocodestatsreq.go | 6 + internal/models/promocodestatsresp.go | 10 + internal/models/recoveryreq.go | 8 + internal/models/tariff.go | 46 - internal/models/usage.go | 8 + internal/models/user.go | 46 - internal/proto/broker/models.pb.go | 314 ----- internal/proto/discount/audit.model.pb.go | 192 --- internal/proto/discount/discount.model.pb.go | 1132 ----------------- internal/proto/discount/service.pb.go | 524 -------- internal/proto/discount/service_grpc.pb.go | 404 ------ internal/repository/codeword_repository.go | 100 -- internal/repository/errors.go | 13 - internal/repository/promocode.go | 55 + internal/repository/promocode_repository.go | 272 ---- internal/repository/promocode_stats.go | 72 -- internal/repository/recover.go | 41 + internal/repository/stats.go | 20 + internal/repository/user_repository.go | 37 - .../server/http/{http_server.go => http.go} | 6 +- internal/service/promocode.go | 77 ++ internal/service/recover.go | 57 + internal/service/stats.go | 27 + internal/services/promocode_service.go | 211 --- internal/services/recovery_service.go | 135 -- internal/utils/encrypt/encrypt_util.go | 81 -- internal/utils/genID/gen_id.go | 8 - internal/utils/transfer/privilege.go | 31 - internal/utils/transfer/tariff.go | 17 - internal/worker/purge_worker/purge_worker.go | 60 - .../worker/recovery_worker/recovery_worker.go | 129 -- docs/openapi.yaml => openapi.yaml | 120 +- pkg/closer/closer.go | 37 - template/cmd/{{.ProjectName}}/main.go.tmpl | 10 +- template/internal/app/app.go.tmpl | 52 +- tests/e2e/promo_test.go | 599 --------- tests/e2e/recover_test.go | 122 -- tests/helpers/jwt.go | 38 - tests/repository_test/repository_test.go | 518 -------- utils/authenticator.go | 46 - utils/jwt.go | 89 -- 85 files changed, 957 insertions(+), 6495 deletions(-) delete mode 100644 .env delete mode 100644 cmd/codeword/main.go create mode 100644 cmd/main.go create mode 100644 database.puml delete mode 100644 deployment/local/docker-compose.yaml delete mode 100644 deployment/staging/docker-compose.yaml delete mode 100644 deployment/test/docker-compose.yaml delete mode 100644 internal/adapters/client/auth.go delete mode 100644 internal/adapters/client/mail.go delete mode 100644 internal/controller/promocode/promocode_controller.go delete mode 100644 internal/controller/promocode/route.go delete mode 100644 internal/controller/recovery/recovery_controller.go delete mode 100644 internal/controller/recovery/route.go create mode 100644 internal/controllers/promocode.go create mode 100644 internal/controllers/recover.go create mode 100644 internal/controllers/stats.go delete mode 100644 internal/errors/errors.go delete mode 100644 internal/initialize/clients.go delete mode 100644 internal/initialize/config.go delete mode 100644 internal/initialize/encrypt.go delete mode 100644 internal/initialize/grpc.go delete mode 100644 internal/initialize/kafka.go delete mode 100644 internal/initialize/mongo.go delete mode 100644 internal/initialize/redis.go delete mode 100644 internal/kafka/tariff/producer.go create mode 100644 internal/models/activatereq.go create mode 100644 internal/models/activateresp.go delete mode 100644 internal/models/auth.go create mode 100644 internal/models/createfastlinkreq.go create mode 100644 internal/models/createfastlinkresp.go delete mode 100644 internal/models/deps.go create mode 100644 internal/models/discount.go create mode 100644 internal/models/editpromocodereq.go create mode 100644 internal/models/filter.go create mode 100644 internal/models/getpromocodeslistreq.go create mode 100644 internal/models/getpromocodeslistresp.go create mode 100644 internal/models/privilege.go create mode 100644 internal/models/promocode.go create mode 100644 internal/models/promocodereq.go create mode 100644 internal/models/promocodestatsreq.go create mode 100644 internal/models/promocodestatsresp.go create mode 100644 internal/models/recoveryreq.go delete mode 100644 internal/models/tariff.go create mode 100644 internal/models/usage.go delete mode 100644 internal/models/user.go delete mode 100644 internal/proto/broker/models.pb.go delete mode 100644 internal/proto/discount/audit.model.pb.go delete mode 100644 internal/proto/discount/discount.model.pb.go delete mode 100644 internal/proto/discount/service.pb.go delete mode 100644 internal/proto/discount/service_grpc.pb.go delete mode 100644 internal/repository/codeword_repository.go delete mode 100644 internal/repository/errors.go create mode 100644 internal/repository/promocode.go delete mode 100644 internal/repository/promocode_repository.go delete mode 100644 internal/repository/promocode_stats.go create mode 100644 internal/repository/recover.go create mode 100644 internal/repository/stats.go delete mode 100644 internal/repository/user_repository.go rename internal/server/http/{http_server.go => http.go} (86%) create mode 100644 internal/service/promocode.go create mode 100644 internal/service/recover.go create mode 100644 internal/service/stats.go delete mode 100644 internal/services/promocode_service.go delete mode 100644 internal/services/recovery_service.go delete mode 100644 internal/utils/encrypt/encrypt_util.go delete mode 100644 internal/utils/genID/gen_id.go delete mode 100644 internal/utils/transfer/privilege.go delete mode 100644 internal/utils/transfer/tariff.go delete mode 100644 internal/worker/purge_worker/purge_worker.go delete mode 100644 internal/worker/recovery_worker/recovery_worker.go rename docs/openapi.yaml => openapi.yaml (85%) delete mode 100644 pkg/closer/closer.go delete mode 100644 tests/e2e/promo_test.go delete mode 100644 tests/e2e/recover_test.go delete mode 100644 tests/helpers/jwt.go delete mode 100644 tests/repository_test/repository_test.go delete mode 100644 utils/authenticator.go delete mode 100644 utils/jwt.go diff --git a/.env b/.env deleted file mode 100644 index ccc52be..0000000 --- a/.env +++ /dev/null @@ -1,65 +0,0 @@ -# General application settings -APP_NAME=codeword -HTTP_HOST="localhost" -HTTP_PORT="8080" - -# MongoDB settings -MONGO_HOST="127.0.0.1" -MONGO_PORT="27020" -MONGO_USER="test" -MONGO_PASSWORD="test" -MONGO_DB="admin" -MONGO_AUTH="admin" - -# Redis settings -REDIS_ADDR="localhost:6379" -REDIS_PASS="admin" -REDIS_DB=2 - -# Keys -PUBLIC_CURVE_KEY="-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAEbnIvjIMle4rqVol6K2XUqOxHy1KJoNoZdKJrRUPKL4=\n-----END PUBLIC KEY-----" - -PRIVATE_CURVE_KEY="-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIKn0BKwF3vZvODgWAnUIwQhd8de5oZhY48gc23EWfrfs\n-----END PRIVATE KEY-----" - -JWT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- - MIICWwIBAAKBgHgnvr7O2tiApjJfid1orFnIGm6980fZp+Lpbjo+NC/0whMFga2B - iw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6BdA4TS2kB9Kf0wn0+7wSlyikH - oKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y+3GyaOY536H47qyXAgMBAAEC - gYAOphnVPXbk6lpYzdkLC1Xn5EOEuNfOLLURLxBnPWozZo26r/Mtahu/9mYhrYlv - PP8r6mxta3VIil8iOdZyOLa/4d1LPd+UehgEXIJEiYXLtn7RS5eUnoPuQxssfs1k - OWjdN8p6SzppleegFTvGRX4KM3cDLfSphOk8JuBCrpSSYQJBAOdqizTSrdKMTuVe - c7Jk1JOJkyFuFs+N5zeryyeFGH7IpRdWy0rkWMxIUAi8Ap1vYVBPHv4tDOo3sy5X - VLc/knkCQQCE62pg+0TmsrhO/2Pgog6MLBkzlzXYMRp/01HbmznwYF+ejfPnzLkz - hnUlxRUNK3lhXM/7H6oAjvqF2R72u/OPAkEAterkmdbQfEZ+MwNoEiH/lie9OLdx - SSI1VGdBYcTYN7qFRW6eizYstBJYkDU0HQ0Uw+we4hMKJwk4W0KdvxxDiQJAeqlB - V1QqBneBbK10PzVuFV8QtrJhJyxRVwrtbKq38iMNuqUnI4+ijXEUpJFWVvv6nKXo - 7McQvEk12dU/JNTX8wJAOlAtSNjp9tVwpMpC0w2St1eKc1L2SknjeohA5ldoBz8sGeZsPhTU3eHSD1neAZXLKN5K68z3zFBr20ubY9nyLw== - -----END RSA PRIVATE KEY-----" - -JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm6980fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6BdA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y+3GyaOY536H47qyXAgMBAAE=\n-----END PUBLIC KEY-----" - -JWT_ISSUER="pena-auth-service" - -JWT_AUDIENCE="pena" -# SIGN_SECRET="group" - -SIGN_SECRET="secret" - -# SMTP settings -SMTP_API_URL="https://api.smtp.bz/v1/smtp/send" -SMTP_HOST="connect.mailclient.bz" -SMTP_PORT="587" -SMTP_UNAME="kotilion.95@gmail.com" -SMTP_PASS="vWwbCSg4bf0p" -SMTP_API_KEY="P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev" -SMTP_SENDER="noreply@mailing.pena.digital" - -# URL settings -DEFAULT_REDIRECTION_URL = "def.url" -AUTH_EXCHANGE_URL = "http://localhost:8000/auth/exchange" -DISCOUNT_ADDRESS = "http://CHANGEME:1234" -RECOVERY_URL = "http://127.0.0.1:8080/recover/" - -# Kafka settings -KAFKA_BROKERS="localhost:9092" -KAFKA_TOPIC_TARIFF="tariffs" \ No newline at end of file diff --git a/blueprint.yaml b/blueprint.yaml index c86b65b..f7da08a 100644 --- a/blueprint.yaml +++ b/blueprint.yaml @@ -1,4 +1,4 @@ -ProjectName: codeword +templateProjectName: codeword Description: Service for exchanging codewords Template: @@ -12,3 +12,9 @@ Modules: - name: APP_NAME type: string default: "{{.ProjectName}}" + openapi: + model_save_path: ./internal/models + controller_save_path: ./internal/controllers + service_save_path: ./internal/service + repository_save_path: ./internal/repository + server_save_path: ./internal/server/http diff --git a/cmd/codeword/main.go b/cmd/codeword/main.go deleted file mode 100644 index 3d84e25..0000000 --- a/cmd/codeword/main.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "codeword/internal/app" - "codeword/internal/initialize" - "context" - "fmt" - "go.uber.org/zap" - "os" - "os/signal" - "syscall" -) - -func main() { - logger, err := zap.NewProduction() - if err != nil { - fmt.Printf("Failed to initialize logger: %v\n", err) - os.Exit(1) - } - - config, err := initialize.LoadConfig() - if err != nil { - logger.Fatal("Failed to load config", zap.Error(err)) - } - - ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) - defer stop() - - if err = app.Run(ctx, *config, logger); err != nil { - logger.Fatal("App exited with error", zap.Error(err)) - } -} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..b4c4588 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "codeword/internal/app" + "context" + "os/signal" + "syscall" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + "github.com/caarlos0/env/v8" +) + +func main() { + cfgLogger := zap.NewDevelopmentConfig() + cfgLogger.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + cfgLogger.EncoderConfig.ConsoleSeparator = " " + + logger, err := cfgLogger.Build() + if err != nil { + panic(err) + } + + ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer cancel() + + var config app.Config + + err = env.Parse(config) + if err != nil { + panic(err) + } + + if err := app.Run(ctx, config, logger); err != nil { + logger.Fatal("Failed to run app", zap.Any("Error", err)) + } +} diff --git a/database.puml b/database.puml new file mode 100644 index 0000000..e723239 --- /dev/null +++ b/database.puml @@ -0,0 +1,48 @@ +@startuml Database + +map Usage { + key => **string** + time => **string** //date-time// +} + +map Discount { + factor => **integer** + layer => **integer** + target => **string** + threshold => **integer** +} + +map Privilege { + amount => **integer** + privilegeID => **string** +} + +map PromoCode { + id => **string** //primary_key// + activationCount => **integer** + bonus => **bonus** + codeword => **string** + createdAt => **string** //date-time// + delete => **boolean** + description => **string** + fastLinks => **[]string** + dueTo => **integer** + greetings => **string** + offLimit => **boolean** + outdated => **boolean** +} + +map Bonus { + discount => **discount** + privilege => **privilege** +} + +map Filter { + active => **boolean** + text => **string** +} + +Bonus::discount -> Discount +Bonus::privilege -> Privilege + +@enduml \ No newline at end of file diff --git a/deployment/local/docker-compose.yaml b/deployment/local/docker-compose.yaml deleted file mode 100644 index d77ec4a..0000000 --- a/deployment/local/docker-compose.yaml +++ /dev/null @@ -1,28 +0,0 @@ -version: '3.8' - -services: - mongo: - image: mongo - ports: - - "27020:27017" - environment: - - MONGO_INITDB_ROOT_USERNAME=test - - MONGO_INITDB_ROOT_PASSWORD=test - - MONGO_INITDB_AUTH_MECHANISM=SCRAM-SHA-1 - volumes: - - mongo_data:/data/db - - redis: - image: redis:latest - ports: - - "6379:6379" - environment: - - REDIS_PASSWORD=admin - - REDIS_DB=2 - command: [ "redis-server", "--requirepass", "admin", "--databases", "16", "--maxmemory", "2gb", "--maxmemory-policy", "allkeys-lru" ] - volumes: - - redis_data:/data - -volumes: - mongo_data: - redis_data: \ No newline at end of file diff --git a/deployment/staging/docker-compose.yaml b/deployment/staging/docker-compose.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/deployment/test/docker-compose.yaml b/deployment/test/docker-compose.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/go.mod b/go.mod index fc04dda..36a0201 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/twmb/franz-go v1.15.4 go.mongodb.org/mongo-driver v1.13.1 - go.uber.org/zap v1.26.0 + go.uber.org/zap v1.27.0 google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac google.golang.org/grpc v1.60.1 google.golang.org/protobuf v1.32.0 diff --git a/go.sum b/go.sum index 523b7ea..0b63c53 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,8 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 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= 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= diff --git a/internal/adapters/client/auth.go b/internal/adapters/client/auth.go deleted file mode 100644 index 225d282..0000000 --- a/internal/adapters/client/auth.go +++ /dev/null @@ -1,66 +0,0 @@ -package client - -import ( - "codeword/internal/models" - "encoding/json" - "fmt" - "github.com/gofiber/fiber/v2" - "go.uber.org/zap" -) - -type AuthClientDeps struct { - AuthUrl string - FiberClient *fiber.Client - Logger *zap.Logger -} - -type AuthClient struct { - deps AuthClientDeps -} - -func NewAuthClient(deps AuthClientDeps) *AuthClient { - if deps.FiberClient == nil { - deps.FiberClient = fiber.AcquireClient() - } - return &AuthClient{ - deps: deps, - } -} - -func (a *AuthClient) RefreshAuthToken(userID, signature string) (*models.RefreshResponse, error) { - body := models.AuthRequestBody{ - UserID: userID, - Signature: signature, - } - - bodyBytes, err := json.Marshal(body) - if err != nil { - a.deps.Logger.Error("Failed to encode request body", zap.Error(err)) - return nil, err - } - - agent := a.deps.FiberClient.Post(a.deps.AuthUrl) - agent.Set("Content-Type", "application/json").Body(bodyBytes) - - statusCode, resBody, errs := agent.Bytes() - if len(errs) > 0 { - for _, err := range errs { - a.deps.Logger.Error("Error in exchange auth token request", zap.Error(err)) - } - return nil, fmt.Errorf("request failed: %v", errs) - } - - if statusCode != fiber.StatusOK { - errorMessage := fmt.Sprintf("received an incorrect response from the authentication service: %d", statusCode) - a.deps.Logger.Error(errorMessage, zap.Int("status", statusCode)) - return nil, fmt.Errorf(errorMessage) - } - - var tokens models.RefreshResponse - if err := json.Unmarshal(resBody, &tokens); err != nil { - a.deps.Logger.Error("failed to unmarshal auth service response", zap.Error(err)) - return nil, err - } - - return &tokens, nil -} diff --git a/internal/adapters/client/mail.go b/internal/adapters/client/mail.go deleted file mode 100644 index 849d74a..0000000 --- a/internal/adapters/client/mail.go +++ /dev/null @@ -1,84 +0,0 @@ -package client - -import ( - "bytes" - "fmt" - "github.com/gofiber/fiber/v2" - "go.uber.org/zap" - "mime/multipart" -) - -type RecoveryEmailSenderDeps struct { - SmtpApiUrl string - SmtpHost string - SmtpPort string - SmtpSender string - Username string - Password string - ApiKey string - FiberClient *fiber.Client - Logger *zap.Logger - RecoveryUrl string -} - -type RecoveryEmailSender struct { - deps RecoveryEmailSenderDeps -} - -func NewRecoveryEmailSender(deps RecoveryEmailSenderDeps) *RecoveryEmailSender { - if deps.FiberClient == nil { - deps.FiberClient = fiber.AcquireClient() - } - return &RecoveryEmailSender{ - deps: deps, - } -} - -func (r *RecoveryEmailSender) SendRecoveryEmail(email string, signature string) error { - url := r.deps.SmtpApiUrl - - fmt.Println(email, signature) - - message := r.deps.RecoveryUrl + signature - - form := new(bytes.Buffer) - writer := multipart.NewWriter(form) - defer writer.Close() - - fields := map[string]string{ - "from": r.deps.SmtpSender, - "to": email, - "subject": "Восстановление доступа", - "html": message, - } - - for key, value := range fields { - if err := writer.WriteField(key, value); err != nil { - return err - } - } - - if err := writer.Close(); err != nil { - return err - } - - req := r.deps.FiberClient.Post(url).Body(form.Bytes()).ContentType(writer.FormDataContentType()) - if r.deps.ApiKey != "" { - req.Set("Authorization", r.deps.ApiKey) - } - - statusCode, body, errs := req.Bytes() - if errs != nil { - r.deps.Logger.Error("Error sending request", zap.Error(errs[0])) - return errs[0] - } - - if statusCode != fiber.StatusOK { - err := fmt.Errorf("the SMTP service returned an error: %s Response body: %s", statusCode, body) - r.deps.Logger.Error("Error sending email", zap.Error(err)) - return err - } - - //r.deps.Logger.Info("Recovery email sent", zap.String("email", email)) - return nil -} diff --git a/internal/app/app.go b/internal/app/app.go index 9e082d9..5c2ad74 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -1,159 +1,84 @@ package app import ( - "codeword/internal/controller/promocode" - "codeword/internal/controller/recovery" - "codeword/internal/initialize" + "codeword/internal/controllers" "codeword/internal/repository" - httpserver "codeword/internal/server/http" - "codeword/internal/services" - "codeword/internal/worker/purge_worker" - "codeword/internal/worker/recovery_worker" - "codeword/pkg/closer" - "codeword/utils" + "codeword/internal/server/http" + "codeword/internal/service" "context" - "errors" - "github.com/twmb/franz-go/pkg/kgo" + "go.uber.org/zap" - "time" ) -func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error { +type Config struct { + AppName string `env:"APP_NAME"` +} + +func Run(ctx context.Context, config Config, logger *zap.Logger) error { defer func() { if r := recover(); r != nil { logger.Error("Recovered from a panic", zap.Any("error", r)) } }() - logger.Info("Starting application", zap.String("AppName", cfg.AppName)) + logger.Info("App started", zap.Any("config", config)) ctx, cancel := context.WithCancel(ctx) defer cancel() - shutdownGroup := closer.NewCloserGroup() + // Инициализация репозиториев - mdb, err := initialize.MongoDB(ctx, cfg) - if err != nil { - logger.Error("Failed to initialize MongoDB", zap.Error(err)) - return err - } + promocodeRepository := repository.NewPromocodeRepository() - if err = initialize.InitDatabaseIndexes(ctx, mdb, logger); err != nil { - logger.Error("Failed to initialize db indexes", zap.Error(err)) - return err - } + recoverRepository := repository.NewRecoverRepository() - kafkaTariffClient, err := kgo.NewClient( - kgo.SeedBrokers(cfg.KafkaBrokers), - kgo.ConsumeResetOffset(kgo.NewOffset().AtStart()), - kgo.DefaultProduceTopic(cfg.KafkaTopic), - ) - if err != nil { - return err - } + statsRepository := repository.NewStatsRepository() - err = kafkaTariffClient.Ping(ctx) - if err != nil { - return err - } + // Инициализация сервисов - discountRpcClient, err := initialize.DiscountGRPCClient(cfg.DiscountServiceAddress) - if err != nil { - logger.Error("failed to connect to discount service", zap.Error(err)) - return err - } + promocodeService := service.NewPromocodeService(promocodeRepository) - brokers := initialize.NewBrokers(initialize.BrokersDeps{ - Logger: logger, - TariffClient: kafkaTariffClient, - Topic: cfg.KafkaTopic, - }) + recoverService := service.NewRecoverService(recoverRepository) - rdb, err := initialize.Redis(ctx, cfg) - if err != nil { - logger.Error("failed to connect to redis db", zap.Error(err)) - return err - } + statsService := service.NewStatsService(statsRepository) - encrypt := initialize.Encrypt(cfg) + // Инициализация контроллеров - promoCodeRepo := repository.NewPromoCodeRepository(mdb.Collection("promoCodes")) - statsRepo := repository.NewStatsRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("promoStats")}) - codewordRepo := repository.NewCodewordRepository(repository.Deps{Rdb: rdb, Mdb: mdb.Collection("codeword")}) - userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: mdb.Collection("users")}) + promocodeController := controllers.NewPromocodeController(promocodeService) - recoveryEmailSender := initialize.RecoveryEmailSender(cfg, logger) - authClient := initialize.AuthClient(cfg, logger) + recoverController := controllers.NewRecoverController(recoverService) - recoveryService := services.NewRecoveryService(services.Deps{ - Logger: logger, - CodewordRepository: codewordRepo, - UserRepository: userRepo, - Encrypt: encrypt, - AuthClient: authClient, - }) + statsController := controllers.NewStatsController(statsService) - promoService := services.NewPromoCodeService(services.PromoDeps{ - Logger: logger, - PromoCodeRepo: promoCodeRepo, - StatsRepo: statsRepo, - Kafka: brokers.TariffProducer, - DiscountClient: discountRpcClient, - }) + // Создание сервера + server := http.NewServer(http.ServerConfig{ + Controllers: []http.Controller{ - jwtUtil := utils.NewJWT(&cfg) - authMiddleware := utils.NewAuthenticator(jwtUtil) + promocodeController, - recoveryController := recovery.NewRecoveryController(logger, recoveryService, cfg.DefaultRedirectionURL) - promoCodeController := promocode.NewPromoCodeController(promocode.Deps{Logger: logger, PromoCodeService: promoService, AuthMiddleware: authMiddleware}) + recoverController, - recoveryWC := recovery_worker.NewRecoveryWC(recovery_worker.Deps{ - Logger: logger, - Redis: rdb, - EmailSender: recoveryEmailSender, - Mongo: mdb.Collection("codeword"), - }) - - purgeWC := purge_worker.NewPurgeWC(purge_worker.Deps{ - Logger: logger, - Mongo: mdb.Collection("codeword"), - }) - - go recoveryWC.Start(ctx) - go purgeWC.Start(ctx) - - server := httpserver.NewServer(httpserver.ServerConfig{ - Logger: logger, - Controllers: []httpserver.Controller{recoveryController, promoCodeController}, + statsController, + }, }) go func() { - if err := server.Start(cfg.HTTPHost + ":" + cfg.HTTPPort); err != nil { + err := server.Start("Host + : + Port") + if err != nil { logger.Error("Server startup error", zap.Error(err)) cancel() } }() + // Вывод маршрутов server.ListRoutes() - shutdownGroup.Add(closer.CloserFunc(server.Shutdown)) - shutdownGroup.Add(closer.CloserFunc(mdb.Client().Disconnect)) - shutdownGroup.Add(closer.CloserFunc(recoveryWC.Stop)) - shutdownGroup.Add(closer.CloserFunc(purgeWC.Stop)) - <-ctx.Done() - timeoutCtx, timeoutCancel := context.WithTimeout(context.Background(), 10*time.Second) - defer timeoutCancel() - if err := shutdownGroup.Call(timeoutCtx); err != nil { - if errors.Is(err, context.DeadlineExceeded) { - logger.Error("Shutdown timed out", zap.Error(err)) - } else { - logger.Error("Failed to shutdown services gracefully", zap.Error(err)) - } - return err - } + logger.Info("App shutting down gracefully") + + //TODO + // Остановка сервера - logger.Info("Application has stopped") return nil } diff --git a/internal/controller/promocode/promocode_controller.go b/internal/controller/promocode/promocode_controller.go deleted file mode 100644 index bc822a0..0000000 --- a/internal/controller/promocode/promocode_controller.go +++ /dev/null @@ -1,206 +0,0 @@ -package promocode - -import ( - "codeword/internal/models" - "codeword/internal/repository" - "codeword/internal/services" - "errors" - "github.com/gofiber/fiber/v2" - "go.uber.org/zap" -) - -type Deps struct { - Logger *zap.Logger - PromoCodeService *services.PromoCodeService - AuthMiddleware func(*fiber.Ctx) error -} - -type PromoCodeController struct { - logger *zap.Logger - promoCodeService *services.PromoCodeService - authMiddleware func(*fiber.Ctx) error -} - -func NewPromoCodeController(deps Deps) *PromoCodeController { - return &PromoCodeController{ - logger: deps.Logger, - promoCodeService: deps.PromoCodeService, - authMiddleware: deps.AuthMiddleware, - } -} - -func (p *PromoCodeController) CreatePromoCode(c *fiber.Ctx) error { - var req models.PromoCode - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) - } - - if req.Codeword == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword is required"}) - } - - createdPromoCode, err := p.promoCodeService.CreatePromoCode(c.Context(), &req) - if err != nil { - p.logger.Error("Failed to create promocode", zap.Error(err)) - - if errors.Is(err, repository.ErrDuplicateCodeword) { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Duplicate Codeword"}) - } - - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - return c.Status(fiber.StatusOK).JSON(createdPromoCode) -} - -func (p *PromoCodeController) EditPromoCode(c *fiber.Ctx) error { - var req models.ReqEditPromoCode - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) - } - - if req.ID == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "promocode ID is required"}) - } - - editedPromoCode, err := p.promoCodeService.EditPromoCode(c.Context(), &req) - if err != nil { - p.logger.Error("Failed to edit promocode", zap.Error(err)) - - if errors.Is(err, repository.ErrPromoCodeNotFound) { - return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) - } - - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - return c.Status(fiber.StatusOK).JSON(editedPromoCode) -} - -func (p *PromoCodeController) GetList(c *fiber.Ctx) error { - var req models.GetPromoCodesListReq - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) - } - - promoCodes, count, err := p.promoCodeService.GetPromoCodesList(c.Context(), &req) - if err != nil { - p.logger.Error("Failed to retrieve promocode list", zap.Error(err)) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - resp := models.GetPromoCodesListResp{ - Count: count, - Items: promoCodes, - } - return c.Status(fiber.StatusOK).JSON(resp) -} - -func (p *PromoCodeController) Activate(c *fiber.Ctx) error { - err := p.authMiddleware(c) - if err != nil { - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err}) - } - - userID := c.Locals(models.AuthJWTDecodedUserIDKey).(string) - if userID == "" { - return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "failed to get jwt payload"}) - } - - var req models.ActivateReq - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) - } - - if req.Codeword == "" && req.FastLink == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword or fastlink is required"}) - } - - greetings, err := p.promoCodeService.ActivatePromo(c.Context(), &req, userID) - if err != nil { - p.logger.Error("Failed to activate promocode", zap.Error(err)) - - switch { - case errors.Is(err, repository.ErrPromoCodeNotFound): - return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) - case errors.Is(err, repository.ErrPromoCodeAlreadyActivated): - return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "PromoCode already activated"}) - case errors.Is(err, repository.ErrPromoCodeExpired): - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()}) - case errors.Is(err, repository.ErrPromoCodeExhausted): - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode exhausted"}) - default: - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - } - - return c.Status(fiber.StatusOK).JSON(models.ActivateResp{Greetings: greetings}) -} - -func (p *PromoCodeController) Delete(c *fiber.Ctx) error { - promoCodeID := c.Params("promocodeID") - - if promoCodeID == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"}) - } - - err := p.promoCodeService.DeletePromoCode(c.Context(), promoCodeID) - if err != nil { - p.logger.Error("Failed to delete promocode", zap.Error(err)) - - if errors.Is(err, repository.ErrPromoCodeNotFound) { - return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) - } - - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - return c.SendStatus(fiber.StatusOK) -} - -func (p *PromoCodeController) CreateFastLink(c *fiber.Ctx) error { - var req struct { - PromoCodeID string `json:"id"` - } - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) - } - - if req.PromoCodeID == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"}) - } - - fastLink, err := p.promoCodeService.CreateFastLink(c.Context(), req.PromoCodeID) - if err != nil { - p.logger.Error("Failed to create fastlink", zap.Error(err)) - - if errors.Is(err, repository.ErrPromoCodeNotFound) { - return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) - } - - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - return c.Status(fiber.StatusCreated).JSON(fiber.Map{"fastlink": fastLink}) -} - -func (p *PromoCodeController) GetStats(c *fiber.Ctx) error { - var req struct { - PromoCodeID string `json:"id"` - } - - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) - } - - if req.PromoCodeID == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"}) - } - - promoStats, err := p.promoCodeService.GetStats(c.Context(), req.PromoCodeID) - if err != nil { - p.logger.Error("Failed getting promo stats", zap.Error(err)) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - return c.Status(fiber.StatusOK).JSON(promoStats) -} diff --git a/internal/controller/promocode/route.go b/internal/controller/promocode/route.go deleted file mode 100644 index af93df7..0000000 --- a/internal/controller/promocode/route.go +++ /dev/null @@ -1,18 +0,0 @@ -package promocode - -import "github.com/gofiber/fiber/v2" - -func (p *PromoCodeController) Register(router fiber.Router) { - router.Post("/create", p.CreatePromoCode) - router.Put("/edit", p.EditPromoCode) - router.Post("/getList", p.GetList) - router.Post("/activate", p.Activate) - router.Delete("/:promocodeID", p.Delete) - router.Post("/fastlink", p.CreateFastLink) - router.Get("/stats", p.GetStats) - -} - -func (p *PromoCodeController) Name() string { - return "promocode" -} diff --git a/internal/controller/recovery/recovery_controller.go b/internal/controller/recovery/recovery_controller.go deleted file mode 100644 index b120227..0000000 --- a/internal/controller/recovery/recovery_controller.go +++ /dev/null @@ -1,134 +0,0 @@ -package recovery - -import ( - "codeword/internal/models" - "codeword/internal/repository" - "codeword/internal/services" - "encoding/base64" - "errors" - "fmt" - "github.com/gofiber/fiber/v2" - "go.uber.org/zap" - "time" -) - -type RecoveryController struct { - logger *zap.Logger - service *services.RecoveryService - defaultURL string -} - -func NewRecoveryController(logger *zap.Logger, service *services.RecoveryService, defaultRedirectionURL string) *RecoveryController { - return &RecoveryController{ - logger: logger, - service: service, - defaultURL: defaultRedirectionURL, - } -} - -func (r *RecoveryController) HandleLiveness(c *fiber.Ctx) error { - return c.SendStatus(fiber.StatusOK) -} - -func (r *RecoveryController) HandlePingDB(c *fiber.Ctx) error { - startTime := time.Now() - if err := r.service.Ping(c.Context()); err != nil { - r.logger.Error("Failed to ping the database", zap.Error(err)) - return c.Status(fiber.StatusServiceUnavailable).SendString("DB ping failed") - } - duration := time.Since(startTime) - - durationMillis := duration.Milliseconds() - responseMessage := fmt.Sprintf("DB ping success - Time taken: %d ms", durationMillis) - - return c.Status(fiber.StatusOK).SendString(responseMessage) -} - -func (r *RecoveryController) HandleRecoveryRequest(c *fiber.Ctx) error { - var req models.RecoveryRequest - if err := c.BodyParser(&req); err != nil { - r.logger.Error("Failed to parse recovery request", zap.Error(err)) - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Bad Request"}) - } - - if req.Email == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "email is required"}) - } - - referralURL := c.Get("Referrer") - - if req.RedirectionURL == "" && referralURL != "" { - req.RedirectionURL = referralURL - } else if req.RedirectionURL == "" { - req.RedirectionURL = r.defaultURL - } - - user, err := r.service.FindUserByEmail(c.Context(), req.Email) - if err != nil || user == nil { - r.logger.Error("Failed to find user by email", zap.Error(err)) - return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"}) - } - - key, err := r.service.GenerateKey() - if err != nil { - r.logger.Error("Failed to generate key", zap.Error(err)) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - signUrl := req.RedirectionURL - sign := base64.URLEncoding.EncodeToString(key) - - id, err := r.service.StoreRecoveryRecord(c.Context(), models.StoreRecDeps{UserID: user.ID.Hex(), Email: user.Email, Key: sign, Url: signUrl}) - if err != nil { - r.logger.Error("Failed to store recovery record", zap.Error(err)) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - signWithID := sign + id // подпись с id записи - - err = r.service.RecoveryEmailTask(c.Context(), models.RecEmailDeps{UserID: user.ID.Hex(), Email: req.Email, SignWithID: signWithID, ID: id}) - if err != nil { - r.logger.Error("Failed to send recovery email", zap.Error(err)) - - if errors.Is(err, repository.ErrAlreadyReported) { - return c.Status(fiber.StatusAlreadyReported).JSON(fiber.Map{"error": "already reported"}) - } - - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - return c.Status(fiber.StatusOK).JSON(fiber.Map{"message": "Recovery email sent successfully"}) - -} - -func (r *RecoveryController) HandleRecoveryLink(c *fiber.Ctx) error { - sign := c.Params("sign") - - record, err := r.service.GetRecoveryRecord(c.Context(), sign) - if err != nil { - r.logger.Error("Failed to get recovery record", zap.Error(err)) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - if time.Since(record.CreatedAt) > 15*time.Minute { - r.logger.Error("Recovery link expired", zap.String("signature", sign)) - return c.Status(fiber.StatusNotAcceptable).JSON(fiber.Map{"error": "Recovery link expired"}) - } - - tokens, err := r.service.ExchangeForTokens(record.UserID, record.Sign) - if err != nil { - r.logger.Error("Failed to exchange recovery link for tokens", zap.Error(err)) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) - } - - c.Cookie(&fiber.Cookie{ - Name: "refreshToken", - Value: tokens["refreshToken"], - Domain: ".pena.digital", - Expires: time.Now().Add(30 * 24 * time.Hour), - Secure: true, - HTTPOnly: true, - }) - - return c.Redirect(record.SignUrl + "?auth=" + tokens["accessToken"]) -} diff --git a/internal/controller/recovery/route.go b/internal/controller/recovery/route.go deleted file mode 100644 index c2d6431..0000000 --- a/internal/controller/recovery/route.go +++ /dev/null @@ -1,14 +0,0 @@ -package recovery - -import "github.com/gofiber/fiber/v2" - -func (r *RecoveryController) Register(router fiber.Router) { - router.Get("/liveness", r.HandleLiveness) - router.Get("/readiness", r.HandlePingDB) - router.Post("/recover", r.HandleRecoveryRequest) - router.Get("/recover/:sign", r.HandleRecoveryLink) -} - -func (r *RecoveryController) Name() string { - return "" -} diff --git a/internal/controllers/promocode.go b/internal/controllers/promocode.go new file mode 100644 index 0000000..2602850 --- /dev/null +++ b/internal/controllers/promocode.go @@ -0,0 +1,135 @@ +package controllers + +import ( + "codeword/internal/models" + "codeword/internal/service" + + "github.com/gofiber/fiber/v2" +) + +type PromocodeController struct { + PromocodeService *service.PromocodeService +} + +func NewPromocodeController(service *service.PromocodeService) *PromocodeController { + return &PromocodeController{ + PromocodeService: service, + } +} + +func (c *PromocodeController) Register(router fiber.Router) { + + router.Post("/promocode/create", c.Createpromocode) + + router.Put("/promocode/edit", c.Editpromocode) + + router.Post("/promocode/fastlink", c.Createfastlink) + + router.Delete("/promocode/{promocodeID}", c.Delete) + + router.Post("/promocode/activate", c.Activate) + + router.Post("/promocode/getList", c.Getlist) + +} + +func (c *PromocodeController) Name() string { + return "" +} + +func (c *PromocodeController) Createpromocode(ctx *fiber.Ctx) error { + // Обработчик для метода Createpromocode + + var request models.PromoCodeReq + if err := ctx.BodyParser(&request); err != nil { + return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + response, err := c.PromocodeService.Createpromocode(ctx.Context(), &request) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.Status(fiber.StatusOK).JSON(response) + +} + +func (c *PromocodeController) Editpromocode(ctx *fiber.Ctx) error { + // Обработчик для метода Editpromocode + + var request models.EditPromoCodeReq + if err := ctx.BodyParser(&request); err != nil { + return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + response, err := c.PromocodeService.Editpromocode(ctx.Context(), &request) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.Status(fiber.StatusOK).JSON(response) + +} + +func (c *PromocodeController) Createfastlink(ctx *fiber.Ctx) error { + // Обработчик для метода Createfastlink + + var request models.CreateFastLinkReq + if err := ctx.BodyParser(&request); err != nil { + return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + response, err := c.PromocodeService.Createfastlink(ctx.Context(), &request) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.Status(fiber.StatusOK).JSON(response) + +} + +func (c *PromocodeController) Delete(ctx *fiber.Ctx) error { + // Обработчик для метода Delete + + err := c.PromocodeService.Delete(ctx.Context()) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.SendStatus(fiber.StatusOK) + +} + +func (c *PromocodeController) Activate(ctx *fiber.Ctx) error { + // Обработчик для метода Activate + + var request models.ActivateReq + if err := ctx.BodyParser(&request); err != nil { + return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + response, err := c.PromocodeService.Activate(ctx.Context(), &request) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.Status(fiber.StatusOK).JSON(response) + +} + +func (c *PromocodeController) Getlist(ctx *fiber.Ctx) error { + // Обработчик для метода Getlist + + var request models.GetPromoCodesListReq + if err := ctx.BodyParser(&request); err != nil { + return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + response, err := c.PromocodeService.Getlist(ctx.Context(), &request) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.Status(fiber.StatusOK).JSON(response) + +} diff --git a/internal/controllers/recover.go b/internal/controllers/recover.go new file mode 100644 index 0000000..dfe1c05 --- /dev/null +++ b/internal/controllers/recover.go @@ -0,0 +1,87 @@ +package controllers + +import ( + "codeword/internal/models" + "codeword/internal/service" + + "github.com/gofiber/fiber/v2" +) + +type RecoverController struct { + RecoverService *service.RecoverService +} + +func NewRecoverController(service *service.RecoverService) *RecoverController { + return &RecoverController{ + RecoverService: service, + } +} + +func (c *RecoverController) Register(router fiber.Router) { + + router.Get("/readiness", c.Readiness) + + router.Post("/recover", c.Recovery) + + router.Get("/recover/{sign}", c.Recoverylink) + + router.Get("/liveness", c.Liveness) + +} + +func (c *RecoverController) Name() string { + return "" +} + +func (c *RecoverController) Readiness(ctx *fiber.Ctx) error { + // Обработчик для метода Readiness + + err := c.RecoverService.Readiness(ctx.Context()) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.SendStatus(fiber.StatusOK) + +} + +func (c *RecoverController) Recovery(ctx *fiber.Ctx) error { + // Обработчик для метода Recovery + + var request models.RecoveryReq + if err := ctx.BodyParser(&request); err != nil { + return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + err := c.RecoverService.Recovery(ctx.Context(), &request) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.SendStatus(fiber.StatusOK) + +} + +func (c *RecoverController) Recoverylink(ctx *fiber.Ctx) error { + // Обработчик для метода Recoverylink + + err := c.RecoverService.Recoverylink(ctx.Context()) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.SendStatus(fiber.StatusOK) + +} + +func (c *RecoverController) Liveness(ctx *fiber.Ctx) error { + // Обработчик для метода Liveness + + err := c.RecoverService.Liveness(ctx.Context()) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.SendStatus(fiber.StatusOK) + +} diff --git a/internal/controllers/stats.go b/internal/controllers/stats.go new file mode 100644 index 0000000..6386bbf --- /dev/null +++ b/internal/controllers/stats.go @@ -0,0 +1,45 @@ +package controllers + +import ( + "codeword/internal/models" + "codeword/internal/service" + + "github.com/gofiber/fiber/v2" +) + +type StatsController struct { + StatsService *service.StatsService +} + +func NewStatsController(service *service.StatsService) *StatsController { + return &StatsController{ + StatsService: service, + } +} + +func (c *StatsController) Register(router fiber.Router) { + + router.Get("/promocode/stats", c.Getstats) + +} + +func (c *StatsController) Name() string { + return "" +} + +func (c *StatsController) Getstats(ctx *fiber.Ctx) error { + // Обработчик для метода Getstats + + var request models.PromoCodeStatsReq + if err := ctx.BodyParser(&request); err != nil { + return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) + } + + response, err := c.StatsService.Getstats(ctx.Context(), &request) + + if err != nil { + return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") + } + return ctx.Status(fiber.StatusOK).JSON(response) + +} diff --git a/internal/errors/errors.go b/internal/errors/errors.go deleted file mode 100644 index df9aae3..0000000 --- a/internal/errors/errors.go +++ /dev/null @@ -1,3 +0,0 @@ -package errors - -// пока не нужен diff --git a/internal/initialize/clients.go b/internal/initialize/clients.go deleted file mode 100644 index e32051b..0000000 --- a/internal/initialize/clients.go +++ /dev/null @@ -1,30 +0,0 @@ -package initialize - -import ( - "codeword/internal/adapters/client" - "github.com/gofiber/fiber/v2" - "go.uber.org/zap" -) - -func RecoveryEmailSender(cfg Config, logger *zap.Logger) *client.RecoveryEmailSender { - return client.NewRecoveryEmailSender(client.RecoveryEmailSenderDeps{ - SmtpApiUrl: cfg.SmtpApiUrl, - SmtpHost: cfg.SmtpHost, - SmtpPort: cfg.SmtpPort, - SmtpSender: cfg.SmtpSender, - Username: cfg.SmtpUsername, - Password: cfg.SmtpPassword, - ApiKey: cfg.SmtpApiKey, - FiberClient: &fiber.Client{}, - Logger: logger, - RecoveryUrl: cfg.RecoveryUrl, - }) -} - -func AuthClient(cfg Config, logger *zap.Logger) *client.AuthClient { - return client.NewAuthClient(client.AuthClientDeps{ - AuthUrl: cfg.AuthURL, - Logger: logger, - FiberClient: &fiber.Client{}, - }) -} diff --git a/internal/initialize/config.go b/internal/initialize/config.go deleted file mode 100644 index 23c78b1..0000000 --- a/internal/initialize/config.go +++ /dev/null @@ -1,53 +0,0 @@ -package initialize - -import ( - "github.com/caarlos0/env/v8" - "github.com/joho/godotenv" - "log" -) - -type Config struct { - AppName string `env:"APP_NAME" envDefault:"codeword"` - HTTPHost string `env:"HTTP_HOST" envDefault:"localhost"` - HTTPPort string `env:"HTTP_PORT" envDefault:"3000"` - MongoHost string `env:"MONGO_HOST" envDefault:"127.0.0.1"` - MongoPort string `env:"MONGO_PORT" envDefault:"27020"` - MongoUser string `env:"MONGO_USER" envDefault:"test"` - MongoPassword string `env:"MONGO_PASSWORD" envDefault:"test"` - MongoDatabase string `env:"MONGO_DB" envDefault:"admin"` - MongoAuth string `env:"MONGO_AUTH" envDefault:"admin"` - PublicCurveKey string `env:"PUBLIC_CURVE_KEY"` - PrivateCurveKey string `env:"PRIVATE_CURVE_KEY"` - SignSecret string `env:"SIGN_SECRET"` - RedisAddr string `env:"REDIS_ADDR" envDefault:"localhost:6379"` - RedisPassword string `env:"REDIS_PASS" envDefault:"admin"` - RedisDB int `env:"REDIS_DB" envDefault:"2"` - SmtpApiUrl string `env:"SMTP_API_URL"` - SmtpHost string `env:"SMTP_HOST"` - SmtpPort string `env:"SMTP_PORT"` - SmtpUsername string `env:"SMTP_UNAME"` - SmtpPassword string `env:"SMTP_PASS"` - SmtpApiKey string `env:"SMTP_API_KEY"` - SmtpSender string `env:"SMTP_SENDER"` - DefaultRedirectionURL string `env:"DEFAULT_REDIRECTION_URL"` - AuthURL string `env:"AUTH_EXCHANGE_URL"` - KafkaBrokers string `env:"KAFKA_BROKERS"` - KafkaTopic string `env:"KAFKA_TOPIC_TARIFF"` - DiscountServiceAddress string `env:"DISCOUNT_ADDRESS"` - RecoveryUrl string `env:"RECOVERY_URL"` - PrivateKey string `env:"JWT_PRIVATE_KEY"` - PublicKey string `env:"JWT_PUBLIC_KEY,required"` - Issuer string `env:"JWT_ISSUER,required"` - Audience string `env:"JWT_AUDIENCE,required"` -} - -func LoadConfig() (*Config, error) { - if err := godotenv.Load(); err != nil { - log.Print("No .env file found") - } - var config Config - if err := env.Parse(&config); err != nil { - return nil, err - } - return &config, nil -} diff --git a/internal/initialize/encrypt.go b/internal/initialize/encrypt.go deleted file mode 100644 index 366147d..0000000 --- a/internal/initialize/encrypt.go +++ /dev/null @@ -1,13 +0,0 @@ -package initialize - -import ( - "codeword/internal/utils/encrypt" -) - -func Encrypt(cfg Config) *encrypt.Encrypt { - return encrypt.New(&encrypt.EncryptDeps{ - PublicKey: cfg.PublicCurveKey, - PrivateKey: cfg.PrivateCurveKey, - SignSecret: cfg.SignSecret, - }) -} diff --git a/internal/initialize/grpc.go b/internal/initialize/grpc.go deleted file mode 100644 index 692ca21..0000000 --- a/internal/initialize/grpc.go +++ /dev/null @@ -1,26 +0,0 @@ -package initialize - -import ( - "codeword/internal/proto/discount" - "context" - "google.golang.org/grpc" - "time" -) - -func DiscountGRPCClient(address string) (discount.DiscountServiceClient, error) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - options := []grpc.DialOption{ - grpc.WithInsecure(), - //grpc.WithBlock(), - } - - conn, err := grpc.DialContext(ctx, address, options...) - if err != nil { - return nil, err - } - - discountClient := discount.NewDiscountServiceClient(conn) - return discountClient, nil -} diff --git a/internal/initialize/kafka.go b/internal/initialize/kafka.go deleted file mode 100644 index 8b4019d..0000000 --- a/internal/initialize/kafka.go +++ /dev/null @@ -1,27 +0,0 @@ -package initialize - -import ( - "codeword/internal/kafka/tariff" - "github.com/twmb/franz-go/pkg/kgo" - "go.uber.org/zap" -) - -type BrokersDeps struct { - Logger *zap.Logger - TariffClient *kgo.Client - Topic string -} - -type Brokers struct { - TariffProducer *tariff.Producer -} - -func NewBrokers(deps BrokersDeps) *Brokers { - return &Brokers{ - TariffProducer: tariff.NewProducer(tariff.ProducerDeps{ - Logger: deps.Logger, - Client: deps.TariffClient, - Topic: deps.Topic, - }), - } -} diff --git a/internal/initialize/mongo.go b/internal/initialize/mongo.go deleted file mode 100644 index c947b4a..0000000 --- a/internal/initialize/mongo.go +++ /dev/null @@ -1,50 +0,0 @@ -package initialize - -import ( - "codeword/internal/repository" - "context" - "go.mongodb.org/mongo-driver/mongo" - "go.uber.org/zap" - mdb "penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo" - "time" -) - -func MongoDB(ctx context.Context, cfg Config) (*mongo.Database, error) { - dbConfig := &mdb.Configuration{ - Host: cfg.MongoHost, - Port: cfg.MongoPort, - User: cfg.MongoUser, - Password: cfg.MongoPassword, - DatabaseName: cfg.MongoDatabase, - Auth: cfg.MongoAuth, - } - - newCtx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - - mongoDeps := &mdb.ConnectDeps{ - Configuration: dbConfig, - Timeout: 10 * time.Second, - } - - db, err := mdb.Connect(newCtx, mongoDeps) - if err != nil { - return nil, err - } - - err = db.Client().Ping(newCtx, nil) - if err != nil { - return nil, err - } - - return db, nil -} - -func InitDatabaseIndexes(ctx context.Context, mdb *mongo.Database, logger *zap.Logger) error { - if err := repository.InitPromoCodeIndexes(ctx, mdb.Collection("promoCodes")); err != nil { - logger.Error("Failed to initialize promoCodes indexes", zap.Error(err)) - return err - } - - return nil -} diff --git a/internal/initialize/redis.go b/internal/initialize/redis.go deleted file mode 100644 index d8de002..0000000 --- a/internal/initialize/redis.go +++ /dev/null @@ -1,21 +0,0 @@ -package initialize - -import ( - "context" - "github.com/go-redis/redis/v8" -) - -func Redis(ctx context.Context, cfg Config) (*redis.Client, error) { - rdb := redis.NewClient(&redis.Options{ - Addr: cfg.RedisAddr, - Password: cfg.RedisPassword, - DB: cfg.RedisDB, - }) - - status := rdb.Ping(ctx) - if err := status.Err(); err != nil { - return nil, err - } - - return rdb, nil -} diff --git a/internal/kafka/tariff/producer.go b/internal/kafka/tariff/producer.go deleted file mode 100644 index 69a5e92..0000000 --- a/internal/kafka/tariff/producer.go +++ /dev/null @@ -1,56 +0,0 @@ -package tariff - -import ( - "codeword/internal/models" - "codeword/internal/utils/transfer" - "context" - "github.com/twmb/franz-go/pkg/kgo" - "go.uber.org/zap" - "google.golang.org/protobuf/proto" - "log" -) - -type ProducerDeps struct { - Logger *zap.Logger - Client *kgo.Client - Topic string -} - -type Producer struct { - logger *zap.Logger - client *kgo.Client - topic string -} - -func NewProducer(deps ProducerDeps) *Producer { - if deps.Logger == nil { - log.Panicln("logger is nil on ") - } - - if deps.Client == nil { - log.Panicln("Kafka client is nil on ") - } - - return &Producer{ - logger: deps.Logger, - client: deps.Client, - topic: deps.Topic, - } -} - -func (p *Producer) Send(ctx context.Context, userID string, tariff *models.Tariff) error { - bytes, err := proto.Marshal(transfer.TariffModelToProtoMessage(userID, tariff)) - if err != nil { - p.logger.Error("failed to marshal tariff model", zap.Error(err)) - return err - } - - // упростил, возможно зря, но теперь возвращаем одну ошибку, просто прерываем цикл при первой встретившейся ошибке - err = p.client.ProduceSync(ctx, &kgo.Record{Topic: p.topic, Value: bytes}).FirstErr() - if err != nil { - p.logger.Error("failed to send tariff to Kafka", zap.Error(err)) - return err - } - - return nil -} diff --git a/internal/models/activatereq.go b/internal/models/activatereq.go new file mode 100644 index 0000000..beae274 --- /dev/null +++ b/internal/models/activatereq.go @@ -0,0 +1,8 @@ +package models + +type ActivateReq struct { + /* - Кодовое слово для активации промокода*/ + Codeword string `json:"codeword"` + /* - Быстрая ссылка для активации промокода*/ + Fastlink string `json:"fastLink"` +} diff --git a/internal/models/activateresp.go b/internal/models/activateresp.go new file mode 100644 index 0000000..514fd16 --- /dev/null +++ b/internal/models/activateresp.go @@ -0,0 +1,6 @@ +package models + +type ActivateResp struct { + /* - Слово успешной активации промокода*/ + Greetings string `json:"greetings"` +} diff --git a/internal/models/auth.go b/internal/models/auth.go deleted file mode 100644 index 204def2..0000000 --- a/internal/models/auth.go +++ /dev/null @@ -1,14 +0,0 @@ -package models - -type AuthRequestBody struct { - UserID string `json:"userId"` - Signature string `json:"signature"` -} - -type RefreshResponse struct { - AccessToken string `json:"accessToken"` - RefreshToken string `json:"refreshToken"` -} - -const AuthJWTDecodedUserIDKey = "userID" -const AuthJWTDecodedAccessTokenKey = "access-token" diff --git a/internal/models/bonus.go b/internal/models/bonus.go index d14150c..2979253 100644 --- a/internal/models/bonus.go +++ b/internal/models/bonus.go @@ -1,79 +1,8 @@ package models -import ( - "go.mongodb.org/mongo-driver/bson/primitive" - "time" -) - -type PromoCode struct { - ID primitive.ObjectID `json:"id" bson:"_id"` - Codeword string `json:"codeword" bson:"codeword"` // то, что будет вводить пользователь, чтобы получить плюшки - Description string `json:"description" bson:"description"` // описание, необходимое менеджеру в админке - Greetings string `json:"greetings" bson:"greetings"` // текст, выдаваемый пользователю в ответ на активацию промокода - DueTo int64 `json:"dueTo" bson:"dueTo"` // таймштамп времени окончания работы активации промокода - ActivationCount int64 `json:"activationCount" bson:"activationCount"` // предел количества активаций промокода - Bonus struct { - Privilege struct { - PrivilegeID string `json:"privilegeID" bson:"privilegeID"` // айдишник привилегии, которая будет выдаваться - Amount uint64 `json:"amount" bson:"amount"` // количество - } `json:"privilege" bson:"privilege"` - Discount struct { - Layer uint32 `json:"layer" bson:"layer"` // 1|2 - Factor float64 `json:"factor" bson:"factor"` // процент скидки, вернее множитель, при котором достигается этот процент скидки - Target string `json:"target" bson:"target"` // PrivilegeID или ServiceKey в зависимости от слоя - Threshold int64 `json:"threshold" bson:"threshold"` // граничное значение, при пересечении которого применяется эта скидка - } `json:"discount" bson:"discount"` - } `json:"bonus" bson:"bonus"` - Outdated bool `json:"outdated" bson:"outdated"` - OffLimit bool `json:"offLimit" bson:"offLimit"` - Delete bool `json:"delete" bson:"delete"` - CreatedAt time.Time `json:"createdAt" bson:"createdAt"` - FastLinks []string `json:"fastLinks" bson:"fastLinks"` -} - -type ReqEditPromoCode struct { - ID string `json:"id" bson:"_id"` //айдишник промокода, который обновляем - Description *string `json:"description,omitempty" bson:"description"` // описание, необходимое менеджеру в админке - Greetings *string `json:"greetings,omitempty" bson:"greetings"` // текст, выдаваемый пользователю в ответ на активацию промокода - - DueTo *int64 `json:"dueTo,omitempty" bson:"dueTo"` // таймштамп времени окончания работы активации промокода - ActivationCount *int64 `json:"activationCount,omitempty" bson:"activationCount"` // предел количества активаций промокода - - Delete *bool `json:"delete,omitempty" bson:"delete"` -} - -type GetPromoCodesListReqFilter struct { - Text string `json:"text"` // полнотекстовый поиск пo Codeword, Decription, Greetings полям - Active bool `json:"active"` // если true, то выбирать deleted==false && outdated== false && offlimit == false -} - -type GetPromoCodesListReq struct { - Page int `json:"page"` //номер страницы выборки. начинается с 0. по сути, skip для выборки из mongodb - Limit int `json:"limit"` //размер страницы выборки. больше 10, меньше 250. отвечает за skip = page*limit, и за limit - Filter GetPromoCodesListReqFilter `json:"filter"` -} - -type GetPromoCodesListResp struct { - Count int64 `json:"count"` // количество в выборке всего - Items []PromoCode `json:"items"` // "страница" промокодов -} - -type ActivateReq struct { - Codeword string `json:"codeword"` - FastLink string `json:"fastLink"` -} - -type ActivateResp struct { - Greetings string `json:"greetings"` // поле из активированного промокода -} - -type PromoCodeStats struct { - ID string `bson:"_id,omitempty" json:"id,omitempty"` - UsageCount int `bson:"usageCount" json:"usageCount"` - UsageMap map[string][]Usage `bson:"usageMap" json:"usageMap"` -} - -type Usage struct { - Key string `bson:"key" json:"key"` - Time time.Time `bson:"time" json:"time"` +type Bonus struct { + /* - Скидка*/ + Discount Discount `json:"discount"` + /* - Привилегия*/ + Privilege Privilege `json:"privilege"` } diff --git a/internal/models/createfastlinkreq.go b/internal/models/createfastlinkreq.go new file mode 100644 index 0000000..9d4df0d --- /dev/null +++ b/internal/models/createfastlinkreq.go @@ -0,0 +1,6 @@ +package models + +type CreateFastLinkReq struct { + /* - ID промокода, для которого нужно создать быструю ссылку*/ + ID string `json:"id"` +} diff --git a/internal/models/createfastlinkresp.go b/internal/models/createfastlinkresp.go new file mode 100644 index 0000000..c618770 --- /dev/null +++ b/internal/models/createfastlinkresp.go @@ -0,0 +1,6 @@ +package models + +type CreateFastLinkResp struct { + /* - Быстрая ссылка для активации промокода*/ + Fastlink string `json:"fastlink"` +} diff --git a/internal/models/deps.go b/internal/models/deps.go deleted file mode 100644 index 824660d..0000000 --- a/internal/models/deps.go +++ /dev/null @@ -1,15 +0,0 @@ -package models - -type StoreRecDeps struct { - UserID string - Email string - Key string - Url string -} - -type RecEmailDeps struct { - UserID string - Email string - SignWithID string - ID string -} diff --git a/internal/models/discount.go b/internal/models/discount.go new file mode 100644 index 0000000..9c08e7b --- /dev/null +++ b/internal/models/discount.go @@ -0,0 +1,12 @@ +package models + +type Discount struct { + /* - Уровень скидки*/ + Layer int `json:"layer"` + /* - Цель скидки*/ + Target string `json:"target"` + /* - Порог скидки*/ + Threshold int `json:"threshold"` + /* - Множитель скидки*/ + Factor int `json:"factor"` +} diff --git a/internal/models/editpromocodereq.go b/internal/models/editpromocodereq.go new file mode 100644 index 0000000..d689031 --- /dev/null +++ b/internal/models/editpromocodereq.go @@ -0,0 +1,16 @@ +package models + +type EditPromoCodeReq struct { + /* - Количество активаций промокода*/ + Activationcount int `json:"ActivationCount"` + /* - Флаг удаления промокода*/ + Delete bool `json:"Delete"` + /* - Описание промокода*/ + Description string `json:"Description"` + /* - Дата окончания промокода в формате Unix time*/ + Dueto int `json:"DueTo"` + /* - Приветственное сообщение после активации промокода*/ + Greetings string `json:"Greetings"` + /* - Идентификатор промокода, который требуется обновить*/ + ID string `json:"ID"` +} diff --git a/internal/models/filter.go b/internal/models/filter.go new file mode 100644 index 0000000..b272c76 --- /dev/null +++ b/internal/models/filter.go @@ -0,0 +1,8 @@ +package models + +type Filter struct { + /* - Флаг для фильтрации активных промокодов*/ + Active bool `json:"active"` + /* - Текстовый фильтр для поиска промокодов*/ + Text string `json:"text"` +} diff --git a/internal/models/getpromocodeslistreq.go b/internal/models/getpromocodeslistreq.go new file mode 100644 index 0000000..40ed511 --- /dev/null +++ b/internal/models/getpromocodeslistreq.go @@ -0,0 +1,10 @@ +package models + +type GetPromoCodesListReq struct { + /* - */ + Filter Filter `json:"filter"` + /* - Максимальное количество элементов на странице*/ + Limit int `json:"limit"` + /* - Номер страницы*/ + Page int `json:"page"` +} diff --git a/internal/models/getpromocodeslistresp.go b/internal/models/getpromocodeslistresp.go new file mode 100644 index 0000000..311129d --- /dev/null +++ b/internal/models/getpromocodeslistresp.go @@ -0,0 +1,8 @@ +package models + +type GetPromoCodesListResp struct { + /* - Общее количество промокодов*/ + Count int `json:"count"` + /* - */ + Items []PromoCode `json:"items"` +} diff --git a/internal/models/privilege.go b/internal/models/privilege.go new file mode 100644 index 0000000..53ae962 --- /dev/null +++ b/internal/models/privilege.go @@ -0,0 +1,8 @@ +package models + +type Privilege struct { + /* - Количество привилегии*/ + Amount int `json:"amount"` + /* - Идентификатор привилегии*/ + Privilegeid string `json:"privilegeID"` +} diff --git a/internal/models/promocode.go b/internal/models/promocode.go new file mode 100644 index 0000000..aae1de6 --- /dev/null +++ b/internal/models/promocode.go @@ -0,0 +1,28 @@ +package models + +type PromoCode struct { + /* - Идентификатор промокода*/ + ID string `json:"id"` + /* - Количество активаций промокода*/ + Activationcount int `json:"activationCount"` + /* - Бонус, предоставляемый с промокодом*/ + Bonus Bonus `json:"bonus"` + /* - Кодовое слово для активации промокода*/ + Codeword string `json:"codeword"` + /* - Дата и время создания промокода*/ + Createdat string `json:"createdAt"` + /* - Флаг*/ + Delete bool `json:"delete"` + /* - Описание промокода*/ + Description string `json:"description"` + /* - Список быстрых ссылок для активации промокода*/ + Fastlinks []string `json:"fastLinks"` + /* - Дата истечения действия промокода в формате Unix time*/ + Dueto int `json:"dueTo"` + /* - Приветственное сообщение после активации промокода*/ + Greetings string `json:"greetings"` + /* - Флаг*/ + Offlimit bool `json:"offLimit"` + /* - Флаг*/ + Outdated bool `json:"outdated"` +} diff --git a/internal/models/promocodereq.go b/internal/models/promocodereq.go new file mode 100644 index 0000000..98fc76f --- /dev/null +++ b/internal/models/promocodereq.go @@ -0,0 +1,18 @@ +package models + +type PromoCodeReq struct { + /* - Количество активаций промокода*/ + Activationcount int `json:"activationCount"` + /* - Бонус*/ + Bonus Bonus `json:"bonus"` + /* - Кодовое слово для активации промокода*/ + Codeword string `json:"codeword"` + /* - Описание промокода*/ + Description string `json:"description"` + /* - Дата истечения действия промокода в формате Unix time*/ + Dueto int `json:"dueTo"` + /* - Список быстрых ссылок для активации промокода*/ + Fastlinks []string `json:"fastLinks"` + /* - Приветственное сообщение после активации промокода*/ + Greetings string `json:"greetings"` +} diff --git a/internal/models/promocodestatsreq.go b/internal/models/promocodestatsreq.go new file mode 100644 index 0000000..b437c70 --- /dev/null +++ b/internal/models/promocodestatsreq.go @@ -0,0 +1,6 @@ +package models + +type PromoCodeStatsReq struct { + /* - */ + Promocodeid string `json:"promoCodeID"` +} diff --git a/internal/models/promocodestatsresp.go b/internal/models/promocodestatsresp.go new file mode 100644 index 0000000..0c73d9e --- /dev/null +++ b/internal/models/promocodestatsresp.go @@ -0,0 +1,10 @@ +package models + +type PromoCodeStatsResp struct { + /* - Идентификатор промокода*/ + ID string `json:"id"` + /* - Количество использований промокода*/ + Usagecount int `json:"usageCount"` + /* - Карта использования промокода*/ + Usagemap Usagemap `json:"usageMap"` +} diff --git a/internal/models/recoveryreq.go b/internal/models/recoveryreq.go new file mode 100644 index 0000000..a12bcad --- /dev/null +++ b/internal/models/recoveryreq.go @@ -0,0 +1,8 @@ +package models + +type RecoveryReq struct { + /* - Электронная почта, на которую нужно отправить инструкции по восстановлению*/ + Email string `json:"email"` + /* - URL-адрес, на который перенаправляется пользователь*/ + Redirectionurl string `json:"redirectionURL"` +} diff --git a/internal/models/tariff.go b/internal/models/tariff.go deleted file mode 100644 index 00da357..0000000 --- a/internal/models/tariff.go +++ /dev/null @@ -1,46 +0,0 @@ -package models - -import ( - "codeword/internal/proto/broker" - "time" -) - -type Tariff struct { - ID string `json:"_id"` - Name string `json:"name"` - Price uint64 `json:"price,omitempty"` - IsCustom bool `json:"isCustom"` - Privileges []Privilege `json:"privileges"` - Deleted bool `json:"isDeleted"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - DeletedAt *time.Time `json:"deletedAt,omitempty"` -} - -type Privilege struct { - ID string `json:"_id"` - Name string `json:"name"` - PrivilegeID string `json:"privilegeId"` - ServiceKey string `json:"serviceKey"` - Description string `json:"description"` - Amount uint64 `json:"amount"` - Type PrivilegeType `json:"type"` - Value string `json:"value"` - Price uint64 `json:"price"` -} - -type PrivilegeType string - -const ( - PrivilegeTypeCount = "count" - PrivilegeTypeDay = "day" - PrivilegeTypeFull = "full" -) - -var ( - PrivilegeBrokerTypeMap = map[PrivilegeType]broker.PrivilegeType{ - PrivilegeTypeFull: broker.PrivilegeType_Full, - PrivilegeTypeDay: broker.PrivilegeType_Day, - PrivilegeTypeCount: broker.PrivilegeType_Count, - } -) diff --git a/internal/models/usage.go b/internal/models/usage.go new file mode 100644 index 0000000..f3ac86a --- /dev/null +++ b/internal/models/usage.go @@ -0,0 +1,8 @@ +package models + +type Usage struct { + /* - fastlink или codeword в зависимости от того что применялось*/ + Key string `json:"key"` + /* - Время использования промокода*/ + Time string `json:"time"` +} diff --git a/internal/models/user.go b/internal/models/user.go deleted file mode 100644 index b1e32bf..0000000 --- a/internal/models/user.go +++ /dev/null @@ -1,46 +0,0 @@ -package models - -import ( - "go.mongodb.org/mongo-driver/bson/primitive" - "time" -) - -type User struct { - ID primitive.ObjectID `bson:"_id,omitempty"` - Login string `bson:"login,omitempty"` - Email string `bson:"email,omitempty"` - Password string `bson:"password,omitempty"` - PhoneNumber string `bson:"phoneNumber,omitempty"` - IsDeleted bool `bson:"isDeleted,omitempty"` - CreatedAt time.Time `bson:"createdAt,omitempty"` - UpdatedAt time.Time `bson:"updatedAt,omitempty"` - DeletedAt *time.Time `bson:"deletedAt,omitempty"` -} - -type RestoreRequest struct { - ID primitive.ObjectID `bson:"_id,omitempty"` - CreatedAt time.Time `bson:"created_at,omitempty"` - Sign string `bson:"sign,omitempty"` - SignUrl string `bson:"sign_url,omitempty"` - SignID string `bson:"sign_id"` - Email string `bson:"email,omitempty"` - UserID string `bson:"user_id,omitempty"` - Sent bool `bson:"sent"` - SentAt time.Time `bson:"sent_at"` -} - -type RecoveryRecord struct { - ID string - UserID string - Email string - Key string -} - -type RecoveryRequest struct { - Email string `json:"email"` - RedirectionURL string `json:"redirectionURL"` -} - -type RecoveryLinkRequest struct { - Sign string `json:"sign"` -} diff --git a/internal/proto/broker/models.pb.go b/internal/proto/broker/models.pb.go deleted file mode 100644 index cb81617..0000000 --- a/internal/proto/broker/models.pb.go +++ /dev/null @@ -1,314 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: kafka/models.proto - -package broker - -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 PrivilegeType int32 - -const ( - PrivilegeType_Full PrivilegeType = 0 - PrivilegeType_Day PrivilegeType = 1 - PrivilegeType_Count PrivilegeType = 2 -) - -// Enum value maps for PrivilegeType. -var ( - PrivilegeType_name = map[int32]string{ - 0: "Full", - 1: "Day", - 2: "Count", - } - PrivilegeType_value = map[string]int32{ - "Full": 0, - "Day": 1, - "Count": 2, - } -) - -func (x PrivilegeType) Enum() *PrivilegeType { - p := new(PrivilegeType) - *p = x - return p -} - -func (x PrivilegeType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PrivilegeType) Descriptor() protoreflect.EnumDescriptor { - return file_broker_models_proto_enumTypes[0].Descriptor() -} - -func (PrivilegeType) Type() protoreflect.EnumType { - return &file_broker_models_proto_enumTypes[0] -} - -func (x PrivilegeType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PrivilegeType.Descriptor instead. -func (PrivilegeType) EnumDescriptor() ([]byte, []int) { - return file_broker_models_proto_rawDescGZIP(), []int{0} -} - -type PrivilegeMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PrivilegeID string `protobuf:"bytes,1,opt,name=PrivilegeID,proto3" json:"PrivilegeID,omitempty"` - ServiceKey string `protobuf:"bytes,2,opt,name=ServiceKey,proto3" json:"ServiceKey,omitempty"` - Type PrivilegeType `protobuf:"varint,3,opt,name=Type,proto3,enum=kafka.PrivilegeType" json:"Type,omitempty"` - Value string `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"` - Amount uint64 `protobuf:"varint,5,opt,name=Amount,proto3" json:"Amount,omitempty"` -} - -func (x *PrivilegeMessage) Reset() { - *x = PrivilegeMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_broker_models_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PrivilegeMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PrivilegeMessage) ProtoMessage() {} - -func (x *PrivilegeMessage) ProtoReflect() protoreflect.Message { - mi := &file_broker_models_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 PrivilegeMessage.ProtoReflect.Descriptor instead. -func (*PrivilegeMessage) Descriptor() ([]byte, []int) { - return file_broker_models_proto_rawDescGZIP(), []int{0} -} - -func (x *PrivilegeMessage) GetPrivilegeID() string { - if x != nil { - return x.PrivilegeID - } - return "" -} - -func (x *PrivilegeMessage) GetServiceKey() string { - if x != nil { - return x.ServiceKey - } - return "" -} - -func (x *PrivilegeMessage) GetType() PrivilegeType { - if x != nil { - return x.Type - } - return PrivilegeType_Full -} - -func (x *PrivilegeMessage) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -func (x *PrivilegeMessage) GetAmount() uint64 { - if x != nil { - return x.Amount - } - return 0 -} - -type TariffMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Privileges []*PrivilegeMessage `protobuf:"bytes,1,rep,name=Privileges,proto3" json:"Privileges,omitempty"` - UserID string `protobuf:"bytes,2,opt,name=UserID,proto3" json:"UserID,omitempty"` -} - -func (x *TariffMessage) Reset() { - *x = TariffMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_broker_models_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TariffMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TariffMessage) ProtoMessage() {} - -func (x *TariffMessage) ProtoReflect() protoreflect.Message { - mi := &file_broker_models_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 TariffMessage.ProtoReflect.Descriptor instead. -func (*TariffMessage) Descriptor() ([]byte, []int) { - return file_broker_models_proto_rawDescGZIP(), []int{1} -} - -func (x *TariffMessage) GetPrivileges() []*PrivilegeMessage { - if x != nil { - return x.Privileges - } - return nil -} - -func (x *TariffMessage) GetUserID() string { - if x != nil { - return x.UserID - } - return "" -} - -var File_broker_models_proto protoreflect.FileDescriptor - -var file_broker_models_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x22, 0xad, 0x01, - 0x0a, 0x10, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x49, - 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, - 0x67, 0x65, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4b, - 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x69, 0x76, - 0x69, 0x6c, 0x65, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x61, 0x0a, - 0x0d, 0x54, 0x61, 0x72, 0x69, 0x66, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, - 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x69, 0x76, - 0x69, 0x6c, 0x65, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x50, 0x72, - 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, - 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, - 0x2a, 0x2d, 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, - 0x61, 0x79, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x02, 0x42, - 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_broker_models_proto_rawDescOnce sync.Once - file_broker_models_proto_rawDescData = file_broker_models_proto_rawDesc -) - -func file_broker_models_proto_rawDescGZIP() []byte { - file_broker_models_proto_rawDescOnce.Do(func() { - file_broker_models_proto_rawDescData = protoimpl.X.CompressGZIP(file_broker_models_proto_rawDescData) - }) - return file_broker_models_proto_rawDescData -} - -var file_broker_models_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_broker_models_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_broker_models_proto_goTypes = []interface{}{ - (PrivilegeType)(0), // 0: kafka.PrivilegeType - (*PrivilegeMessage)(nil), // 1: kafka.PrivilegeMessage - (*TariffMessage)(nil), // 2: kafka.TariffMessage -} -var file_broker_models_proto_depIdxs = []int32{ - 0, // 0: kafka.PrivilegeMessage.Type:type_name -> kafka.PrivilegeType - 1, // 1: kafka.TariffMessage.Privileges:type_name -> kafka.PrivilegeMessage - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_broker_models_proto_init() } -func file_broker_models_proto_init() { - if File_broker_models_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_broker_models_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PrivilegeMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_broker_models_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TariffMessage); 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_broker_models_proto_rawDesc, - NumEnums: 1, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_broker_models_proto_goTypes, - DependencyIndexes: file_broker_models_proto_depIdxs, - EnumInfos: file_broker_models_proto_enumTypes, - MessageInfos: file_broker_models_proto_msgTypes, - }.Build() - File_broker_models_proto = out.File - file_broker_models_proto_rawDesc = nil - file_broker_models_proto_goTypes = nil - file_broker_models_proto_depIdxs = nil -} diff --git a/internal/proto/discount/audit.model.pb.go b/internal/proto/discount/audit.model.pb.go deleted file mode 100644 index 7c2347e..0000000 --- a/internal/proto/discount/audit.model.pb.go +++ /dev/null @@ -1,192 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: discount/audit.model.proto - -package discount - -import ( - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - _ "google.golang.org/protobuf/types/known/emptypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - 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 Audit struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=UpdatedAt,proto3" json:"UpdatedAt,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=CreatedAt,proto3" json:"CreatedAt,omitempty"` - DeletedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=DeletedAt,proto3,oneof" json:"DeletedAt,omitempty"` - Deleted bool `protobuf:"varint,4,opt,name=Deleted,proto3" json:"Deleted,omitempty"` -} - -func (x *Audit) Reset() { - *x = Audit{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_audit_model_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Audit) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Audit) ProtoMessage() {} - -func (x *Audit) ProtoReflect() protoreflect.Message { - mi := &file_discount_audit_model_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 Audit.ProtoReflect.Descriptor instead. -func (*Audit) Descriptor() ([]byte, []int) { - return file_discount_audit_model_proto_rawDescGZIP(), []int{0} -} - -func (x *Audit) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -func (x *Audit) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *Audit) GetDeletedAt() *timestamppb.Timestamp { - if x != nil { - return x.DeletedAt - } - return nil -} - -func (x *Audit) GetDeleted() bool { - if x != nil { - return x.Deleted - } - return false -} - -var File_discount_audit_model_proto protoreflect.FileDescriptor - -var file_discount_audit_model_proto_rawDesc = []byte{ - 0x0a, 0x1a, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, - 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xe2, 0x01, 0x0a, 0x05, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x09, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x12, 0x3d, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, - 0x00, 0x52, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x88, 0x01, 0x01, 0x12, - 0x18, 0x0a, 0x07, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_discount_audit_model_proto_rawDescOnce sync.Once - file_discount_audit_model_proto_rawDescData = file_discount_audit_model_proto_rawDesc -) - -func file_discount_audit_model_proto_rawDescGZIP() []byte { - file_discount_audit_model_proto_rawDescOnce.Do(func() { - file_discount_audit_model_proto_rawDescData = protoimpl.X.CompressGZIP(file_discount_audit_model_proto_rawDescData) - }) - return file_discount_audit_model_proto_rawDescData -} - -var file_discount_audit_model_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_discount_audit_model_proto_goTypes = []interface{}{ - (*Audit)(nil), // 0: discount.Audit - (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp -} -var file_discount_audit_model_proto_depIdxs = []int32{ - 1, // 0: discount.Audit.UpdatedAt:type_name -> google.protobuf.Timestamp - 1, // 1: discount.Audit.CreatedAt:type_name -> google.protobuf.Timestamp - 1, // 2: discount.Audit.DeletedAt:type_name -> google.protobuf.Timestamp - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_discount_audit_model_proto_init() } -func file_discount_audit_model_proto_init() { - if File_discount_audit_model_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_discount_audit_model_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Audit); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_discount_audit_model_proto_msgTypes[0].OneofWrappers = []interface{}{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_discount_audit_model_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_discount_audit_model_proto_goTypes, - DependencyIndexes: file_discount_audit_model_proto_depIdxs, - MessageInfos: file_discount_audit_model_proto_msgTypes, - }.Build() - File_discount_audit_model_proto = out.File - file_discount_audit_model_proto_rawDesc = nil - file_discount_audit_model_proto_goTypes = nil - file_discount_audit_model_proto_depIdxs = nil -} diff --git a/internal/proto/discount/discount.model.pb.go b/internal/proto/discount/discount.model.pb.go deleted file mode 100644 index c0fce2b..0000000 --- a/internal/proto/discount/discount.model.pb.go +++ /dev/null @@ -1,1132 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: discount/discount.model.proto - -package discount - -import ( - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - _ "google.golang.org/protobuf/types/known/emptypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - 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 TargetScope int32 - -const ( - TargetScope_Sum TargetScope = 0 - TargetScope_Group TargetScope = 1 - TargetScope_Each TargetScope = 2 -) - -// Enum value maps for TargetScope. -var ( - TargetScope_name = map[int32]string{ - 0: "Sum", - 1: "Group", - 2: "Each", - } - TargetScope_value = map[string]int32{ - "Sum": 0, - "Group": 1, - "Each": 2, - } -) - -func (x TargetScope) Enum() *TargetScope { - p := new(TargetScope) - *p = x - return p -} - -func (x TargetScope) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (TargetScope) Descriptor() protoreflect.EnumDescriptor { - return file_discount_discount_model_proto_enumTypes[0].Descriptor() -} - -func (TargetScope) Type() protoreflect.EnumType { - return &file_discount_discount_model_proto_enumTypes[0] -} - -func (x TargetScope) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use TargetScope.Descriptor instead. -func (TargetScope) EnumDescriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{0} -} - -type DiscountOptional struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` - Name *string `protobuf:"bytes,2,opt,name=Name,proto3,oneof" json:"Name,omitempty"` - Layer *uint32 `protobuf:"varint,3,opt,name=Layer,proto3,oneof" json:"Layer,omitempty"` - Description *string `protobuf:"bytes,4,opt,name=Description,proto3,oneof" json:"Description,omitempty"` - Condition *DiscountCondition `protobuf:"bytes,5,opt,name=Condition,proto3,oneof" json:"Condition,omitempty"` - Target *DiscountCalculationTarget `protobuf:"bytes,6,opt,name=Target,proto3,oneof" json:"Target,omitempty"` - Deprecated *bool `protobuf:"varint,7,opt,name=Deprecated,proto3,oneof" json:"Deprecated,omitempty"` -} - -func (x *DiscountOptional) Reset() { - *x = DiscountOptional{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DiscountOptional) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DiscountOptional) ProtoMessage() {} - -func (x *DiscountOptional) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_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 DiscountOptional.ProtoReflect.Descriptor instead. -func (*DiscountOptional) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{0} -} - -func (x *DiscountOptional) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *DiscountOptional) GetName() string { - if x != nil && x.Name != nil { - return *x.Name - } - return "" -} - -func (x *DiscountOptional) GetLayer() uint32 { - if x != nil && x.Layer != nil { - return *x.Layer - } - return 0 -} - -func (x *DiscountOptional) GetDescription() string { - if x != nil && x.Description != nil { - return *x.Description - } - return "" -} - -func (x *DiscountOptional) GetCondition() *DiscountCondition { - if x != nil { - return x.Condition - } - return nil -} - -func (x *DiscountOptional) GetTarget() *DiscountCalculationTarget { - if x != nil { - return x.Target - } - return nil -} - -func (x *DiscountOptional) GetDeprecated() bool { - if x != nil && x.Deprecated != nil { - return *x.Deprecated - } - return false -} - -type Discounts struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Discounts []*Discount `protobuf:"bytes,1,rep,name=Discounts,proto3" json:"Discounts,omitempty"` -} - -func (x *Discounts) Reset() { - *x = Discounts{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Discounts) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Discounts) ProtoMessage() {} - -func (x *Discounts) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_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 Discounts.ProtoReflect.Descriptor instead. -func (*Discounts) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{1} -} - -func (x *Discounts) GetDiscounts() []*Discount { - if x != nil { - return x.Discounts - } - return nil -} - -type Discount struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` - Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` - Layer uint32 `protobuf:"varint,3,opt,name=Layer,proto3" json:"Layer,omitempty"` - Description string `protobuf:"bytes,4,opt,name=Description,proto3" json:"Description,omitempty"` - Condition *DiscountCondition `protobuf:"bytes,5,opt,name=Condition,proto3" json:"Condition,omitempty"` - Target *DiscountCalculationTarget `protobuf:"bytes,6,opt,name=Target,proto3" json:"Target,omitempty"` - Audit *Audit `protobuf:"bytes,7,opt,name=Audit,proto3" json:"Audit,omitempty"` - Deprecated bool `protobuf:"varint,8,opt,name=Deprecated,proto3" json:"Deprecated,omitempty"` -} - -func (x *Discount) Reset() { - *x = Discount{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Discount) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Discount) ProtoMessage() {} - -func (x *Discount) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_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 Discount.ProtoReflect.Descriptor instead. -func (*Discount) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{2} -} - -func (x *Discount) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *Discount) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Discount) GetLayer() uint32 { - if x != nil { - return x.Layer - } - return 0 -} - -func (x *Discount) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Discount) GetCondition() *DiscountCondition { - if x != nil { - return x.Condition - } - return nil -} - -func (x *Discount) GetTarget() *DiscountCalculationTarget { - if x != nil { - return x.Target - } - return nil -} - -func (x *Discount) GetAudit() *Audit { - if x != nil { - return x.Audit - } - return nil -} - -func (x *Discount) GetDeprecated() bool { - if x != nil { - return x.Deprecated - } - return false -} - -type DiscountCalculationTarget struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Products []*ProductTarget `protobuf:"bytes,1,rep,name=Products,proto3" json:"Products,omitempty"` - Factor float64 `protobuf:"fixed64,2,opt,name=Factor,proto3" json:"Factor,omitempty"` - TargetScope *TargetScope `protobuf:"varint,3,opt,name=TargetScope,proto3,enum=discount.TargetScope,oneof" json:"TargetScope,omitempty"` - TargetGroup *string `protobuf:"bytes,4,opt,name=TargetGroup,proto3,oneof" json:"TargetGroup,omitempty"` - Overhelm *bool `protobuf:"varint,5,opt,name=Overhelm,proto3,oneof" json:"Overhelm,omitempty"` -} - -func (x *DiscountCalculationTarget) Reset() { - *x = DiscountCalculationTarget{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DiscountCalculationTarget) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DiscountCalculationTarget) ProtoMessage() {} - -func (x *DiscountCalculationTarget) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_proto_msgTypes[3] - 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 DiscountCalculationTarget.ProtoReflect.Descriptor instead. -func (*DiscountCalculationTarget) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{3} -} - -func (x *DiscountCalculationTarget) GetProducts() []*ProductTarget { - if x != nil { - return x.Products - } - return nil -} - -func (x *DiscountCalculationTarget) GetFactor() float64 { - if x != nil { - return x.Factor - } - return 0 -} - -func (x *DiscountCalculationTarget) GetTargetScope() TargetScope { - if x != nil && x.TargetScope != nil { - return *x.TargetScope - } - return TargetScope_Sum -} - -func (x *DiscountCalculationTarget) GetTargetGroup() string { - if x != nil && x.TargetGroup != nil { - return *x.TargetGroup - } - return "" -} - -func (x *DiscountCalculationTarget) GetOverhelm() bool { - if x != nil && x.Overhelm != nil { - return *x.Overhelm - } - return false -} - -type DiscountCondition struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Period *PeriodCondition `protobuf:"bytes,1,opt,name=Period,proto3,oneof" json:"Period,omitempty"` - User *string `protobuf:"bytes,2,opt,name=User,proto3,oneof" json:"User,omitempty"` - UserType *string `protobuf:"bytes,3,opt,name=UserType,proto3,oneof" json:"UserType,omitempty"` - Coupon *string `protobuf:"bytes,4,opt,name=Coupon,proto3,oneof" json:"Coupon,omitempty"` - PurchasesAmount *uint64 `protobuf:"varint,5,opt,name=PurchasesAmount,proto3,oneof" json:"PurchasesAmount,omitempty"` - CartPurchasesAmount *uint64 `protobuf:"varint,6,opt,name=CartPurchasesAmount,proto3,oneof" json:"CartPurchasesAmount,omitempty"` - Product *string `protobuf:"bytes,7,opt,name=Product,proto3,oneof" json:"Product,omitempty"` - Term *uint64 `protobuf:"varint,8,opt,name=Term,proto3,oneof" json:"Term,omitempty"` - Usage *uint64 `protobuf:"varint,9,opt,name=Usage,proto3,oneof" json:"Usage,omitempty"` - PriceFrom *uint64 `protobuf:"varint,10,opt,name=PriceFrom,proto3,oneof" json:"PriceFrom,omitempty"` - Group *string `protobuf:"bytes,11,opt,name=Group,proto3,oneof" json:"Group,omitempty"` -} - -func (x *DiscountCondition) Reset() { - *x = DiscountCondition{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DiscountCondition) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DiscountCondition) ProtoMessage() {} - -func (x *DiscountCondition) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_proto_msgTypes[4] - 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 DiscountCondition.ProtoReflect.Descriptor instead. -func (*DiscountCondition) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{4} -} - -func (x *DiscountCondition) GetPeriod() *PeriodCondition { - if x != nil { - return x.Period - } - return nil -} - -func (x *DiscountCondition) GetUser() string { - if x != nil && x.User != nil { - return *x.User - } - return "" -} - -func (x *DiscountCondition) GetUserType() string { - if x != nil && x.UserType != nil { - return *x.UserType - } - return "" -} - -func (x *DiscountCondition) GetCoupon() string { - if x != nil && x.Coupon != nil { - return *x.Coupon - } - return "" -} - -func (x *DiscountCondition) GetPurchasesAmount() uint64 { - if x != nil && x.PurchasesAmount != nil { - return *x.PurchasesAmount - } - return 0 -} - -func (x *DiscountCondition) GetCartPurchasesAmount() uint64 { - if x != nil && x.CartPurchasesAmount != nil { - return *x.CartPurchasesAmount - } - return 0 -} - -func (x *DiscountCondition) GetProduct() string { - if x != nil && x.Product != nil { - return *x.Product - } - return "" -} - -func (x *DiscountCondition) GetTerm() uint64 { - if x != nil && x.Term != nil { - return *x.Term - } - return 0 -} - -func (x *DiscountCondition) GetUsage() uint64 { - if x != nil && x.Usage != nil { - return *x.Usage - } - return 0 -} - -func (x *DiscountCondition) GetPriceFrom() uint64 { - if x != nil && x.PriceFrom != nil { - return *x.PriceFrom - } - return 0 -} - -func (x *DiscountCondition) GetGroup() string { - if x != nil && x.Group != nil { - return *x.Group - } - return "" -} - -type ProductTarget struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` - Factor float64 `protobuf:"fixed64,2,opt,name=Factor,proto3" json:"Factor,omitempty"` - Overhelm *bool `protobuf:"varint,3,opt,name=Overhelm,proto3,oneof" json:"Overhelm,omitempty"` -} - -func (x *ProductTarget) Reset() { - *x = ProductTarget{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProductTarget) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProductTarget) ProtoMessage() {} - -func (x *ProductTarget) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_proto_msgTypes[5] - 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 ProductTarget.ProtoReflect.Descriptor instead. -func (*ProductTarget) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{5} -} - -func (x *ProductTarget) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *ProductTarget) GetFactor() float64 { - if x != nil { - return x.Factor - } - return 0 -} - -func (x *ProductTarget) GetOverhelm() bool { - if x != nil && x.Overhelm != nil { - return *x.Overhelm - } - return false -} - -type PeriodCondition struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - From *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=From,proto3" json:"From,omitempty"` - To *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=To,proto3" json:"To,omitempty"` -} - -func (x *PeriodCondition) Reset() { - *x = PeriodCondition{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PeriodCondition) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PeriodCondition) ProtoMessage() {} - -func (x *PeriodCondition) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_proto_msgTypes[6] - 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 PeriodCondition.ProtoReflect.Descriptor instead. -func (*PeriodCondition) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{6} -} - -func (x *PeriodCondition) GetFrom() *timestamppb.Timestamp { - if x != nil { - return x.From - } - return nil -} - -func (x *PeriodCondition) GetTo() *timestamppb.Timestamp { - if x != nil { - return x.To - } - return nil -} - -type UserInformation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` - Type string `protobuf:"bytes,2,opt,name=Type,proto3" json:"Type,omitempty"` - PurchasesAmount uint64 `protobuf:"varint,3,opt,name=PurchasesAmount,proto3" json:"PurchasesAmount,omitempty"` - CartPurchasesAmount uint64 `protobuf:"varint,4,opt,name=CartPurchasesAmount,proto3" json:"CartPurchasesAmount,omitempty"` -} - -func (x *UserInformation) Reset() { - *x = UserInformation{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UserInformation) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserInformation) ProtoMessage() {} - -func (x *UserInformation) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_proto_msgTypes[7] - 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 UserInformation.ProtoReflect.Descriptor instead. -func (*UserInformation) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{7} -} - -func (x *UserInformation) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *UserInformation) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *UserInformation) GetPurchasesAmount() uint64 { - if x != nil { - return x.PurchasesAmount - } - return 0 -} - -func (x *UserInformation) GetCartPurchasesAmount() uint64 { - if x != nil { - return x.CartPurchasesAmount - } - return 0 -} - -type ProductInformation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` - Price uint64 `protobuf:"varint,2,opt,name=Price,proto3" json:"Price,omitempty"` - Term *uint64 `protobuf:"varint,3,opt,name=Term,proto3,oneof" json:"Term,omitempty"` - Usage *uint64 `protobuf:"varint,4,opt,name=Usage,proto3,oneof" json:"Usage,omitempty"` - Group *string `protobuf:"bytes,5,opt,name=Group,proto3,oneof" json:"Group,omitempty"` -} - -func (x *ProductInformation) Reset() { - *x = ProductInformation{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_discount_model_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProductInformation) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProductInformation) ProtoMessage() {} - -func (x *ProductInformation) ProtoReflect() protoreflect.Message { - mi := &file_discount_discount_model_proto_msgTypes[8] - 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 ProductInformation.ProtoReflect.Descriptor instead. -func (*ProductInformation) Descriptor() ([]byte, []int) { - return file_discount_discount_model_proto_rawDescGZIP(), []int{8} -} - -func (x *ProductInformation) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *ProductInformation) GetPrice() uint64 { - if x != nil { - return x.Price - } - return 0 -} - -func (x *ProductInformation) GetTerm() uint64 { - if x != nil && x.Term != nil { - return *x.Term - } - return 0 -} - -func (x *ProductInformation) GetUsage() uint64 { - if x != nil && x.Usage != nil { - return *x.Usage - } - return 0 -} - -func (x *ProductInformation) GetGroup() string { - if x != nil && x.Group != nil { - return *x.Group - } - return "" -} - -var File_discount_discount_model_proto protoreflect.FileDescriptor - -var file_discount_discount_model_proto_rawDesc = []byte{ - 0x0a, 0x1d, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, - 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0xef, 0x02, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x17, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, - 0x19, 0x0a, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, - 0x52, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x02, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, - 0x01, 0x12, 0x3e, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x48, 0x03, 0x52, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, - 0x01, 0x12, 0x40, 0x0a, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x04, 0x52, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x48, 0x05, 0x52, 0x0a, 0x44, 0x65, 0x70, 0x72, 0x65, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x4e, 0x61, 0x6d, - 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, - 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, - 0x74, 0x65, 0x64, 0x22, 0x3d, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, - 0x12, 0x30, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x73, 0x22, 0xa5, 0x02, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, - 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x43, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x05, 0x41, 0x75, 0x64, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x75, - 0x64, 0x69, 0x74, 0x52, 0x05, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x22, 0x9b, 0x02, 0x0a, 0x19, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, 0x16, 0x0a, - 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x46, - 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x3c, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, - 0x63, 0x6f, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, - 0x65, 0x48, 0x00, 0x52, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, - 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0b, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x4f, 0x76, - 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x08, - 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x0b, 0x0a, 0x09, 0x5f, - 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x22, 0xa8, 0x04, 0x0a, 0x11, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, - 0x0a, 0x06, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, - 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x50, 0x65, 0x72, - 0x69, 0x6f, 0x64, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, - 0x1f, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x02, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, - 0x12, 0x1b, 0x0a, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x03, 0x52, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, - 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x48, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, - 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x13, - 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x48, 0x05, 0x52, 0x13, 0x43, 0x61, 0x72, - 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x88, - 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, - 0x48, 0x07, 0x52, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x55, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x48, 0x08, 0x52, 0x05, 0x55, 0x73, - 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x46, - 0x72, 0x6f, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x48, 0x09, 0x52, 0x09, 0x50, 0x72, 0x69, - 0x63, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0a, 0x52, 0x05, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, - 0x07, 0x0a, 0x05, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x55, 0x73, 0x65, - 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, - 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, - 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, - 0x5f, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x54, 0x65, 0x72, - 0x6d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, - 0x50, 0x72, 0x69, 0x63, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x22, 0x65, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x08, - 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, - 0x52, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, - 0x09, 0x5f, 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x22, 0x6d, 0x0a, 0x0f, 0x50, 0x65, - 0x72, 0x69, 0x6f, 0x64, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, - 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x2a, 0x0a, - 0x02, 0x54, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, 0x54, 0x6f, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x55, 0x73, - 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, - 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, - 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x43, - 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, - 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa6, 0x01, - 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x54, 0x65, - 0x72, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x04, 0x54, 0x65, 0x72, 0x6d, - 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x48, 0x01, 0x52, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, - 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, - 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x54, 0x65, - 0x72, 0x6d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x08, 0x0a, 0x06, - 0x5f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2a, 0x2b, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x75, 0x6d, 0x10, 0x00, 0x12, 0x09, - 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x61, 0x63, - 0x68, 0x10, 0x02, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_discount_discount_model_proto_rawDescOnce sync.Once - file_discount_discount_model_proto_rawDescData = file_discount_discount_model_proto_rawDesc -) - -func file_discount_discount_model_proto_rawDescGZIP() []byte { - file_discount_discount_model_proto_rawDescOnce.Do(func() { - file_discount_discount_model_proto_rawDescData = protoimpl.X.CompressGZIP(file_discount_discount_model_proto_rawDescData) - }) - return file_discount_discount_model_proto_rawDescData -} - -var file_discount_discount_model_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_discount_discount_model_proto_msgTypes = make([]protoimpl.MessageInfo, 9) -var file_discount_discount_model_proto_goTypes = []interface{}{ - (TargetScope)(0), // 0: discount.TargetScope - (*DiscountOptional)(nil), // 1: discount.DiscountOptional - (*Discounts)(nil), // 2: discount.Discounts - (*Discount)(nil), // 3: discount.Discount - (*DiscountCalculationTarget)(nil), // 4: discount.DiscountCalculationTarget - (*DiscountCondition)(nil), // 5: discount.DiscountCondition - (*ProductTarget)(nil), // 6: discount.ProductTarget - (*PeriodCondition)(nil), // 7: discount.PeriodCondition - (*UserInformation)(nil), // 8: discount.UserInformation - (*ProductInformation)(nil), // 9: discount.ProductInformation - (*Audit)(nil), // 10: discount.Audit - (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp -} -var file_discount_discount_model_proto_depIdxs = []int32{ - 5, // 0: discount.DiscountOptional.Condition:type_name -> discount.DiscountCondition - 4, // 1: discount.DiscountOptional.Target:type_name -> discount.DiscountCalculationTarget - 3, // 2: discount.Discounts.Discounts:type_name -> discount.Discount - 5, // 3: discount.Discount.Condition:type_name -> discount.DiscountCondition - 4, // 4: discount.Discount.Target:type_name -> discount.DiscountCalculationTarget - 10, // 5: discount.Discount.Audit:type_name -> discount.Audit - 6, // 6: discount.DiscountCalculationTarget.Products:type_name -> discount.ProductTarget - 0, // 7: discount.DiscountCalculationTarget.TargetScope:type_name -> discount.TargetScope - 7, // 8: discount.DiscountCondition.Period:type_name -> discount.PeriodCondition - 11, // 9: discount.PeriodCondition.From:type_name -> google.protobuf.Timestamp - 11, // 10: discount.PeriodCondition.To:type_name -> google.protobuf.Timestamp - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name -} - -func init() { file_discount_discount_model_proto_init() } -func file_discount_discount_model_proto_init() { - if File_discount_discount_model_proto != nil { - return - } - file_discount_audit_model_proto_init() - if !protoimpl.UnsafeEnabled { - file_discount_discount_model_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiscountOptional); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Discounts); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Discount); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiscountCalculationTarget); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiscountCondition); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProductTarget); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeriodCondition); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserInformation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_discount_model_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProductInformation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_discount_discount_model_proto_msgTypes[0].OneofWrappers = []interface{}{} - file_discount_discount_model_proto_msgTypes[3].OneofWrappers = []interface{}{} - file_discount_discount_model_proto_msgTypes[4].OneofWrappers = []interface{}{} - file_discount_discount_model_proto_msgTypes[5].OneofWrappers = []interface{}{} - file_discount_discount_model_proto_msgTypes[8].OneofWrappers = []interface{}{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_discount_discount_model_proto_rawDesc, - NumEnums: 1, - NumMessages: 9, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_discount_discount_model_proto_goTypes, - DependencyIndexes: file_discount_discount_model_proto_depIdxs, - EnumInfos: file_discount_discount_model_proto_enumTypes, - MessageInfos: file_discount_discount_model_proto_msgTypes, - }.Build() - File_discount_discount_model_proto = out.File - file_discount_discount_model_proto_rawDesc = nil - file_discount_discount_model_proto_goTypes = nil - file_discount_discount_model_proto_depIdxs = nil -} diff --git a/internal/proto/discount/service.pb.go b/internal/proto/discount/service.pb.go deleted file mode 100644 index 84ea7d9..0000000 --- a/internal/proto/discount/service.pb.go +++ /dev/null @@ -1,524 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: discount/service.proto - -package discount - -import ( - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - 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 GetDiscountByIDRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` -} - -func (x *GetDiscountByIDRequest) Reset() { - *x = GetDiscountByIDRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetDiscountByIDRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetDiscountByIDRequest) ProtoMessage() {} - -func (x *GetDiscountByIDRequest) ProtoReflect() protoreflect.Message { - mi := &file_discount_service_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 GetDiscountByIDRequest.ProtoReflect.Descriptor instead. -func (*GetDiscountByIDRequest) Descriptor() ([]byte, []int) { - return file_discount_service_proto_rawDescGZIP(), []int{0} -} - -func (x *GetDiscountByIDRequest) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -type ApplyDiscountRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserInformation *UserInformation `protobuf:"bytes,1,opt,name=UserInformation,proto3" json:"UserInformation,omitempty"` - Products []*ProductInformation `protobuf:"bytes,2,rep,name=Products,proto3" json:"Products,omitempty"` - Date *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=Date,proto3" json:"Date,omitempty"` - Coupon *string `protobuf:"bytes,4,opt,name=Coupon,proto3,oneof" json:"Coupon,omitempty"` -} - -func (x *ApplyDiscountRequest) Reset() { - *x = ApplyDiscountRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_service_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ApplyDiscountRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ApplyDiscountRequest) ProtoMessage() {} - -func (x *ApplyDiscountRequest) ProtoReflect() protoreflect.Message { - mi := &file_discount_service_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 ApplyDiscountRequest.ProtoReflect.Descriptor instead. -func (*ApplyDiscountRequest) Descriptor() ([]byte, []int) { - return file_discount_service_proto_rawDescGZIP(), []int{1} -} - -func (x *ApplyDiscountRequest) GetUserInformation() *UserInformation { - if x != nil { - return x.UserInformation - } - return nil -} - -func (x *ApplyDiscountRequest) GetProducts() []*ProductInformation { - if x != nil { - return x.Products - } - return nil -} - -func (x *ApplyDiscountRequest) GetDate() *timestamppb.Timestamp { - if x != nil { - return x.Date - } - return nil -} - -func (x *ApplyDiscountRequest) GetCoupon() string { - if x != nil && x.Coupon != nil { - return *x.Coupon - } - return "" -} - -type ApplyDiscountResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Price uint64 `protobuf:"varint,1,opt,name=Price,proto3" json:"Price,omitempty"` - AppliedDiscounts []*Discount `protobuf:"bytes,2,rep,name=AppliedDiscounts,proto3" json:"AppliedDiscounts,omitempty"` -} - -func (x *ApplyDiscountResponse) Reset() { - *x = ApplyDiscountResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_service_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ApplyDiscountResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ApplyDiscountResponse) ProtoMessage() {} - -func (x *ApplyDiscountResponse) ProtoReflect() protoreflect.Message { - mi := &file_discount_service_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 ApplyDiscountResponse.ProtoReflect.Descriptor instead. -func (*ApplyDiscountResponse) Descriptor() ([]byte, []int) { - return file_discount_service_proto_rawDescGZIP(), []int{2} -} - -func (x *ApplyDiscountResponse) GetPrice() uint64 { - if x != nil { - return x.Price - } - return 0 -} - -func (x *ApplyDiscountResponse) GetAppliedDiscounts() []*Discount { - if x != nil { - return x.AppliedDiscounts - } - return nil -} - -type CreateDiscountRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` - Layer uint32 `protobuf:"varint,2,opt,name=Layer,proto3" json:"Layer,omitempty"` - Description string `protobuf:"bytes,3,opt,name=Description,proto3" json:"Description,omitempty"` - Condition *DiscountCondition `protobuf:"bytes,4,opt,name=Condition,proto3" json:"Condition,omitempty"` - Target *DiscountCalculationTarget `protobuf:"bytes,5,opt,name=Target,proto3" json:"Target,omitempty"` -} - -func (x *CreateDiscountRequest) Reset() { - *x = CreateDiscountRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_discount_service_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateDiscountRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateDiscountRequest) ProtoMessage() {} - -func (x *CreateDiscountRequest) ProtoReflect() protoreflect.Message { - mi := &file_discount_service_proto_msgTypes[3] - 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 CreateDiscountRequest.ProtoReflect.Descriptor instead. -func (*CreateDiscountRequest) Descriptor() ([]byte, []int) { - return file_discount_service_proto_rawDescGZIP(), []int{3} -} - -func (x *CreateDiscountRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *CreateDiscountRequest) GetLayer() uint32 { - if x != nil { - return x.Layer - } - return 0 -} - -func (x *CreateDiscountRequest) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *CreateDiscountRequest) GetCondition() *DiscountCondition { - if x != nil { - return x.Condition - } - return nil -} - -func (x *CreateDiscountRequest) GetTarget() *DiscountCalculationTarget { - if x != nil { - return x.Target - } - return nil -} - -var File_discount_service_proto protoreflect.FileDescriptor - -var file_discount_service_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x44, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x22, 0xed, 0x01, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x6c, - 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x43, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, - 0x2e, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x44, 0x61, 0x74, 0x65, 0x12, - 0x1b, 0x0a, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, - 0x5f, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x22, 0x6d, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x6c, 0x79, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, - 0x64, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0xdb, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x09, - 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x32, 0x80, 0x07, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, - 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, - 0x12, 0x0a, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x66, 0x0a, 0x10, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, - 0x12, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, - 0x13, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, - 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x69, 0x0a, 0x12, 0x44, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, - 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x12, - 0x6d, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x73, 0x12, 0x1e, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70, - 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70, - 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a, 0x22, 0x0f, 0x2f, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x5f, - 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, - 0x44, 0x12, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, - 0x0e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, - 0x5b, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x3a, 0x01, - 0x2a, 0x22, 0x09, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x0f, - 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x1a, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x12, 0x2e, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, - 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x1a, 0x0e, 0x2f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x5b, 0x0a, 0x0e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x2e, 0x64, - 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x19, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x32, 0x0e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x5e, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, - 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x2a, 0x0e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_discount_service_proto_rawDescOnce sync.Once - file_discount_service_proto_rawDescData = file_discount_service_proto_rawDesc -) - -func file_discount_service_proto_rawDescGZIP() []byte { - file_discount_service_proto_rawDescOnce.Do(func() { - file_discount_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_discount_service_proto_rawDescData) - }) - return file_discount_service_proto_rawDescData -} - -var file_discount_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_discount_service_proto_goTypes = []interface{}{ - (*GetDiscountByIDRequest)(nil), // 0: discount.GetDiscountByIDRequest - (*ApplyDiscountRequest)(nil), // 1: discount.ApplyDiscountRequest - (*ApplyDiscountResponse)(nil), // 2: discount.ApplyDiscountResponse - (*CreateDiscountRequest)(nil), // 3: discount.CreateDiscountRequest - (*UserInformation)(nil), // 4: discount.UserInformation - (*ProductInformation)(nil), // 5: discount.ProductInformation - (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp - (*Discount)(nil), // 7: discount.Discount - (*DiscountCondition)(nil), // 8: discount.DiscountCondition - (*DiscountCalculationTarget)(nil), // 9: discount.DiscountCalculationTarget - (*emptypb.Empty)(nil), // 10: google.protobuf.Empty - (*DiscountOptional)(nil), // 11: discount.DiscountOptional - (*Discounts)(nil), // 12: discount.Discounts -} -var file_discount_service_proto_depIdxs = []int32{ - 4, // 0: discount.ApplyDiscountRequest.UserInformation:type_name -> discount.UserInformation - 5, // 1: discount.ApplyDiscountRequest.Products:type_name -> discount.ProductInformation - 6, // 2: discount.ApplyDiscountRequest.Date:type_name -> google.protobuf.Timestamp - 7, // 3: discount.ApplyDiscountResponse.AppliedDiscounts:type_name -> discount.Discount - 8, // 4: discount.CreateDiscountRequest.Condition:type_name -> discount.DiscountCondition - 9, // 5: discount.CreateDiscountRequest.Target:type_name -> discount.DiscountCalculationTarget - 10, // 6: discount.DiscountService.GetAllDiscounts:input_type -> google.protobuf.Empty - 0, // 7: discount.DiscountService.GetUserDiscounts:input_type -> discount.GetDiscountByIDRequest - 1, // 8: discount.DiscountService.DetermineDiscounts:input_type -> discount.ApplyDiscountRequest - 1, // 9: discount.DiscountService.ApplyDiscounts:input_type -> discount.ApplyDiscountRequest - 0, // 10: discount.DiscountService.GetDiscountByID:input_type -> discount.GetDiscountByIDRequest - 3, // 11: discount.DiscountService.CreateDiscount:input_type -> discount.CreateDiscountRequest - 11, // 12: discount.DiscountService.ReplaceDiscount:input_type -> discount.DiscountOptional - 11, // 13: discount.DiscountService.UpdateDiscount:input_type -> discount.DiscountOptional - 0, // 14: discount.DiscountService.DeleteDiscount:input_type -> discount.GetDiscountByIDRequest - 12, // 15: discount.DiscountService.GetAllDiscounts:output_type -> discount.Discounts - 12, // 16: discount.DiscountService.GetUserDiscounts:output_type -> discount.Discounts - 12, // 17: discount.DiscountService.DetermineDiscounts:output_type -> discount.Discounts - 2, // 18: discount.DiscountService.ApplyDiscounts:output_type -> discount.ApplyDiscountResponse - 7, // 19: discount.DiscountService.GetDiscountByID:output_type -> discount.Discount - 7, // 20: discount.DiscountService.CreateDiscount:output_type -> discount.Discount - 7, // 21: discount.DiscountService.ReplaceDiscount:output_type -> discount.Discount - 7, // 22: discount.DiscountService.UpdateDiscount:output_type -> discount.Discount - 7, // 23: discount.DiscountService.DeleteDiscount:output_type -> discount.Discount - 15, // [15:24] is the sub-list for method output_type - 6, // [6:15] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name -} - -func init() { file_discount_service_proto_init() } -func file_discount_service_proto_init() { - if File_discount_service_proto != nil { - return - } - file_discount_discount_model_proto_init() - if !protoimpl.UnsafeEnabled { - file_discount_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetDiscountByIDRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyDiscountRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyDiscountResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_discount_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateDiscountRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_discount_service_proto_msgTypes[1].OneofWrappers = []interface{}{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_discount_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_discount_service_proto_goTypes, - DependencyIndexes: file_discount_service_proto_depIdxs, - MessageInfos: file_discount_service_proto_msgTypes, - }.Build() - File_discount_service_proto = out.File - file_discount_service_proto_rawDesc = nil - file_discount_service_proto_goTypes = nil - file_discount_service_proto_depIdxs = nil -} diff --git a/internal/proto/discount/service_grpc.pb.go b/internal/proto/discount/service_grpc.pb.go deleted file mode 100644 index e9161fb..0000000 --- a/internal/proto/discount/service_grpc.pb.go +++ /dev/null @@ -1,404 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc (unknown) -// source: discount/service.proto - -package discount - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// 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 ( - DiscountService_GetAllDiscounts_FullMethodName = "/discount.DiscountService/GetAllDiscounts" - DiscountService_GetUserDiscounts_FullMethodName = "/discount.DiscountService/GetUserDiscounts" - DiscountService_DetermineDiscounts_FullMethodName = "/discount.DiscountService/DetermineDiscounts" - DiscountService_ApplyDiscounts_FullMethodName = "/discount.DiscountService/ApplyDiscounts" - DiscountService_GetDiscountByID_FullMethodName = "/discount.DiscountService/GetDiscountByID" - DiscountService_CreateDiscount_FullMethodName = "/discount.DiscountService/CreateDiscount" - DiscountService_ReplaceDiscount_FullMethodName = "/discount.DiscountService/ReplaceDiscount" - DiscountService_UpdateDiscount_FullMethodName = "/discount.DiscountService/UpdateDiscount" - DiscountService_DeleteDiscount_FullMethodName = "/discount.DiscountService/DeleteDiscount" -) - -// DiscountServiceClient is the client API for DiscountService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type DiscountServiceClient interface { - GetAllDiscounts(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Discounts, error) - GetUserDiscounts(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discounts, error) - DetermineDiscounts(ctx context.Context, in *ApplyDiscountRequest, opts ...grpc.CallOption) (*Discounts, error) - ApplyDiscounts(ctx context.Context, in *ApplyDiscountRequest, opts ...grpc.CallOption) (*ApplyDiscountResponse, error) - GetDiscountByID(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discount, error) - CreateDiscount(ctx context.Context, in *CreateDiscountRequest, opts ...grpc.CallOption) (*Discount, error) - ReplaceDiscount(ctx context.Context, in *DiscountOptional, opts ...grpc.CallOption) (*Discount, error) - UpdateDiscount(ctx context.Context, in *DiscountOptional, opts ...grpc.CallOption) (*Discount, error) - DeleteDiscount(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discount, error) -} - -type discountServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewDiscountServiceClient(cc grpc.ClientConnInterface) DiscountServiceClient { - return &discountServiceClient{cc} -} - -func (c *discountServiceClient) GetAllDiscounts(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Discounts, error) { - out := new(Discounts) - err := c.cc.Invoke(ctx, DiscountService_GetAllDiscounts_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) GetUserDiscounts(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discounts, error) { - out := new(Discounts) - err := c.cc.Invoke(ctx, DiscountService_GetUserDiscounts_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) DetermineDiscounts(ctx context.Context, in *ApplyDiscountRequest, opts ...grpc.CallOption) (*Discounts, error) { - out := new(Discounts) - err := c.cc.Invoke(ctx, DiscountService_DetermineDiscounts_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) ApplyDiscounts(ctx context.Context, in *ApplyDiscountRequest, opts ...grpc.CallOption) (*ApplyDiscountResponse, error) { - out := new(ApplyDiscountResponse) - err := c.cc.Invoke(ctx, DiscountService_ApplyDiscounts_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) GetDiscountByID(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discount, error) { - out := new(Discount) - err := c.cc.Invoke(ctx, DiscountService_GetDiscountByID_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) CreateDiscount(ctx context.Context, in *CreateDiscountRequest, opts ...grpc.CallOption) (*Discount, error) { - out := new(Discount) - err := c.cc.Invoke(ctx, DiscountService_CreateDiscount_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) ReplaceDiscount(ctx context.Context, in *DiscountOptional, opts ...grpc.CallOption) (*Discount, error) { - out := new(Discount) - err := c.cc.Invoke(ctx, DiscountService_ReplaceDiscount_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) UpdateDiscount(ctx context.Context, in *DiscountOptional, opts ...grpc.CallOption) (*Discount, error) { - out := new(Discount) - err := c.cc.Invoke(ctx, DiscountService_UpdateDiscount_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *discountServiceClient) DeleteDiscount(ctx context.Context, in *GetDiscountByIDRequest, opts ...grpc.CallOption) (*Discount, error) { - out := new(Discount) - err := c.cc.Invoke(ctx, DiscountService_DeleteDiscount_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// DiscountServiceServer is the server API for DiscountService service. -// All implementations should embed UnimplementedDiscountServiceServer -// for forward compatibility -type DiscountServiceServer interface { - GetAllDiscounts(context.Context, *emptypb.Empty) (*Discounts, error) - GetUserDiscounts(context.Context, *GetDiscountByIDRequest) (*Discounts, error) - DetermineDiscounts(context.Context, *ApplyDiscountRequest) (*Discounts, error) - ApplyDiscounts(context.Context, *ApplyDiscountRequest) (*ApplyDiscountResponse, error) - GetDiscountByID(context.Context, *GetDiscountByIDRequest) (*Discount, error) - CreateDiscount(context.Context, *CreateDiscountRequest) (*Discount, error) - ReplaceDiscount(context.Context, *DiscountOptional) (*Discount, error) - UpdateDiscount(context.Context, *DiscountOptional) (*Discount, error) - DeleteDiscount(context.Context, *GetDiscountByIDRequest) (*Discount, error) -} - -// UnimplementedDiscountServiceServer should be embedded to have forward compatible implementations. -type UnimplementedDiscountServiceServer struct { -} - -func (UnimplementedDiscountServiceServer) GetAllDiscounts(context.Context, *emptypb.Empty) (*Discounts, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetAllDiscounts not implemented") -} -func (UnimplementedDiscountServiceServer) GetUserDiscounts(context.Context, *GetDiscountByIDRequest) (*Discounts, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetUserDiscounts not implemented") -} -func (UnimplementedDiscountServiceServer) DetermineDiscounts(context.Context, *ApplyDiscountRequest) (*Discounts, error) { - return nil, status.Errorf(codes.Unimplemented, "method DetermineDiscounts not implemented") -} -func (UnimplementedDiscountServiceServer) ApplyDiscounts(context.Context, *ApplyDiscountRequest) (*ApplyDiscountResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ApplyDiscounts not implemented") -} -func (UnimplementedDiscountServiceServer) GetDiscountByID(context.Context, *GetDiscountByIDRequest) (*Discount, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetDiscountByID not implemented") -} -func (UnimplementedDiscountServiceServer) CreateDiscount(context.Context, *CreateDiscountRequest) (*Discount, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateDiscount not implemented") -} -func (UnimplementedDiscountServiceServer) ReplaceDiscount(context.Context, *DiscountOptional) (*Discount, error) { - return nil, status.Errorf(codes.Unimplemented, "method ReplaceDiscount not implemented") -} -func (UnimplementedDiscountServiceServer) UpdateDiscount(context.Context, *DiscountOptional) (*Discount, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateDiscount not implemented") -} -func (UnimplementedDiscountServiceServer) DeleteDiscount(context.Context, *GetDiscountByIDRequest) (*Discount, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteDiscount not implemented") -} - -// UnsafeDiscountServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to DiscountServiceServer will -// result in compilation errors. -type UnsafeDiscountServiceServer interface { - mustEmbedUnimplementedDiscountServiceServer() -} - -func RegisterDiscountServiceServer(s grpc.ServiceRegistrar, srv DiscountServiceServer) { - s.RegisterService(&DiscountService_ServiceDesc, srv) -} - -func _DiscountService_GetAllDiscounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).GetAllDiscounts(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_GetAllDiscounts_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).GetAllDiscounts(ctx, req.(*emptypb.Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_GetUserDiscounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetDiscountByIDRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).GetUserDiscounts(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_GetUserDiscounts_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).GetUserDiscounts(ctx, req.(*GetDiscountByIDRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_DetermineDiscounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ApplyDiscountRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).DetermineDiscounts(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_DetermineDiscounts_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).DetermineDiscounts(ctx, req.(*ApplyDiscountRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_ApplyDiscounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ApplyDiscountRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).ApplyDiscounts(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_ApplyDiscounts_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).ApplyDiscounts(ctx, req.(*ApplyDiscountRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_GetDiscountByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetDiscountByIDRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).GetDiscountByID(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_GetDiscountByID_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).GetDiscountByID(ctx, req.(*GetDiscountByIDRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_CreateDiscount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateDiscountRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).CreateDiscount(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_CreateDiscount_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).CreateDiscount(ctx, req.(*CreateDiscountRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_ReplaceDiscount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DiscountOptional) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).ReplaceDiscount(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_ReplaceDiscount_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).ReplaceDiscount(ctx, req.(*DiscountOptional)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_UpdateDiscount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DiscountOptional) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).UpdateDiscount(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_UpdateDiscount_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).UpdateDiscount(ctx, req.(*DiscountOptional)) - } - return interceptor(ctx, in, info, handler) -} - -func _DiscountService_DeleteDiscount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetDiscountByIDRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DiscountServiceServer).DeleteDiscount(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: DiscountService_DeleteDiscount_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DiscountServiceServer).DeleteDiscount(ctx, req.(*GetDiscountByIDRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// DiscountService_ServiceDesc is the grpc.ServiceDesc for DiscountService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var DiscountService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "discount.DiscountService", - HandlerType: (*DiscountServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetAllDiscounts", - Handler: _DiscountService_GetAllDiscounts_Handler, - }, - { - MethodName: "GetUserDiscounts", - Handler: _DiscountService_GetUserDiscounts_Handler, - }, - { - MethodName: "DetermineDiscounts", - Handler: _DiscountService_DetermineDiscounts_Handler, - }, - { - MethodName: "ApplyDiscounts", - Handler: _DiscountService_ApplyDiscounts_Handler, - }, - { - MethodName: "GetDiscountByID", - Handler: _DiscountService_GetDiscountByID_Handler, - }, - { - MethodName: "CreateDiscount", - Handler: _DiscountService_CreateDiscount_Handler, - }, - { - MethodName: "ReplaceDiscount", - Handler: _DiscountService_ReplaceDiscount_Handler, - }, - { - MethodName: "UpdateDiscount", - Handler: _DiscountService_UpdateDiscount_Handler, - }, - { - MethodName: "DeleteDiscount", - Handler: _DiscountService_DeleteDiscount_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "discount/service.proto", -} diff --git a/internal/repository/codeword_repository.go b/internal/repository/codeword_repository.go deleted file mode 100644 index d2a9fec..0000000 --- a/internal/repository/codeword_repository.go +++ /dev/null @@ -1,100 +0,0 @@ -package repository - -import ( - "codeword/internal/models" - "context" - "encoding/json" - "github.com/go-redis/redis/v8" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/readpref" - "time" -) - -type CodewordRepository struct { - mdb *mongo.Collection - rdb *redis.Client -} - -func NewCodewordRepository(deps Deps) *CodewordRepository { - - return &CodewordRepository{mdb: deps.Mdb, rdb: deps.Rdb} -} - -// сохраняем полученные данные о пользователе и подписи в бд -func (r *CodewordRepository) StoreRecoveryRecord(ctx context.Context, deps models.StoreRecDeps) (string, error) { - newID := primitive.NewObjectID() - signID := deps.Key + newID.Hex() - record := models.RestoreRequest{ - ID: newID, - UserID: deps.UserID, - Email: deps.Email, - Sign: deps.Key, - SignUrl: deps.Url, - SignID: signID, - CreatedAt: time.Now(), - } - - _, err := r.mdb.InsertOne(ctx, record) - if err != nil { - return "", err - } - - return newID.Hex(), nil -} - -// добавляем в очередь данные для отправки на почту в редис -func (r *CodewordRepository) InsertToQueue(ctx context.Context, deps models.RecEmailDeps) error { - sendLockKey := "email:sendLock:" + deps.Email - ttl := 5 * time.Minute - - lockSuccess, err := r.rdb.SetNX(ctx, sendLockKey, "1", ttl).Result() - if err != nil { - return err - } - if !lockSuccess { - return ErrAlreadyReported - } - - task := models.RecoveryRecord{ - ID: deps.ID, - UserID: deps.UserID, - Email: deps.Email, - Key: deps.SignWithID, - } - - taskBytes, err := json.Marshal(task) - if err != nil { - return err - } - - return r.rdb.Set(ctx, "email:task:"+deps.Email, taskBytes, ttl).Err() -} - -// получаем данные юзера по подписи -func (r *CodewordRepository) GetRecoveryRecord(ctx context.Context, key string) (*models.RestoreRequest, error) { - var restoreRequest models.RestoreRequest - - filter := bson.M{"sign_id": key} - - err := r.mdb.FindOne(ctx, filter).Decode(&restoreRequest) - if err != nil { - return nil, err - } - - return &restoreRequest, nil -} - -// пингует в монгу чтобы проверить подключение -func (r *CodewordRepository) Ping(ctx context.Context) error { - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - if err := r.mdb.Database().Client().Ping(ctx, readpref.Primary()); err != nil { - return err - } - if err := r.rdb.Ping(ctx).Err(); err != nil { - return err - } - return nil -} diff --git a/internal/repository/errors.go b/internal/repository/errors.go deleted file mode 100644 index c941611..0000000 --- a/internal/repository/errors.go +++ /dev/null @@ -1,13 +0,0 @@ -package repository - -import "errors" - -var ( - ErrPromoUserNotFound = errors.New("user not found") - ErrAlreadyReported = errors.New("already reported") - ErrDuplicateCodeword = errors.New("duplicate codeword") - ErrPromoCodeNotFound = errors.New("promo code not found") - ErrPromoCodeExpired = errors.New("promo code is expired") - ErrPromoCodeExhausted = errors.New("promo code is exhausted") - ErrPromoCodeAlreadyActivated = errors.New("promo code is already activated") -) diff --git a/internal/repository/promocode.go b/internal/repository/promocode.go new file mode 100644 index 0000000..8925a49 --- /dev/null +++ b/internal/repository/promocode.go @@ -0,0 +1,55 @@ +package repository + +import ( + "codeword/internal/models" + "context" +) + +type PromocodeRepository struct { +} + +func NewPromocodeRepository() *PromocodeRepository { + return &PromocodeRepository{} +} + +func (r *PromocodeRepository) Createpromocode(ctx context.Context, request *models.PromoCodeReq) (*models.PromoCode, error) { + //TODO:IMPLEMENT ME + + return &models.PromoCode{}, nil + +} + +func (r *PromocodeRepository) Editpromocode(ctx context.Context, request *models.EditPromoCodeReq) (*models.PromoCode, error) { + //TODO:IMPLEMENT ME + + return &models.PromoCode{}, nil + +} + +func (r *PromocodeRepository) Createfastlink(ctx context.Context, request *models.CreateFastLinkReq) (*models.CreateFastLinkResp, error) { + //TODO:IMPLEMENT ME + + return &models.CreateFastLinkResp{}, nil + +} + +func (r *PromocodeRepository) Delete(ctx context.Context) error { + //TODO:IMPLEMENT ME + + return nil + +} + +func (r *PromocodeRepository) Activate(ctx context.Context, request *models.ActivateReq) (*models.ActivateResp, error) { + //TODO:IMPLEMENT ME + + return &models.ActivateResp{}, nil + +} + +func (r *PromocodeRepository) Getlist(ctx context.Context, request *models.GetPromoCodesListReq) (*models.GetPromoCodesListResp, error) { + //TODO:IMPLEMENT ME + + return &models.GetPromoCodesListResp{}, nil + +} diff --git a/internal/repository/promocode_repository.go b/internal/repository/promocode_repository.go deleted file mode 100644 index 47826f5..0000000 --- a/internal/repository/promocode_repository.go +++ /dev/null @@ -1,272 +0,0 @@ -package repository - -import ( - "codeword/internal/models" - "context" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "time" -) - -// структура для горутины чтобы ошибки не пропускать -type countResult struct { - count int64 - err error -} - -type PromoCodeRepository struct { - mdb *mongo.Collection -} - -func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository { - return &PromoCodeRepository{mdb: mdb} -} - -func InitPromoCodeIndexes(ctx context.Context, mdb *mongo.Collection) error { - uniqueIndexModel := mongo.IndexModel{ - Keys: bson.D{ - {Key: "codeword", Value: 1}, - {Key: "delete", Value: 1}, - }, - Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.M{"delete": false}), - } - _, err := mdb.Indexes().CreateOne(ctx, uniqueIndexModel) - if err != nil { - return err - } - - textIndexModel := mongo.IndexModel{ - Keys: bson.D{ - {Key: "codeword", Value: "text"}, - {Key: "description", Value: "text"}, - {Key: "greetings", Value: "text"}, - }, - Options: options.Index().SetName("TextIndex"), - } - _, err = mdb.Indexes().CreateOne(ctx, textIndexModel) - if err != nil { - return err - } - - return nil -} - -func (r *PromoCodeRepository) CreatePromoCode(ctx context.Context, req *models.PromoCode) (*models.PromoCode, error) { - req.CreatedAt = time.Now() - req.ID = primitive.NewObjectID() - if req.FastLinks == nil { - req.FastLinks = []string{} - } - - _, err := r.mdb.InsertOne(ctx, req) - if err != nil { - if writeErr, ok := err.(mongo.WriteException); ok { - for _, writeError := range writeErr.WriteErrors { - if writeError.Code == 11000 { - return nil, ErrDuplicateCodeword - } - } - } - - return nil, err - } - - return req, nil -} - -func (r *PromoCodeRepository) EditPromoCode(ctx context.Context, req *models.ReqEditPromoCode) (*models.PromoCode, error) { - promoCodeID, err := primitive.ObjectIDFromHex(req.ID) - if err != nil { - return nil, err - } - - updateFields := bson.M{} - if req.Description != nil { - updateFields["description"] = *req.Description - } - if req.Greetings != nil { - updateFields["greetings"] = *req.Greetings - } - if req.DueTo != nil { - updateFields["dueTo"] = *req.DueTo - } - if req.ActivationCount != nil { - updateFields["activationCount"] = *req.ActivationCount - } - if req.Delete != nil { - updateFields["delete"] = *req.Delete - } - - if len(updateFields) == 0 { - return r.GetPromoCodeByID(ctx, promoCodeID) - } - - update := bson.M{"$set": updateFields} - result, err := r.mdb.UpdateOne(ctx, bson.M{"_id": promoCodeID}, update) - if err != nil { - return nil, err - } - - if result.MatchedCount == 0 { - return nil, ErrPromoCodeNotFound - } - - return r.GetPromoCodeByID(ctx, promoCodeID) -} - -func (r *PromoCodeRepository) GetPromoCodeByID(ctx context.Context, promoCodeID primitive.ObjectID) (*models.PromoCode, error) { - var promoCode models.PromoCode - err := r.mdb.FindOne(ctx, bson.M{"_id": promoCodeID}).Decode(&promoCode) - if err != nil { - if err == mongo.ErrNoDocuments { - return nil, ErrPromoCodeNotFound - } - - return nil, err - } - - return &promoCode, nil -} - -func (r *PromoCodeRepository) GetPromoCodesList(ctx context.Context, req *models.GetPromoCodesListReq) ([]models.PromoCode, int64, error) { - filter := bson.M{} - - if req.Filter.Text != "" { - filter["$text"] = bson.M{"$search": req.Filter.Text} - } - - if req.Filter.Active { - filter["delete"] = false - filter["outdated"] = false - filter["offLimit"] = false - } else { - filter["$or"] = []interface{}{ - bson.M{"delete": true}, - bson.M{"outdated": true}, - bson.M{"offLimit": true}, - } - } - - opt := options.Find().SetSkip(int64(req.Page * req.Limit)).SetLimit(int64(req.Limit)) - - var countChan = make(chan countResult) - go func() { - defer close(countChan) - count, err := r.mdb.CountDocuments(ctx, filter) - countChan <- countResult{count, err} - }() - - cursor, err := r.mdb.Find(ctx, filter, opt) - if err != nil { - return nil, 0, err - } - defer cursor.Close(ctx) - - var promoCodes = make([]models.PromoCode, 0) - for cursor.Next(ctx) { - var p models.PromoCode - if err := cursor.Decode(&p); err != nil { - return nil, 0, err - } - promoCodes = append(promoCodes, p) - } - - if err := cursor.Err(); err != nil { - return nil, 0, err - } - - result := <-countChan - if result.err != nil { - return nil, 0, result.err - } - count := result.count - - return promoCodes, count, nil -} - -func (r *PromoCodeRepository) ActivatePromo(ctx context.Context, req *models.ActivateReq) (*models.PromoCode, error) { - var promoCode models.PromoCode - - var filter bson.M - if req.Codeword != "" { - filter = bson.M{ - "codeword": req.Codeword, - } - } else if req.FastLink != "" { - filter = bson.M{ - "fastLinks": req.FastLink, - } - } - - opts := options.FindOneAndUpdate().SetReturnDocument(options.After) - - err := r.mdb.FindOneAndUpdate(ctx, filter, bson.M{"$inc": bson.M{"activationCount": -1}}, opts).Decode(&promoCode) - if err != nil { - if err == mongo.ErrNoDocuments { - return nil, ErrPromoCodeNotFound - } - return nil, err - } - - if promoCode.ActivationCount <= 0 && promoCode.DueTo > time.Now().Unix() { - if !promoCode.OffLimit { - update := bson.M{"$set": bson.M{"offLimit": true}} - _, err := r.mdb.UpdateOne(ctx, filter, update) - if err != nil { - return nil, err - } - } - } - return &promoCode, nil -} - -func (r *PromoCodeRepository) IncreaseActivationCount(ctx context.Context, promoCodeID primitive.ObjectID) error { - filter := bson.M{"_id": promoCodeID} - update := bson.M{"$inc": bson.M{"activationCount": 1}} - _, err := r.mdb.UpdateOne(ctx, filter, update) - if err != nil { - return err - } - - return nil -} - -func (r *PromoCodeRepository) DeletePromoCode(ctx context.Context, promoCodeID string) error { - id, err := primitive.ObjectIDFromHex(promoCodeID) - if err != nil { - return err - } - - result, err := r.mdb.UpdateOne( - ctx, - bson.M{"_id": id, "delete": false}, - bson.M{"$set": bson.M{"delete": true}}, - ) - if err != nil { - return err - } - - if result.MatchedCount == 0 { - return ErrPromoCodeNotFound - } - - return nil -} - -func (r *PromoCodeRepository) AddFastLink(ctx context.Context, promoCodeID primitive.ObjectID, xid string) error { - filter := bson.M{"_id": promoCodeID, "delete": false} - update := bson.M{"$push": bson.M{"fastLinks": xid}} - - result, err := r.mdb.UpdateOne(ctx, filter, update) - if err != nil { - return err - } - - if result.MatchedCount == 0 { - return ErrPromoCodeNotFound - } - - return nil -} diff --git a/internal/repository/promocode_stats.go b/internal/repository/promocode_stats.go deleted file mode 100644 index 1daf023..0000000 --- a/internal/repository/promocode_stats.go +++ /dev/null @@ -1,72 +0,0 @@ -package repository - -import ( - "codeword/internal/models" - "context" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "time" -) - -type StatsRepository struct { - mdb *mongo.Collection -} - -func NewStatsRepository(deps Deps) *StatsRepository { - - return &StatsRepository{mdb: deps.Mdb} -} - -func (r *StatsRepository) UpdateStatistics(ctx context.Context, req *models.ActivateReq, promoCode *models.PromoCode, userID string) error { - filter := bson.M{"_id": promoCode.ID, "usageMap." + userID: bson.M{"$exists": true}} - count, err := r.mdb.CountDocuments(ctx, filter) - if err != nil { - return err - } - - if count >= 1 { - return ErrPromoCodeAlreadyActivated - } - - var key string - if req.FastLink != "" { - key = req.FastLink - } else { - key = req.Codeword - } - - usage := models.Usage{ - Key: key, - Time: time.Now(), - } - - update := bson.M{ - "$inc": bson.M{"usageCount": 1}, - "$push": bson.M{ - "usageMap." + userID: usage, - }, - } - - opts := options.Update().SetUpsert(true) - _, err = r.mdb.UpdateOne(ctx, bson.M{"_id": promoCode.ID}, update, opts) - return err -} - -func (r *StatsRepository) GetStatistics(ctx context.Context, promoCodeID string) (*models.PromoCodeStats, error) { - objID, err := primitive.ObjectIDFromHex(promoCodeID) - if err != nil { - return nil, err - } - - filter := bson.M{"_id": objID} - - var promoCodeStats models.PromoCodeStats - err = r.mdb.FindOne(ctx, filter).Decode(&promoCodeStats) - if err != nil { - return nil, err - } - - return &promoCodeStats, nil -} diff --git a/internal/repository/recover.go b/internal/repository/recover.go new file mode 100644 index 0000000..a442e0e --- /dev/null +++ b/internal/repository/recover.go @@ -0,0 +1,41 @@ +package repository + +import ( + "codeword/internal/models" + "context" +) + +type RecoverRepository struct { +} + +func NewRecoverRepository() *RecoverRepository { + return &RecoverRepository{} +} + +func (r *RecoverRepository) Readiness(ctx context.Context) error { + //TODO:IMPLEMENT ME + + return nil + +} + +func (r *RecoverRepository) Recovery(ctx context.Context, request *models.RecoveryReq) error { + //TODO:IMPLEMENT ME + + return nil + +} + +func (r *RecoverRepository) Recoverylink(ctx context.Context) error { + //TODO:IMPLEMENT ME + + return nil + +} + +func (r *RecoverRepository) Liveness(ctx context.Context) error { + //TODO:IMPLEMENT ME + + return nil + +} diff --git a/internal/repository/stats.go b/internal/repository/stats.go new file mode 100644 index 0000000..285cf89 --- /dev/null +++ b/internal/repository/stats.go @@ -0,0 +1,20 @@ +package repository + +import ( + "codeword/internal/models" + "context" +) + +type StatsRepository struct { +} + +func NewStatsRepository() *StatsRepository { + return &StatsRepository{} +} + +func (r *StatsRepository) Getstats(ctx context.Context, request *models.PromoCodeStatsReq) (*models.PromoCodeStatsResp, error) { + //TODO:IMPLEMENT ME + + return &models.PromoCodeStatsResp{}, nil + +} diff --git a/internal/repository/user_repository.go b/internal/repository/user_repository.go deleted file mode 100644 index 97a62ae..0000000 --- a/internal/repository/user_repository.go +++ /dev/null @@ -1,37 +0,0 @@ -package repository - -import ( - "codeword/internal/models" - "context" - "github.com/go-redis/redis/v8" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" -) - -type Deps struct { - Mdb *mongo.Collection - Rdb *redis.Client -} - -type UserRepository struct { - mdb *mongo.Collection -} - -func NewUserRepository(deps Deps) *UserRepository { - - return &UserRepository{mdb: deps.Mdb} -} - -// ищем пользователя по мейлу в коллекции users -func (r *UserRepository) FindByEmail(ctx context.Context, email string) (*models.User, error) { - var user models.User - - err := r.mdb.FindOne(ctx, bson.M{"login": email}).Decode(&user) - if err != nil { - if err == mongo.ErrNoDocuments { - return nil, nil - } - return nil, ErrPromoUserNotFound - } - return &user, nil -} diff --git a/internal/server/http/http_server.go b/internal/server/http/http.go similarity index 86% rename from internal/server/http/http_server.go rename to internal/server/http/http.go index 4bb0aed..f2a8bff 100644 --- a/internal/server/http/http_server.go +++ b/internal/server/http/http.go @@ -3,17 +3,15 @@ package http import ( "context" "fmt" + "github.com/gofiber/fiber/v2" - "go.uber.org/zap" ) type ServerConfig struct { - Logger *zap.Logger Controllers []Controller } type Server struct { - Logger *zap.Logger Controllers []Controller app *fiber.App } @@ -22,7 +20,6 @@ func NewServer(config ServerConfig) *Server { app := fiber.New() s := &Server{ - Logger: config.Logger, Controllers: config.Controllers, app: app, } @@ -34,7 +31,6 @@ func NewServer(config ServerConfig) *Server { func (s *Server) Start(addr string) error { if err := s.app.Listen(addr); err != nil { - s.Logger.Error("Failed to start server", zap.Error(err)) return err } return nil diff --git a/internal/service/promocode.go b/internal/service/promocode.go new file mode 100644 index 0000000..de03788 --- /dev/null +++ b/internal/service/promocode.go @@ -0,0 +1,77 @@ +package service + +import ( + "codeword/internal/models" + "codeword/internal/repository" + "context" +) + +type PromocodeService struct { + PromocodeRepository *repository.PromocodeRepository +} + +func NewPromocodeService(repository *repository.PromocodeRepository) *PromocodeService { + return &PromocodeService{ + PromocodeRepository: repository, + } +} + +func (s *PromocodeService) Createpromocode(ctx context.Context, request *models.PromoCodeReq) (*models.PromoCode, error) { + + response, err := s.PromocodeRepository.Createpromocode(ctx, request) + if err != nil { + return nil, err + } + return response, nil + +} + +func (s *PromocodeService) Editpromocode(ctx context.Context, request *models.EditPromoCodeReq) (*models.PromoCode, error) { + + response, err := s.PromocodeRepository.Editpromocode(ctx, request) + if err != nil { + return nil, err + } + return response, nil + +} + +func (s *PromocodeService) Createfastlink(ctx context.Context, request *models.CreateFastLinkReq) (*models.CreateFastLinkResp, error) { + + response, err := s.PromocodeRepository.Createfastlink(ctx, request) + if err != nil { + return nil, err + } + return response, nil + +} + +func (s *PromocodeService) Delete(ctx context.Context) error { + + err := s.PromocodeRepository.Delete(ctx) + if err != nil { + return err + } + return nil + +} + +func (s *PromocodeService) Activate(ctx context.Context, request *models.ActivateReq) (*models.ActivateResp, error) { + + response, err := s.PromocodeRepository.Activate(ctx, request) + if err != nil { + return nil, err + } + return response, nil + +} + +func (s *PromocodeService) Getlist(ctx context.Context, request *models.GetPromoCodesListReq) (*models.GetPromoCodesListResp, error) { + + response, err := s.PromocodeRepository.Getlist(ctx, request) + if err != nil { + return nil, err + } + return response, nil + +} diff --git a/internal/service/recover.go b/internal/service/recover.go new file mode 100644 index 0000000..b6185dc --- /dev/null +++ b/internal/service/recover.go @@ -0,0 +1,57 @@ +package service + +import ( + "codeword/internal/models" + "codeword/internal/repository" + "context" +) + +type RecoverService struct { + RecoverRepository *repository.RecoverRepository +} + +func NewRecoverService(repository *repository.RecoverRepository) *RecoverService { + return &RecoverService{ + RecoverRepository: repository, + } +} + +func (s *RecoverService) Readiness(ctx context.Context) error { + + err := s.RecoverRepository.Readiness(ctx) + if err != nil { + return err + } + return nil + +} + +func (s *RecoverService) Recovery(ctx context.Context, request *models.RecoveryReq) error { + + err := s.RecoverRepository.Recovery(ctx, request) + if err != nil { + return err + } + return nil + +} + +func (s *RecoverService) Recoverylink(ctx context.Context) error { + + err := s.RecoverRepository.Recoverylink(ctx) + if err != nil { + return err + } + return nil + +} + +func (s *RecoverService) Liveness(ctx context.Context) error { + + err := s.RecoverRepository.Liveness(ctx) + if err != nil { + return err + } + return nil + +} diff --git a/internal/service/stats.go b/internal/service/stats.go new file mode 100644 index 0000000..fe044c7 --- /dev/null +++ b/internal/service/stats.go @@ -0,0 +1,27 @@ +package service + +import ( + "codeword/internal/models" + "codeword/internal/repository" + "context" +) + +type StatsService struct { + StatsRepository *repository.StatsRepository +} + +func NewStatsService(repository *repository.StatsRepository) *StatsService { + return &StatsService{ + StatsRepository: repository, + } +} + +func (s *StatsService) Getstats(ctx context.Context, request *models.PromoCodeStatsReq) (*models.PromoCodeStatsResp, error) { + + response, err := s.StatsRepository.Getstats(ctx, request) + if err != nil { + return nil, err + } + return response, nil + +} diff --git a/internal/services/promocode_service.go b/internal/services/promocode_service.go deleted file mode 100644 index 2150cd4..0000000 --- a/internal/services/promocode_service.go +++ /dev/null @@ -1,211 +0,0 @@ -package services - -import ( - "codeword/internal/kafka/tariff" - "codeword/internal/models" - "codeword/internal/proto/discount" - "codeword/internal/repository" - "codeword/internal/utils/genID" - "context" - "errors" - "fmt" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.uber.org/zap" - "time" -) - -type PromoCodeRepository interface { - CreatePromoCode(ctx context.Context, req *models.PromoCode) (*models.PromoCode, error) - EditPromoCode(ctx context.Context, req *models.ReqEditPromoCode) (*models.PromoCode, error) - GetPromoCodesList(ctx context.Context, req *models.GetPromoCodesListReq) ([]models.PromoCode, int64, error) - ActivatePromo(ctx context.Context, req *models.ActivateReq) (*models.PromoCode, error) - DeletePromoCode(ctx context.Context, promoCodeID string) error - GetPromoCodeByID(ctx context.Context, promoCodeID primitive.ObjectID) (*models.PromoCode, error) - AddFastLink(ctx context.Context, promoCodeID primitive.ObjectID, xid string) error - IncreaseActivationCount(ctx context.Context, promoCodeID primitive.ObjectID) error -} - -type PromoStatsRepository interface { - UpdateStatistics(ctx context.Context, req *models.ActivateReq, promoCode *models.PromoCode, userID string) error - GetStatistics(ctx context.Context, promoCodeID string) (*models.PromoCodeStats, error) -} - -type PromoDeps struct { - Logger *zap.Logger - PromoCodeRepo PromoCodeRepository - StatsRepo PromoStatsRepository - Kafka *tariff.Producer - DiscountClient discount.DiscountServiceClient -} - -type PromoCodeService struct { - logger *zap.Logger - promoCodeRepo PromoCodeRepository - statsRepo PromoStatsRepository - kafka *tariff.Producer - discountClient discount.DiscountServiceClient -} - -func NewPromoCodeService(deps PromoDeps) *PromoCodeService { - return &PromoCodeService{ - logger: deps.Logger, - promoCodeRepo: deps.PromoCodeRepo, - statsRepo: deps.StatsRepo, - kafka: deps.Kafka, - discountClient: deps.DiscountClient, - } -} - -func (s *PromoCodeService) CreatePromoCode(ctx context.Context, req *models.PromoCode) (*models.PromoCode, error) { - promoCode, err := s.promoCodeRepo.CreatePromoCode(ctx, req) - if err != nil { - s.logger.Error("Failed to add promocode in database", zap.Error(err)) - return nil, err - } - - return promoCode, nil -} - -func (s *PromoCodeService) EditPromoCode(ctx context.Context, req *models.ReqEditPromoCode) (*models.PromoCode, error) { - editedPromoCode, err := s.promoCodeRepo.EditPromoCode(ctx, req) - if err != nil { - s.logger.Error("Failed to edit promocode in database", zap.Error(err)) - return nil, err - } - - return editedPromoCode, nil -} - -func (s *PromoCodeService) GetPromoCodesList(ctx context.Context, req *models.GetPromoCodesListReq) ([]models.PromoCode, int64, error) { - promoCodes, count, err := s.promoCodeRepo.GetPromoCodesList(ctx, req) - if err != nil { - s.logger.Error("Failed to get list promocodes from database", zap.Error(err)) - return nil, 0, err - } - - return promoCodes, count, nil -} - -// todo одумать еще реализацию этого дела, надо уточнить как разделяется ответственность в бонусе между привилегией и скидкой -// разделяется ли она или они всегда вместе, если разделяются то что-то из этого может быть пустым либо все заполеннное, -// соответсвенно надо сделать соответствующие проверки до записи в кафку и до отправки в дискаунт сервис - -func (s *PromoCodeService) ActivatePromo(ctx context.Context, req *models.ActivateReq, userID string) (string, error) { - promoCode, err := s.promoCodeRepo.ActivatePromo(ctx, req) - if err != nil { - s.logger.Error("Failed to activate promocode", zap.Error(err)) - return "", err - } - //todo такая реализация проверок кажется довольно массивной, думаю как то это стоит сделать параллельно обхаживая все условия - if promoCode.DueTo < time.Now().Unix() && promoCode.OffLimit { - err := s.promoCodeRepo.IncreaseActivationCount(ctx, promoCode.ID) - if err != nil { - return "", err - } - return "", fmt.Errorf("%w: expired on %s", repository.ErrPromoCodeExpired, time.Unix(promoCode.DueTo, 0).Format(time.RFC3339)) - } - - if promoCode.DueTo == 0 && promoCode.ActivationCount < 0 { - err := s.promoCodeRepo.IncreaseActivationCount(ctx, promoCode.ID) - if err != nil { - return "", err - } - return "", repository.ErrPromoCodeExhausted - } - - err = s.statsRepo.UpdateStatistics(ctx, req, promoCode, userID) - if err != nil { - if errors.Is(err, repository.ErrPromoCodeAlreadyActivated) { - err := s.promoCodeRepo.IncreaseActivationCount(ctx, promoCode.ID) - if err != nil { - return "", err - } - return "", repository.ErrPromoCodeAlreadyActivated - } - s.logger.Error("Failed add in stats", zap.Error(err)) - return "", err - } - - var postfix string - - if req.FastLink != "" { - postfix = fmt.Sprintf(":(%s)", req.FastLink) - } - - var privileges []models.Privilege - privilege := models.Privilege{ - PrivilegeID: promoCode.Bonus.Privilege.PrivilegeID, - Amount: promoCode.Bonus.Privilege.Amount, - } - privileges = append(privileges, privilege) - - fakeTariff := &models.Tariff{ - Name: promoCode.Codeword + postfix, - Privileges: privileges, - Deleted: promoCode.Delete, - CreatedAt: promoCode.CreatedAt, - } - if err := s.kafka.Send(ctx, userID, fakeTariff); err != nil { - s.logger.Error("Failed to send fake tariff to Kafka", zap.Error(err)) - return "", err - } - - disOverHelm := true - discountRequest := &discount.CreateDiscountRequest{ - Name: promoCode.Codeword + postfix, - Layer: promoCode.Bonus.Discount.Layer, - Description: "", - Condition: &discount.DiscountCondition{ - Coupon: &promoCode.Codeword, - User: &userID, - }, - Target: &discount.DiscountCalculationTarget{ - Factor: promoCode.Bonus.Discount.Factor, - Overhelm: &disOverHelm, - }, - } - - _, err = s.discountClient.CreateDiscount(ctx, discountRequest) - if err != nil { - s.logger.Error("Failed to create discount", zap.Error(err)) - return "", err - } - - return promoCode.Greetings, nil -} - -func (s *PromoCodeService) DeletePromoCode(ctx context.Context, promoCodeID string) error { - err := s.promoCodeRepo.DeletePromoCode(ctx, promoCodeID) - if err != nil { - s.logger.Error("Failed simple delete promocode from database", zap.Error(err)) - return err - } - - return nil -} - -func (s *PromoCodeService) CreateFastLink(ctx context.Context, promoCodeID string) (string, error) { - xid := genID.GenerateXID() - promoID, err := primitive.ObjectIDFromHex(promoCodeID) - if err != nil { - s.logger.Error("Failed conversion promoCodeID to ObjectID", zap.Error(err)) - return "", err - } - - err = s.promoCodeRepo.AddFastLink(ctx, promoID, xid) - if err != nil { - s.logger.Error("Failed to add fastlink for promocode by promocode id", zap.Error(err)) - return "", err - } - - return xid, nil -} - -func (s *PromoCodeService) GetStats(ctx context.Context, promoCodeID string) (*models.PromoCodeStats, error) { - promoStats, err := s.statsRepo.GetStatistics(ctx, promoCodeID) - if err != nil { - s.logger.Error("Failed getting promo stats", zap.Error(err)) - return nil, err - } - return promoStats, nil -} diff --git a/internal/services/recovery_service.go b/internal/services/recovery_service.go deleted file mode 100644 index 348b834..0000000 --- a/internal/services/recovery_service.go +++ /dev/null @@ -1,135 +0,0 @@ -package services - -import ( - "codeword/internal/adapters/client" - "codeword/internal/models" - "codeword/internal/utils/encrypt" - "context" - "encoding/base64" - "go.uber.org/zap" -) - -type CodewordRepository interface { - StoreRecoveryRecord(ctx context.Context, deps models.StoreRecDeps) (string, error) - InsertToQueue(ctx context.Context, deps models.RecEmailDeps) error - Ping(ctx context.Context) error - GetRecoveryRecord(ctx context.Context, key string) (*models.RestoreRequest, error) -} - -type UserRepository interface { - FindByEmail(ctx context.Context, email string) (*models.User, error) -} - -type Deps struct { - Logger *zap.Logger - CodewordRepository CodewordRepository - UserRepository UserRepository - Encrypt *encrypt.Encrypt - AuthClient *client.AuthClient -} - -type RecoveryService struct { - logger *zap.Logger - repositoryCodeword CodewordRepository - repositoryUser UserRepository - encrypt *encrypt.Encrypt - authClient *client.AuthClient -} - -func NewRecoveryService(deps Deps) *RecoveryService { - return &RecoveryService{ - logger: deps.Logger, - repositoryCodeword: deps.CodewordRepository, - repositoryUser: deps.UserRepository, - encrypt: deps.Encrypt, - authClient: deps.AuthClient, - } -} - -// GenerateKey генерирует ключ, используя шифрование на основе эллиптической кривой -func (s *RecoveryService) GenerateKey() ([]byte, error) { - key, err := s.encrypt.SignCommonSecret() - if err != nil { - s.logger.Error("Failed to generate unique key for user", zap.Error(err)) - return nil, err - } - return key, nil -} - -// вызывает пингование в бд -func (s *RecoveryService) Ping(ctx context.Context) error { - err := s.repositoryCodeword.Ping(ctx) - if err != nil { - s.logger.Error("Failed to ping database", zap.Error(err)) - return err - } - return nil -} - -// FindUserByEmail ищет пользователя по электронной почте -func (s *RecoveryService) FindUserByEmail(ctx context.Context, email string) (*models.User, error) { - user, err := s.repositoryUser.FindByEmail(ctx, email) - if err != nil { - s.logger.Error("Failed to find user by email", zap.String("email", email), zap.Error(err)) - return nil, err - } - return user, nil -} - -// StoreRecoveryRecord сохраняет запись восстановления в базе данных -func (s *RecoveryService) StoreRecoveryRecord(ctx context.Context, deps models.StoreRecDeps) (string, error) { - id, err := s.repositoryCodeword.StoreRecoveryRecord(ctx, models.StoreRecDeps{UserID: deps.UserID, Email: deps.Email, Key: deps.Key, Url: deps.Url}) - if err != nil { - s.logger.Error("Failed save data in mongoDB for email", zap.String("email", deps.Email), zap.Error(err)) - return "", err - } - return id, nil -} - -// RecoveryEmailTask посылает письмо для восстановления доступа пользователю -func (s *RecoveryService) RecoveryEmailTask(ctx context.Context, deps models.RecEmailDeps) error { - err := s.repositoryCodeword.InsertToQueue(ctx, models.RecEmailDeps{UserID: deps.UserID, Email: deps.Email, SignWithID: deps.SignWithID, ID: deps.ID}) - if err != nil { - s.logger.Error("Failed creating a task to send a worker by email", zap.String("email", deps.Email), zap.Error(err)) - return err - } - return nil -} - -// GetRecoveryRecord получает запись восстановления из базы данных -func (s *RecoveryService) GetRecoveryRecord(ctx context.Context, key string) (*models.RestoreRequest, error) { - req, err := s.repositoryCodeword.GetRecoveryRecord(ctx, key) - if err != nil { - s.logger.Error("Failed to obtain signature recovery data", zap.String("signature", key), zap.Error(err)) - return nil, err - } - - byteKey, err := base64.URLEncoding.DecodeString(req.Sign) - if err != nil { - s.logger.Error("Failed to decode string signature to []byte format", zap.String("signature", key), zap.Error(err)) - return nil, err - } - - // сомнительный вариант но как я думаю верный, что false==err - result, err := s.encrypt.VerifySignature(byteKey) - if err != nil || !result { - s.logger.Error("Failed to verify signature", zap.String("signature", key), zap.Error(err)) - return nil, err - } - - return req, nil -} - -// меняет подпись на токены идя в auth сервис -func (s *RecoveryService) ExchangeForTokens(userID string, signature string) (map[string]string, error) { - tokens, err := s.authClient.RefreshAuthToken(userID, signature) - if err != nil { - s.logger.Error("Failed to refresh auth token", zap.Error(err)) - return nil, err - } - - return map[string]string{ - "accessToken": tokens.AccessToken, - "refreshToken": tokens.RefreshToken, - }, nil -} diff --git a/internal/utils/encrypt/encrypt_util.go b/internal/utils/encrypt/encrypt_util.go deleted file mode 100644 index 9f2d4ac..0000000 --- a/internal/utils/encrypt/encrypt_util.go +++ /dev/null @@ -1,81 +0,0 @@ -package encrypt - -import ( - "crypto/ed25519" - "crypto/x509" - "encoding/pem" - "errors" - "fmt" -) - -type EncryptDeps struct { - PublicKey string - PrivateKey string - SignSecret string -} - -type Encrypt struct { - publicKey string - privateKey string - signSecret string -} - -func New(deps *EncryptDeps) *Encrypt { - return &Encrypt{ - publicKey: deps.PublicKey, - privateKey: deps.PrivateKey, - signSecret: deps.SignSecret, - } -} - -func (receiver *Encrypt) VerifySignature(signature []byte) (isValid bool, err error) { - defer func() { - if recovered := recover(); recovered != nil { - err = fmt.Errorf("recovered verify error on of : %v", recovered) - } - }() - - block, _ := pem.Decode([]byte(receiver.publicKey)) - if block == nil { - return false, fmt.Errorf("public key block is nil") - } - - rawPublicKey, err := x509.ParsePKIXPublicKey(block.Bytes) - if err != nil { - return false, fmt.Errorf("failed parse public key on of : %w", err) - } - - publicKey, ok := rawPublicKey.(ed25519.PublicKey) - if !ok { - return false, errors.New("public key is not of type ed25519.PublicKey") - } - - return ed25519.Verify(publicKey, []byte(receiver.signSecret), signature), nil -} - -// TODO подумать над тем чтобы подпись генерилась каждый раз разгая -func (receiver *Encrypt) SignCommonSecret() (signature []byte, err error) { - defer func() { - if recovered := recover(); recovered != nil { - fmt.Printf("recovered sign error: \n%+v\n", receiver) - err = fmt.Errorf("recovered sign error on of : %v", recovered) - } - }() - - block, _ := pem.Decode([]byte(receiver.privateKey)) - if block == nil { - return []byte{}, fmt.Errorf("failed decode private key %s on of : %w", receiver.privateKey, err) - } - - rawPrivateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) - if err != nil { - return []byte{}, fmt.Errorf("failed parse private key on of : %w", err) - } - - privateKey, ok := rawPrivateKey.(ed25519.PrivateKey) - if !ok { - return []byte{}, fmt.Errorf("failed convert to ed25519.PrivateKey on of : %w", err) - } - - return ed25519.Sign(privateKey, []byte(receiver.signSecret)), nil -} diff --git a/internal/utils/genID/gen_id.go b/internal/utils/genID/gen_id.go deleted file mode 100644 index 2a6610f..0000000 --- a/internal/utils/genID/gen_id.go +++ /dev/null @@ -1,8 +0,0 @@ -package genID - -import "github.com/rs/xid" - -func GenerateXID() string { - id := xid.New() - return id.String() -} diff --git a/internal/utils/transfer/privilege.go b/internal/utils/transfer/privilege.go deleted file mode 100644 index 60bb9c5..0000000 --- a/internal/utils/transfer/privilege.go +++ /dev/null @@ -1,31 +0,0 @@ -package transfer - -import ( - "codeword/internal/models" - "codeword/internal/proto/broker" -) - -func PrivilegeModelToProto(privilege *models.Privilege) *broker.PrivilegeMessage { - if privilege == nil { - return &broker.PrivilegeMessage{} - } - - return &broker.PrivilegeMessage{ - PrivilegeID: privilege.PrivilegeID, - ServiceKey: privilege.ServiceKey, - Type: models.PrivilegeBrokerTypeMap[privilege.Type], - Value: privilege.Value, - Amount: privilege.Amount, - } -} - -func PrivilegeArrayModelToProto(privileges []models.Privilege) []*broker.PrivilegeMessage { - privilegesProto := make([]*broker.PrivilegeMessage, len(privileges)) - - for index, privilege := range privileges { - privilegeCopy := privilege - privilegesProto[index] = PrivilegeModelToProto(&privilegeCopy) - } - - return privilegesProto -} diff --git a/internal/utils/transfer/tariff.go b/internal/utils/transfer/tariff.go deleted file mode 100644 index 592c56e..0000000 --- a/internal/utils/transfer/tariff.go +++ /dev/null @@ -1,17 +0,0 @@ -package transfer - -import ( - "codeword/internal/models" - "codeword/internal/proto/broker" -) - -func TariffModelToProtoMessage(userID string, tariffModel *models.Tariff) *broker.TariffMessage { - if tariffModel == nil { - return &broker.TariffMessage{} - } - - return &broker.TariffMessage{ - UserID: userID, - Privileges: PrivilegeArrayModelToProto(tariffModel.Privileges), - } -} diff --git a/internal/worker/purge_worker/purge_worker.go b/internal/worker/purge_worker/purge_worker.go deleted file mode 100644 index 017c7f5..0000000 --- a/internal/worker/purge_worker/purge_worker.go +++ /dev/null @@ -1,60 +0,0 @@ -package purge_worker - -import ( - "context" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.uber.org/zap" - "time" -) - -type Deps struct { - Logger *zap.Logger - Mongo *mongo.Collection -} - -type PurgeWorker struct { - logger *zap.Logger - mongo *mongo.Collection -} - -func NewPurgeWC(deps Deps) *PurgeWorker { - return &PurgeWorker{ - logger: deps.Logger, - mongo: deps.Mongo, - } -} - -func (wc *PurgeWorker) Start(ctx context.Context) { - ticker := time.NewTicker(1 * time.Hour) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - wc.processTasks(ctx) - - case <-ctx.Done(): - return - } - } -} - -func (wc *PurgeWorker) processTasks(ctx context.Context) { - wc.logger.Info("Checking cleaning records") - - oneHourAgo := time.Now().Add(-1 * time.Hour) - - filter := bson.M{"created_at": bson.M{"$lt": oneHourAgo}} - - result, err := wc.mongo.DeleteMany(ctx, filter) - if err != nil { - wc.logger.Error("Error when trying to delete old entries", zap.Error(err)) - } else { - wc.logger.Info("Deleted documents", zap.Int64("count", result.DeletedCount)) - } -} - -func (wc *PurgeWorker) Stop(ctx context.Context) error { - return nil -} diff --git a/internal/worker/recovery_worker/recovery_worker.go b/internal/worker/recovery_worker/recovery_worker.go deleted file mode 100644 index df79493..0000000 --- a/internal/worker/recovery_worker/recovery_worker.go +++ /dev/null @@ -1,129 +0,0 @@ -package recovery_worker - -import ( - "codeword/internal/adapters/client" - "codeword/internal/models" - "context" - "encoding/json" - "github.com/go-redis/redis/v8" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo" - "go.uber.org/zap" - "time" -) - -type Deps struct { - Logger *zap.Logger - Redis *redis.Client - EmailSender *client.RecoveryEmailSender - Mongo *mongo.Collection -} - -type RecoveryWorker struct { - logger *zap.Logger - redis *redis.Client - emailSender *client.RecoveryEmailSender - mongo *mongo.Collection -} - -func NewRecoveryWC(deps Deps) *RecoveryWorker { - return &RecoveryWorker{ - logger: deps.Logger, - redis: deps.Redis, - emailSender: deps.EmailSender, - mongo: deps.Mongo, - } -} - -func (wc *RecoveryWorker) Start(ctx context.Context) { - ticker := time.NewTicker(10 * time.Second) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - wc.processTasks(ctx) - case <-ctx.Done(): - return - } - } -} - -func (wc *RecoveryWorker) processTasks(ctx context.Context) { - var cursor uint64 - for { - var keys []string - var err error - keys, cursor, err = wc.redis.Scan(ctx, cursor, "email:task:*", 0).Result() - if err != nil { - wc.logger.Error("Failed to scan for email tasks", zap.Error(err)) - break - } - - for _, key := range keys { - taskBytes, err := wc.redis.GetDel(ctx, key).Result() - if err == redis.Nil { - continue - } else if err != nil { - wc.logger.Error("Failed to getdel recovery task", zap.String("key", key), zap.Error(err)) - continue - } - - var task models.RecoveryRecord - if json.Unmarshal([]byte(taskBytes), &task) != nil { - wc.logger.Error("Failed to unmarshal recovery task", zap.String("key", key), zap.String("task", taskBytes)) - continue - } - - err = wc.sendRecoveryTask(ctx, task) - if err != nil { - wc.logger.Error("Failed to send recovery task", zap.String("key", key), zap.Error(err)) - } - } - if cursor == 0 { - break - } - } -} - -func (wc *RecoveryWorker) sendRecoveryTask(ctx context.Context, task models.RecoveryRecord) error { - err := wc.emailSender.SendRecoveryEmail(task.Email, task.Key) - if err != nil { - wc.logger.Error("Failed to send recovery email", zap.Error(err)) - return err - } - - update := bson.M{ - "$set": bson.M{ - "sent": true, - "sent_at": time.Now(), - }, - } - - objectID, err := primitive.ObjectIDFromHex(task.ID) - if err != nil { - wc.logger.Error("Invalid ObjectID", zap.String("ID", task.ID), zap.Error(err)) - return err - } - - filter := bson.M{"_id": objectID} - - result, err := wc.mongo.UpdateOne(ctx, filter, update) - if err != nil { - wc.logger.Error("Failed to update restore request", zap.Error(err)) - return err - } - - if result.ModifiedCount == 0 { - wc.logger.Warn("No documents were updated - this may indicate the document was not found", - zap.String("ID", task.ID)) - } - - //wc.logger.Info("Recovery email sent and restore request updated successfully", zap.String("email", task.Email)) - return nil -} - -func (wc *RecoveryWorker) Stop(ctx context.Context) error { - return nil -} diff --git a/docs/openapi.yaml b/openapi.yaml similarity index 85% rename from docs/openapi.yaml rename to openapi.yaml index 2d59bb6..fc3d1f9 100644 --- a/docs/openapi.yaml +++ b/openapi.yaml @@ -45,7 +45,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/RecoveryRequest' + $ref: '#/components/schemas/RecoveryReq' responses: '200': description: Запрос на восстановление принят @@ -109,7 +109,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ReqEditPromoCode' + $ref: '#/components/schemas/EditPromoCodeReq' responses: '200': description: Промокод успешно обновлен @@ -208,14 +208,14 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/CreateFastLinkRequest' + $ref: '#/components/schemas/CreateFastLinkReq' responses: '200': description: Быстрая ссылка для промокода успешно создана content: application/json: schema: - $ref: '#/components/schemas/CreateFastLinkResponse' + $ref: '#/components/schemas/CreateFastLinkResp' '400': description: Неверный запрос, отсутствует идентификатор промокода '404': @@ -235,14 +235,14 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/PromoCodeStatsRequest' + $ref: '#/components/schemas/PromoCodeStatsReq' responses: '200': description: Статистика промокода успешно получена content: application/json: schema: - $ref: '#/components/schemas/PromoCodeStats' + $ref: '#/components/schemas/PromoCodeStatsResp' '400': description: Неверный запрос '500': @@ -251,7 +251,7 @@ paths: components: schemas: - RecoveryRequest: + RecoveryReq: type: object required: - email @@ -263,14 +263,14 @@ components: redirectionURL: type: string description: URL-адрес, на который перенаправляется пользователь - PromoCodeStatsRequest: + PromoCodeStatsReq: type: object properties: promoCodeID: type: string required: - promoCodeID - PromoCodeStats: + PromoCodeStatsResp: type: object properties: id: @@ -298,7 +298,7 @@ components: format: date-time description: Время использования промокода - CreateFastLinkRequest: + CreateFastLinkReq: type: object properties: id: @@ -307,7 +307,7 @@ components: required: - id - CreateFastLinkResponse: + CreateFastLinkResp: type: object properties: fastlink: @@ -393,33 +393,8 @@ components: bonus: type: object description: Бонус, предоставляемый с промокодом - properties: - privilege: - type: object - description: Привилегия - properties: - privilegeID: - type: string - description: Идентификатор привилегии - amount: - type: integer - description: Количество привилегии - discount: - type: object - description: Скидка - properties: - layer: - type: integer - description: Уровень скидки - factor: - type: number - description: Множитель скидки - target: - type: string - description: Слой - threshold: - type: integer - description: Граничное значение + items: + $ref: '#/components/schemas/Bonus' outdated: type: boolean description: Флаг @@ -439,7 +414,7 @@ components: type: string description: Список быстрых ссылок для активации промокода - ReqEditPromoCode: + EditPromoCodeReq: type: object properties: ID: @@ -486,35 +461,48 @@ components: bonus: type: object description: Бонус - properties: - privilege: - type: object - description: Привилегия - properties: - privilegeID: - type: string - description: Идентификатор привилегии - amount: - type: integer - description: Количество привилегии - discount: - type: object - description: Скидка - properties: - layer: - type: integer - description: Уровень скидки - factor: - type: number - description: Множитель скидки - target: - type: string - description: Слой - threshold: - type: integer - description: Граничное значение + items: + $ref: '#/components/schemas/Bonus' fastLinks: type: array items: type: string description: Список быстрых ссылок для активации промокода + + Bonus: + type: object + description: Бонус + properties: + privilege: + $ref: '#/components/schemas/Privilege' + discount: + $ref: '#/components/schemas/Discount' + + Privilege: + type: object + description: Привилегия + properties: + privilegeID: + type: string + description: Идентификатор привилегии + amount: + type: integer + description: Количество привилегии + + Discount: + type: object + description: Скидка + properties: + layer: + type: integer + description: Уровень скидки + factor: + type: integer + description: Множитель скидки + target: + type: string + description: Цель скидки + threshold: + type: integer + description: Порог скидки + diff --git a/pkg/closer/closer.go b/pkg/closer/closer.go deleted file mode 100644 index fdfbaf1..0000000 --- a/pkg/closer/closer.go +++ /dev/null @@ -1,37 +0,0 @@ -package closer - -import ( - "context" -) - -type Closer interface { - Close(ctx context.Context) error -} - -type CloserFunc func(ctx context.Context) error - -func (cf CloserFunc) Close(ctx context.Context) error { - return cf(ctx) -} - -type CloserGroup struct { - closers []Closer -} - -func NewCloserGroup() *CloserGroup { - return &CloserGroup{} -} - -func (cg *CloserGroup) Add(c Closer) { - cg.closers = append(cg.closers, c) -} - -func (cg *CloserGroup) Call(ctx context.Context) error { - var closeErr error - for i := len(cg.closers) - 1; i >= 0; i-- { - if err := cg.closers[i].Close(ctx); err != nil && closeErr == nil { - closeErr = err - } - } - return closeErr -} diff --git a/template/cmd/{{.ProjectName}}/main.go.tmpl b/template/cmd/{{.ProjectName}}/main.go.tmpl index 00bcebb..a8d8b4f 100644 --- a/template/cmd/{{.ProjectName}}/main.go.tmpl +++ b/template/cmd/{{.ProjectName}}/main.go.tmpl @@ -7,14 +7,14 @@ import ( "{{.Vars.ProjectName}}/internal/app" - {{.Modules.logger.Import}} - {{.Modules.logger.ImportCore}} + "{{.Modules.logger.Import}}" + "{{.Modules.logger.ImportCore}}" - {{.Modules.env.Import}} + "{{.Modules.env.Import}}" ) func main() { - {{.Modules.logger.Init}} + {{.Modules.logger.Declaration "logger"}} ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer cancel() @@ -26,4 +26,4 @@ func main() { if err := app.Run(ctx, config, logger); err != nil { {{.Modules.logger.Message "Fatal" "Failed to run app" "Error" "err"}} } -} +} \ No newline at end of file diff --git a/template/internal/app/app.go.tmpl b/template/internal/app/app.go.tmpl index 1b72ed9..d5ff19d 100644 --- a/template/internal/app/app.go.tmpl +++ b/template/internal/app/app.go.tmpl @@ -3,17 +3,65 @@ package app import ( "context" - {{.Modules.logger.Import}} + "{{.Modules.logger.Import}}" ) {{.Modules.env.Struct}} func Run(ctx context.Context, config Config, logger {{.Modules.logger.Type}}) error { + defer func() { + if r := recover(); r != nil { + logger.Error("Recovered from a panic", zap.Any("error", r)) + } + }() + {{.Modules.logger.Message "info" "App started" "config" "config"}} + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + // Инициализация репозиториев + {{range $key, $value := .LayersData.Repositories}} + {{$key}}Repository := {{$value.PackageName}}.New{{$value.Name}}Repository() + {{end}} + + // Инициализация сервисов + {{range $key, $value := .LayersData.Services}} + {{$key}}Service := {{$value.PackageName}}.New{{$value.Name}}Service({{$key}}Repository) + {{end}} + + // Инициализация контроллеров + {{range $key, $value := .LayersData.Controllers}} + {{$key}}Controller := {{$value.PackageName}}.New{{$value.Name}}Controller({{$key}}Service) + {{end}} + +// Создание сервера + server := {{.LayersData.ServerData}}.NewServer({{.LayersData.ServerData}}.ServerConfig{ + Controllers: []{{.LayersData.ServerData}}.Controller{ + {{range $key, $value := .LayersData.Controllers}} + {{$key}}Controller, + {{end}} + }, + }) + + go func() { + err := server.Start("Host + : + Port") + if err != nil { + logger.Error("Server startup error", zap.Error(err)) + cancel() + } + }() + + // Вывод маршрутов + server.ListRoutes() + <-ctx.Done() logger.Info("App shutting down gracefully") + //TODO + // Остановка сервера + + return nil -} +} \ No newline at end of file diff --git a/tests/e2e/promo_test.go b/tests/e2e/promo_test.go deleted file mode 100644 index 822dfd1..0000000 --- a/tests/e2e/promo_test.go +++ /dev/null @@ -1,599 +0,0 @@ -package e2e - -import ( - "codeword/internal/models" - "codeword/tests/helpers" - "encoding/json" - "fmt" - "github.com/gofiber/fiber/v2" - "github.com/pioz/faker" - "github.com/stretchr/testify/assert" - "go.mongodb.org/mongo-driver/bson/primitive" - "strconv" - "testing" -) - -var promoID string -var fastLink string - -// CreatePromoCode -func TestCreatePromoCode(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("CreatePromoCode-success", func(t *testing.T) { - for i := 0; i < 10; i++ { - jsonString := `{ - "codeword": "example", - "description": "Example description", - "greetings": "Example greetings", - "dueTo": 1734429225, - "activationCount": 100, - "bonus": { - "privilege": { - "privilegeID": "examplePrivilegeID", - "amount": 50 - }, - "discount": { - "layer": 1, - "factor": 0.2, - "target": "exampleTarget", - "threshold": 500 - } - }, - "outdated": false, - "offLimit": false, - "delete": false - }` - - var reqBody models.PromoCode - err := json.Unmarshal([]byte(jsonString), &reqBody) - assert.NoError(t, err) - if i != 0 { - reqBody.Codeword = reqBody.Codeword + faker.String() + strconv.Itoa(i) - } - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/create").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusCreated, statusCode) - - var response models.PromoCode - err = json.Unmarshal(resBody, &response) - assert.NoError(t, err) - promoID = response.ID.Hex() - fmt.Println(response) - } - - }) - t.Run("CreatePromoCode-duplicate", func(t *testing.T) { - jsonString := `{ - "codeword": "example", - "description": "Example description", - "greetings": "Example greetings", - "dueTo": 1734429225, - "activationCount": 100, - "bonus": { - "privilege": { - "privilegeID": "examplePrivilegeID", - "amount": 50 - }, - "discount": { - "layer": 1, - "factor": 0.2, - "target": "exampleTarget", - "threshold": 500 - } - }, - "outdated": false, - "offLimit": false, - "delete": false - }` - - var reqBody models.PromoCode - err := json.Unmarshal([]byte(jsonString), &reqBody) - assert.NoError(t, err) - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/create").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err = json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) - t.Run("CreatePromoCode-invalid request payload", func(t *testing.T) { - jsonString := `{ - "example": "example", - "description": "Example description", - "greetings": "Example greetings", - "dueTo": 1734429225, - "activationCount": 100, - "bonus": { - "privilege": { - "privilegeID": "examplePrivilegeID", - "amount": 50 - }, - "discount": { - "layer": 1, - "factor": 0.2, - "target": "exampleTarget", - "threshold": 500 - } - }, - "outdated": false, - "offLimit": false, - "delete": false - }` - - req := client.Post(BaseUrl+"/promocode/create").Set("Content-Type", "application/json").Body([]byte(jsonString)) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) - t.Run("CreatePromoCode-nil codeword", func(t *testing.T) { - jsonString := `{ - "description": "Example description", - "greetings": "Example greetings", - "dueTo": 1734429225, - "activationCount": 100, - "bonus": { - "privilege": { - "privilegeID": "examplePrivilegeID", - "amount": 50 - }, - "discount": { - "layer": 1, - "factor": 0.2, - "target": "exampleTarget", - "threshold": 500 - } - }, - "outdated": false, - "offLimit": false, - "delete": false - }` - - var reqBody models.PromoCode - err := json.Unmarshal([]byte(jsonString), &reqBody) - assert.NoError(t, err) - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/create").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err = json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) -} - -// EditPromoCode -func TestEditPromoCode(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("EditPromoCode-success", func(t *testing.T) { - reqBody := models.ReqEditPromoCode{ - ID: promoID, - Description: toString("Updated description"), - Greetings: toString("Updated greetings"), - DueTo: toInt64(1734429225), - ActivationCount: toInt64(150), - Delete: toBool(false), - } - - reqJSON, _ := json.Marshal(reqBody) - req := client.Put(BaseUrl+"/promocode/edit").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusOK, statusCode) - - var response models.PromoCode - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response) - }) - - t.Run("EditPromoCode-success one column", func(t *testing.T) { - reqBody := models.ReqEditPromoCode{ - ID: promoID, - Greetings: toString("Updated greetings one"), - } - - reqJSON, _ := json.Marshal(reqBody) - req := client.Put(BaseUrl+"/promocode/edit").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusOK, statusCode) - - var response models.PromoCode - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response) - }) - - t.Run("EditPromoCode-promocod not found", func(t *testing.T) { - reqBody := models.ReqEditPromoCode{ - ID: primitive.NewObjectID().Hex(), - Description: toString("Updated description"), - Greetings: toString("Updated greetings"), - DueTo: toInt64(1734429225), - ActivationCount: toInt64(150), - Delete: toBool(false), - } - - reqJSON, _ := json.Marshal(reqBody) - req := client.Put(BaseUrl+"/promocode/edit").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusNotFound, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) - - t.Run("EditPromoCode-invalid request payload", func(t *testing.T) { - reqBody := map[string]interface{}{ - "invalid_field": "example", - "description": "Updated description", - "greetings": "Updated greetings", - "dueTo": 1734429225, - "activationCount": 150, - "delete": false, - } - - reqJSON, _ := json.Marshal(reqBody) - req := client.Put(BaseUrl+"/promocode/edit").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) -} - -func toString(s string) *string { - return &s -} - -func toInt64(i int64) *int64 { - return &i -} - -func toBool(b bool) *bool { - return &b -} - -// CreateFastLink -func TestCreateFastLink(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("CreateFastLink-success", func(t *testing.T) { - reqBody := struct { - PromoCodeID string `json:"id"` - }{ - PromoCodeID: promoID, - } - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/fastlink").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - fmt.Println(string(resBody)) - assert.Equal(t, fiber.StatusCreated, statusCode) - - var response map[string]string - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fastLink = response["fastlink"] - fmt.Println(response["fastlink"]) - }) - - t.Run("CreateFastLink-missing promoCodeID", func(t *testing.T) { - req := client.Post(BaseUrl+"/promocode/fastlink").Set("Content-Type", "application/json").Body([]byte(`{}`)) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) - - t.Run("CreateFastLink-promocode not found", func(t *testing.T) { - reqBody := map[string]string{"id": primitive.NewObjectID().Hex()} - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/fastlink").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusNotFound, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) -} - -// GetPromoCodesList -func TestGetPromoCodesList(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("GetPromoCodesList-success", func(t *testing.T) { - reqBody := models.GetPromoCodesListReq{ - Page: 0, - Limit: 10, - Filter: models.GetPromoCodesListReqFilter{ - Text: "example", - Active: true, - }, - } - - reqJSON, _ := json.Marshal(reqBody) - req := client.Post(BaseUrl+"/promocode/getList").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusOK, statusCode) - - var response models.GetPromoCodesListResp - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response) - }) - - t.Run("GetPromoCodesList-invalid request payload", func(t *testing.T) { - req := client.Post(BaseUrl+"/promocode/getList").Set("Content-Type", "application/json").Body([]byte("invalid json")) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) -} - -// ActivatePromoCode -func TestActivatePromoCode(t *testing.T) { - client := fiber.AcquireClient() - jwtUtil := helpers.InitializeJWT() - token, tokenErr := jwtUtil.Create(ExampleUserID) - fmt.Println(token) - if isNoError := assert.NoError(t, tokenErr); !isNoError { - return - } - t.Run("ActivatePromoCode-success codeword", func(t *testing.T) { - reqBody := models.ActivateReq{ - Codeword: "example", - } - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/activate").Set("Content-Type", "application/json").Set("Authorization", "Bearer "+token).Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - fmt.Println(string(resBody)) - - assert.Equal(t, fiber.StatusOK, statusCode) - fmt.Println(statusCode) - var response models.ActivateResp - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response) - }) - - t.Run("ActivatePromoCode-success fastLink", func(t *testing.T) { - reqBody := models.ActivateReq{ - FastLink: fastLink, - } - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/activate").Set("Content-Type", "application/json").Set("Authorization", "Bearer "+token).Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusOK, statusCode) - var response models.ActivateResp - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response) - }) - - t.Run("ActivatePromoCode-missing userid", func(t *testing.T) { - reqBody := models.ActivateReq{ - Codeword: "example", - } - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/activate").Set("Content-Type", "application/json").Set("Authorization", "Bearer "+token).Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) - - t.Run("ActivatePromoCode-missing codeword and fastlink", func(t *testing.T) { - - req := client.Post(BaseUrl+"/promocode/activate").Set("Content-Type", "application/json").Set("Authorization", "Bearer "+token).Body(nil) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusBadRequest, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) - - t.Run("ActivatePromoCode-promocode not found", func(t *testing.T) { - reqBody := models.ActivateReq{ - Codeword: "none", - } - - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/promocode/activate").Set("Content-Type", "application/json").Set("Authorization", "Bearer "+token).Body(reqJSON) - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusNotFound, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) -} - -// GetPromoStats -func TestGetPromoStats(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("GetAllStats", func(t *testing.T) { - - reqBody := struct { - PromoCodeID string `json:"id"` - }{ - PromoCodeID: promoID, - } - - reqJSON, _ := json.Marshal(reqBody) - req := client.Get(BaseUrl+"/promocode/stats").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusOK, statusCode) - - var response []models.PromoCodeStats - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response) - }) -} - -// DeletePromoCode -func TestDeletePromoCode(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("DeletePromoCode-success", func(t *testing.T) { - - req := client.Delete(BaseUrl + "/promocode/" + promoID) - - statusCode, _, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusOK, statusCode) - }) - - t.Run("DeletePromoCode-promocode not found", func(t *testing.T) { - - req := client.Delete(BaseUrl + "/promocode/" + primitive.NewObjectID().Hex()) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.Error(t, errs[0]) - } - - assert.Equal(t, fiber.StatusNotFound, statusCode) - - var response map[string]interface{} - err := json.Unmarshal(resBody, &response) - assert.NoError(t, err) - fmt.Println(response["error"]) - }) -} diff --git a/tests/e2e/recover_test.go b/tests/e2e/recover_test.go deleted file mode 100644 index 0aab88f..0000000 --- a/tests/e2e/recover_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package e2e - -import ( - "codeword/internal/models" - "encoding/json" - "fmt" - "github.com/gofiber/fiber/v2" - "github.com/stretchr/testify/assert" - "testing" - "time" -) - -// todo добавить другие константы такие как exampleUserID -const ( - BaseUrl = "http://localhost:8080" - ValidSign = "GSiyv5zBITGshqnvYLHKtXE3e4yZjKGvruOVFWuUuj9Nvaps28-Zt6RDq9n47eaNUlay1-nUVld61I3xoAAgCA==65b286c2f13095d96792079d" - ExampleUserID = "6597babdd1ba7e2dbd32d7e3" -) - -// post handler -func TestRecoveryHandler(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("HandleRecoveryRequest", func(t *testing.T) { - reqBody := models.RecoveryRequest{ - Email: "adminSOLO", - RedirectionURL: "http://redirect.com", - } - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/recover").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, resBody, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusOK, statusCode) - - var responseMap map[string]interface{} - err := json.Unmarshal(resBody, &responseMap) - assert.NoError(t, err) - fmt.Println(responseMap) - }) - - t.Run("HandleRecoveryRequest-AlreadyReported", func(t *testing.T) { - reqBody := models.RecoveryRequest{ - Email: "adminSOLO", - RedirectionURL: "http://redirect.com", - } - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/recover").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, _, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusAlreadyReported, statusCode) - }) - - t.Run("HandleRecoveryRequest_MissingEmail", func(t *testing.T) { - reqBody := models.RecoveryRequest{ - RedirectionURL: "http://redirect.com", - } - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/recover").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, _, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusBadRequest, statusCode) - }) - - t.Run("HandleRecoveryRequest_UserNotFound", func(t *testing.T) { - reqBody := models.RecoveryRequest{ - Email: "nonexistent@example.com", - RedirectionURL: "http://redirect.com", - } - reqJSON, _ := json.Marshal(reqBody) - - req := client.Post(BaseUrl+"/recover").Set("Content-Type", "application/json").Body(reqJSON) - - statusCode, _, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusNotFound, statusCode) - }) -} - -// get handler -func TestRecoveryLinkHandler(t *testing.T) { - client := fiber.AcquireClient() - - t.Run("HandleRecoveryLink_ValidSign", func(t *testing.T) { - req := client.Get(BaseUrl + "/recover/" + ValidSign) - statusCode, _, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - - assert.Equal(t, fiber.StatusOK, statusCode) - - fmt.Println("Recovery link handled successfully") - }) - time.Sleep(15 * time.Minute) - t.Run("HandleRecoveryLink_ExpiredSign", func(t *testing.T) { - req := client.Get(BaseUrl + "/recover/" + ValidSign) - statusCode, _, errs := req.Bytes() - if len(errs) != 0 { - assert.NoError(t, errs[0]) - } - assert.Equal(t, fiber.StatusNotAcceptable, statusCode) - fmt.Println("Recovery link with expired sign handled correctly") - }) -} diff --git a/tests/helpers/jwt.go b/tests/helpers/jwt.go deleted file mode 100644 index a0134ab..0000000 --- a/tests/helpers/jwt.go +++ /dev/null @@ -1,38 +0,0 @@ -package helpers - -import ( - "codeword/internal/initialize" - "codeword/utils" - "strings" -) - -func InitializeJWT() *utils.JWT { - publicKey := strings.Replace(`-----BEGIN PUBLIC KEY----- - MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69 - 80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B - dA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y - +3GyaOY536H47qyXAgMBAAE= - -----END PUBLIC KEY-----`, "\t", "", -1) - - privateKey := strings.Replace(`-----BEGIN RSA PRIVATE KEY----- - MIICWwIBAAKBgHgnvr7O2tiApjJfid1orFnIGm6980fZp+Lpbjo+NC/0whMFga2B - iw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6BdA4TS2kB9Kf0wn0+7wSlyikH - oKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y+3GyaOY536H47qyXAgMBAAEC - gYAOphnVPXbk6lpYzdkLC1Xn5EOEuNfOLLURLxBnPWozZo26r/Mtahu/9mYhrYlv - PP8r6mxta3VIil8iOdZyOLa/4d1LPd+UehgEXIJEiYXLtn7RS5eUnoPuQxssfs1k - OWjdN8p6SzppleegFTvGRX4KM3cDLfSphOk8JuBCrpSSYQJBAOdqizTSrdKMTuVe - c7Jk1JOJkyFuFs+N5zeryyeFGH7IpRdWy0rkWMxIUAi8Ap1vYVBPHv4tDOo3sy5X - VLc/knkCQQCE62pg+0TmsrhO/2Pgog6MLBkzlzXYMRp/01HbmznwYF+ejfPnzLkz - hnUlxRUNK3lhXM/7H6oAjvqF2R72u/OPAkEAterkmdbQfEZ+MwNoEiH/lie9OLdx - SSI1VGdBYcTYN7qFRW6eizYstBJYkDU0HQ0Uw+we4hMKJwk4W0KdvxxDiQJAeqlB - V1QqBneBbK10PzVuFV8QtrJhJyxRVwrtbKq38iMNuqUnI4+ijXEUpJFWVvv6nKXo - 7McQvEk12dU/JNTX8wJAOlAtSNjp9tVwpMpC0w2St1eKc1L2SknjeohA5ldoBz8sGeZsPhTU3eHSD1neAZXLKN5K68z3zFBr20ubY9nyLw== - -----END RSA PRIVATE KEY-----`, "\t", "", -1) - - return utils.NewJWT(&initialize.Config{ - PrivateKey: privateKey, - PublicKey: publicKey, - Audience: "pena", - Issuer: "pena-auth-service", - }) -} diff --git a/tests/repository_test/repository_test.go b/tests/repository_test/repository_test.go deleted file mode 100644 index 724a137..0000000 --- a/tests/repository_test/repository_test.go +++ /dev/null @@ -1,518 +0,0 @@ -package repository_test - -import ( - "codeword/internal/models" - "codeword/internal/repository" - "context" - "fmt" - "github.com/stretchr/testify/require" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "log" - "strconv" - "testing" - "time" - - "github.com/pioz/faker" - "github.com/stretchr/testify/assert" -) - -const mongoURI = "mongodb://test:test@127.0.0.1:27020/?authMechanism=SCRAM-SHA-256&authSource=admin&directConnection=true" - -// codeword unit tests -func TestFindByEmail(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - client, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - if err != nil { - log.Fatalf("Failed to connect to MongoDB: %v", err) - } - - defer func() { - if err := client.Disconnect(ctx); err != nil { - log.Fatalf("Failed to disconnect MongoDB client: %v", err) - } - }() - - if err := client.Ping(ctx, nil); err != nil { - log.Fatalf("Failed to ping MongoDB: %v", err) - } - - db := client.Database("admin") - - userRepo := repository.NewUserRepository(repository.Deps{Rdb: nil, Mdb: db.Collection("users")}) - - t.Run("FindByEmail - existing user", func(t *testing.T) { - user, err := userRepo.FindByEmail(ctx, "admin") - assert.NoError(t, err) - assert.NotNil(t, user) - fmt.Println(user.Email) - assert.Equal(t, "admin", user.Login) - }) - - t.Run("FindByEmail - non-existing user", func(t *testing.T) { - user, err := userRepo.FindByEmail(ctx, "neadmin") - assert.NoError(t, err) - assert.Nil(t, user) - }) - -} - -func TestStoreRecoveryRecord(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - codeword := database.Collection("codeword") - _ = codeword.Drop(ctx) - - userRepo := repository.NewCodewordRepository(repository.Deps{Rdb: nil, Mdb: codeword}) - - for i := 0; i < 10; i++ { - userID := faker.String() - email := faker.Email() - key := "test_recovery_key" - - id, err := userRepo.StoreRecoveryRecord(ctx, models.StoreRecDeps{UserID: userID, Email: email, Key: key, Url: "def.url"}) - assert.NoError(t, err) - fmt.Println(id) - - var storedRecord models.RestoreRequest - err = codeword.FindOne(ctx, bson.M{"user_id": userID}).Decode(&storedRecord) - assert.NoError(t, err) - assert.Equal(t, email, storedRecord.Email) - assert.Equal(t, key, storedRecord.Sign) - } - - _ = database.Drop(ctx) -} - -func TestGetRecoveryRecord(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - codeword := database.Collection("codeword") - _ = codeword.Drop(ctx) - - userRepo := repository.NewCodewordRepository(repository.Deps{Rdb: nil, Mdb: codeword}) - - ID := primitive.NewObjectID() - userID := "6597babdd1ba7e2dbd32d7e3" - email := "test@mail.ru" - key := "test_recovery_key" - - record := models.RestoreRequest{ - ID: ID, - UserID: userID, - Email: email, - Sign: key, - SignUrl: "def.url", - SignID: key + userID, - CreatedAt: time.Now(), - } - - _, err = codeword.InsertOne(ctx, record) - assert.NoError(t, err) - - result, err := userRepo.GetRecoveryRecord(ctx, key+userID) - assert.NoError(t, err) - assert.Equal(t, userID, result.UserID) - assert.Equal(t, email, result.Email) - assert.Equal(t, key, result.Sign) - - _ = database.Drop(ctx) -} - -// promoCode unit tests - -func TestInitPromoCodeIndexes(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) -} - -func TestCreatePromoCode(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - _ = promoCode.Drop(ctx) - - userRepo := repository.NewPromoCodeRepository(promoCode) - - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) - - t.Run("CreatePromoCode - success", func(t *testing.T) { - req := &models.PromoCode{ - Codeword: "test_codeword", - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - } - createdPromoCode, err := userRepo.CreatePromoCode(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, createdPromoCode) - assert.Equal(t, "test_codeword", createdPromoCode.Codeword) - }) - - t.Run("CreatePromoCode - duplicate codeword", func(t *testing.T) { - req := &models.PromoCode{ - Codeword: "test_codeword", - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - } - _, err := userRepo.CreatePromoCode(ctx, req) - assert.Error(t, err) - }) -} - -func TestEditPromoCode(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - _ = promoCode.Drop(ctx) - - userRepo := repository.NewPromoCodeRepository(promoCode) - - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) - - req := &models.PromoCode{ - Codeword: "test_codeword", - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - } - createdPromoCode, err := userRepo.CreatePromoCode(ctx, req) - require.NoError(t, err) - - newDescription := "New Description" - - t.Run("EditPromoCode - success", func(t *testing.T) { - editReq := &models.ReqEditPromoCode{ - ID: createdPromoCode.ID.Hex(), - Description: &newDescription, - } - editedPromoCode, err := userRepo.EditPromoCode(ctx, editReq) - assert.NoError(t, err) - assert.NotNil(t, editedPromoCode) - assert.Equal(t, "New Description", editedPromoCode.Description) - }) - - t.Run("EditPromoCode - promo code not found", func(t *testing.T) { - nonExistingID := primitive.NewObjectID().Hex() - editReq := &models.ReqEditPromoCode{ - ID: nonExistingID, - } - _, err := userRepo.EditPromoCode(ctx, editReq) - assert.Error(t, err) - }) -} - -func TestGetPromoCodeByID(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - _ = promoCode.Drop(ctx) - - userRepo := repository.NewPromoCodeRepository(promoCode) - - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) - - req := &models.PromoCode{ - Codeword: "test_codeword", - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - } - createdPromoCode, err := userRepo.CreatePromoCode(ctx, req) - require.NoError(t, err) - - t.Run("GetPromoCodeByID - success", func(t *testing.T) { - result, err := userRepo.GetPromoCodeByID(ctx, createdPromoCode.ID) - assert.NoError(t, err) - assert.NotNil(t, result) - assert.Equal(t, createdPromoCode.Codeword, result.Codeword) - }) - - t.Run("GetPromoCodeByID - promo code not found", func(t *testing.T) { - nonExistingID := primitive.NewObjectID() - _, err := userRepo.GetPromoCodeByID(ctx, nonExistingID) - assert.Error(t, err) - }) -} - -func TestGetPromoCodesList(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - _ = promoCode.Drop(ctx) - - userRepo := repository.NewPromoCodeRepository(promoCode) - - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) - for i := 0; i < 1111; i++ { - - req := &models.PromoCode{ - Codeword: "test" + faker.String() + strconv.Itoa(i), - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - Delete: faker.Bool(), - Outdated: faker.Bool(), - OffLimit: faker.Bool(), - } - createdPromoCode, err := userRepo.CreatePromoCode(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, createdPromoCode) - } - t.Run("GetPromoCodesList - true", func(t *testing.T) { - filter := models.GetPromoCodesListReqFilter{ - Text: "test", - Active: true, - } - req := &models.GetPromoCodesListReq{ - Page: 0, - Limit: 10, - Filter: filter, - } - promoCodes, count, err := userRepo.GetPromoCodesList(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, promoCodes) - assert.True(t, count >= 0) - }) - - t.Run("GetPromoCodesList - false", func(t *testing.T) { - filter := models.GetPromoCodesListReqFilter{ - Text: "test", - Active: false, - } - req := &models.GetPromoCodesListReq{ - Page: 0, - Limit: 10, - Filter: filter, - } - promoCodes, count, err := userRepo.GetPromoCodesList(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, promoCodes) - assert.True(t, count >= 0) - }) -} - -func TestActivatePromo(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - _ = promoCode.Drop(ctx) - - userRepo := repository.NewPromoCodeRepository(promoCode) - - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) - - req := &models.PromoCode{ - Codeword: "test_codeword", - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - } - createdPromoCode, err := userRepo.CreatePromoCode(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, createdPromoCode) - - xid := "test_xid" - err = userRepo.AddFastLink(ctx, createdPromoCode.ID, xid) - assert.NoError(t, err) - - t.Run("ActivatePromo Codeword - success", func(t *testing.T) { - req := &models.ActivateReq{ - UserID: "6597babdd1ba7e2dbd32d7e3", - Codeword: "test_codeword", - } - activatedPromoCode, err := userRepo.ActivatePromo(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, activatedPromoCode) - }) - - t.Run("ActivatePromo FastLink - success", func(t *testing.T) { - req := &models.ActivateReq{ - UserID: "6597babdd1ba7e2dbd32d7e3", - FastLink: "test_xid", - } - activatedPromoCode, err := userRepo.ActivatePromo(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, activatedPromoCode) - }) - - t.Run("ActivatePromo - promo code not found", func(t *testing.T) { - req := &models.ActivateReq{ - UserID: "6597babdd1ba7e2dbd32d7e3", - Codeword: "non_existing_codeword", - } - _, err := userRepo.ActivatePromo(ctx, req) - assert.Error(t, err) - }) -} - -func TestDeletePromoCode(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - _ = promoCode.Drop(ctx) - - userRepo := repository.NewPromoCodeRepository(promoCode) - - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) - - req := &models.PromoCode{ - Codeword: "test_codeword", - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - } - createdPromoCode, err := userRepo.CreatePromoCode(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, createdPromoCode) - - t.Run("DeletePromoCode - success", func(t *testing.T) { - err := userRepo.DeletePromoCode(ctx, createdPromoCode.ID.Hex()) - assert.NoError(t, err) - }) - - t.Run("DeletePromoCode - promo code not found", func(t *testing.T) { - nonExistingID := primitive.NewObjectID().Hex() - err := userRepo.DeletePromoCode(ctx, nonExistingID) - assert.Error(t, err) - }) -} - -func TestAddFastLink(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - mongoClient, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - require.NoError(t, err) - defer func() { - _ = mongoClient.Disconnect(ctx) - }() - - database := mongoClient.Database("admin") - promoCode := database.Collection("promoCode") - _ = promoCode.Drop(ctx) - - userRepo := repository.NewPromoCodeRepository(promoCode) - - err = repository.InitPromoCodeIndexes(ctx, promoCode) - assert.NoError(t, err) - - req := &models.PromoCode{ - Codeword: "test_codeword", - Description: faker.String(), - Greetings: faker.String(), - DueTo: 1737280065, - ActivationCount: 100, - } - createdPromoCode, err := userRepo.CreatePromoCode(ctx, req) - assert.NoError(t, err) - assert.NotNil(t, createdPromoCode) - - t.Run("AddFastLink - success", func(t *testing.T) { - xid := "test_xid" - err := userRepo.AddFastLink(ctx, createdPromoCode.ID, xid) - assert.NoError(t, err) - }) - - t.Run("AddFastLink - promo code not found", func(t *testing.T) { - nonExistingID := primitive.NewObjectID() - xid := "test_xid" - err := userRepo.AddFastLink(ctx, nonExistingID, xid) - assert.Error(t, err) - }) -} diff --git a/utils/authenticator.go b/utils/authenticator.go deleted file mode 100644 index 193fcd4..0000000 --- a/utils/authenticator.go +++ /dev/null @@ -1,46 +0,0 @@ -package utils - -import ( - "codeword/internal/models" - "fmt" - "strings" - - "github.com/gofiber/fiber/v2" -) - -const ( - prefix = "Bearer " -) - -func NewAuthenticator(jwtUtil *JWT) func(*fiber.Ctx) error { - return func(c *fiber.Ctx) error { - if jwtUtil == nil { - return fmt.Errorf("jwt util is nil") - } - - if err := authenticate(c, jwtUtil); err != nil { - return fmt.Errorf("authentication error:%d", err) - } - - return nil - } -} - -func authenticate(c *fiber.Ctx, jwtUtil *JWT) error { - authHeader := c.Get("Authorization") - if authHeader == "" || !strings.HasPrefix(authHeader, prefix) { - return fmt.Errorf("failed to parse jws from request header: %s", authHeader) - } - - jws := strings.TrimPrefix(authHeader, prefix) - - userID, validateErr := jwtUtil.Validate(jws) - if validateErr != nil { - return validateErr - } - - c.Locals(models.AuthJWTDecodedUserIDKey, userID) - c.Locals(models.AuthJWTDecodedAccessTokenKey, jws) - - return nil -} diff --git a/utils/jwt.go b/utils/jwt.go deleted file mode 100644 index 4584dee..0000000 --- a/utils/jwt.go +++ /dev/null @@ -1,89 +0,0 @@ -package utils - -import ( - "codeword/internal/initialize" - "errors" - "fmt" - "github.com/golang-jwt/jwt/v5" - "time" -) - -type JWT struct { - privateKey []byte - publicKey []byte - algorithm *jwt.SigningMethodRSA - expiresIn time.Duration - issuer string - audience string -} - -func NewJWT(configuration *initialize.Config) *JWT { - return &JWT{ - privateKey: []byte(configuration.PrivateKey), - publicKey: []byte(configuration.PublicKey), - issuer: configuration.Issuer, - audience: configuration.Audience, - algorithm: jwt.SigningMethodRS256, - expiresIn: 15 * time.Minute, - } -} - -func (j *JWT) Create(id string) (string, error) { - privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(j.privateKey) - if err != nil { - return "", fmt.Errorf("failed to parse private key on of : %w", err) - } - - now := time.Now().UTC() - - claims := jwt.MapClaims{ - "id": id, - "exp": now.Add(j.expiresIn).Unix(), - "aud": j.audience, - "iss": j.issuer, - } - - token, err := jwt.NewWithClaims(j.algorithm, claims).SignedString(privateKey) - if err != nil { - return "", fmt.Errorf("failed to sing on of : %w", err) - } - - return token, nil -} - -func (j *JWT) Validate(tokenString string) (string, error) { - key, err := jwt.ParseRSAPublicKeyFromPEM(j.publicKey) - if err != nil { - return "", fmt.Errorf("failed to parse rsa public key on of : %w", err) - } - - parseCallback := func(token *jwt.Token) (any, error) { - if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { - return nil, fmt.Errorf("unexpected signing method: %s", token.Header["alg"]) - } - - return key, nil - } - - token, err := jwt.Parse( - tokenString, - parseCallback, - jwt.WithAudience(j.audience), - jwt.WithIssuer(j.issuer), - ) - if err != nil { - return "", fmt.Errorf("failed to parse jwt token on of : %w", err) - } - - claims, ok := token.Claims.(jwt.MapClaims) - if !ok || !token.Valid { - return "", errors.New("token is invalid on of ") - } - - data, ok := claims["id"].(string) - if !ok { - return "", errors.New("data is empty or not a string on of ") - } - - return data, nil -}