add stats repo.
This commit is contained in:
+3
-2
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func handler(key string, callback func(c *gin.Context) (interface{}, error)) gin.HandlerFunc {
|
||||
@@ -26,7 +27,7 @@ func handler(key string, callback func(c *gin.Context) (interface{}, error)) gin
|
||||
StatusLabels: models.StatusLabels,
|
||||
}
|
||||
|
||||
if s.Stats != nil {
|
||||
if s.Stats != nil && !strings.Contains(c.FullPath(), "/stats/") {
|
||||
options.Stats = make(map[int]models.Stat)
|
||||
for _, stat := range s.Stats {
|
||||
options.Stats[stat.ID] = stat
|
||||
@@ -73,7 +74,7 @@ func scopeIDMiddleware(db database.Database) gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
scope, err := db.Scopes().Find(c.Request.Context(), scopeID, c.Request.Method != "GET")
|
||||
scope, err := db.Scopes().Find(c.Request.Context(), scopeID, strings.Contains(c.FullPath(), "/stats/") || c.Request.Method != "GET")
|
||||
if err != nil || !scope.HasMember(auth.UserID(c)) {
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{
|
||||
Code: http.StatusNotFound,
|
||||
|
||||
+138
@@ -47,4 +47,142 @@ func Projects(g *gin.RouterGroup, db database.Database) {
|
||||
|
||||
return db.Projects(getScope(c).ID).Create(c.Request.Context(), *project)
|
||||
}))
|
||||
|
||||
g.PUT("/:id", handler("project", func(c *gin.Context) (interface{}, error) {
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
update := &models.ProjectUpdate{}
|
||||
err = c.BindJSON(update)
|
||||
if err != nil {
|
||||
return nil, slerrors.BadRequest("Invalid JSON input: " + err.Error())
|
||||
}
|
||||
|
||||
project, err := db.Projects(getScope(c).ID).Find(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return db.Projects(getScope(c).ID).Update(c.Request.Context(), *project, *update)
|
||||
}))
|
||||
|
||||
g.POST("/:id/requirements", handler("project", func(c *gin.Context) (interface{}, error) {
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
requirement := &models.ProjectRequirement{}
|
||||
err = c.BindJSON(requirement)
|
||||
if err != nil {
|
||||
return nil, slerrors.BadRequest("Invalid JSON input: " + err.Error())
|
||||
}
|
||||
|
||||
if requirement.Name == "" {
|
||||
return nil, slerrors.BadRequest("Requirement name cannot be empty.")
|
||||
}
|
||||
if !requirement.Status.Valid() {
|
||||
return nil, slerrors.BadRequest("Bad requirement status.")
|
||||
}
|
||||
for _, stat := range requirement.Stats {
|
||||
if getScope(c).Stat(stat.ID) == nil {
|
||||
return nil, slerrors.Forbidden("One or more stats are not part of scope.")
|
||||
}
|
||||
if stat.Required < 0 {
|
||||
return nil, slerrors.BadRequest("-1 stats are not allowed when creating project requirements.")
|
||||
}
|
||||
}
|
||||
|
||||
project, err := db.Projects(getScope(c).ID).Find(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return db.Projects(getScope(c).ID).AddRequirement(c.Request.Context(), project.ProjectEntry, *requirement)
|
||||
}))
|
||||
|
||||
g.PUT("/:id/requirements/:rid", handler("project", func(c *gin.Context) (interface{}, error) {
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rid, err := reqInt(c, "rid")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
update := &models.ProjectRequirementUpdate{}
|
||||
err = c.BindJSON(update)
|
||||
if err != nil {
|
||||
return nil, slerrors.BadRequest("Invalid JSON input: " + err.Error())
|
||||
}
|
||||
|
||||
if update.Name != nil && *update.Name == "" {
|
||||
return nil, slerrors.BadRequest("Requirement name cannot be empty.")
|
||||
}
|
||||
if update.Status != nil && !update.Status.Valid() {
|
||||
return nil, slerrors.BadRequest("Bad requirement status.")
|
||||
}
|
||||
for _, stat := range update.Stats {
|
||||
if getScope(c).Stat(stat.ID) == nil {
|
||||
return nil, slerrors.Forbidden("One or more stats are not part of scope.")
|
||||
}
|
||||
}
|
||||
|
||||
project, err := db.Projects(getScope(c).ID).Find(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requirement := project.Requirement(rid)
|
||||
if requirement == nil {
|
||||
return nil, slerrors.NotFound("Project requirement")
|
||||
}
|
||||
|
||||
return db.Projects(getScope(c).ID).UpdateRequirement(c.Request.Context(), project.ProjectEntry, *requirement, *update)
|
||||
}))
|
||||
|
||||
g.DELETE("/:id/requirements/:rid", handler("project", func(c *gin.Context) (interface{}, error) {
|
||||
deleteItems := c.Query("deleteItems") == "true"
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rid, err := reqInt(c, "rid")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
project, err := db.Projects(getScope(c).ID).Find(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requirement := project.Requirement(rid)
|
||||
if requirement == nil {
|
||||
return nil, slerrors.NotFound("Project requirement")
|
||||
}
|
||||
|
||||
return db.Projects(getScope(c).ID).DeleteRequirement(c.Request.Context(), project.ProjectEntry, *requirement, deleteItems)
|
||||
}))
|
||||
|
||||
g.DELETE("/:id", handler("project", func(c *gin.Context) (interface{}, error) {
|
||||
deleteItems := c.Query("deleteItems") == "true"
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
project, err := db.Projects(getScope(c).ID).Find(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = db.Projects(getScope(c).ID).Delete(c.Request.Context(), project.ProjectEntry, deleteItems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return project, nil
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/database"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/models"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Stats(g *gin.RouterGroup, db database.Database) {
|
||||
g.Use(scopeIDMiddleware(db))
|
||||
|
||||
g.GET("/", handler("stats", func(c *gin.Context) (interface{}, error) {
|
||||
return getScope(c).Stats, nil
|
||||
}))
|
||||
|
||||
g.GET("/:id", handler("stat", func(c *gin.Context) (interface{}, error) {
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stat := getScope(c).Stat(id)
|
||||
if stat == nil {
|
||||
return nil, slerrors.NotFound("Stat")
|
||||
}
|
||||
|
||||
return stat, nil
|
||||
}))
|
||||
|
||||
g.POST("/", handler("stat", func(c *gin.Context) (interface{}, error) {
|
||||
stat := &models.Stat{}
|
||||
err := c.BindJSON(stat)
|
||||
if err != nil {
|
||||
return nil, slerrors.BadRequest("Invalid JSON input: " + err.Error())
|
||||
}
|
||||
|
||||
if stat.Name == "" {
|
||||
return nil, slerrors.BadRequest("Project name cannot be blank")
|
||||
}
|
||||
if stat.Weight < 0 {
|
||||
return nil, slerrors.BadRequest("Negative weight not allowed")
|
||||
}
|
||||
for key, value := range stat.AllowedAmounts {
|
||||
if value <= 0 {
|
||||
return nil, slerrors.BadRequest("Invalid allowed amount: " + key + " (0/-1 only allowed when updating to delete them)")
|
||||
}
|
||||
}
|
||||
|
||||
return db.Stats(getScope(c).ID).Create(c.Request.Context(), *stat)
|
||||
}))
|
||||
|
||||
g.PUT("/:id", handler("stat", func(c *gin.Context) (interface{}, error) {
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
update := &models.StatUpdate{}
|
||||
err = c.BindJSON(update)
|
||||
if err != nil {
|
||||
return nil, slerrors.BadRequest("Invalid JSON input: " + err.Error())
|
||||
}
|
||||
|
||||
stat := getScope(c).Stat(id)
|
||||
if stat == nil {
|
||||
return nil, slerrors.NotFound("Stat")
|
||||
}
|
||||
|
||||
if update.Name != nil && *update.Name == "" {
|
||||
return nil, slerrors.BadRequest("Project name cannot be blank")
|
||||
}
|
||||
if update.Weight != nil && *update.Weight < 0 {
|
||||
return nil, slerrors.BadRequest("Negative weight not allowed")
|
||||
}
|
||||
|
||||
return db.Stats(getScope(c).ID).Update(c.Request.Context(), *stat, *update)
|
||||
}))
|
||||
|
||||
g.DELETE("/:id", handler("stat", func(c *gin.Context) (interface{}, error) {
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stat := getScope(c).Stat(id)
|
||||
if stat == nil {
|
||||
return nil, slerrors.NotFound("Stat")
|
||||
}
|
||||
|
||||
err = db.Stats(getScope(c).ID).Delete(c.Request.Context(), *stat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stat, nil
|
||||
}))
|
||||
}
|
||||
Reference in New Issue
Block a user