Fix Adaptive Scheduler, Update email handlers, telegram notifications
This commit is contained in:
parent
17326a16a0
commit
a3fa964c58
|
@ -488,7 +488,7 @@ func (h *Handler) editChore(c *gin.Context) {
|
||||||
go func() {
|
go func() {
|
||||||
h.nPlanner.GenerateNotifications(c, updatedChore)
|
h.nPlanner.GenerateNotifications(c, updatedChore)
|
||||||
}()
|
}()
|
||||||
if oldChore.ThingChore.ThingID != 0 {
|
if oldChore.ThingChore != nil {
|
||||||
// TODO: Add check to see if dissociation is necessary
|
// TODO: Add check to see if dissociation is necessary
|
||||||
h.tRepo.DissociateThingWithChore(c, oldChore.ThingChore.ThingID, oldChore.ID)
|
h.tRepo.DissociateThingWithChore(c, oldChore.ThingChore.ThingID, oldChore.ID)
|
||||||
|
|
||||||
|
@ -562,6 +562,8 @@ func (h *Handler) deleteChore(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.nRepo.DeleteAllChoreNotifications(id)
|
h.nRepo.DeleteAllChoreNotifications(id)
|
||||||
|
h.tRepo.DissociateChoreWithThing(c, id)
|
||||||
|
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"message": "Chore deleted successfully",
|
"message": "Chore deleted successfully",
|
||||||
})
|
})
|
||||||
|
@ -800,8 +802,16 @@ func (h *Handler) completeChore(c *gin.Context) {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var nextDueDate *time.Time
|
||||||
nextDueDate, err := scheduleNextDueDate(chore, completedDate)
|
if chore.FrequencyType == "adaptive" {
|
||||||
|
history, err := h.choreRepo.GetChoreHistoryWithLimit(c, chore.ID, 5)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{
|
||||||
|
"error": "Error getting chore history",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
nextDueDate, err = scheduleAdaptiveNextDueDate(chore, completedDate, history)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error scheduling next due date: %s", err)
|
log.Printf("Error scheduling next due date: %s", err)
|
||||||
c.JSON(500, gin.H{
|
c.JSON(500, gin.H{
|
||||||
|
@ -809,6 +819,17 @@ func (h *Handler) completeChore(c *gin.Context) {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nextDueDate, err = scheduleNextDueDate(chore, completedDate)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error scheduling next due date: %s", err)
|
||||||
|
c.JSON(500, gin.H{
|
||||||
|
"error": "Error scheduling next due date",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
choreHistory, err := h.choreRepo.GetChoreHistory(c, chore.ID)
|
choreHistory, err := h.choreRepo.GetChoreHistory(c, chore.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(500, gin.H{
|
c.JSON(500, gin.H{
|
||||||
|
@ -871,6 +892,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))
|
||||||
|
@ -957,6 +1009,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)
|
||||||
|
|
|
@ -26,7 +26,7 @@ type Chore struct {
|
||||||
UpdatedAt time.Time `json:"updatedAt" gorm:"column:updated_at"` // When the chore was last updated
|
UpdatedAt time.Time `json:"updatedAt" gorm:"column:updated_at"` // When the chore was last updated
|
||||||
CreatedBy int `json:"createdBy" gorm:"column:created_by"` // Who created the chore
|
CreatedBy int `json:"createdBy" gorm:"column:created_by"` // Who created the chore
|
||||||
UpdatedBy int `json:"updatedBy" gorm:"column:updated_by"` // Who last updated the chore
|
UpdatedBy int `json:"updatedBy" gorm:"column:updated_by"` // Who last updated the chore
|
||||||
ThingChore tModel.ThingChore `json:"thingChore" gorm:"foreignkey:chore_id;references:id;<-:false"` // ThingChore relationship
|
ThingChore *tModel.ThingChore `json:"thingChore" gorm:"foreignkey:chore_id;references:id;<-:false"` // ThingChore relationship
|
||||||
}
|
}
|
||||||
type ChoreAssignees struct {
|
type ChoreAssignees struct {
|
||||||
ID int `json:"-" gorm:"primary_key"`
|
ID int `json:"-" gorm:"primary_key"`
|
||||||
|
@ -70,3 +70,16 @@ 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"`
|
||||||
|
Notes *string `json:"notes" gorm:"column:notes"`
|
||||||
|
CreatedBy int `json:"createdBy" gorm:"column:created_by"`
|
||||||
|
}
|
||||||
|
|
|
@ -111,6 +111,13 @@ func (r *ChoreRepository) GetChoreHistory(c context.Context, choreID int) ([]*ch
|
||||||
}
|
}
|
||||||
return histories, nil
|
return histories, nil
|
||||||
}
|
}
|
||||||
|
func (r *ChoreRepository) GetChoreHistoryWithLimit(c context.Context, choreID int, limit int) ([]*chModel.ChoreHistory, error) {
|
||||||
|
var histories []*chModel.ChoreHistory
|
||||||
|
if err := r.db.WithContext(c).Where("chore_id = ?", choreID).Order("completed_at desc").Limit(limit).Find(&histories).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return histories, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ChoreRepository) UpdateChoreAssignees(c context.Context, assignees []*chModel.ChoreAssignees) error {
|
func (r *ChoreRepository) UpdateChoreAssignees(c context.Context, assignees []*chModel.ChoreAssignees) error {
|
||||||
return r.db.WithContext(c).Save(&assignees).Error
|
return r.db.WithContext(c).Save(&assignees).Error
|
||||||
|
@ -214,3 +221,42 @@ 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.notes,
|
||||||
|
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,
|
||||||
|
notes
|
||||||
|
|
||||||
|
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, recent_history.last_completed_date, recent_history.last_assigned_to, recent_history.notes").
|
||||||
|
First(&choreDetail).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
return &choreDetail, nil
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ func scheduleNextDueDate(chore *chModel.Chore, completedDate time.Time) (*time.T
|
||||||
} else if chore.FrequencyType == "yearly" {
|
} else if chore.FrequencyType == "yearly" {
|
||||||
nextDueDate = baseDate.AddDate(1, 0, 0)
|
nextDueDate = baseDate.AddDate(1, 0, 0)
|
||||||
} else if chore.FrequencyType == "adaptive" {
|
} else if chore.FrequencyType == "adaptive" {
|
||||||
|
|
||||||
// TODO: calculate next due date based on the history of the chore
|
// TODO: calculate next due date based on the history of the chore
|
||||||
// calculate the difference between the due date and now in days:
|
// calculate the difference between the due date and now in days:
|
||||||
diff := completedDate.UTC().Sub(chore.NextDueDate.UTC())
|
diff := completedDate.UTC().Sub(chore.NextDueDate.UTC())
|
||||||
|
@ -129,6 +130,33 @@ func scheduleNextDueDate(chore *chModel.Chore, completedDate time.Time) (*time.T
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func scheduleAdaptiveNextDueDate(chore *chModel.Chore, completedDate time.Time, history []*chModel.ChoreHistory) (*time.Time, error) {
|
||||||
|
// will generate due date base on history and the different between the completed date and the due date
|
||||||
|
// the more recent the higher weight
|
||||||
|
if len(history) <= 1 {
|
||||||
|
if chore.NextDueDate != nil {
|
||||||
|
diff := completedDate.UTC().Sub(chore.NextDueDate.UTC())
|
||||||
|
nextDueDate := completedDate.UTC().Add(diff)
|
||||||
|
return &nextDueDate, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
var weight float64
|
||||||
|
var totalWeight float64
|
||||||
|
var nextDueDate time.Time
|
||||||
|
for i := 0; i < len(history)-1; i++ {
|
||||||
|
delay := history[i].CompletedAt.UTC().Sub(history[i+1].CompletedAt.UTC()).Seconds()
|
||||||
|
weight = delay * float64(len(history)-i)
|
||||||
|
totalWeight += weight
|
||||||
|
}
|
||||||
|
// calculate the average delay
|
||||||
|
averageDelay := totalWeight / float64(len(history)-1)
|
||||||
|
// calculate the difference between the completed date and the due date
|
||||||
|
nextDueDate = completedDate.UTC().Add(time.Duration(averageDelay) * time.Second)
|
||||||
|
|
||||||
|
return &nextDueDate, nil
|
||||||
|
}
|
||||||
|
|
||||||
func RemoveAssigneeAndReassign(chore *chModel.Chore, userID int) {
|
func RemoveAssigneeAndReassign(chore *chModel.Chore, userID int) {
|
||||||
for i, assignee := range chore.Assignees {
|
for i, assignee := range chore.Assignees {
|
||||||
if assignee.UserID == userID {
|
if assignee.UserID == userID {
|
||||||
|
|
|
@ -48,6 +48,9 @@ func (n *NotificationPlanner) GenerateNotifications(c context.Context, chore *ch
|
||||||
var mt *chModel.NotificationMetadata
|
var mt *chModel.NotificationMetadata
|
||||||
if err := json.Unmarshal([]byte(*chore.NotificationMetadata), &mt); err != nil {
|
if err := json.Unmarshal([]byte(*chore.NotificationMetadata), &mt); err != nil {
|
||||||
log.Error("Error unmarshalling notification metadata", err)
|
log.Error("Error unmarshalling notification metadata", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if chore.NextDueDate == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if mt.DueDate {
|
if mt.DueDate {
|
||||||
|
@ -83,7 +86,7 @@ func generateDueNotifications(chore *chModel.Chore, users []*cModel.UserCircleDe
|
||||||
TypeID: 1,
|
TypeID: 1,
|
||||||
UserID: user.ID,
|
UserID: user.ID,
|
||||||
TargetID: fmt.Sprint(user.ChatID),
|
TargetID: fmt.Sprint(user.ChatID),
|
||||||
Text: fmt.Sprintf("📅 Reminder: '%s' is due today and assigned to %s.", chore.Name, assignee.DisplayName),
|
Text: fmt.Sprintf("📅 Reminder: *%s* is due today and assigned to %s.", chore.Name, assignee.DisplayName),
|
||||||
}
|
}
|
||||||
notifications = append(notifications, notification)
|
notifications = append(notifications, notification)
|
||||||
}
|
}
|
||||||
|
@ -109,7 +112,7 @@ func generatePreDueNotifications(chore *chModel.Chore, users []*cModel.UserCircl
|
||||||
TypeID: 3,
|
TypeID: 3,
|
||||||
UserID: user.ID,
|
UserID: user.ID,
|
||||||
TargetID: fmt.Sprint(user.ChatID),
|
TargetID: fmt.Sprint(user.ChatID),
|
||||||
Text: fmt.Sprintf("📢 Heads up! Chore '%s' is due soon (on %s) and assigned to %s.", chore.Name, chore.NextDueDate.Format("January 2nd"), assignee.DisplayName),
|
Text: fmt.Sprintf("📢 Heads up! *%s* is due soon (on %s) and assigned to %s.", chore.Name, chore.NextDueDate.Format("January 2nd"), assignee.DisplayName),
|
||||||
}
|
}
|
||||||
notifications = append(notifications, notification)
|
notifications = append(notifications, notification)
|
||||||
|
|
||||||
|
@ -138,7 +141,7 @@ func generateOverdueNotifications(chore *chModel.Chore, users []*cModel.UserCirc
|
||||||
TypeID: 2,
|
TypeID: 2,
|
||||||
UserID: user.ID,
|
UserID: user.ID,
|
||||||
TargetID: fmt.Sprint(user.ChatID),
|
TargetID: fmt.Sprint(user.ChatID),
|
||||||
Text: fmt.Sprintf("🚨 '%s' is now %d hours overdue. Please complete it as soon as possible. (Assigned to %s)", chore.Name, hours, assignee.DisplayName),
|
Text: fmt.Sprintf("🚨 *%s* is now %d hours overdue. Please complete it as soon as possible. (Assigned to %s)", chore.Name, hours, assignee.DisplayName),
|
||||||
}
|
}
|
||||||
notifications = append(notifications, notification)
|
notifications = append(notifications, notification)
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ func (tn *TelegramNotifier) SendChoreCompletion(c context.Context, chore *chMode
|
||||||
if user.ChatID == 0 {
|
if user.ChatID == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
text := fmt.Sprintf("🎉 '%s' is completed! is off the list, %s! 🌟 ", chore.Name, user.DisplayName)
|
text := fmt.Sprintf("🎉 *%s* is completed! is off the list, %s! 🌟 ", chore.Name, user.DisplayName)
|
||||||
msg := tgbotapi.NewMessage(user.ChatID, text)
|
msg := tgbotapi.NewMessage(user.ChatID, text)
|
||||||
msg.ParseMode = "Markdown"
|
msg.ParseMode = "Markdown"
|
||||||
_, err := tn.bot.Send(msg)
|
_, err := tn.bot.Send(msg)
|
||||||
|
|
|
@ -261,6 +261,16 @@ func (h *Handler) DeleteThing(c *gin.Context) {
|
||||||
c.JSON(403, gin.H{"error": "Forbidden"})
|
c.JSON(403, gin.H{"error": "Forbidden"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// confirm there are no chores associated with the thing:
|
||||||
|
thingChores, err := h.tRepo.GetThingChoresByThingId(c, thing.ID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"error": "Unable to find tasks linked to this thing"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(thingChores) > 0 {
|
||||||
|
c.JSON(405, gin.H{"error": "Unable to delete thing with associated tasks"})
|
||||||
|
return
|
||||||
|
}
|
||||||
if err := h.tRepo.DeleteThing(c, thingID); err != nil {
|
if err := h.tRepo.DeleteThing(c, thingID); err != nil {
|
||||||
c.JSON(500, gin.H{"error": err.Error()})
|
c.JSON(500, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
|
|
|
@ -70,6 +70,10 @@ func (r *ThingRepository) DissociateThingWithChore(c context.Context, thingID in
|
||||||
return r.db.WithContext(c).Where("thing_id = ? AND chore_id = ?", thingID, choreID).Delete(&tModel.ThingChore{}).Error
|
return r.db.WithContext(c).Where("thing_id = ? AND chore_id = ?", thingID, choreID).Delete(&tModel.ThingChore{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ThingRepository) DissociateChoreWithThing(c context.Context, choreID int) error {
|
||||||
|
return r.db.WithContext(c).Where("chore_id = ?", choreID).Delete(&tModel.ThingChore{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ThingRepository) GetThingHistoryWithOffset(c context.Context, thingID int, offset int) ([]*tModel.ThingHistory, error) {
|
func (r *ThingRepository) GetThingHistoryWithOffset(c context.Context, thingID int, offset int) ([]*tModel.ThingHistory, error) {
|
||||||
var thingHistory []*tModel.ThingHistory
|
var thingHistory []*tModel.ThingHistory
|
||||||
if err := r.db.WithContext(c).Model(&tModel.ThingHistory{}).Where("thing_id = ?", thingID).Order("created_at desc").Offset(offset).Limit(10).Find(&thingHistory).Error; err != nil {
|
if err := r.db.WithContext(c).Model(&tModel.ThingHistory{}).Where("thing_id = ?", thingID).Order("created_at desc").Offset(offset).Limit(10).Find(&thingHistory).Error; err != nil {
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -281,9 +283,8 @@ func (h *Handler) resetPassword(c *gin.Context) {
|
||||||
}
|
}
|
||||||
user, err := h.userRepo.FindByEmail(c, req.Email)
|
user, err := h.userRepo.FindByEmail(c, req.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusNotFound, gin.H{
|
c.JSON(http.StatusOK, gin.H{})
|
||||||
"error": "User not found",
|
log.Error("account.handler.resetPassword failed to find user")
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user.Provider != 0 {
|
if user.Provider != 0 {
|
||||||
|
|
Loading…
Reference in New Issue