diff --git a/apiserver/internal/apis/caldav.go b/apiserver/internal/apis/caldav.go index 2ae5125..03c0cf6 100644 --- a/apiserver/internal/apis/caldav.go +++ b/apiserver/internal/apis/caldav.go @@ -2,6 +2,7 @@ package apis import ( "bytes" + "context" "encoding/xml" "io" "net/http" @@ -12,6 +13,7 @@ import ( authMW "dkhalife.com/tasks/core/internal/middleware/auth" models "dkhalife.com/tasks/core/internal/models" cRepo "dkhalife.com/tasks/core/internal/repos/caldav" + nRepo "dkhalife.com/tasks/core/internal/repos/notifier" tRepo "dkhalife.com/tasks/core/internal/repos/task" "dkhalife.com/tasks/core/internal/services/logging" "dkhalife.com/tasks/core/internal/utils/auth" @@ -20,18 +22,21 @@ import ( "dkhalife.com/tasks/core/internal/ws" jwt "github.com/appleboy/gin-jwt/v2" "github.com/gin-gonic/gin" + "go.uber.org/zap" ) type CalDAVAPIHandler struct { tRepo *tRepo.TaskRepository cRepo *cRepo.CalDavRepository + nRepo *nRepo.NotificationRepository ws *ws.WSServer } -func CalDAVAPI(tRepo *tRepo.TaskRepository, cRepo *cRepo.CalDavRepository, wsServer *ws.WSServer) *CalDAVAPIHandler { +func CalDAVAPI(tRepo *tRepo.TaskRepository, cRepo *cRepo.CalDavRepository, nRepo *nRepo.NotificationRepository, wsServer *ws.WSServer) *CalDAVAPIHandler { return &CalDAVAPIHandler{ tRepo: tRepo, cRepo: cRepo, + nRepo: nRepo, ws: wsServer, } } @@ -272,6 +277,12 @@ func (h *CalDAVAPIHandler) handlePut(c *gin.Context) { log.Errorf("Error getting updated task: %s", err.Error()) // Don't fail the request if we can't broadcast } else { + // Regenerate notifications for the updated task + go func(task *models.Task, logger *zap.SugaredLogger) { + ctx := logging.ContextWithLogger(context.Background(), logger) + h.nRepo.GenerateNotifications(ctx, task) + }(updatedTask, log) + // Broadcast the update to all connected clients for this user h.ws.BroadcastToUser(currentIdentity.UserID, ws.WSResponse{ Action: "task_updated", diff --git a/apiserver/internal/models/recurrence.go b/apiserver/internal/models/recurrence.go index 1bdf2f0..43689ea 100644 --- a/apiserver/internal/models/recurrence.go +++ b/apiserver/internal/models/recurrence.go @@ -34,6 +34,6 @@ type Frequency struct { On RepeatOn `json:"on" validate:"required_if=Type interval custom" gorm:"type:varchar(18);default:null"` Every int `json:"every" validate:"required_if=On interval" gorm:"type:int;default:null"` Unit IntervalUnit `json:"unit" validate:"required_if=On interval" gorm:"type:varchar(9);default:null"` - Days []int32 `json:"days" validate:"required_if=Type custom On days_of_the_week,dive,gte=0,lte=6" gorm:"serializer:json;type:json"` - Months []int32 `json:"months" validate:"required_if=Type custom On day_of_the_months,dive,gte=0,lte=11" gorm:"serializer:json;type:json"` + Days []int32 `json:"days" validate:"required_if=Type custom On days_of_the_week,dive,gte=0,lte=6" gorm:"serializer:json"` + Months []int32 `json:"months" validate:"required_if=Type custom On day_of_the_months,dive,gte=0,lte=11" gorm:"serializer:json"` } diff --git a/apiserver/internal/models/user.go b/apiserver/internal/models/user.go index 5b7f2db..7fe2ca1 100644 --- a/apiserver/internal/models/user.go +++ b/apiserver/internal/models/user.go @@ -60,7 +60,7 @@ type AppToken struct { UserID int `json:"user_id" gorm:"column:user_id;not null"` Name string `json:"name" gorm:"column:name;not null"` Token string `json:"token" gorm:"column:token;index;not null"` - Scopes []string `json:"scopes" gorm:"column:scopes;serializer:json;type:json"` + Scopes []string `json:"scopes" gorm:"column:scopes;serializer:json"` CreatedAt time.Time `json:"-" gorm:"column:created_at;default:CURRENT_TIMESTAMP"` ExpiresAt time.Time `json:"expires_at" gorm:"column:expires_at;default:CURRENT_TIMESTAMP"` User User `json:"-" gorm:"foreignKey:UserID"` diff --git a/apiserver/internal/services/tasks/task.go b/apiserver/internal/services/tasks/task.go index 8430b3b..dc20438 100644 --- a/apiserver/internal/services/tasks/task.go +++ b/apiserver/internal/services/tasks/task.go @@ -372,6 +372,11 @@ func (s *TaskService) UpdateDueDate(ctx context.Context, userID, taskID int, req } } + go func(task *models.Task, logger *zap.SugaredLogger) { + ctx := logging.ContextWithLogger(context.Background(), logger) + s.n.GenerateNotifications(ctx, task) + }(task, log) + s.ws.BroadcastToUser(userID, ws.WSResponse{ Action: "task_updated", Data: task,