Reminders
π Overviewβ
internal/api/v1/crm/services/reminder.service.js keeps track of follow-up reminders tied to contacts or deals. It calculates category counters (upcoming, past due, completed), enforces visibility via entity ownership, stitches in assignment data, and posts every mutation to the CRM activity timeline. Controllers validate JOI payloads while this service performs aggregation, pagination, permission checks, and Mongo updates.
ποΈ Collections Usedβ
π Full Schema: See Database Collections Documentation
crm.remindersβ
- Operations: Core CRUD, aggregations for
getAllReminder, read markers, pin ordering - Model:
shared/models/reminder.js - Usage Context: Stores reminder metadata, linked entity
_ids, assignments, and read history (read_by)
crm.activityβ
- Operations: Insert/delete mirror entries via
addActivity - Model:
shared/models/activity.js - Usage Context: Keeps the global timeline in sync with reminder lifecycle events
Related Entity Collectionsβ
crm.contacts,crm.dealsare consulted to validate access and to hydrate response payloads whenexpand=true
π Data Flowβ
flowchart TD
Client -->|REST| Controller
Controller --> ReminderService
ReminderService -->|check access| ContactsDeals[(Contacts / Deals)]
ReminderService -->|aggregate| Reminders[(crm.reminders)]
ReminderService -->|log event| Activity[(crm.activity)]
Reminders --> Response
π§ Service Entry Pointsβ
Aggregated Overviewβ
getAllReminder({ account_id, uid, page, limit, type })- Runs a facet aggregation to compute category counts and page data by
type(upcoming,past_due,completed) - Filters on assigned user and account and returns pinned-first ordering
- Runs a facet aggregation to compute category counts and page data by
Entity-Scoped Listingβ
-
getReminder({ account_id, uid, contact_id, deal_id, page, limit, expand, type, is_owner })- Validates contact/deal access using ownership, followers, or visibility before querying reminders
- Applies pagination, optional population (controlled by
expand), and surfaces assigned user/contact/deal snapshots - Non-owners either need to have created the reminder or be attached to an accessible entity
-
filterReminder({ account_id, uid, contact_id, deal_id, page, limit, type, expand, body, is_owner })- Adds advanced filters (date ranges, assigned users, status) while enforcing the same entity permissions as
getReminder - Returns pinned-first lists with pagination metadata
- Adds advanced filters (date ranges, assigned users, status) while enforcing the same entity permissions as
Creation & Updatesβ
-
postReminder({ account_id, uid, body, is_owner, auth })- Ensures the linked contact/deal is accessible before persisting
- Creates the reminder, populates associations, then calls
addActivityso the timeline captures the task
-
updateReminder({ account_id, uid, expand, id, is_owner, body })- Rejects empty payloads and revalidates entity access for non-owners before applying updates
- Returns the freshly populated reminder
Read State & Deletionβ
-
updateRead({ account_id, uid, id })- Uses
$addToSetto track which users marked a reminder as read
- Uses
-
updateReadAll({ account_id, uid })- Bulk-updates
read_byfor the requesting user across all reminders in the account
- Bulk-updates
-
deleteOneReminder({ account_id, uid, id })- Removes the reminder document and any related
crm.activityrows referencing it
- Removes the reminder document and any related
-
getOneReminder({ account_id, uid, expand, id })- Loads a single reminder with populated account/contact/deal/assigned references for detail views
π Integration Pointsβ
Internalβ
utilities.generatePaginationstandardises pagination blocksaddActivitypostsreminderevents when new tasks are createdreminderExpandOptionstoggles population based on theexpandquery parameter
Externalβ
- None directlyβthe notification layer consumes activity feed data downstream
β οΈ Edge Cases & Guardrailsβ
- Permission checks: Non-owners must either create the reminder or have access to the linked entity via visibility/owner/follower rules
- Pinned ordering: Lists sort pinned reminders before chronological order to surface high-priority tasks
- Category counts:
getAllRemindercalculatesupcoming,past_due, andcompletedtotals in a single aggregation pass - Read tracking:
updateReadandupdateReadAllde-dupe user IDs with$addToSet - Activity cleanup: Deleting a reminder also removes corresponding activity entries to avoid orphaned timeline events