donetick/internal/subtask/repo/repository.go
Mo Tarbin 81acbd8eba Add subtask model and repository, implement webhook notification handling
fix Issue with Scheduler
Support NotificationPlatformWebhook
support Discord as notification target
2025-03-05 19:52:10 -05:00

109 lines
3.1 KiB
Go

package repo
import (
"context"
"time"
stModel "donetick.com/core/internal/subtask/model"
"gorm.io/gorm"
)
type SubTasksRepository struct {
db *gorm.DB
}
func NewSubTasksRepository(db *gorm.DB) *SubTasksRepository {
return &SubTasksRepository{db}
}
func (r *SubTasksRepository) CreateSubtasks(c context.Context, tx *gorm.DB, subtasks *[]stModel.SubTask, choreID int) error {
if tx != nil {
return tx.Model(&stModel.SubTask{}).Save(subtasks).Error
}
return r.db.WithContext(c).Save(subtasks).Error
}
func (r *SubTasksRepository) UpdateSubtask(c context.Context, choreId int, toBeRemove []stModel.SubTask, toBeAdd []stModel.SubTask) error {
return r.db.WithContext(c).Transaction(func(tx *gorm.DB) error {
if len(toBeRemove) == 0 && len(toBeAdd) == 0 {
return nil
}
if len(toBeRemove) > 0 {
if err := tx.Delete(toBeRemove).Error; err != nil {
return err
}
}
if len(toBeAdd) > 0 {
var insertions []stModel.SubTask
var updates []stModel.SubTask
for _, subtask := range toBeAdd {
if subtask.ID <= 0 {
// we interpret this as a new subtask
subtask.ID = 0
insertions = append(insertions, subtask)
} else {
updates = append(updates, subtask)
}
}
if len(insertions) > 0 {
if err := tx.Create(&insertions).Error; err != nil {
return err
}
}
if len(updates) > 0 {
for _, subtask := range updates {
values := map[string]interface{}{
"name": subtask.Name,
"order_id": subtask.OrderID,
"completed_at": subtask.CompletedAt,
"completed_by": subtask.CompletedBy,
"parent_id": subtask.ParentId,
}
if err := tx.Model(&stModel.SubTask{}).Where("chore_id = ? AND id = ?", choreId, subtask.ID).Updates(values).Error; err != nil {
return err
}
}
}
}
return nil
})
}
func (r *SubTasksRepository) DeleteSubtask(c context.Context, tx *gorm.DB, subtaskID int) error {
if tx != nil {
return r.deleteSubtaskWithChildren(c, tx, subtaskID)
}
return r.db.WithContext(c).Transaction(func(tx *gorm.DB) error {
return r.deleteSubtaskWithChildren(c, tx, subtaskID)
})
}
func (r *SubTasksRepository) deleteSubtaskWithChildren(c context.Context, tx *gorm.DB, subtaskID int) error {
var childSubtasks []stModel.SubTask
if err := tx.Where("parent_id = ?", subtaskID).Find(&childSubtasks).Error; err != nil {
return err
}
for _, child := range childSubtasks {
if err := r.deleteSubtaskWithChildren(c, tx, child.ID); err != nil {
return err
}
}
return tx.Delete(&stModel.SubTask{}, subtaskID).Error
}
func (r *SubTasksRepository) UpdateSubTaskStatus(c context.Context, userID int, subtaskID int, completedAt *time.Time) error {
return r.db.Model(&stModel.SubTask{}).Where("id = ?", subtaskID).Updates(map[string]interface{}{
"completed_at": completedAt,
"completed_by": userID,
}).Error
}
func (r *SubTasksRepository) ResetSubtasksCompletion(c context.Context, choreID int) error {
return r.db.Model(&stModel.SubTask{}).Where("chore_id = ?", choreID).Updates(map[string]interface{}{
"completed_at": nil,
"completed_by": nil,
}).Error
}