notification = model(Notification::class); $this->userNotification = model(UserNotification::class); } public function index() { $user = $this->getCurrentUser(); if (!$user) { return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED); } $page = max(1, (int) ($this->request->getGet('page') ?? 1)); $perPage = min(100, max(1, (int) ($this->request->getGet('per_page') ?? 20))); $read = $this->request->getGet('read'); $query = $this->userNotification->newQuery() ->select([ 'notifications.*', 'user_notifications.is_read AS is_read', 'user_notifications.read_at', ]) ->join('notifications', 'notifications.id', '=', 'user_notifications.notification_id') ->where('user_notifications.user_id', (int) $user->id); if ($read !== null) { $isRead = filter_var($read, FILTER_VALIDATE_BOOLEAN); $query->where('user_notifications.is_read', $isRead ? 1 : 0); } $result = $this->paginate($query, $page, $perPage); return $this->success($result, 'Notifications retrieved successfully'); } public function show($id = null) { $user = $this->getCurrentUser(); if (!$user) { return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED); } $notification = $this->userNotification->newQuery() ->select([ 'notifications.*', 'user_notifications.is_read AS is_read', 'user_notifications.read_at', ]) ->join('notifications', 'notifications.id', '=', 'user_notifications.notification_id') ->where('user_notifications.user_id', (int) $user->id) ->where('user_notifications.notification_id', $id) ->first(); if (!$notification) { return $this->error('Notification not found', Response::HTTP_NOT_FOUND); } return $this->success($notification, 'Notification retrieved successfully'); } public function markRead($id = null) { $user = $this->getCurrentUser(); if (!$user) { return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED); } $userNotification = $this->userNotification->newQuery() ->where('user_id', (int) $user->id) ->where('notification_id', $id) ->first(); if (!$userNotification) { return $this->error('Notification not found', Response::HTTP_NOT_FOUND); } try { $this->userNotification->update($userNotification->id, [ 'is_read' => 1, 'read_at' => Carbon::now('UTC')->format('Y-m-d H:i:s'), ]); return $this->success(null, 'Notification marked as read'); } catch (\Throwable $e) { log_message('error', 'Notification mark read error: ' . (string) $e->getMessage()); return $this->respondError('Failed to mark notification as read', Response::HTTP_INTERNAL_SERVER_ERROR); } } }