package api import ( "github.com/gin-gonic/gin" "github.com/gissleh/stufflog/database" "github.com/gissleh/stufflog/internal/auth" "github.com/gissleh/stufflog/internal/generate" "github.com/gissleh/stufflog/internal/slerrors" "github.com/gissleh/stufflog/models" "github.com/gissleh/stufflog/services" "time" ) func Project(g *gin.RouterGroup, db database.Database) { l := services.Loader{DB: db} g.GET("/", handler("projects", func(c *gin.Context) (interface{}, error) { filter := models.ProjectFilter{} if setting := c.Query("active"); setting != "" { active := setting == "true" filter.Active = &active } if setting := c.Query("expiring"); setting != "" { filter.Expiring = setting == "true" } if setting := c.Query("favorite"); setting != "" { favorite := setting == "true" filter.Favorite = &favorite } return l.ListProjects(c, filter) })) g.GET("/:id", handler("project", func(c *gin.Context) (interface{}, error) { return l.FindProject(c, c.Param("id")) })) g.POST("/", handler("project", func(c *gin.Context) (interface{}, error) { project := models.Project{} err := c.BindJSON(&project) if err != nil { return nil, slerrors.BadRequest("Invalid JSON") } if project.EndTime != nil && project.EndTime.Before(time.Now()) { return nil, slerrors.BadRequest("Project end time must be later than current time.") } project.ID = generate.ProjectID() project.UserID = auth.UserID(c) project.CreatedTime = time.Now().UTC() err = db.Projects().Insert(c.Request.Context(), project) if err != nil { return nil, err } return &models.ProjectResult{ Project: project, Tasks: []*models.TaskResult{}, }, nil })) g.PUT("/:id", handler("project", func(c *gin.Context) (interface{}, error) { update := models.ProjectUpdate{} err := c.BindJSON(&update) if err != nil { return nil, slerrors.BadRequest("Invalid JSON") } project, err := l.FindProject(c.Request.Context(), c.Param("id")) if err != nil { return nil, err } project.Update(update) err = db.Projects().Update(c.Request.Context(), project.Project) if err != nil { return nil, err } return project, nil })) g.DELETE("/:id", handler("project", func(c *gin.Context) (interface{}, error) { project, err := l.FindProject(c.Request.Context(), c.Param("id")) if err != nil { return nil, err } if len(project.Tasks) > 0 { return nil, slerrors.Forbidden("cannot delete non-empty projects.") } err = db.Projects().Delete(c.Request.Context(), project.Project) if err != nil { return nil, err } return project, nil })) }