package user import ( "context" "time" "wish-list-api/api/presenter" "wish-list-api/pkg/entities" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" ) type Repository interface { CreateUser(user *entities.User) (*entities.User, error) ReadUser(ID string) (*entities.User, error) ReadUserByEmail(email string) (*entities.User, error) ReadAllUsers() (*[]presenter.User, error) UpdateUser(user *entities.User) (*entities.User, error) DeleteUser(ID string) error ReadUserByTelegramID(telegramID int64) (*entities.User, error) UpdateUserTelegramData(user *entities.User) (*entities.User, error) } type repository struct { Collection *mongo.Collection } func NewRepo(collection *mongo.Collection) Repository { return &repository{ Collection: collection, } } func NewMongoRepository(collection *mongo.Collection) Repository { return NewRepo(collection) } func (r *repository) CreateUser(user *entities.User) (*entities.User, error) { user.ID = primitive.NewObjectID() user.CreatedAt = time.Now() user.UpdatedAt = time.Now() _, err := r.Collection.InsertOne(context.Background(), user) if err != nil { return nil, err } return user, nil } func (r *repository) ReadUser(ID string) (*entities.User, error) { var user entities.User objectID, err := primitive.ObjectIDFromHex(ID) if err != nil { return nil, err } err = r.Collection.FindOne(context.Background(), bson.M{"_id": objectID}).Decode(&user) if err != nil { return nil, err } return &user, nil } func (r *repository) ReadUserByEmail(email string) (*entities.User, error) { var user entities.User err := r.Collection.FindOne(context.Background(), bson.M{"email": email}).Decode(&user) if err != nil { return nil, err } return &user, nil } func (r *repository) ReadAllUsers() (*[]presenter.User, error) { var users []presenter.User cursor, err := r.Collection.Find(context.Background(), bson.M{}) if err != nil { return nil, err } for cursor.Next(context.TODO()) { var user presenter.User _ = cursor.Decode(&user) users = append(users, user) } return &users, nil } func (r *repository) UpdateUser(user *entities.User) (*entities.User, error) { user.UpdatedAt = time.Now() _, err := r.Collection.UpdateOne( context.Background(), bson.M{"_id": user.ID}, bson.M{"$set": user}, ) if err != nil { return nil, err } return user, nil } func (r *repository) DeleteUser(ID string) error { objectID, err := primitive.ObjectIDFromHex(ID) if err != nil { return err } _, err = r.Collection.DeleteOne(context.Background(), bson.M{"_id": objectID}) if err != nil { return err } return nil } func (r *repository) ReadUserByTelegramID(telegramID int64) (*entities.User, error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() var user entities.User filter := bson.M{"telegram_id": telegramID} err := r.Collection.FindOne(ctx, filter).Decode(&user) if err != nil { if err == mongo.ErrNoDocuments { return nil, nil } return nil, err } return &user, nil } func (r *repository) UpdateUserTelegramData(user *entities.User) (*entities.User, error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() user.UpdatedAt = time.Now() user.LastLoginDate = time.Now() filter := bson.M{"_id": user.ID} update := bson.M{"$set": bson.M{ "telegram_id": user.TelegramID, "telegram_username": user.TelegramUsername, "first_name": user.FirstName, "last_name": user.LastName, "photo_url": user.PhotoURL, "last_login_date": user.LastLoginDate, "updated_at": user.UpdatedAt, }} _, err := r.Collection.UpdateOne(ctx, filter, update) if err != nil { return nil, err } return user, nil }