This commit is contained in:
Pavel 2024-01-15 16:32:46 +03:00
parent e5c3b3786d
commit 33d0c25397
6 changed files with 98 additions and 29 deletions

@ -28,9 +28,11 @@ paths:
requestBody:
required: true
content:
application/x-www-form-urlencoded:
application/json:
schema:
type: object
required:
- email
properties:
email:
type: string
@ -257,6 +259,60 @@ paths:
error:
type: string
/promocode/fastlink:
post:
summary: Создать быструю ссылку для промокода
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: string
description: ID промокода, для которого нужно создать быструю ссылку
responses:
'201':
description: Быстрая ссылка для промокода успешно создана
content:
application/json:
schema:
type: object
properties:
fastlink:
type: string
description: Быстрая ссылка для активации промокода
'400':
description: Неверный запрос, отсутствует идентификатор промокода
content:
application/json:
schema:
type: object
properties:
error:
type: string
'404':
description: Промокод не найден
content:
application/json:
schema:
type: object
properties:
error:
type: string
'500':
description: Внутренняя ошибка сервера
content:
application/json:
schema:
type: object
properties:
error:
type: string
components:
schemas:
@ -436,12 +492,13 @@ components:
ActivateReq:
type: object
required:
- codeword
properties:
codeword:
type: string
description: Кодовое слово промокода, которое требуется активировать
fastLink:
type: string
description: Быстрая ссылка для активации промокода
ActivateResp:
type: object

@ -26,6 +26,12 @@ func Run(ctx context.Context, cfg initialize.Config, logger *zap.Logger) error {
cancel()
}
if err = initialize.InitDatabaseIndexes(ctx, mdb, logger); err != nil {
logger.Error("Failed to initialize db indexes", zap.Error(err))
cancel()
return err
}
rdb, err := initialize.Redis(ctx, cfg)
encrypt := initialize.Encrypt(cfg)

@ -135,9 +135,8 @@ func (p *PromoCodeController) Delete(c *fiber.Ctx) error {
// todo затестить и добавить в opnapi
func (p *PromoCodeController) CreateFastLink(c *fiber.Ctx) error {
// нужно что-то получать из Localstorage например id или codeword
var req struct {
PromoCodeID string `json:"promoCodeID"`
PromoCodeID string `json:"id"`
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"})

@ -2,10 +2,8 @@ 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"
@ -57,14 +55,10 @@ func (r *RecoveryController) HandleRecoveryRequest(c *fiber.Ctx) error {
}
user, err := r.service.FindUserByEmail(c.Context(), req.Email)
if err != nil {
if err != nil || user == nil {
r.logger.Error("Failed to find user by email", zap.Error(err))
if errors.Is(err, repository.ErrPromoUserNotFound) {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
}
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
}
key, err := r.service.GenerateKey()
@ -96,20 +90,16 @@ func (r *RecoveryController) HandleRecoveryRequest(c *fiber.Ctx) error {
}
func (r *RecoveryController) HandleRecoveryLink(c *fiber.Ctx) error {
var req models.RecoveryLinkRequest
if err := c.BodyParser(&req); err != nil {
r.logger.Error("Failed to parse recovery link request", zap.Error(err))
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Bad Request"})
}
sign := c.Params("sign")
record, err := r.service.GetRecoveryRecord(c.Context(), req.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", req.Sign))
r.logger.Error("Recovery link expired", zap.String("signature", sign))
return c.Status(fiber.StatusNotAcceptable).JSON(fiber.Map{"error": "Recovery link expired"})
}

@ -1,9 +1,11 @@
package initialize
import (
"codeword/internal/repository"
mdb "codeword/pkg/mongo"
"context"
"go.mongodb.org/mongo-driver/mongo"
"go.uber.org/zap"
"time"
)
@ -17,7 +19,7 @@ func MongoDB(ctx context.Context, cfg Config) (*mongo.Database, error) {
MongoAuth: cfg.MongoAuth,
}
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
newCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
mongoDeps := &mdb.ConnectDeps{
@ -25,15 +27,24 @@ func MongoDB(ctx context.Context, cfg Config) (*mongo.Database, error) {
Timeout: 10 * time.Second,
}
db, err := mdb.Connect(ctx, mongoDeps)
db, err := mdb.Connect(newCtx, mongoDeps)
if err != nil {
return nil, err
}
err = db.Client().Ping(ctx, nil)
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
}

@ -27,7 +27,10 @@ type PromoCodeRepository struct {
}
func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository {
// todo заменить паники вроде как в роде не круто их юзать
return &PromoCodeRepository{mdb: mdb}
}
func InitPromoCodeIndexes(ctx context.Context, mdb *mongo.Collection) error {
uniqueIndexModel := mongo.IndexModel{
Keys: bson.D{
{Key: "codeword", Value: 1},
@ -35,9 +38,9 @@ func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository {
},
Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.M{"delete": false}),
}
_, err := mdb.Indexes().CreateOne(context.Background(), uniqueIndexModel)
_, err := mdb.Indexes().CreateOne(ctx, uniqueIndexModel)
if err != nil {
panic(err)
return err
}
textIndexModel := mongo.IndexModel{
@ -48,17 +51,20 @@ func NewPromoCodeRepository(mdb *mongo.Collection) *PromoCodeRepository {
},
Options: options.Index().SetName("TextIndex"),
}
_, err = mdb.Indexes().CreateOne(context.Background(), textIndexModel)
_, err = mdb.Indexes().CreateOne(ctx, textIndexModel)
if err != nil {
panic(err)
return err
}
return &PromoCodeRepository{mdb: mdb}
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 {