CRM Module
π― Overviewβ
internal/api/v1/crm powers DashClicks' customer relationship management stack. It combines ten focused services that orchestrate contacts, deals, pipelines, reminders, and automations while enforcing account-level permissions, owner visibility rules, and data hygiene workflows. Controllers keep HTTP concerns thin; almost all business decisions live inside the service layer.
The module exposes /v1/crm/* routes, backs the dashboard CRM experience, and feeds reporting as well as downstream automation systems (notifications, queue-manager jobs, warehouse exports).
π Directory Structureβ
internal/api/v1/crm/
βββ .gitignore
βββ index.js # Router bootstrap that mounts entity routers
βββ README.md # Developer setup guide specific to CRM module
βββ controllers/ # Express controllers (automation, contact, deal, ...)
β βββ automation.controller.js
β βββ contact.controller.js
β βββ deal.controller.js
β βββ field.controller.js
β βββ import.controller.js
β βββ index.js
β βββ note.controller.js
β βββ pipeline.controller.js
β βββ reminder.controller.js
β βββ tag.controller.js
βββ routes/ # Router definitions + middleware wiring per entity
β βββ automation.route.js
β βββ contact.route.js
β βββ deal.route.js
β βββ field.route.js
β βββ import.route.js
β βββ index.js
β βββ note.route.js
β βββ pipeline.route.js
β βββ reminder.route.js
β βββ stage.route.js
β βββ tag.route.js
βββ services/ # Business logic layer (contact.service.js, etc.)
β βββ automation.service.js
β βββ contact.service.js
β βββ deal.service.js
β βββ field.service.js
β βββ import.service.js
β βββ index.js
β βββ note.service.js
β βββ pipeline.service.js
β βββ reminder.service.js
β βββ stage.service.js
β βββ tag.service.js
βββ tests/ # Jest suites (service/controller specs + fixtures)
β βββ automation.test.js
β βββ contact.test.js
β βββ deal.test.js
β βββ field.test.js
β βββ note.test.js
β βββ pipeline.test.js
β βββ reminder.test.js
β βββ stage.test.js
β βββ tag.test.js
β βββ fixtures/
β βββ field.js
βββ utils/ # Shared helpers (contact/deal/pipeline mappers, expansions)
β βββ automation.js
β βββ contact.js
β βββ deal.js
β βββ field.js
β βββ index.js
β βββ pipeline.js
β βββ stage.js
βββ validations/ # Joi schemas by domain (contact/, deal/, reminder/, ...)
βββ index.js
βββ automation/
β βββ index.js
βββ contact/
β βββ attachment.js
β βββ filter.js
β βββ getAll.js
β βββ index.js
β βββ search.js
β βββ business/
β β βββ business-put.js
β β βββ business.js
β β βββ get.js
β β βββ getAll.js
β β βββ index.js
β βββ person/
β βββ get.js
β βββ getAll.js
β βββ index.js
β βββ person-put.js
β βββ person.js
βββ deal/
β βββ index.js
βββ field/
β βββ index.js
βββ import/
β βββ index.js
βββ note/
β βββ index.js
βββ pipeline/
β βββ index.js
βββ reminder/
β βββ index.js
βββ stage/
β βββ index.js
βββ tag/
βββ index.js
Each subdirectory mirrors the service names below; there are no Git-tracked models/ or utilities/ folders here because Mongoose models and helpers are copied from shared/ at build time (see repository guide).
ποΈ MongoDB Collectionsβ
π Full Schema: See Database Collections Documentation
Core Entitiesβ
crm.contactsβ person/business records with embedded addresses, custom fields, attachmentscrm.dealsβ pipeline-bound opportunities with stage, owner, value, and automation flagscrm.pipeline/crm.pipeline.stagesβ pipeline definitions, stage ordering, automation metadatacrm.activityβ audit log of notes, reminders, stage changes (read via utilities)crm.remindersβ scheduled follow-ups and taskscrm.notesβ entity notes + threaded commentscrm.tagsβ account-scoped tagging taxonomy
Supporting Collectionsβ
_accountsβ sub-account linkage and configurationcrm.contact.import.resultsβ status + diagnostics for import jobsqueuesβ background jobs spawned by CRM services (imports, mass linking, automations)automation.logsβ execution history for stage automations
ποΈ Architecture Overviewβ
Key Responsibilitiesβ
- Normalise and secure CRUD for CRM entities under strict account/owner scoping
- Link contacts β deals β pipelines for reporting and automation triggers
- Provide mass operations (bulk delete, export, import) backed by queues
- Surface analytics endpoints (new contacts, pipeline leaderboards, automation logs)
Design Decisionsβ
- Service-first pattern: Controllers defer to services; tests target services directly
- Owner visibility enforcement: Most queries branch on
is_ownerflag and account preferences - Mongoose aggregations: Heavy pipelines compute filtered lists, analytics, exports
- Background work: Expensive flows push jobs into
Queueor Google Pub/Sub - Shared utilities:
utils/contact|deal|pipelinesupply reusable expansion, mapping, tag validation, timezone helpers
π Submodulesβ
| Domain | Doc | What it covers |
|---|---|---|
| Contacts | π₯ Contacts | People & businesses, linking, exports, mass updates |
| Deals | πΌ Deals | Pipeline-scoped opportunities, attachments, automation flags |
| Pipelines | π Pipelines | Pipeline CRUD, analytics, automation logs |
| Stages | βοΈ Stages | Per-pipeline stage CRUD and automation snapshots |
| Automation | π€ Automation | Stage-triggered workflow definitions and lifecycle |
| Notes | π Notes | Notes, comments, activity fan-out |
| Reminders | β° Reminders | Task queues, categorisation, completion rules |
| Tags | π Tags | Tag CRUD, locking, bulk removal side-effects |
| Fields | π§© Fields | Custom property configuration + user layout alignment |
| Import | π₯ Import | CSV/connector ingestion and queue orchestration |
π Data Flowβ
flowchart TD
subgraph Contact Intake
A[Create/Import Request] --> B{Validate + Map}
B -->|pass| C[Persist Contact]
C --> D[Expand/Enrich]
D --> E[Queue Background Work]
end
subgraph Deal Lifecycle
F[Deal Mutations] --> G[Pipeline Stage Logic]
G --> H{Automation?
Stage change?}
H -->|yes| I[Trigger Jobs + Logs]
G --> J[Currency Normalisation]
end
C -. links .-> F
E --> K[Queue Collection]
I --> L[automation.logs]
K --> M[Queue Manager]
M --> N[Notifications / Imports / Mass updates]
π Configuration & Dependenciesβ
| Variable | Description | Required |
|---|---|---|
BASE_CURRENCY | Fallback currency for deal/pipeline conversions | β |
GOOGLE_CLOUD_PROJECT_ID | Pub/Sub project used by import service | β (imports) |
APP_SECRET | JWT secret for internal socket notifications (contact linking) | β (contacts) |
CONVERSATION_SOCKET | Base URL for socket emit service when notifying support | β (contacts) |
External Servicesβ
- Wasabi S3 via
shared/utilities/wasabifor contact exports + attachment cleanup - Google Pub/Sub for asynchronous imports (CSV + connectors)
- Queue Manager for mass association jobs, automation retries, reminder fan-out
- Currency util uses shared exchanger to display pipeline totals consistently
π Quick Startβ
- Install shared dependencies:
pnpm install(root) followed bynpm run dev:buildas outlined in repo guide. - Start CRM service through VS Code debug configuration βInternal API β CRMβ. This ensures symlinked models/utilities and proper env injection.
- Seed required configs: confirm
BASE_CURRENCY, Pub/Sub credentials, and Wasabi keys exist in environment. - Run targeted tests before shipping changes:
pnpm test --filter crm(integration suites cover controllers + services). - Copy shared models if editing
shared/dependencies:npm run copySharedFiles.