Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add profile #17

Open
wants to merge 38 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
fa999ed
handlers_tests
Oct 17, 2024
76128d3
accessLogMiddleware
Oct 27, 2024
592e62c
add image upload
KranjQ Oct 29, 2024
a48e0d2
add profile repo and image
KranjQ Oct 31, 2024
cb2e784
like & match handlers
Oct 31, 2024
861005b
add profile endpoints and image endpoints
KranjQ Oct 31, 2024
d70be1e
add logger records
KranjQ Nov 2, 2024
2621128
like/dislike and match handler
Nov 3, 2024
5c63acc
add endpoint for get current profile
KranjQ Nov 3, 2024
f95dee6
Delete .idea/.gitignore
KranjQ Nov 3, 2024
5055012
Delete .idea/2024_2_SaraFun.iml
KranjQ Nov 3, 2024
23459b0
Delete .idea/modules.xml
KranjQ Nov 3, 2024
dbf4821
Delete .idea/vcs.xml
KranjQ Nov 3, 2024
73edac6
добавил миддлвару на корс
KranjQ Nov 3, 2024
1b03c2f
fix
KranjQ Nov 3, 2024
bc9b3f9
добавил логгер для корс миддлвары
KranjQ Nov 3, 2024
0e6347c
fix logger
KranjQ Nov 3, 2024
1596782
фикс
KranjQ Nov 3, 2024
d7b9a93
rename update profile
KranjQ Nov 3, 2024
1f4e3b7
add id in json response
KranjQ Nov 4, 2024
ddf17cb
change get profile endpoints json response
KranjQ Nov 4, 2024
ae33495
fix returns
KranjQ Nov 4, 2024
5026013
request-id
Nov 4, 2024
5f6ce58
Delete .idea/.gitignore
KranjQ Nov 4, 2024
36c281a
Delete .idea/2024_2_SaraFun.iml
KranjQ Nov 4, 2024
299033a
Delete .idea/modules.xml
KranjQ Nov 4, 2024
13ee1b2
Delete .idea/vcs.xml
KranjQ Nov 4, 2024
7f1c9f9
add tests for profile
KranjQ Nov 4, 2024
5f05f53
fix conflicts
KranjQ Nov 4, 2024
9ccbefe
fix conflicts
KranjQ Nov 4, 2024
108bd85
add reaction endpoints, usecase and repo
KranjQ Nov 4, 2024
7a8c935
fix registartion create session, add tests
KranjQ Nov 5, 2024
c68ace4
change getuserlist
KranjQ Nov 5, 2024
7980401
add tests
KranjQ Nov 5, 2024
7dd26a8
add request_id on all level
KranjQ Nov 5, 2024
e2bb070
add new handlers tests
Nov 5, 2024
ec2a838
new test handlers
Nov 6, 2024
1be02b3
Merge pull request #19 from go-park-mail-ru/handlerTestsNew
KranjQ Nov 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@ sparkit-run:
sparkit-down:
docker-compose -f $(DOCKER_DIR)/docker-compose.yml down

.PHONY: sparkit-test
sparkit-test:
go test -coverprofile=coverage.out -coverpkg=$(go list ./... | grep -v "/mocks" | paste -sd ',') ./...

.PHONY: sparkit-test-cover
sparkit-test-cover:
go tool cover -func=coverage.out

