Add actionable push notifications and fix recurring task completion
Features: - Add task action buttons to push notifications (complete, view, cancel, etc.) - Add button types logic for different task states (overdue, in_progress, etc.) - Implement Chain of Responsibility pattern for task categorization - Add comprehensive kanban categorization documentation Fixes: - Reset recurring task status to Pending after completion so tasks appear in correct kanban column (was staying in "In Progress") - Fix PostgreSQL EXTRACT function error in overdue notifications query - Update seed data to properly set next_due_date for recurring tasks Admin: - Add tasks list to residence detail page - Fix task edit page to properly handle all fields 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -324,6 +324,67 @@ func TestTaskService_CreateCompletion(t *testing.T) {
|
||||
assert.Equal(t, "Completed successfully", resp.Notes)
|
||||
}
|
||||
|
||||
func TestTaskService_CreateCompletion_RecurringTask_ResetsStatusToPending(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
testutil.SeedLookupData(t, db)
|
||||
taskRepo := repositories.NewTaskRepository(db)
|
||||
residenceRepo := repositories.NewResidenceRepository(db)
|
||||
service := NewTaskService(taskRepo, residenceRepo)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Get the "In Progress" status (ID=2) and a recurring frequency
|
||||
var inProgressStatus models.TaskStatus
|
||||
db.Where("name = ?", "In Progress").First(&inProgressStatus)
|
||||
|
||||
var monthlyFrequency models.TaskFrequency
|
||||
db.Where("name = ?", "Monthly").First(&monthlyFrequency)
|
||||
|
||||
// Create a recurring task with "In Progress" status
|
||||
dueDate := time.Now().AddDate(0, 0, 7) // Due in 7 days
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "Recurring Task",
|
||||
StatusID: &inProgressStatus.ID,
|
||||
FrequencyID: &monthlyFrequency.ID,
|
||||
DueDate: &dueDate,
|
||||
NextDueDate: &dueDate,
|
||||
IsCancelled: false,
|
||||
IsArchived: false,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
// Complete the task
|
||||
req := &requests.CreateTaskCompletionRequest{
|
||||
TaskID: task.ID,
|
||||
Notes: "Monthly maintenance done",
|
||||
}
|
||||
|
||||
resp, err := service.CreateCompletion(req, user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.NotZero(t, resp.ID)
|
||||
|
||||
// Verify the task in the response has status reset to "Pending" (ID=1)
|
||||
require.NotNil(t, resp.Task, "Response should include the updated task")
|
||||
require.NotNil(t, resp.Task.StatusID, "Task should have a status ID")
|
||||
assert.Equal(t, uint(1), *resp.Task.StatusID, "Recurring task status should be reset to Pending (ID=1) after completion")
|
||||
|
||||
// Verify NextDueDate was updated (should be ~30 days from now for monthly)
|
||||
require.NotNil(t, resp.Task.NextDueDate, "Recurring task should have NextDueDate set")
|
||||
expectedNextDue := time.Now().AddDate(0, 0, 30) // Monthly = 30 days
|
||||
assert.WithinDuration(t, expectedNextDue, *resp.Task.NextDueDate, 24*time.Hour, "NextDueDate should be approximately 30 days from now")
|
||||
|
||||
// Also verify by reloading from database directly
|
||||
var reloadedTask models.Task
|
||||
db.Preload("Status").First(&reloadedTask, task.ID)
|
||||
require.NotNil(t, reloadedTask.StatusID)
|
||||
assert.Equal(t, uint(1), *reloadedTask.StatusID, "Database should show Pending status")
|
||||
assert.Equal(t, "Pending", reloadedTask.Status.Name)
|
||||
}
|
||||
|
||||
func TestTaskService_GetCompletion(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
Reference in New Issue
Block a user