package verification import ( verificationmodel "git.sendico.io/tech/sxchnge/product/verification/model" "strings" ri "git.sendico.io/tech/sxchnge/shared/database/repository/index" "git.sendico.io/tech/sxchnge/shared/database/template" "git.sendico.io/tech/sxchnge/shared/database/transaction" "git.sendico.io/tech/sxchnge/shared/logging" "git.sendico.io/tech/sxchnge/shared/ratelimit/store" "git.sendico.io/tech/sxchnge/shared/service" "go.mongodb.org/mongo-driver/v2/mongo" "go.uber.org/zap" ) type verificationDB struct { template.DBImp[*verificationmodel.VerificationToken] tf transaction.Factory limits ratelimits.Store } func (db *verificationDB) WithIssuanceLimits(limits ratelimits.Store) *verificationDB { db.limits = limits return db } const verificationContextIdempotencyIndexName = "uniq_verification_context_idempotency_v2" func Create( logger mlogger.Logger, db *mongo.Database, tf transaction.Factory, ) (*verificationDB, error) { return CreateWithCollection(logger, db, tf, "") } func CreateWithCollection( logger mlogger.Logger, db *mongo.Database, tf transaction.Factory, collection string, ) (*verificationDB, error) { if strings.TrimSpace(collection) == "" { collection = mservice.VerificationTokens } p := &verificationDB{ DBImp: *template.Create[*verificationmodel.VerificationToken](logger, mservice.Type(collection), db), tf: tf, } if err := p.Repository.CreateIndex(&ri.Definition{ Keys: []ri.Key{{Field: "verifyTokenHash", Sort: ri.Asc}}, Unique: true, Name: "unique_token_hash", }); err != nil { p.Logger.Error("Failed to create unique verifyTokenHash index", zap.Error(err)) return nil, err } if err := p.Repository.CreateIndex(&ri.Definition{ Keys: []ri.Key{ {Field: "accountRef", Sort: ri.Asc}, {Field: "purpose", Sort: ri.Asc}, {Field: "target", Sort: ri.Asc}, {Field: "contextRef", Sort: ri.Asc}, {Field: "idempotencyKey", Sort: ri.Asc}, }, Unique: true, Sparse: true, Name: verificationContextIdempotencyIndexName, }); err != nil { p.Logger.Error("Failed to create unique idempotency index on verification context", zap.Error(err)) return nil, err } ttl := int32(2678400) // 30 days if err := p.Repository.CreateIndex(&ri.Definition{ Keys: []ri.Key{{Field: "expiresAt", Sort: ri.Asc}}, TTL: &ttl, Name: "ttl_expires_at", }); err != nil { p.Logger.Error("Failed to create TTL index on expiresAt", zap.Error(err)) return nil, err } return p, nil }