Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Rajiv Geraev committed May 29, 2024
1 parent 304e709 commit fd7f011
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 0 deletions.
32 changes: 32 additions & 0 deletions config/database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package config

import (
"context"
"log"
"time"

"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

var (
MongoDB *mongo.Database
)

func ConnectDB() {
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal(err)
}

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

err = client.Connect(ctx)
if err != nil {
log.Fatal(err)
}

MongoDB = client.Database("testdb")
log.Println("Connected to MongoDB!")
}
32 changes: 32 additions & 0 deletions controllers/invitation_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package controllers

import (
"encoding/json"
"net/http"

"github.com/gorilla/mux"
"github.com/rajivgeraev/services"
)

type InvitationRequest struct {
Email string `json:"email" binding:"required,email"`
}

func RegisterInvitation(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
code := vars["code"]

var req InvitationRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

err := services.RegisterUser(code, req.Email)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

w.WriteHeader(http.StatusOK)
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module invitations

go 1.21.0

require (
github.com/gorilla/mux v1.8.1
github.com/joho/godotenv v1.5.1
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
26 changes: 26 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"log"
"net/http"

"github.com/gorilla/mux"
"github.com/joho/godotenv"

"github.com/rajivgeraev/routes"
)

func main() {
// Загрузка переменных окружения из файла .env
if err := godotenv.Load(); err != nil {
log.Fatal("Error loading .env file")
}

router := mux.NewRouter()

// Инициализация маршрутов
routes.InitializeRoutes(router)

// Запуск сервера
log.Fatal(http.ListenAndServe(":8080", router))
}
11 changes: 11 additions & 0 deletions models/invitation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package models

import "go.mongodb.org/mongo-driver/bson/primitive"

type Invitation struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
Code string `bson:"code"`
MaxUses int `bson:"max_uses"`
UsedCount int `bson:"used_count"`
Emails []string `bson:"emails"`
}
10 changes: 10 additions & 0 deletions routes/routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package routes

import (
"github.com/gorilla/mux"
"github.com/rajivgeraev/controllers"
)

func InitializeRoutes(router *mux.Router) {
router.HandleFunc("/api/v1/invitations/{code}", controllers.RegisterInvitation).Methods("POST")
}
43 changes: 43 additions & 0 deletions services/services.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package services

import (
"context"
"errors"
"time"

"github.com/rajivgeraev/config"
"github.com/rajivgeraev/models"

"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

func RegisterUser(code, email string) error {
collection := config.MongoDB.Collection("invitations")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

filter := bson.M{"code": code}
update := bson.M{
"$addToSet": bson.M{"emails": email},
"$inc": bson.M{"used_count": 1},
}

opts := options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(false)
var updatedInvitation models.Invitation

err := collection.FindOneAndUpdate(ctx, filter, update, opts).Decode(&updatedInvitation)
if err != nil {
if err == mongo.ErrNoDocuments {
return errors.New("invitation code not found")
}
return err
}

if updatedInvitation.UsedCount > updatedInvitation.MaxUses {
return errors.New("invitation code has been used maximum times")
}

return nil
}

0 comments on commit fd7f011

Please sign in to comment.