152 lines
4.1 KiB
Go
152 lines
4.1 KiB
Go
package api
|
|
|
|
import (
|
|
_ "FamilyHub/src/api/docs"
|
|
"FamilyHub/src/api/routers"
|
|
"FamilyHub/src/api/services"
|
|
"FamilyHub/src/config"
|
|
"FamilyHub/src/database"
|
|
"FamilyHub/src/integrations/ocr"
|
|
"FamilyHub/src/integrations/receiptProvider"
|
|
"FamilyHub/src/repositories"
|
|
"context"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
swaggerFiles "github.com/swaggo/files"
|
|
ginSwagger "github.com/swaggo/gin-swagger"
|
|
)
|
|
|
|
type Server struct {
|
|
httpServer *http.Server
|
|
ocr ocr.OCR
|
|
}
|
|
|
|
func NewServer(cfg config.Config) *Server {
|
|
dbManager := &database.Database{
|
|
ConnectionString: cfg.DBConnectionString,
|
|
MigrationsPath: "file://migrations",
|
|
}
|
|
dbConn, err := dbManager.Connect()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := dbManager.RunMigrations(dbConn); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if !cfg.DebugMode {
|
|
gin.SetMode(gin.ReleaseMode)
|
|
}
|
|
router := gin.New()
|
|
router.Use(gin.Logger())
|
|
//router.Use(requestLoggingMiddleware())
|
|
router.Use(gin.RecoveryWithWriter(os.Stderr))
|
|
if cfg.OpenAPIEnabled {
|
|
openAPIEndpoint := cfg.OpenAPIEndpoint
|
|
if openAPIEndpoint == "" {
|
|
openAPIEndpoint = "/openapi"
|
|
}
|
|
swaggerHandler := ginSwagger.WrapHandler(swaggerFiles.Handler)
|
|
|
|
serveSwaggerIndex := func(c *gin.Context) {
|
|
recorder := httptest.NewRecorder()
|
|
proxyCtx, _ := gin.CreateTestContext(recorder)
|
|
proxyCtx.Request = c.Request.Clone(c.Request.Context())
|
|
proxyCtx.Request.URL.Path = openAPIEndpoint + "/index.html"
|
|
proxyCtx.Request.RequestURI = openAPIEndpoint + "/index.html"
|
|
|
|
swaggerHandler(proxyCtx)
|
|
|
|
for key, values := range recorder.Header() {
|
|
for _, value := range values {
|
|
c.Writer.Header().Add(key, value)
|
|
}
|
|
}
|
|
|
|
body := strings.Replace(
|
|
recorder.Body.String(),
|
|
"<head>",
|
|
"<head><base href=\""+openAPIEndpoint+"/\">",
|
|
1,
|
|
)
|
|
|
|
c.Status(recorder.Code)
|
|
_, _ = c.Writer.WriteString(body)
|
|
}
|
|
|
|
router.GET(openAPIEndpoint, serveSwaggerIndex)
|
|
router.GET(openAPIEndpoint+"/*any", func(c *gin.Context) {
|
|
if c.Param("any") == "/" {
|
|
serveSwaggerIndex(c)
|
|
return
|
|
}
|
|
|
|
swaggerHandler(c)
|
|
})
|
|
}
|
|
|
|
apiV1 := router.Group("/api/v1")
|
|
|
|
transactionRepo := repositories.NewTransactionsSQLRepository(dbConn)
|
|
activityRepo := repositories.NewActivitySQLRepository(dbConn)
|
|
|
|
ocrSvc, err := ocr.NewGoogleOCR(context.Background())
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
receiptRepo := repositories.NewReceiptsSQLRepository(dbConn)
|
|
receiptProvider_ := receiptProvider.NewReceiptProvider()
|
|
receiptService := services.NewReceiptService(receiptProvider_, receiptRepo, transactionRepo)
|
|
|
|
transactionService := services.NewTransactionService(transactionRepo, activityRepo)
|
|
transactionCreationService := services.NewTransactionCreationService(transactionService, receiptService, ocrSvc)
|
|
transactionRouter := routers.NewTransactionsRouter(transactionService, transactionCreationService)
|
|
transactionRouter.RegisterRoutes(apiV1)
|
|
|
|
activityService := services.NewActivityService(activityRepo)
|
|
activityRouter := routers.NewActivitiesRouter(activityService)
|
|
activityRouter.RegisterRoutes(apiV1)
|
|
|
|
usersRepo := repositories.NewUsersSQLRepository(dbConn)
|
|
usersService := services.NewUserService(usersRepo)
|
|
usersRouter := routers.NewUsersRouter(usersService)
|
|
usersRouter.RegisterRoutes(apiV1)
|
|
|
|
familyRepo := repositories.NewFamilySQLRepository(dbConn)
|
|
familyService := services.NewFamilyService(familyRepo)
|
|
familyRouter := routers.NewFamiliesRouter(familyService)
|
|
familyRouter.RegisterRoutes(apiV1)
|
|
|
|
otpRepo := repositories.NewOTPSQLRepository(dbConn)
|
|
authService := services.NewAuthService(usersRepo, otpRepo)
|
|
authRouter := routers.NewAuthRouter(authService)
|
|
authRouter.RegisterRouter(apiV1)
|
|
|
|
// подключаем статику Vue — должно быть последним
|
|
registerStaticFiles(router, "src/api/dist")
|
|
return &Server{
|
|
httpServer: &http.Server{
|
|
Addr: cfg.APIHost + ":" + cfg.APIPort,
|
|
Handler: router,
|
|
},
|
|
ocr: ocrSvc,
|
|
}
|
|
}
|
|
|
|
func (s *Server) Start() error {
|
|
return s.httpServer.ListenAndServe()
|
|
}
|
|
|
|
func (s *Server) Shutdown(ctx context.Context) error {
|
|
if s.ocr != nil {
|
|
_ = s.ocr.Close()
|
|
}
|
|
return s.httpServer.Shutdown(ctx)
|
|
}
|