Skip to content

Commit

Permalink
Merge pull request #30 from go-park-mail-ru/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
vr009 committed Apr 10, 2024
2 parents 413331c + b98b979 commit 760782d
Show file tree
Hide file tree
Showing 123 changed files with 17,974 additions and 3,556 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci_cd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
name: Deploy App
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/head/test'
if: github.ref == 'refs/heads/dev'
steps:
- name: Pull code
uses: appleboy/ssh-action@master
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.idea
.bin
bin/
*.env
image/
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
OS := $(shell uname -s)

ifneq ("$(wildcard .env)","")
include .env
endif

ifeq ($(OS), Linux)
DOCKER_COMPOSE := docker compose
endif
Expand Down Expand Up @@ -27,16 +31,24 @@ create-migration:
migrate create -dir migrations -ext sql -seq $(TABLE_NAME)

migrate-up:
migrate -path migrations -database "postgres://$(DB_USER):$(DB_PASS)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=disable" up
migrate -path migrations -database "postgres://$(DB_USER):$(DB_PASS)@localhost:$(DB_PORT)/$(DB_NAME)?sslmode=disable" up

migrate-down:
migrate -path migrations -database "postgres://$(DB_USER):$(DB_PASS)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=disable" down
migrate -path migrations -database "postgres://$(DB_USER):$(DB_PASS)@localhost:$(DB_PORT)/$(DB_NAME)?sslmode=disable" down

dev-compose-up:
$(DOCKER_COMPOSE) -f "dev-docker-compose.yaml" up -d

dev-compose-down:
$(DOCKER_COMPOSE) -f "dev-docker-compose.yaml" down

coverage:
go test -json ./... -coverprofile coverprofile_.tmp -coverpkg=./... ; \
cat coverprofile_.tmp |grep -v auth.go| grep -v interfaces.go | grep -v docs.go| grep -v cors.go| grep -v transaction.go| grep -v main.go > coverprofile.tmp ; \
rm coverprofile_.tmp ; \
go tool cover -html coverprofile.tmp ; \
go tool cover -func coverprofile.tmp

swagger:
swag init -g cmd/main/main.go

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@

## Deploy

