package main import ( "log" "net/http" "os" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) func main() { dbPath := os.Getenv("DB_PATH") if dbPath == "" { dbPath = "./timetracking.db" } db := InitDB(dbPath) defer db.Close() app := &App{DB: db} e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"*"}, AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete}, AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, echo.HeaderAuthorization}, })) e.HTTPErrorHandler = customHTTPErrorHandler e.POST("/api/login", app.LoginHandler) protected := e.Group("/api") protected.Use(JWTMiddleware()) { protected.GET("/schedules", app.GetSchedulesHandler) protected.POST("/time-entries", app.CreateTimeEntryHandler) protected.GET("/my-time-entries", app.GetMyTimeEntriesHandler) protected.POST("/time-entries/batch", app.CreateBatchTimeEntriesHandler) protected.DELETE("/my-time-entries/week", app.DeleteWeekEntries) protected.GET("/week-dates", app.GetWeekDates) protected.GET("/week-has-entries", app.CheckWeekHasEntries) protected.GET("/yearly-hours-summary", app.GetYearlyHoursSummaryHandler) protected.GET("/my-info", app.GetMyInfoHandler) } admin := e.Group("/api/admin") admin.Use(JWTMiddleware()) admin.Use(AdminMiddleware()) { admin.POST("/schedules", app.CreateScheduleHandler) admin.DELETE("/schedules/delete", app.DeleteScheduleHandler) admin.POST("/users", app.CreateUserHandler) admin.GET("/users/list", app.GetUsersHandler) admin.DELETE("/users/delete", app.DeleteUserHandler) admin.GET("/time-entries", app.GetAllTimeEntriesHandler) admin.GET("/weekly-hours", app.GetWeeklyHoursHandler) admin.PUT("/users/:id", app.UpdateUserHandler) admin.PUT("/users/:id/reset-password", app.ResetPasswordHandler) admin.PUT("/time-entries/:id", app.UpdateTimeEntryHandler) admin.DELETE("/time-entries/:id", app.DeleteTimeEntryHandler) admin.POST("/time-entry", app.AdminCreateTimeEntryHandler) } e.Static("/", "./static") port := os.Getenv("PORT") if port == "" { port = "8080" } log.Printf("Server starting on port %s", port) e.Logger.Fatal(e.Start(":" + port)) } func customHTTPErrorHandler(err error, c echo.Context) { code := http.StatusInternalServerError message := "Internal Server Error" if he, ok := err.(*echo.HTTPError); ok { code = he.Code message = he.Message.(string) } if !c.Response().Committed { if c.Request().Method == http.MethodHead { c.NoContent(code) } else { c.JSON(code, map[string]string{ "error": message, }) } } }