Add quick-complete endpoint for iOS widget task completion
- Add lightweight POST /api/tasks/:id/quick-complete/ endpoint - Creates task completion with minimal processing for widget use - Returns only 200 OK on success (no response body) - Updates task status and next_due_date based on frequency - Sends completion notification asynchronously 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -593,6 +593,65 @@ func (s *TaskService) CreateCompletion(req *requests.CreateTaskCompletionRequest
|
||||
}, nil
|
||||
}
|
||||
|
||||
// QuickComplete creates a minimal task completion (for widget use)
|
||||
// Returns only success/error, no response body
|
||||
func (s *TaskService) QuickComplete(taskID uint, userID uint) error {
|
||||
// Get the task
|
||||
task, err := s.taskRepo.FindByID(taskID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ErrTaskNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Check access
|
||||
hasAccess, err := s.residenceRepo.HasAccess(task.ResidenceID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !hasAccess {
|
||||
return ErrTaskAccessDenied
|
||||
}
|
||||
|
||||
completedAt := time.Now().UTC()
|
||||
|
||||
completion := &models.TaskCompletion{
|
||||
TaskID: taskID,
|
||||
CompletedByID: userID,
|
||||
CompletedAt: completedAt,
|
||||
Notes: "Completed from widget",
|
||||
}
|
||||
|
||||
if err := s.taskRepo.CreateCompletion(completion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update next_due_date and status based on frequency
|
||||
if task.Frequency == nil || task.Frequency.Days == nil || *task.Frequency.Days == 0 {
|
||||
// One-time task - clear next_due_date and set status to "Completed" (ID=3)
|
||||
task.NextDueDate = nil
|
||||
completedStatusID := uint(3)
|
||||
task.StatusID = &completedStatusID
|
||||
} else {
|
||||
// Recurring task - calculate next due date from completion date + frequency
|
||||
nextDue := completedAt.AddDate(0, 0, *task.Frequency.Days)
|
||||
task.NextDueDate = &nextDue
|
||||
|
||||
// Reset status to "Pending" (ID=1)
|
||||
pendingStatusID := uint(1)
|
||||
task.StatusID = &pendingStatusID
|
||||
}
|
||||
if err := s.taskRepo.Update(task); err != nil {
|
||||
log.Error().Err(err).Uint("task_id", task.ID).Msg("Failed to update task after quick completion")
|
||||
}
|
||||
|
||||
// Send notification (fire and forget)
|
||||
go s.sendTaskCompletedNotification(task, completion)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendTaskCompletedNotification sends notifications when a task is completed
|
||||
func (s *TaskService) sendTaskCompletedNotification(task *models.Task, completion *models.TaskCompletion) {
|
||||
// Get all users with access to this residence
|
||||
|
||||
Reference in New Issue
Block a user