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:
@@ -103,15 +103,6 @@ func createCompletion(t *testing.T, taskID uint) {
|
||||
}
|
||||
}
|
||||
|
||||
// getInProgressStatusID returns the ID of the "In Progress" status
|
||||
func getInProgressStatusID(t *testing.T) *uint {
|
||||
var status models.TaskStatus
|
||||
if err := testDB.Where("name = ?", "In Progress").First(&status).Error; err != nil {
|
||||
t.Logf("In Progress status not found, skipping in-progress tests")
|
||||
return nil
|
||||
}
|
||||
return &status.ID
|
||||
}
|
||||
|
||||
// TaskTestCase defines a test scenario with expected categorization
|
||||
type TaskTestCase struct {
|
||||
@@ -147,8 +138,6 @@ func TestAllThreeLayersMatch(t *testing.T) {
|
||||
in60Days := now.AddDate(0, 0, 60)
|
||||
daysThreshold := 30
|
||||
|
||||
inProgressStatusID := getInProgressStatusID(t)
|
||||
|
||||
// Define all test cases with expected results for each layer
|
||||
testCases := []TaskTestCase{
|
||||
{
|
||||
@@ -293,27 +282,23 @@ func TestAllThreeLayersMatch(t *testing.T) {
|
||||
ExpectDueSoon: false,
|
||||
ExpectUpcoming: false,
|
||||
},
|
||||
}
|
||||
|
||||
// Add in-progress test case only if status exists
|
||||
if inProgressStatusID != nil {
|
||||
testCases = append(testCases, TaskTestCase{
|
||||
{
|
||||
Name: "in_progress_overdue",
|
||||
Task: &models.Task{
|
||||
Title: "in_progress_overdue",
|
||||
NextDueDate: timePtr(yesterday), // Would be overdue
|
||||
StatusID: inProgressStatusID,
|
||||
InProgress: true,
|
||||
IsCancelled: false,
|
||||
IsArchived: false,
|
||||
},
|
||||
ExpectedColumn: categorization.ColumnInProgress, // In Progress takes priority
|
||||
ExpectCompleted: false,
|
||||
ExpectActive: true,
|
||||
ExpectOverdue: true, // Predicate says overdue (doesn't check status)
|
||||
ExpectOverdue: true, // Predicate says overdue (doesn't check InProgress)
|
||||
ExpectDueSoon: false,
|
||||
ExpectUpcoming: false,
|
||||
ExpectInProgress: true,
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
// Create all tasks in database
|
||||
@@ -330,7 +315,6 @@ func TestAllThreeLayersMatch(t *testing.T) {
|
||||
var allTasks []models.Task
|
||||
err := testDB.
|
||||
Preload("Completions").
|
||||
Preload("Status").
|
||||
Where("residence_id = ?", residenceID).
|
||||
Find(&allTasks).Error
|
||||
if err != nil {
|
||||
@@ -490,26 +474,24 @@ func TestAllThreeLayersMatch(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
// Test ScopeInProgress (if status exists)
|
||||
if inProgressStatusID != nil {
|
||||
t.Run("ScopeInProgress", func(t *testing.T) {
|
||||
var scopeResults []models.Task
|
||||
testDB.Model(&models.Task{}).
|
||||
Scopes(scopes.ScopeForResidence(residenceID), scopes.ScopeInProgress).
|
||||
Find(&scopeResults)
|
||||
// Test ScopeInProgress
|
||||
t.Run("ScopeInProgress", func(t *testing.T) {
|
||||
var scopeResults []models.Task
|
||||
testDB.Model(&models.Task{}).
|
||||
Scopes(scopes.ScopeForResidence(residenceID), scopes.ScopeInProgress).
|
||||
Find(&scopeResults)
|
||||
|
||||
predicateCount := 0
|
||||
for _, task := range allTasks {
|
||||
if predicates.IsInProgress(&task) {
|
||||
predicateCount++
|
||||
}
|
||||
predicateCount := 0
|
||||
for _, task := range allTasks {
|
||||
if predicates.IsInProgress(&task) {
|
||||
predicateCount++
|
||||
}
|
||||
}
|
||||
|
||||
if len(scopeResults) != predicateCount {
|
||||
t.Errorf("ScopeInProgress returned %d, predicates found %d", len(scopeResults), predicateCount)
|
||||
}
|
||||
})
|
||||
}
|
||||
if len(scopeResults) != predicateCount {
|
||||
t.Errorf("ScopeInProgress returned %d, predicates found %d", len(scopeResults), predicateCount)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// ========== TEST CATEGORIZATION MATCHES SCOPES FOR KANBAN ==========
|
||||
@@ -527,7 +509,6 @@ func TestAllThreeLayersMatch(t *testing.T) {
|
||||
t.Run("overdue_column", func(t *testing.T) {
|
||||
var scopeResults []models.Task
|
||||
testDB.Model(&models.Task{}).
|
||||
Preload("Status").
|
||||
Scopes(scopes.ScopeForResidence(residenceID), scopes.ScopeOverdue(now)).
|
||||
Find(&scopeResults)
|
||||
|
||||
@@ -612,7 +593,7 @@ func TestSameDayOverdueConsistency(t *testing.T) {
|
||||
|
||||
// Reload with preloads
|
||||
var loadedTask models.Task
|
||||
testDB.Preload("Completions").Preload("Status").First(&loadedTask, task.ID)
|
||||
testDB.Preload("Completions").First(&loadedTask, task.ID)
|
||||
|
||||
// All three layers should agree
|
||||
predicateResult := predicates.IsOverdue(&loadedTask, now)
|
||||
|
||||
Reference in New Issue
Block a user