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:
@@ -91,6 +91,11 @@ type Task struct {
|
||||
|
||||
// Completions
|
||||
Completions []TaskCompletion `gorm:"foreignKey:TaskID" json:"completions,omitempty"`
|
||||
|
||||
// CompletionCount is a computed field populated via subquery for optimized queries.
|
||||
// When populated (>= 0 and Completions slice is empty), predicates should use this
|
||||
// instead of len(Completions) to avoid N+1 queries.
|
||||
CompletionCount int `gorm:"-:all" json:"-"`
|
||||
}
|
||||
|
||||
// TableName returns the table name for GORM
|
||||
@@ -116,7 +121,9 @@ func (t *Task) IsOverdue() bool {
|
||||
return false
|
||||
}
|
||||
// Completed check: NextDueDate == nil AND has completions
|
||||
if t.NextDueDate == nil && len(t.Completions) > 0 {
|
||||
// Supports both preloaded Completions and computed CompletionCount
|
||||
hasCompletions := len(t.Completions) > 0 || t.CompletionCount > 0
|
||||
if t.NextDueDate == nil && hasCompletions {
|
||||
return false
|
||||
}
|
||||
// Effective date: NextDueDate ?? DueDate
|
||||
@@ -143,7 +150,9 @@ func (t *Task) IsDueSoon(days int) bool {
|
||||
return false
|
||||
}
|
||||
// Completed check: NextDueDate == nil AND has completions
|
||||
if t.NextDueDate == nil && len(t.Completions) > 0 {
|
||||
// Supports both preloaded Completions and computed CompletionCount
|
||||
hasCompletions := len(t.Completions) > 0 || t.CompletionCount > 0
|
||||
if t.NextDueDate == nil && hasCompletions {
|
||||
return false
|
||||
}
|
||||
// Effective date: NextDueDate ?? DueDate
|
||||
|
||||
Reference in New Issue
Block a user