Add performance optimizations and database indexes
Database Indexes (migrations 006-009): - Add case-insensitive indexes for auth lookups (email, username) - Add composite indexes for task kanban queries - Add indexes for notification, document, and completion queries - Add unique index for active share codes - Remove redundant idx_share_code_active and idx_notification_user_sent Repository Optimizations: - Add FindResidenceIDsByUser() lightweight method (IDs only, no preloads) - Optimize GetResidenceUsers() with single UNION query (was 2 queries) - Optimize kanban completion preloads to minimal columns (id, task_id, completed_at) Service Optimizations: - Remove Category/Priority/Frequency preloads from task queries - Remove summary calculations from CRUD responses (client calculates) - Use lightweight FindResidenceIDsByUser() instead of full FindByUser() These changes reduce database load and response times for common operations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -533,13 +533,14 @@ func TestRecurringTask_Lifecycle_FirstCompletion(t *testing.T) {
|
||||
err = taskRepo.CreateCompletion(completion)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Reload to get frequency
|
||||
// Reload task
|
||||
task, err = taskRepo.FindByID(task.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Simulate the next_due_date update (from task_service.CreateCompletion)
|
||||
// For recurring task: NextDueDate = CompletedAt + FrequencyDays
|
||||
nextDue := completedAt.AddDate(0, 0, *task.Frequency.Days)
|
||||
// Note: Frequency is no longer preloaded for performance, use the weeklyFreq we already have
|
||||
nextDue := completedAt.AddDate(0, 0, *weeklyFreq.Days)
|
||||
task.NextDueDate = &nextDue
|
||||
err = taskRepo.Update(task)
|
||||
require.NoError(t, err)
|
||||
@@ -603,7 +604,8 @@ func TestRecurringTask_Lifecycle_MultipleCompletions(t *testing.T) {
|
||||
})
|
||||
|
||||
task, _ = taskRepo.FindByID(task.ID)
|
||||
nextDue1 := completedAt1.AddDate(0, 0, *task.Frequency.Days)
|
||||
// Note: Frequency is no longer preloaded for performance, use weeklyFreq we already have
|
||||
nextDue1 := completedAt1.AddDate(0, 0, *weeklyFreq.Days)
|
||||
task.NextDueDate = &nextDue1
|
||||
taskRepo.Update(task)
|
||||
|
||||
@@ -632,7 +634,8 @@ func TestRecurringTask_Lifecycle_MultipleCompletions(t *testing.T) {
|
||||
})
|
||||
|
||||
task, _ = taskRepo.FindByID(task.ID)
|
||||
nextDue2 := completedAt2.AddDate(0, 0, *task.Frequency.Days)
|
||||
// Note: Frequency is no longer preloaded for performance, use weeklyFreq we already have
|
||||
nextDue2 := completedAt2.AddDate(0, 0, *weeklyFreq.Days)
|
||||
task.NextDueDate = &nextDue2
|
||||
taskRepo.Update(task)
|
||||
|
||||
@@ -725,7 +728,7 @@ func TestKanbanBoard_OneTimeTaskCompletion_MovesToCompleted(t *testing.T) {
|
||||
db.Create(task)
|
||||
|
||||
// Before completion - should be in due_soon
|
||||
board, err := taskRepo.GetKanbanData(residence.ID, 30)
|
||||
board, err := taskRepo.GetKanbanData(residence.ID, 30, time.Now().UTC())
|
||||
require.NoError(t, err)
|
||||
|
||||
dueSoonCount := 0
|
||||
@@ -751,7 +754,7 @@ func TestKanbanBoard_OneTimeTaskCompletion_MovesToCompleted(t *testing.T) {
|
||||
db.Save(task)
|
||||
|
||||
// After completion - should be in completed
|
||||
board, err = taskRepo.GetKanbanData(residence.ID, 30)
|
||||
board, err = taskRepo.GetKanbanData(residence.ID, 30, time.Now().UTC())
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, col := range board.Columns {
|
||||
@@ -790,7 +793,7 @@ func TestKanbanBoard_RecurringTaskCompletion_StaysActionable(t *testing.T) {
|
||||
db.Create(task)
|
||||
|
||||
// Before completion - should be overdue
|
||||
board, err := taskRepo.GetKanbanData(residence.ID, 30)
|
||||
board, err := taskRepo.GetKanbanData(residence.ID, 30, time.Now().UTC())
|
||||
require.NoError(t, err)
|
||||
|
||||
var overdueCount, completedCount, dueSoonCount int
|
||||
@@ -821,7 +824,7 @@ func TestKanbanBoard_RecurringTaskCompletion_StaysActionable(t *testing.T) {
|
||||
db.Save(task)
|
||||
|
||||
// After completion - should be in due_soon, NOT completed
|
||||
board, err = taskRepo.GetKanbanData(residence.ID, 30)
|
||||
board, err = taskRepo.GetKanbanData(residence.ID, 30, time.Now().UTC())
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, col := range board.Columns {
|
||||
|
||||
Reference in New Issue
Block a user