Add GetChoreDetail endpoint to retrieve detailed chore information

This commit is contained in:
Mo Tarbin 2024-07-06 02:36:14 -04:00
parent f115d70c49
commit 45e18c8edd
4 changed files with 82 additions and 0 deletions

View File

@ -873,6 +873,37 @@ func (h *Handler) GetChoreHistory(c *gin.Context) {
}) })
} }
func (h *Handler) GetChoreDetail(c *gin.Context) {
currentUser, ok := auth.CurrentUser(c)
if !ok {
c.JSON(500, gin.H{
"error": "Error getting current user",
})
return
}
rawID := c.Param("id")
id, err := strconv.Atoi(rawID)
if err != nil {
c.JSON(400, gin.H{
"error": "Invalid ID",
})
return
}
detailed, err := h.choreRepo.GetChoreDetailByID(c, id, currentUser.CircleID)
if err != nil {
c.JSON(500, gin.H{
"error": "Error getting chore history",
})
return
}
c.JSON(200, gin.H{
"res": detailed,
})
}
func checkNextAssignee(chore *chModel.Chore, choresHistory []*chModel.ChoreHistory, performerID int) (int, error) { func checkNextAssignee(chore *chModel.Chore, choresHistory []*chModel.ChoreHistory, performerID int) (int, error) {
// copy the history to avoid modifying the original: // copy the history to avoid modifying the original:
history := make([]*chModel.ChoreHistory, len(choresHistory)) history := make([]*chModel.ChoreHistory, len(choresHistory))
@ -959,6 +990,7 @@ func Routes(router *gin.Engine, h *Handler, auth *jwt.GinJWTMiddleware) {
choresRoutes.PUT("/", h.editChore) choresRoutes.PUT("/", h.editChore)
choresRoutes.POST("/", h.createChore) choresRoutes.POST("/", h.createChore)
choresRoutes.GET("/:id", h.getChore) choresRoutes.GET("/:id", h.getChore)
choresRoutes.GET("/:id/details", h.GetChoreDetail)
choresRoutes.GET("/:id/history", h.GetChoreHistory) choresRoutes.GET("/:id/history", h.GetChoreHistory)
choresRoutes.POST("/:id/do", h.completeChore) choresRoutes.POST("/:id/do", h.completeChore)
choresRoutes.POST("/:id/skip", h.skipChore) choresRoutes.POST("/:id/skip", h.skipChore)

View File

@ -70,3 +70,15 @@ type Tag struct {
// CircleID int `json:"circleId" gorm:"primaryKey;autoIncrement:false"` // CircleID int `json:"circleId" gorm:"primaryKey;autoIncrement:false"`
// TagID int `json:"tagId" gorm:"primaryKey;autoIncrement:false"` // TagID int `json:"tagId" gorm:"primaryKey;autoIncrement:false"`
// } // }
type ChoreDetail struct {
ID int `json:"id" gorm:"column:id"`
Name string `json:"name" gorm:"column:name"`
FrequencyType string `json:"frequencyType" gorm:"column:frequency_type"`
NextDueDate *time.Time `json:"nextDueDate" gorm:"column:next_due_date"`
AssignedTo int `json:"assignedTo" gorm:"column:assigned_to"`
LastCompletedDate *time.Time `json:"lastCompletedDate" gorm:"column:last_completed_date"`
LastCompletedBy *int `json:"lastCompletedBy" gorm:"column:last_completed_by"`
TotalCompletedCount int `json:"totalCompletedCount" gorm:"column:total_completed"`
CreatedBy int `json:"createdBy" gorm:"column:created_by"`
}

View File

@ -214,3 +214,39 @@ func (r *ChoreRepository) SetDueDate(c context.Context, choreID int, dueDate tim
func (r *ChoreRepository) SetDueDateIfNotExisted(c context.Context, choreID int, dueDate time.Time) error { func (r *ChoreRepository) SetDueDateIfNotExisted(c context.Context, choreID int, dueDate time.Time) error {
return r.db.WithContext(c).Model(&chModel.Chore{}).Where("id = ? and next_due_date is null", choreID).Update("next_due_date", dueDate).Error return r.db.WithContext(c).Model(&chModel.Chore{}).Where("id = ? and next_due_date is null", choreID).Update("next_due_date", dueDate).Error
} }
func (r *ChoreRepository) GetChoreDetailByID(c context.Context, choreID int, circleID int) (*chModel.ChoreDetail, error) {
var choreDetail chModel.ChoreDetail
if err := r.db.WithContext(c).
Table("chores").
Select(`
chores.id,
chores.name,
chores.frequency_type,
chores.next_due_date,
chores.assigned_to,
chores.created_by,
recent_history.last_completed_date,
recent_history.last_assigned_to as last_completed_by,
COUNT(chore_histories.id) as total_completed`).
Joins("LEFT JOIN chore_histories ON chores.id = chore_histories.chore_id").
Joins(`LEFT JOIN (
SELECT
chore_id,
assigned_to AS last_assigned_to,
completed_at AS last_completed_date
FROM chore_histories
WHERE (chore_id, completed_at) IN (
SELECT chore_id, MAX(completed_at)
FROM chore_histories
GROUP BY chore_id
)
) AS recent_history ON chores.id = recent_history.chore_id`).
Where("chores.id = ? and chores.circle_id = ?", choreID, circleID).
Group("chores.id").
First(&choreDetail).Error; err != nil {
return nil, err
}
return &choreDetail, nil
}

View File

@ -69,6 +69,7 @@ func (h *Handler) signUp(c *gin.Context) {
type SignUpReq struct { type SignUpReq struct {
Username string `json:"username" binding:"required,min=4,max=20"` Username string `json:"username" binding:"required,min=4,max=20"`
Password string `json:"password" binding:"required,min=8,max=45"` Password string `json:"password" binding:"required,min=8,max=45"`
Email string `json:"email" binding:"required,email"`
DisplayName string `json:"displayName"` DisplayName string `json:"displayName"`
} }
var signupReq SignUpReq var signupReq SignUpReq
@ -96,6 +97,7 @@ func (h *Handler) signUp(c *gin.Context) {
Username: signupReq.Username, Username: signupReq.Username,
Password: password, Password: password,
DisplayName: signupReq.DisplayName, DisplayName: signupReq.DisplayName,
Email: signupReq.Email,
CreatedAt: time.Now(), CreatedAt: time.Now(),
UpdatedAt: time.Now(), UpdatedAt: time.Now(),
}); err != nil { }); err != nil {