[Tean](http://5.35.16.157).
[Tean](https://tean.homes/).
Binary file added bin/mockgen
Binary file not shown.
5 changes: 3 additions & 2 deletions build/main.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
FROM golang:1.21.0-alpine AS builder

COPY . /github.com/go-park-mail-ru/2024_1_TeaStealers/

COPY go.mod go.sum /github.com/go-park-mail-ru/2024_1_TeaStealers/
WORKDIR /github.com/go-park-mail-ru/2024_1_TeaStealers/

COPY . .

RUN go mod download
RUN go clean --modcache
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -o ./.bin ./cmd/main/main.go
Expand Down
5 changes: 5 additions & 0 deletions build/postgres.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM postgres:latest

RUN apt-get update && apt-get install -y postgresql-contrib postgis

RUN echo "CREATE EXTENSION IF NOT EXISTS \"postgis\";" >> /docker-entrypoint-initdb.d/init.sql
151 changes: 89 additions & 62 deletions cmd/main/main.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
package main

import (
advertH "2024_1_TeaStealers/internal/pkg/adverts/delivery"
advertR "2024_1_TeaStealers/internal/pkg/adverts/repo"
advertUc "2024_1_TeaStealers/internal/pkg/adverts/usecase"
advertsH "2024_1_TeaStealers/internal/pkg/adverts/delivery"
advertsR "2024_1_TeaStealers/internal/pkg/adverts/repo"
advertsUc "2024_1_TeaStealers/internal/pkg/adverts/usecase"
authH "2024_1_TeaStealers/internal/pkg/auth/delivery"
authR "2024_1_TeaStealers/internal/pkg/auth/repo"
authUc "2024_1_TeaStealers/internal/pkg/auth/usecase"
buildingH "2024_1_TeaStealers/internal/pkg/buildings/delivery"
buildingR "2024_1_TeaStealers/internal/pkg/buildings/repo"
buildingUc "2024_1_TeaStealers/internal/pkg/buildings/usecase"
companyH "2024_1_TeaStealers/internal/pkg/companies/delivery"
companyR "2024_1_TeaStealers/internal/pkg/companies/repo"
companyUc "2024_1_TeaStealers/internal/pkg/companies/usecase"
imageH "2024_1_TeaStealers/internal/pkg/images/delivery"
complexH "2024_1_TeaStealers/internal/pkg/complexes/delivery"
complexR "2024_1_TeaStealers/internal/pkg/complexes/repo"
complexUc "2024_1_TeaStealers/internal/pkg/complexes/usecase"
imageH "2024_1_TeaStealers/internal/pkg/images/delivery/http"
imageR "2024_1_TeaStealers/internal/pkg/images/repo"
imageUc "2024_1_TeaStealers/internal/pkg/images/usecase"
"2024_1_TeaStealers/internal/pkg/middleware"
userH "2024_1_TeaStealers/internal/pkg/users/delivery"
userR "2024_1_TeaStealers/internal/pkg/users/repo"
userUc "2024_1_TeaStealers/internal/pkg/users/usecase"
"context"
"database/sql"
"fmt"
Expand All @@ -33,6 +36,7 @@ import (
"github.com/joho/godotenv"
_ "github.com/lib/pq"
httpSwagger "github.com/swaggo/http-swagger"
"go.uber.org/zap"
)

// @title Sample Project API
Expand All @@ -44,6 +48,7 @@ import (
// @schemes http https
func main() {
_ = godotenv.Load()
logger := zap.Must(zap.NewDevelopment())
db, err := sql.Open("postgres", fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=disable",
os.Getenv("DB_USER"),
os.Getenv("DB_PASS"),
Expand All @@ -54,63 +59,86 @@ func main() {
panic("failed to connect database" + err.Error())
}

http.HandleFunc("/docs/", httpSwagger.WrapHandler)
if err = db.Ping(); err != nil {
log.Println("fail ping postgres")
err = fmt.Errorf("error happened in db.Ping: %w", err)
log.Println(err)
}

r := mux.NewRouter().PathPrefix("/api").Subrouter()
r.Use(middleware.CORSMiddleware)
r.HandleFunc("/ping", pingPongHandler).Methods(http.MethodGet)
r.PathPrefix("/docs/").Handler(httpSwagger.WrapHandler)

authRepo := authR.NewRepository(db, logger)
authUsecase := authUc.NewAuthUsecase(authRepo, logger)
autHandler := authH.NewAuthHandler(authUsecase, logger)

authRepo := authR.NewRepository(db)
authUsecase := authUc.NewAuthUsecase(authRepo)
autHandler := authH.NewAuthHandler(authUsecase)
jwtMd := middleware.NewAuthMiddleware(authUsecase, logger)
csrfMd := middleware.NewCsrfMiddleware()

auth := r.PathPrefix("/auth").Subrouter()
auth.HandleFunc("/signup", autHandler.SignUp).Methods(http.MethodPost, http.MethodOptions)
auth.HandleFunc("/login", autHandler.Login).Methods(http.MethodPost, http.MethodOptions)
auth.Handle("/logout", middleware.JwtMiddleware(http.HandlerFunc(autHandler.Logout))).Methods(http.MethodGet, http.MethodOptions)
auth.HandleFunc("/check_auth", autHandler.CheckAuth).Methods(http.MethodGet, http.MethodOptions)

companyRepo := companyR.NewRepository(db)
companyUsecase := companyUc.NewCompanyUsecase(companyRepo)
companyHandler := companyH.NewCompanyHandler(companyUsecase)

companyApi := r.PathPrefix("/companies").Subrouter()
companyApi.HandleFunc("/", companyHandler.CreateCompany).Methods(http.MethodPost, http.MethodOptions)
companyApi.HandleFunc("/{id}", companyHandler.GetCompanyById).Methods(http.MethodGet, http.MethodOptions)
companyApi.HandleFunc("/list/", companyHandler.GetCompaniesList).Methods(http.MethodGet, http.MethodOptions)
companyApi.HandleFunc("/{id}", companyHandler.DeleteCompanyById).Methods(http.MethodDelete, http.MethodOptions)
companyApi.HandleFunc("/{id}", companyHandler.UpdateCompanyById).Methods(http.MethodPost, http.MethodOptions)

buildingRepo := buildingR.NewRepository(db)
buildingUsecase := buildingUc.NewBuildingUsecase(buildingRepo)
buildingHandler := buildingH.NewBuildingHandler(buildingUsecase)

buildingApi := r.PathPrefix("/buildings").Subrouter()
buildingApi.HandleFunc("/", buildingHandler.CreateBuilding).Methods(http.MethodPost, http.MethodOptions)
buildingApi.HandleFunc("/{id}", buildingHandler.GetBuildingById).Methods(http.MethodGet, http.MethodOptions)
buildingApi.HandleFunc("/list/", buildingHandler.GetBuildingsList).Methods(http.MethodGet, http.MethodOptions)
buildingApi.HandleFunc("/{id}", buildingHandler.DeleteBuildingById).Methods(http.MethodDelete, http.MethodOptions)
buildingApi.HandleFunc("/{id}", buildingHandler.UpdateBuildingById).Methods(http.MethodPost, http.MethodOptions)

advertRepo := advertR.NewRepository(db)
advertUsecase := advertUc.NewAdvertUsecase(advertRepo)
advertHandler := advertH.NewAdvertHandler(advertUsecase)

advertApi := r.PathPrefix("/adverts").Subrouter()
advertApi.HandleFunc("/", advertHandler.CreateAdvert).Methods(http.MethodPost, http.MethodOptions)
advertApi.HandleFunc("/{id}", advertHandler.GetAdvertById).Methods(http.MethodGet, http.MethodOptions)
advertApi.HandleFunc("/list/", advertHandler.GetAdvertsList).Methods(http.MethodGet, http.MethodOptions)
advertApi.HandleFunc("/{id}", advertHandler.DeleteAdvertById).Methods(http.MethodDelete, http.MethodOptions)
advertApi.HandleFunc("/{id}", advertHandler.UpdateAdvertById).Methods(http.MethodPost, http.MethodOptions)

imageRepo := imageR.NewRepository(db)
imageUsecase := imageUc.NewImageUsecase(imageRepo)
imageHandler := imageH.NewImageHandler(imageUsecase)

imageApi := r.PathPrefix("/images").Subrouter()
imageApi.HandleFunc("/", imageHandler.CreateImage).Methods(http.MethodPost, http.MethodOptions)
imageApi.HandleFunc("/list/by/{advert_id}", imageHandler.GetImagesByAdvertId).Methods(http.MethodGet, http.MethodOptions)
imageApi.HandleFunc("/{id}", imageHandler.DeleteImageById).Methods(http.MethodDelete, http.MethodOptions)
// auth.HandleFunc("/signup", autHandler.SignUp).Methods(http.MethodPost, http.MethodOptions)
// auth.HandleFunc("/login", autHandler.Login).Methods(http.MethodPost, http.MethodOptions)
auth.Handle("/signup", csrfMd.SetCSRFToken(http.HandlerFunc(autHandler.SignUp))).Methods(http.MethodPost, http.MethodOptions)
auth.Handle("/login", csrfMd.SetCSRFToken(http.HandlerFunc(autHandler.Login))).Methods(http.MethodPost, http.MethodOptions)
auth.Handle("/logout", jwtMd.JwtTMiddleware(http.HandlerFunc(autHandler.Logout))).Methods(http.MethodGet, http.MethodOptions)
auth.Handle("/check_auth", jwtMd.JwtTMiddleware(http.HandlerFunc(autHandler.CheckAuth))).Methods(http.MethodGet, http.MethodOptions)

advertRepo := advertsR.NewRepository(db, logger)
advertUsecase := advertsUc.NewAdvertUsecase(advertRepo, logger)
advertHandler := advertsH.NewAdvertHandler(advertUsecase, logger)

imageRepo := imageR.NewRepository(db, logger)
imageUsecase := imageUc.NewImageUsecase(imageRepo, logger)
imageHandler := imageH.NewImageHandler(imageUsecase, logger)

advert := r.PathPrefix("/adverts").Subrouter()
advert.HandleFunc("/{id}", advertHandler.GetAdvertById).Methods(http.MethodGet, http.MethodOptions)
advert.Handle("/{id}", jwtMd.JwtTMiddleware(http.HandlerFunc(advertHandler.UpdateAdvertById))).Methods(http.MethodPost, http.MethodOptions)
advert.Handle("/{id}", jwtMd.JwtTMiddleware(http.HandlerFunc(advertHandler.DeleteAdvertById))).Methods(http.MethodDelete, http.MethodOptions)
advert.Handle("/houses/", jwtMd.JwtTMiddleware(http.HandlerFunc(advertHandler.CreateHouseAdvert))).Methods(http.MethodPost, http.MethodOptions)
advert.HandleFunc("/buildings/", advertHandler.GetExistBuildingsByAddress).Methods(http.MethodGet, http.MethodOptions)
advert.Handle("/flats/", jwtMd.JwtTMiddleware(http.HandlerFunc(advertHandler.CreateFlatAdvert))).Methods(http.MethodPost, http.MethodOptions)
advert.HandleFunc("/squarelist/", advertHandler.GetSquareAdvertsList).Methods(http.MethodGet, http.MethodOptions)
advert.HandleFunc("/rectanglelist/", advertHandler.GetRectangeAdvertsList).Methods(http.MethodGet, http.MethodOptions)
advert.Handle("/image/", jwtMd.JwtTMiddleware(http.HandlerFunc(imageHandler.UploadImage))).Methods(http.MethodPost, http.MethodOptions)
advert.HandleFunc("/{id}/image", imageHandler.GetAdvertImages).Methods(http.MethodGet, http.MethodOptions)
advert.Handle("/{id}/image", jwtMd.JwtTMiddleware(http.HandlerFunc(imageHandler.DeleteImage))).Methods(http.MethodDelete, http.MethodOptions)

userRepo := userR.NewRepository(db)
userUsecase := userUc.NewUserUsecase(userRepo)
userHandler := userH.NewUserHandler(userUsecase)

user := r.PathPrefix("/users").Subrouter()
user.Handle("/me", jwtMd.JwtTMiddleware(http.HandlerFunc(userHandler.GetCurUser))).Methods(http.MethodGet, http.MethodOptions)
user.Handle("/avatar", jwtMd.JwtTMiddleware(http.HandlerFunc(userHandler.UpdateUserPhoto))).Methods(http.MethodPost, http.MethodOptions)
user.Handle("/avatar", jwtMd.JwtTMiddleware(http.HandlerFunc(userHandler.DeleteUserPhoto))).Methods(http.MethodDelete, http.MethodOptions)
user.Handle("/info", jwtMd.JwtTMiddleware(http.HandlerFunc(userHandler.UpdateUserInfo))).Methods(http.MethodPost, http.MethodOptions)
user.Handle("/password", jwtMd.JwtTMiddleware(http.HandlerFunc(userHandler.UpdateUserPassword))).Methods(http.MethodPost, http.MethodOptions)
user.Handle("/myadverts", jwtMd.JwtTMiddleware(http.HandlerFunc(advertHandler.GetUserAdverts))).Methods(http.MethodGet, http.MethodOptions)

companyRepo := companyR.NewRepository(db, logger)
companyUsecase := companyUc.NewCompanyUsecase(companyRepo, logger)
companyHandler := companyH.NewCompanyHandler(companyUsecase, logger)

company := r.PathPrefix("/companies").Subrouter()
company.HandleFunc("/", companyHandler.CreateCompany).Methods(http.MethodPost, http.MethodOptions)
company.HandleFunc("/{id}", companyHandler.GetCompanyById).Methods(http.MethodGet, http.MethodOptions)
company.HandleFunc("/images/{id}", companyHandler.UpdateCompanyPhoto).Methods(http.MethodPost, http.MethodOptions)

complexRepo := complexR.NewRepository(db, logger)
complexUsecase := complexUc.NewComplexUsecase(complexRepo, logger)
complexHandler := complexH.NewComplexHandler(complexUsecase, logger)

complex := r.PathPrefix("/complexes").Subrouter()
complex.HandleFunc("/", complexHandler.CreateComplex).Methods(http.MethodPost, http.MethodOptions)
complex.HandleFunc("/{id}", complexHandler.GetComplexById).Methods(http.MethodGet, http.MethodOptions)
complex.HandleFunc("/{id}/rectanglelist/", advertHandler.GetComplexAdverts).Methods(http.MethodGet, http.MethodOptions)
complex.HandleFunc("/houses", complexHandler.CreateHouseAdvert).Methods(http.MethodPost, http.MethodOptions)
complex.HandleFunc("/flats", complexHandler.CreateFlatAdvert).Methods(http.MethodPost, http.MethodOptions)
complex.HandleFunc("/buildings", complexHandler.CreateBuilding).Methods(http.MethodPost, http.MethodOptions)
complex.HandleFunc("/images/{id}", complexHandler.UpdateComplexPhoto).Methods(http.MethodPost, http.MethodOptions)

srv := &http.Server{
Addr: ":8080",
Expand All @@ -124,21 +152,20 @@ func main() {
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)

go func() {
log.Printf("Start server on %s\n", srv.Addr)
logger.Info(fmt.Sprintf("Start server on %s\n", srv.Addr))
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
logger.Error(fmt.Sprintf("listen: %s\n", err))
}
}()

sig := <-signalCh
log.Printf("Received signal: %v\n", sig)
logger.Info(fmt.Sprintf("Received signal: %v\n", sig))

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

if err := srv.Shutdown(ctx); err != nil {
log.Panic("Server shutdown failed: ", err, '\n')

logger.Error(fmt.Sprintf("Server shutdown failed: %s\n", err))
}
}

Expand Down
26 changes: 17 additions & 9 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
version: "3.9"

services:
main:
container_name: mainService
build:
context: .
dockerfile: ./build/main.Dockerfile
ports:
- '8080:8080'
db:
container_name: postgres
image: postgres:latest
restart: always
build:
context: .
dockerfile: ./build/postgres.Dockerfile
volumes:
- type: volume
source: postgresdb-data
Expand All @@ -20,7 +15,20 @@ services:
- ./.env
ports:
- ${DB_PORT}:5432
main:
depends_on:
- db
container_name: mainService
build:
context: .
dockerfile: ./build/main.Dockerfile
ports:
- '8080:8080'
env_file:
- ./.env
volumes:
- "${BASE_DIR}:/docker-cian/images"

volumes:
postgresdb-data:
driver: local
driver: local
Loading

0 comments on commit 760782d

Please sign in to comment.