Replace status_id with in_progress boolean field
- Remove task_statuses lookup table and StatusID foreign key - Add InProgress boolean field to Task model - Add database migration (005_replace_status_with_in_progress) - Update all handlers, services, and repositories - Update admin frontend to display in_progress as checkbox/boolean - Remove Task Statuses tab from admin lookups page - Update tests to use InProgress instead of StatusID - Task categorization now uses InProgress for kanban column assignment 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -173,8 +173,8 @@ func (s *TaskService) CreateTask(req *requests.CreateTaskRequest, userID uint) (
|
||||
Description: req.Description,
|
||||
CategoryID: req.CategoryID,
|
||||
PriorityID: req.PriorityID,
|
||||
StatusID: req.StatusID,
|
||||
FrequencyID: req.FrequencyID,
|
||||
InProgress: req.InProgress,
|
||||
AssignedToID: req.AssignedToID,
|
||||
DueDate: dueDate,
|
||||
NextDueDate: dueDate, // Initialize next_due_date to due_date
|
||||
@@ -230,12 +230,12 @@ func (s *TaskService) UpdateTask(taskID, userID uint, req *requests.UpdateTaskRe
|
||||
if req.PriorityID != nil {
|
||||
task.PriorityID = req.PriorityID
|
||||
}
|
||||
if req.StatusID != nil {
|
||||
task.StatusID = req.StatusID
|
||||
}
|
||||
if req.FrequencyID != nil {
|
||||
task.FrequencyID = req.FrequencyID
|
||||
}
|
||||
if req.InProgress != nil {
|
||||
task.InProgress = *req.InProgress
|
||||
}
|
||||
if req.AssignedToID != nil {
|
||||
task.AssignedToID = req.AssignedToID
|
||||
}
|
||||
@@ -324,13 +324,7 @@ func (s *TaskService) MarkInProgress(taskID, userID uint) (*responses.TaskWithSu
|
||||
return nil, ErrTaskAccessDenied
|
||||
}
|
||||
|
||||
// Find "In Progress" status
|
||||
status, err := s.taskRepo.FindStatusByName("In Progress")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.taskRepo.MarkInProgress(taskID, status.ID); err != nil {
|
||||
if err := s.taskRepo.MarkInProgress(taskID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -534,24 +528,22 @@ func (s *TaskService) CreateCompletion(req *requests.CreateTaskCompletionRequest
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update next_due_date and status based on frequency
|
||||
// - If frequency is "Once" (days = nil or 0), set next_due_date to nil and status to "Completed"
|
||||
// Update next_due_date and in_progress based on frequency
|
||||
// - If frequency is "Once" (days = nil or 0), set next_due_date to nil (marks as completed)
|
||||
// - If frequency is recurring, calculate next_due_date = completion_date + frequency_days
|
||||
// and reset status to "Pending" so task shows in correct kanban column
|
||||
// and reset in_progress to false so task shows in correct kanban column
|
||||
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)
|
||||
// One-time task - clear next_due_date (completion is determined by NextDueDate == nil + has completions)
|
||||
task.NextDueDate = nil
|
||||
completedStatusID := uint(3)
|
||||
task.StatusID = &completedStatusID
|
||||
task.InProgress = false
|
||||
} 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) so task appears in upcoming/due_soon
|
||||
// Reset in_progress to false so task appears in upcoming/due_soon
|
||||
// instead of staying in "In Progress" column
|
||||
pendingStatusID := uint(1)
|
||||
task.StatusID = &pendingStatusID
|
||||
task.InProgress = false
|
||||
}
|
||||
if err := s.taskRepo.Update(task); err != nil {
|
||||
log.Error().Err(err).Uint("task_id", task.ID).Msg("Failed to update task after completion")
|
||||
@@ -633,20 +625,18 @@ func (s *TaskService) QuickComplete(taskID uint, userID uint) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update next_due_date and status based on frequency
|
||||
// Update next_due_date and in_progress 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)
|
||||
// One-time task - clear next_due_date (completion is determined by NextDueDate == nil + has completions)
|
||||
task.NextDueDate = nil
|
||||
completedStatusID := uint(3)
|
||||
task.StatusID = &completedStatusID
|
||||
task.InProgress = false
|
||||
} 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
|
||||
// Reset in_progress to false
|
||||
task.InProgress = false
|
||||
}
|
||||
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")
|
||||
@@ -858,20 +848,6 @@ func (s *TaskService) GetPriorities() ([]responses.TaskPriorityResponse, error)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetStatuses returns all task statuses
|
||||
func (s *TaskService) GetStatuses() ([]responses.TaskStatusResponse, error) {
|
||||
statuses, err := s.taskRepo.GetAllStatuses()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]responses.TaskStatusResponse, len(statuses))
|
||||
for i, st := range statuses {
|
||||
result[i] = *responses.NewTaskStatusResponse(&st)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetFrequencies returns all task frequencies
|
||||
func (s *TaskService) GetFrequencies() ([]responses.TaskFrequencyResponse, error) {
|
||||
frequencies, err := s.taskRepo.GetAllFrequencies()
|
||||
|
||||
Reference in New Issue
Block a user