'boolean', 'created_at' => 'datetime', 'updated_at' => 'datetime', 'filter_params' => 'array', ]; /** * Get the user that owns the notification * Performance: Use only when needed with eager loading */ public function user(): BelongsTo { return $this->belongsTo(User::class); } /** * Scope: Get only unread notifications * Performance: Uses index on is_read column */ public function scopeUnread($query) { return $query->where('is_read', false); } /** * Scope: Get notifications for specific user * Performance: Uses composite index on (user_id, is_read) */ public function scopeForUser($query, $userId) { return $query->where('user_id', $userId); } /** * Scope: Get recent notifications (last 30 days) * Performance: Uses index on created_at column */ public function scopeRecent($query, $days = 30) { return $query->where('created_at', '>=', now()->subDays($days)); } /** * Mark notification as read * Performance: Single update query without model events */ public function markAsRead(): bool { if ($this->is_read) { return true; // Already read, skip update } return $this->update(['is_read' => true]); } /** * Mark multiple notifications as read (bulk operation) * Performance: Single bulk update query */ public static function markMultipleAsRead(array $ids): int { return self::whereIn('id', $ids) ->where('is_read', false) ->update(['is_read' => true]); } /** * Get unread count for user * Performance: Count query without loading records */ public static function getUnreadCount($userId): int { return self::where('user_id', $userId) ->where('is_read', false) ->count(); } /** * Delete old notifications (cleanup) * Performance: Bulk delete with date filter */ public static function deleteOldNotifications($days = 90): int { return self::where('created_at', '<', now()->subDays($days)) ->delete(); } }