Deals
π Overviewβ
internal/api/v1/crm/services/deal.service.js manages every interaction a deal has with a pipeline. It validates pipeline scope, enforces owner/follower visibility, calculates totals with currency conversion, applies tag and DND rules, and orchestrates automation skip/retry flows. Controllers only validate payloadsβthis service runs all Mongo aggregations, expansion helpers, JSON export, and audit handling.
ποΈ Collections Usedβ
π Full Schema: See Database Collections Documentation
crm.dealsβ
- Operations: Heavy read/write, aggregations, CSV export source
- Model:
shared/models/deal.js - Usage Context: Stores deal core data, attachments, automation state, visibility flags
crm.pipelineβ
- Operations: Lookups and helper methods (
getDeals,addDeal,updateDeals) - Model:
shared/models/pipeline.js - Usage Context: Validates account scope and delegates stage-aware mutations
crm.pipeline.stagesβ
- Operations: Aggregated for stage sorting and stats
- Model:
shared/models/pipeline-stage.js - Usage Context: Provides ordering when sorting by stage name
crm.automationsβ
- Operations: Read during automation skip/retry validation
- Model:
shared/models/automation.js - Usage Context: Ensures overrides target a stage+pipeline automation that exists
crm.automation.logsβ
- Operations: Lookups to confirm retry eligibility
- Model:
shared/models/automation-log.js - Usage Context: Guards
retryAutomationDealso only failed runs can be retried
crm.dndβ
- Operations: Read while hydrating deals
- Model:
shared/models/dnd.js - Usage Context: Marks deals with contact-level email/SMS suppression status
π Data Flowβ
flowchart TD
A[Request] --> B{Validate pipeline + access}
B -->|invalid| Z[400 INVALID_PIPELINE]
B --> C[generateFilterObj + build query]
C --> D[Deal.aggregate/search]
D --> E[setPromises]
E --> F[expandDeals]
F --> G[CurrencyUtil.convert]
G --> H[Attach DND + format attachments]
H --> I[Response]
subgraph Mutations
J[Payload] --> K[validateTags + defaults]
K --> L[pipeline.addDeal/updateDeals]
L --> M[expandDeals + CurrencyUtil]
M --> I
end
subgraph Automation Overrides
N[Skip/Retry request] --> O[Find deal scoped to owner visibility]
O --> P[Fetch automation + logs]
P --> Q[Update skip_automations / retry_automations sets]
Q --> I
end
subgraph Export
R[Export request] --> S[Deal.aggregate + mapFields]
S --> T[json2csv]
T --> U[CSV download]
end
π§ Business Logic & Functionsβ
Listing & Exportβ
searchDeal({ id, account_id, uid, page, limit, q, expand, sortField, sortOrder, filter, is_owner, currencyCode, auth })β
- Aggregates deal ids with regex search across core and
additional_infovalues, respecting owner/follower visibility rules. - Applies pagination and custom stage sorting, hydrates results with
setPromises/expandDeals, and converts currency into the accountβs preferred unit. - Returns pagination metadata plus optional expanded associations when
expand=true.
getDeal({ id, account_id, uid, page, limit, account, filter, q, sortField, sortOrder, auth, stage_id, currencyCode })β
- Delegates to
pipeline.getDeals, allowing stage filters and reusable pagination. - After expansion, converts totals via
CurrencyUtil, formats attachments, and surfaces original value/currency for UI diffs.
exportDeal({ id, account_id, uid, q, sortField, sortOrder, filter, expand, is_owner, currencyCode, auth })β
- Reuses search filters, then maps expanded deals through
mapFieldsto align with account CSV configuration. - Streams data through
json2csvand returns the raw CSV buffer for controller delivery.
Creation & Bulk Mutationsβ
postDeal({ id, account_id, uid, auth, currencyCode, body })β
- Validates tag ids, applies defaults (status, currency, owner), and stores total contract value.
- Persists via
pipeline.addDeal, expands the result, and converts value into the callerβs currency context.
putDeal({ id, account_id, uid, body, expand, is_owner, auth })β
- Performs bulk updates across multiple deals using pipeline helpers, enforcing visibility rules when the caller is not the owner.
- Supports inline expansion of returned deals when
expand=true.
updateOneDeal({ id, deal_id, account_id, uid, body, auth, currencyCode })β
- Updates a single deal, recalculates totals, remaps custom fields, and returns an expanded payload with converted currency and attachment metadata.
deleteDeal, deleteMultiDeal, deleteOneDealβ
- Support pipeline-scoped bulk deletion (
deleteDeal), filter-driven mass deletion (deleteMultiDeal), and single deal removal (deleteOneDeal). - All variants validate pipeline ownership, respect
allbulk semantics, and clean references/attachments before returningSUCCESS.
Attachments & Metadataβ
putAttachmentsDeal({ id, deal_id, account_id, auth, body })β
- Uses pipeline helper
updateDealAttachmentto append attachments, returning the updated array. - Relies on upstream upload middlewareβservice only persists metadata.
deleteAttachmentDeal({ id, deal_id, attachmentId, account_id, auth })β
- Validates deal ownership then removes the embedded attachment document before saving.
Automation Overridesβ
skipAutomationDeal({ id, deal, automation, auth })β
- Confirms pipeline scope, visibility, and stage-level ownership before adding the automation id to
skip_automationsand pruning any pending retries.
retryAutomationDeal({ id, deal, automation, auth })β
- Repeats the validation chain, ensures an automation log exists marking the automation as failed, then queues a retry by updating
retry_automations.
π Integration Pointsβ
Internal Dependenciesβ
pipeline.getDeals,pipeline.addDeal,pipeline.updateDeals,pipeline.updateDealAttachmentgenerateFilterObjfor advanced filter DSL β Mongo selectorsdealUtils(setPromises,expandDeals,mapFields,validateTags,checkCsv)CurrencyUtilfor live conversion and currency metadatajson2csvfor export formatting andloggerfor error capture
External Servicesβ
- None directly. File uploads/cleanup are handled upstream; exports are streamed back to the client.
π§ͺ Edge Cases & Special Handlingβ
- Owner visibility: Non-owners can only see deals when visibility is
allor they are listed as owner/follower; enforcement is consistent across search, list, delete, and automation overrides. - Custom field search: Search pipelines unwrap
additional_infoto allow regex queries across dynamic fields. - DND overlay: During expansion, the service resolves DND flags across related contacts and surfaces an
{ email, phone }lockout object. - Contract totals:
total_deal_valuemultiplies value Γ contract length, ensuring reports respect recurring revenue. - Automation safety: Skip/retry paths validate both stage ownership and prior automation state to prevent accidental replays.
β οΈ Important Notesβ
- π¨ Always validate tags via
validateTagsbefore persistingβinvalid ids returnINVALID_TAGSfrom the service. - π° Currency conversions require
BASE_CURRENCY; missing env configuration will trigger conversion failures. - π€ CSV exports stream raw textβcontrollers must set headers (
text/csv) before piping back to clients.