225 changes: 169 additions & 56 deletions cmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,34 @@ import (
"net/http"
"os"
"os/signal"
"sparkit/internal/handlers/addreaction"
"sparkit/internal/handlers/getmatches"
"sparkit/internal/handlers/middleware"
"sparkit/internal/repo/reaction"
"syscall"
"time"

"sparkit/internal/handlers/checkauth"
"sparkit/internal/handlers/deleteimage"
"sparkit/internal/handlers/getcurrentprofile"
"sparkit/internal/handlers/getprofile"
"sparkit/internal/handlers/getuserlist"
"sparkit/internal/handlers/logout"
"sparkit/internal/handlers/middleware/authcheck"
"sparkit/internal/handlers/middleware/corsMiddleware"
"sparkit/internal/handlers/signin"
"sparkit/internal/handlers/signup"
"sparkit/internal/handlers/updateprofile"
"sparkit/internal/handlers/uploadimage"
"sparkit/internal/repo/image"
"sparkit/internal/repo/profile"
"sparkit/internal/repo/session"
"sparkit/internal/repo/user"
imageusecase "sparkit/internal/usecase/image"
profileusecase "sparkit/internal/usecase/profile"
reactionusecase "sparkit/internal/usecase/reaction"
sessionusecase "sparkit/internal/usecase/session"
userusecase "sparkit/internal/usecase/user"
"syscall"
"time"
)

