Move to Donetick Org, first commit
This commit is contained in:
commit
c13dd9addb
42 changed files with 7463 additions and 0 deletions
281
internal/thing/handler.go
Normal file
281
internal/thing/handler.go
Normal file
|
@ -0,0 +1,281 @@
|
|||
package thing
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
auth "donetick.com/core/internal/authorization"
|
||||
chRepo "donetick.com/core/internal/chore/repo"
|
||||
cRepo "donetick.com/core/internal/circle/repo"
|
||||
nRepo "donetick.com/core/internal/notifier/repo"
|
||||
nps "donetick.com/core/internal/notifier/service"
|
||||
tModel "donetick.com/core/internal/thing/model"
|
||||
tRepo "donetick.com/core/internal/thing/repo"
|
||||
"donetick.com/core/logging"
|
||||
jwt "github.com/appleboy/gin-jwt/v2"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
choreRepo *chRepo.ChoreRepository
|
||||
circleRepo *cRepo.CircleRepository
|
||||
nPlanner *nps.NotificationPlanner
|
||||
nRepo *nRepo.NotificationRepository
|
||||
tRepo *tRepo.ThingRepository
|
||||
}
|
||||
|
||||
type ThingRequest struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name" binding:"required"`
|
||||
Type string `json:"type" binding:"required"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
func NewHandler(cr *chRepo.ChoreRepository, circleRepo *cRepo.CircleRepository,
|
||||
np *nps.NotificationPlanner, nRepo *nRepo.NotificationRepository, tRepo *tRepo.ThingRepository) *Handler {
|
||||
return &Handler{
|
||||
choreRepo: cr,
|
||||
circleRepo: circleRepo,
|
||||
nPlanner: np,
|
||||
nRepo: nRepo,
|
||||
tRepo: tRepo,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) CreateThing(c *gin.Context) {
|
||||
log := logging.FromContext(c)
|
||||
currentUser, ok := auth.CurrentUser(c)
|
||||
if !ok {
|
||||
c.JSON(401, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
var req ThingRequest
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
c.JSON(400, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
thing := &tModel.Thing{
|
||||
Name: req.Name,
|
||||
UserID: currentUser.ID,
|
||||
Type: req.Type,
|
||||
State: req.State,
|
||||
}
|
||||
if !isValidThingState(thing) {
|
||||
c.JSON(400, gin.H{"error": "Invalid state"})
|
||||
return
|
||||
}
|
||||
log.Debug("Creating thing", thing)
|
||||
if err := h.tRepo.UpsertThing(c, thing); err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(201, gin.H{
|
||||
"res": thing,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateThingState(c *gin.Context) {
|
||||
currentUser, ok := auth.CurrentUser(c)
|
||||
if !ok {
|
||||
c.JSON(401, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
thingIDRaw := c.Param("id")
|
||||
thingID, err := strconv.Atoi(thingIDRaw)
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"error": "Invalid thing id"})
|
||||
return
|
||||
}
|
||||
|
||||
val := c.Query("value")
|
||||
if val == "" {
|
||||
c.JSON(400, gin.H{"error": "state or increment query param is required"})
|
||||
return
|
||||
}
|
||||
thing, err := h.tRepo.GetThingByID(c, thingID)
|
||||
if thing.UserID != currentUser.ID {
|
||||
c.JSON(403, gin.H{"error": "Forbidden"})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": "Unable to find thing"})
|
||||
return
|
||||
}
|
||||
thing.State = val
|
||||
if !isValidThingState(thing) {
|
||||
c.JSON(400, gin.H{"error": "Invalid state"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.tRepo.UpdateThingState(c, thing); err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
shouldReturn := EvaluateTriggerAndScheduleDueDate(h, c, thing)
|
||||
if shouldReturn {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"res": thing,
|
||||
})
|
||||
}
|
||||
|
||||
func EvaluateTriggerAndScheduleDueDate(h *Handler, c *gin.Context, thing *tModel.Thing) bool {
|
||||
thingChores, err := h.tRepo.GetThingChoresByThingId(c, thing.ID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return true
|
||||
}
|
||||
for _, tc := range thingChores {
|
||||
triggered := EvaluateThingChore(tc, thing.State)
|
||||
if triggered {
|
||||
h.choreRepo.SetDueDateIfNotExisted(c, tc.ChoreID, time.Now().UTC())
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateThing(c *gin.Context) {
|
||||
currentUser, ok := auth.CurrentUser(c)
|
||||
if !ok {
|
||||
c.JSON(401, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
var req ThingRequest
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
c.JSON(400, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
thing, err := h.tRepo.GetThingByID(c, req.ID)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": "Unable to find thing"})
|
||||
return
|
||||
}
|
||||
if thing.UserID != currentUser.ID {
|
||||
c.JSON(403, gin.H{"error": "Forbidden"})
|
||||
return
|
||||
}
|
||||
thing.Name = req.Name
|
||||
thing.Type = req.Type
|
||||
if req.State != "" {
|
||||
thing.State = req.State
|
||||
if !isValidThingState(thing) {
|
||||
c.JSON(400, gin.H{"error": "Invalid state"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := h.tRepo.UpsertThing(c, thing); err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{
|
||||
"res": thing,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) GetAllThings(c *gin.Context) {
|
||||
currentUser, ok := auth.CurrentUser(c)
|
||||
if !ok {
|
||||
c.JSON(401, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
things, err := h.tRepo.GetUserThings(c, currentUser.ID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{
|
||||
"res": things,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) GetThingHistory(c *gin.Context) {
|
||||
currentUser, ok := auth.CurrentUser(c)
|
||||
if !ok {
|
||||
c.JSON(401, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
thingIDRaw := c.Param("id")
|
||||
thingID, err := strconv.Atoi(thingIDRaw)
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"error": "Invalid thing id"})
|
||||
return
|
||||
}
|
||||
|
||||
thing, err := h.tRepo.GetThingByID(c, thingID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": "Unable to find thing"})
|
||||
return
|
||||
}
|
||||
if thing.UserID != currentUser.ID {
|
||||
c.JSON(403, gin.H{"error": "Forbidden"})
|
||||
return
|
||||
}
|
||||
offsetRaw := c.Query("offset")
|
||||
offset, err := strconv.Atoi(offsetRaw)
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"error": "Invalid offset"})
|
||||
return
|
||||
}
|
||||
history, err := h.tRepo.GetThingHistoryWithOffset(c, thingID, offset, 10)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{
|
||||
"res": history,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) DeleteThing(c *gin.Context) {
|
||||
currentUser, ok := auth.CurrentUser(c)
|
||||
if !ok {
|
||||
c.JSON(401, gin.H{"error": "Unauthorized"})
|
||||
return
|
||||
}
|
||||
|
||||
thingIDRaw := c.Param("id")
|
||||
thingID, err := strconv.Atoi(thingIDRaw)
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"error": "Invalid thing id"})
|
||||
return
|
||||
}
|
||||
|
||||
thing, err := h.tRepo.GetThingByID(c, thingID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": "Unable to find thing"})
|
||||
return
|
||||
}
|
||||
if thing.UserID != currentUser.ID {
|
||||
c.JSON(403, gin.H{"error": "Forbidden"})
|
||||
return
|
||||
}
|
||||
if err := h.tRepo.DeleteThing(c, thingID); err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{})
|
||||
}
|
||||
func Routes(r *gin.Engine, h *Handler, auth *jwt.GinJWTMiddleware) {
|
||||
|
||||
thingRoutes := r.Group("things")
|
||||
thingRoutes.Use(auth.MiddlewareFunc())
|
||||
{
|
||||
thingRoutes.POST("", h.CreateThing)
|
||||
thingRoutes.PUT("/:id/state", h.UpdateThingState)
|
||||
thingRoutes.PUT("", h.UpdateThing)
|
||||
thingRoutes.GET("", h.GetAllThings)
|
||||
thingRoutes.GET("/:id/history", h.GetThingHistory)
|
||||
thingRoutes.DELETE("/:id", h.DeleteThing)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue