package mongo import ( "context" "time" "github.com/tech/sendico/payments/storage/model" quotestorage "github.com/tech/sendico/payments/storage/quote" "github.com/tech/sendico/payments/storage/quote/mongo/store" "github.com/tech/sendico/pkg/db" "github.com/tech/sendico/pkg/db/repository" "github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/mlogger" ) // Store implements quotestorage.Repository backed by MongoDB. type Store struct { logger mlogger.Logger ping func(context.Context) error quotes quotestorage.QuotesStore } type options struct { quoteRetention time.Duration } // Option configures the Mongo-backed quotes repository. type Option func(*options) // WithQuoteRetention sets how long quote records are retained after expiry. func WithQuoteRetention(retention time.Duration) Option { return func(opts *options) { opts.quoteRetention = retention } } // New constructs a Mongo-backed quotes repository from a Mongo connection. func New(logger mlogger.Logger, conn *db.MongoConnection, opts ...Option) (*Store, error) { if conn == nil { return nil, merrors.InvalidArgument("payments.quote.storage.mongo: connection is nil") } quotesRepo := repository.CreateMongoRepository(conn.Database(), (&model.PaymentQuoteRecord{}).Collection()) return NewWithRepository(logger, conn.Ping, quotesRepo, opts...) } // NewWithRepository constructs a quotes repository using the provided primitives. func NewWithRepository(logger mlogger.Logger, ping func(context.Context) error, quotesRepo repository.Repository, opts ...Option) (*Store, error) { if ping == nil { return nil, merrors.InvalidArgument("payments.quote.storage.mongo: ping func is nil") } if quotesRepo == nil { return nil, merrors.InvalidArgument("payments.quote.storage.mongo: quotes repository is nil") } cfg := options{} for _, opt := range opts { if opt != nil { opt(&cfg) } } childLogger := logger.Named("quote_storage").Named("mongo") quotesStore, err := store.NewQuotes(childLogger, quotesRepo, cfg.quoteRetention) if err != nil { return nil, err } result := &Store{ logger: childLogger, ping: ping, quotes: quotesStore, } return result, nil } // Ping verifies connectivity with the backing database. func (s *Store) Ping(ctx context.Context) error { if s.ping == nil { return merrors.InvalidArgument("payments.quote.storage.mongo: ping func is nil") } return s.ping(ctx) } // Quotes returns the quotes store. func (s *Store) Quotes() quotestorage.QuotesStore { return s.quotes } var _ quotestorage.Repository = (*Store)(nil)