Database CPU utilization was spiking due to expensive notification COUNT
queries. Analysis revealed two critical issues:
1. Missing database index: Notification count queries were performing
table scans without proper indexing
2. Duplicate WHERE clauses: SQL queries contained redundant read_at IS
NULL conditions, causing unnecessary query complexity
### Root Cause Analysis
The expensive queries were:
```
-- 41.61 calls/sec with duplicate condition
SELECT COUNT(*) FROM "notifications"
WHERE "notifications"."user_id" = $1
AND "notifications"."account_id" = $2
AND "notifications"."snoozed_until" IS NULL
AND "notifications"."read_at" IS NULL
AND "notifications"."read_at" IS NULL -- Duplicate!
```
This was caused by a logic error in NotificationFinder#unread_count
introduced in commit cd06b2b33 (PR #8907). The method assumed
@notifications contained all notifications, but @notifications was
already filtered to unread notifications in most cases.
### The Default Query Flow:
1. Frontend calls: NotificationsAPI.getUnreadCount() →
/notifications/unread_count
2. No parameters sent, so params = {}
3. NotificationFinder setup:
- find_all_notifications: WHERE user_id = ? AND account_id = ?
- filter_snoozed_notifications: WHERE snoozed_until IS NULL
- filter_read_notifications: WHERE read_at IS NULL (because
type_included?('read') is false)
4. unread_count called: Adds another WHERE read_at IS NULL
----
### Solution
1. Added Missing Database Index
- Index: (user_id, account_id, snoozed_until, read_at)
2. Fixed Duplicate WHERE Clause Logic
Optimization #11183 missed a condition where the inbox_id filter is
manually passed. Due to the previous change, the inbox filter was being
discarded for admins, although it continued to work correctly for
agents.
This PR includes a fix for that specific case and adds a spec to
explicitly test it.
- `updated_within' accepts value in seconds and returns all conversations updated in the given period with out pagination. This API will assist in our refetch logic on socket disconnect
ref: #8888
Updating the `unattended` tab to include conversations where the customer responded and is awaiting an agent's response.
Previously it showed only the conversations where the first response was pending.
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This change adds the ability to include a `source_id` param when querying the `/api/v1/accounts/{account_id}/conversations/search` endpoint. It restricts to results to only conversations related to a contact_inbox with the provided parameter. My motivation for adding this feature was to allow an external API to communicate with a specific conversation with only an awareness of the conversation `source_id` from the client.
Co-authored-by: Sojan Jose <sojan@pepalo.com>
* Use conversationPage module for pagination
* Load more conversations
* Reset list if conversation status is changed
* Add specs to conversationPage
* Reset filter when page is re-mounted
* Update text
* Update text
* [#247] Filters conversation by status
* Fixes conversation finder specs
* [#248] Paginates conversation
* Use method name in description
* Move page to default param, add filters on frontend
* Fix code climate issues