package mongo import ( "context" "time" "github.com/tech/sendico/gateway/chain/storage" "github.com/tech/sendico/gateway/chain/storage/mongo/store" "github.com/tech/sendico/pkg/db" "github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/mlogger" "go.mongodb.org/mongo-driver/mongo" "go.uber.org/zap" ) // Store implements storage.Repository backed by MongoDB. type Store struct { logger mlogger.Logger conn *db.MongoConnection db *mongo.Database wallets storage.WalletsStore transfers storage.TransfersStore deposits storage.DepositsStore } // New creates a new Mongo-backed repository. func New(logger mlogger.Logger, conn *db.MongoConnection) (*Store, error) { if conn == nil { return nil, merrors.InvalidArgument("mongo connection is nil") } client := conn.Client() if client == nil { return nil, merrors.Internal("mongo client is not initialised") } result := &Store{ logger: logger.Named("storage").Named("mongo"), conn: conn, db: conn.Database(), } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := result.Ping(ctx); err != nil { result.logger.Error("Mongo ping failed during repository initialisation", zap.Error(err)) return nil, err } walletsStore, err := store.NewWallets(result.logger, result.db) if err != nil { result.logger.Error("Failed to initialise wallets store", zap.Error(err)) return nil, err } transfersStore, err := store.NewTransfers(result.logger, result.db) if err != nil { result.logger.Error("Failed to initialise transfers store", zap.Error(err)) return nil, err } depositsStore, err := store.NewDeposits(result.logger, result.db) if err != nil { result.logger.Error("Failed to initialise deposits store", zap.Error(err)) return nil, err } result.wallets = walletsStore result.transfers = transfersStore result.deposits = depositsStore result.logger.Info("Chain gateway MongoDB storage initialised") return result, nil } // Ping verifies the MongoDB connection. func (s *Store) Ping(ctx context.Context) error { if s.conn == nil { return merrors.InvalidArgument("mongo connection is nil") } return s.conn.Ping(ctx) } // Wallets returns the wallets store. func (s *Store) Wallets() storage.WalletsStore { return s.wallets } // Transfers returns the transfers store. func (s *Store) Transfers() storage.TransfersStore { return s.transfers } // Deposits returns the deposits store. func (s *Store) Deposits() storage.DepositsStore { return s.deposits } var _ storage.Repository = (*Store)(nil)