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:
@@ -29,7 +29,7 @@ import (
|
||||
//
|
||||
// next_due_date IS NULL AND EXISTS (SELECT 1 FROM task_taskcompletion tc WHERE tc.task_id = task_task.id)
|
||||
func IsCompleted(task *models.Task) bool {
|
||||
return task.NextDueDate == nil && len(task.Completions) > 0
|
||||
return task.NextDueDate == nil && HasCompletions(task)
|
||||
}
|
||||
|
||||
// IsActive returns true if the task is not cancelled and not archived.
|
||||
@@ -165,13 +165,27 @@ func IsUpcoming(task *models.Task, now time.Time, daysThreshold int) bool {
|
||||
// =============================================================================
|
||||
|
||||
// HasCompletions returns true if the task has at least one completion record.
|
||||
// Supports both preloaded Completions slice and computed CompletionCount field
|
||||
// for optimized queries that use COUNT subqueries instead of preloading.
|
||||
func HasCompletions(task *models.Task) bool {
|
||||
return len(task.Completions) > 0
|
||||
// If Completions were preloaded, use the slice
|
||||
if len(task.Completions) > 0 {
|
||||
return true
|
||||
}
|
||||
// Otherwise check the computed count (populated via subquery for optimized queries)
|
||||
return task.CompletionCount > 0
|
||||
}
|
||||
|
||||
// CompletionCount returns the number of completions for a task.
|
||||
func CompletionCount(task *models.Task) int {
|
||||
return len(task.Completions)
|
||||
// GetCompletionCount returns the number of completions for a task.
|
||||
// Supports both preloaded Completions slice and computed CompletionCount field
|
||||
// for optimized queries that use COUNT subqueries instead of preloading.
|
||||
func GetCompletionCount(task *models.Task) int {
|
||||
// If Completions were preloaded, use the slice length
|
||||
if len(task.Completions) > 0 {
|
||||
return len(task.Completions)
|
||||
}
|
||||
// Otherwise return the computed count (populated via subquery for optimized queries)
|
||||
return task.CompletionCount
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
@@ -109,9 +109,10 @@ func HasCompletions(task *models.Task) bool {
|
||||
return predicates.HasCompletions(task)
|
||||
}
|
||||
|
||||
// CompletionCount returns the number of completions for a task.
|
||||
func CompletionCount(task *models.Task) int {
|
||||
return predicates.CompletionCount(task)
|
||||
// GetCompletionCount returns the number of completions for a task.
|
||||
// Supports both preloaded Completions slice and computed CompletionCount field.
|
||||
func GetCompletionCount(task *models.Task) int {
|
||||
return predicates.GetCompletionCount(task)
|
||||
}
|
||||
|
||||
// IsRecurring returns true if the task has a recurring frequency.
|
||||
|
||||
Reference in New Issue
Block a user