func main() {
Expand All @@ -45,6 +60,7 @@ func main() {
}
logger, err := cfg.Build()
defer logger.Sync()
sugar := logger.Sugar()
if err != nil {
log.Fatal(err)
}
Expand All @@ -57,25 +73,90 @@ func main() {
}
defer db.Close()

err = db.Ping()
if err != nil {
if err = db.Ping(); err != nil {
log.Fatal(err)
}
fmt.Println("Successfully connected to PostgreSQL!")

createTableSQL := `CREATE TABLE IF NOT EXISTS users (
createUsersTable := `CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(100),
password VARCHAR(100),
Age INT NOT NULL,
Gender VARCHAR(100)
username text,
password text,
profile INT NOT NULL,

CONSTRAINT fk_profile FOREIGN KEY (profile)
REFERENCES profile (id)
ON DELETE SET NULL
ON UPDATE CASCADE
);`
createPhotoTable := `CREATE TABLE IF NOT EXISTS photo (
id SERIAL PRIMARY KEY,
user_id bigint NOT NULL,
link text NOT NULL UNIQUE,

CONSTRAINT fk_user FOREIGN KEY (user_id)
REFERENCES users (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);`

createProfileTable := `CREATE TABLE IF NOT EXISTS profile (
id SERIAL PRIMARY KEY,
firstname text NOT NULL,
lastname text NOT NULL,
age bigint NOT NULL,
gender text NOT NULL,
target text NOT NULL,
about text NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`
createReactionTable := `CREATE TABLE IF NOT EXISTS reaction (
id SERIAL PRIMARY KEY ,
author bigint NOT NULL ,
receiver bigint NOT NULL,
type boolean,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

_, err = db.Exec(createTableSQL)
CONSTRAINT fk_author FOREIGN KEY (author)
REFERENCES users (id)
ON DELETE CASCADE
ON UPDATE CASCADE,

CONSTRAINT fk_receiver FOREIGN KEY (receiver)
REFERENCES users (id)
ON DELETE CASCADE
ON UPDATE CASCADE,

CONSTRAINT unique_pair UNIQUE (author, receiver)
);`
_, err = db.Exec(createProfileTable)
if err != nil {
log.Fatalf("Error creating table: %s", err)
} else {
fmt.Println("Table profile created successfully!")
}

_, err = db.Exec(createUsersTable)
if err != nil {
log.Fatalf("Error creating table: %s", err)
} else {
fmt.Println("Table created successfully!")
fmt.Println("Table users created successfully!")
}

_, err = db.Exec(createPhotoTable)
if err != nil {
log.Fatalf("Error creating table: %s", err)
} else {
fmt.Println("Table photo created successfully!")
}

_, err = db.Exec(createReactionTable)
if err != nil {
log.Fatalf("Error creating reaction table: %s", err)
} else {
fmt.Println("Table reaction created successfully!")
}

url := "redis://reufee:sparkit@sparkit-redis:6379/0"
Expand All @@ -93,75 +174,107 @@ func main() {
if err := redisClient.Ping(ctx).Err(); err != nil {
log.Fatalf("bad ping to redis: %v", err)
}
//userRepo := &pkg.InMemoryUserRepository{DB: db}
//sessionRepo := pkg.InMemorySessionRepository{}
//sessionService := pkg.NewSessionService(sessionRepo)
//userUseCase := userusecase.New(userRepo)
userStorage := user.New(db)
sessionStorage := session.New(redisClient)

userUsecase := userusecase.New(userStorage)
sessionUsecase := sessionusecase.New(sessionStorage)

signUp := signup.NewHandler(userUsecase, sessionUsecase)
signIn := signin.NewHandler(userUsecase, sessionUsecase)
getUsers := getuserlist.NewHandler(userUsecase)
//checkAuth handler
checkAuth := checkauth.NewHandler(sessionUsecase)
//logOut handler
logOut := logout.NewHandler(sessionUsecase)
authMiddleware := authcheck.New(sessionUsecase)
//router := http.NewServeMux()
userStorage := user.New(db, logger)
sessionStorage := session.New(redisClient, logger)
imageStorage := image.New(db, logger)
profileStorage := profile.New(db, logger)
reactionStorage := reaction.New(db, logger)

userUsecase := userusecase.New(userStorage, logger)
sessionUsecase := sessionusecase.New(sessionStorage, logger)
imageUseCase := imageusecase.New(imageStorage, logger)
profileUseCase := profileusecase.New(profileStorage, logger)
reactionUsecase := reactionusecase.New(reactionStorage, logger)

cors := corsMiddleware.New(logger)
signUp := signup.NewHandler(userUsecase, sessionUsecase, profileUseCase, logger)
signIn := signin.NewHandler(userUsecase, sessionUsecase, logger)
getUsers := getuserlist.NewHandler(sessionUsecase, profileUseCase, userUsecase, imageUseCase, logger)
checkAuth := checkauth.NewHandler(sessionUsecase, logger)
logOut := logout.NewHandler(sessionUsecase, logger)
uploadImage := uploadimage.NewHandler(imageUseCase, sessionUsecase, logger)
deleteImage := deleteimage.NewHandler(imageUseCase, logger)
getProfile := getprofile.NewHandler(imageUseCase, profileUseCase, userUsecase, logger)
getCurrentProfile := getcurrentprofile.NewHandler(imageUseCase, profileUseCase, userUsecase, sessionUsecase, logger)
updateProfile := updateprofile.NewHandler(profileUseCase, sessionUsecase, userUsecase, logger)
addReaction := addreaction.NewHandler(reactionUsecase, sessionUsecase, logger)
getMatches := getmatches.NewHandler(reactionUsecase, sessionUsecase, profileUseCase, userUsecase, imageUseCase, logger)
authMiddleware := authcheck.New(sessionUsecase, logger)
accessLogMiddleware := middleware.NewAccessLogMiddleware(sugar)

router := mux.NewRouter()
//router.Handle("/signup", corsMiddleware.CORSMiddleware(http.HandlerFunc(signUp.Handle)))
//router.Handle("/signin", corsMiddleware.CORSMiddleware(http.HandlerFunc(signIn.Handle)))
//router.Handle("/getusers", corsMiddleware.CORSMiddleware(authMiddleware.Handler(http.HandlerFunc(getUsers.Handle))))
//router.Handle("/checkauth", corsMiddleware.CORSMiddleware(http.HandlerFunc(checkAuth.Handle)))
//router.Handle("/logout", corsMiddleware.CORSMiddleware(http.HandlerFunc(logOut.Handle)))
//router.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
// fmt.Fprintf(w, "Hello World\n")
//})

router.Handle("/signup", http.HandlerFunc(signUp.Handle)).Methods("POST")
router.Handle("/signin", http.HandlerFunc(signIn.Handle)).Methods("POST")
router.Handle("/getusers", authMiddleware.Handler(http.HandlerFunc(getUsers.Handle))).Methods("GET")
router.Handle("/checkauth", http.HandlerFunc(checkAuth.Handle)).Methods("GET")
router.Handle("/logout", http.HandlerFunc(logOut.Handle)).Methods("GET")
router.Use(cors.Middleware)
router.Use(accessLogMiddleware.Handler)
router.Handle("/signup", http.HandlerFunc(signUp.Handle)).Methods("POST", http.MethodOptions)
router.Handle("/signin", http.HandlerFunc(signIn.Handle)).Methods("POST", http.MethodOptions)
router.Handle("/getusers", authMiddleware.Handler(http.HandlerFunc(getUsers.Handle))).Methods("GET", http.MethodOptions)
router.Handle("/checkauth", http.HandlerFunc(checkAuth.Handle)).Methods("GET", http.MethodOptions)
router.Handle("/logout", http.HandlerFunc(logOut.Handle)).Methods("GET", http.MethodOptions)
router.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World\n")
logger.Info("Hello World")
})
//loggedMux := accessLogMiddleware(sugar, mux)
router.Handle("/uploadimage", http.HandlerFunc(uploadImage.Handle)).Methods("POST", http.MethodOptions)
router.Handle("/image/{imageId}", http.HandlerFunc(deleteImage.Handle)).Methods("DELETE", http.MethodOptions)
router.Handle("/profile/{userId}", http.HandlerFunc(getProfile.Handle)).Methods("GET", http.MethodOptions)
router.Handle("/updateprofile", http.HandlerFunc(updateProfile.Handle)).Methods("PUT", http.MethodOptions)
router.Handle("/profile", http.HandlerFunc(getCurrentProfile.Handle)).Methods("GET", http.MethodOptions)
router.Handle("/reaction", http.HandlerFunc(addReaction.Handle)).Methods("POST", http.MethodOptions)
router.Handle("/matches", http.HandlerFunc(getMatches.Handle)).Methods("GET", http.MethodOptions)

router.Use(corsMiddleware.CORSMiddleware)
// Создаем HTTP-сервер
srv := &http.Server{
Addr: ":8080",
Handler: router,
}
// Запускаем сервер в отдельной горутине

go func() {
fmt.Println("starting a server")
fmt.Println("Starting the server")
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("Ошибка при запуске сервера: %v\n", err)
fmt.Printf("Error starting server: %v\n", err)
}
}()

// Создаем канал для получения сигналов
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)

// Ожидаем сигнала завершения
<-stop
fmt.Println("Получен сигнал завершения. Завершение работы...")
fmt.Println("Termination signal received. Shutting down...")

// Устанавливаем контекст с таймаутом для завершения
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

// Корректно завершаем работу сервера
if err := srv.Shutdown(ctx); err != nil {
fmt.Printf("Ошибка при завершении работы сервера: %v\n", err)
fmt.Printf("Error shutting down server: %v\n", err)
}

fmt.Println("Сервер завершил работу.")
}

//func accessLogMiddleware(logger *zap.SugaredLogger, next http.Handler) http.Handler {
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// start := time.Now()
// // Оборачиваем ResponseWriter, чтобы захватить статус код
// lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK}
// next.ServeHTTP(lrw, r)
// duration := time.Since(start)
//
// logger.Infow("HTTP Request",
// "method", r.Method,
// "url", r.URL.Path,
// "remote_addr", r.RemoteAddr,
// "status", lrw.statusCode,
// "duration", duration,
// )
// })
//}
//
//// Обертка для ResponseWriter, чтобы захватить статус код
//type loggingResponseWriter struct {
// http.ResponseWriter
// statusCode int
//}
//
//func (lrw *loggingResponseWriter) WriteHeader(code int) {
// lrw.statusCode = code
// lrw.ResponseWriter.WriteHeader(code)
//}
2 changes: 2 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ services:
PSQL_DBNAME: "sparkitDB"
ports:
- '8080:8080'
volumes:
- ~/imagedata:/home/reufee/imagedata

sparkit-postgres:
image: postgres:latest
Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ module sparkit
go 1.22.5

require (
github.com/golang/mock v1.6.0 // indirect
github.com/DATA-DOG/go-sqlmock v1.5.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/redis/go-redis/v9 v9.7.0 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/stretchr/testify v1.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/tools v0.1.1 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading