Change Owner Automation Processor
Overview
The Change Owner automation reassigns deal ownership when deals enter a specific pipeline stage. The previous owner is automatically added as a follower to maintain visibility.
Source File: queue-manager/queues/deals/automations/owner.js
Triggered By: queue-manager/services/deals/automations.js
Business Impact: HIGH - Deal assignment
Processing Logic
sequenceDiagram
participant AUTO as Automation Service
participant QUEUE as Owner Queue
participant DEAL as Deals
participant USER as Users
AUTO->>QUEUE: Add automation job
QUEUE->>USER: Validate new owner exists
QUEUE->>DEAL: Find eligible deals
loop For Each Deal
QUEUE->>DEAL: Check if already owner
alt Not Current Owner
QUEUE->>DEAL: Add old owner to followers
QUEUE->>DEAL: Set new owner
QUEUE->>DEAL: Mark automation triggered
end
end
Key Features
Owner Validation
const ownerID = new mongoose.Types.ObjectId(automation.data.owner);
const ownerData = await User.find({
_id: ownerID,
account: automation.account_id,
}).lean();
if (!ownerData) {
throw new Error('Owner does not exist.');
}
Owner Reassignment
if (deal.owner.toString() === ownerID.toString()) {
throw new Error('Already an owner.');
}
// Add old owner to followers (maintaining visibility)
let tempFollowers = new Set([deal.owner]);
deal.followers
.filter(follower => follower.toString() !== ownerID.toString())
.forEach(follower => tempFollowers.add(new mongoose.Types.ObjectId(follower)));
deal.followers = [...tempFollowers];
// Set new owner
deal.owner = ownerID;
deal.last_updated_by = userID;
await deal.save();
Key Logic
Follower Management
- Add Old Owner: Previous owner automatically becomes follower
- Remove New Owner from Followers: Prevents duplicate (owner + follower)
- Preserve Existing Followers: All other followers retained
- Use Set: Ensures no duplicate followers
Collections Used
Input: deal-automation
Validation: user
Query: deal
Update: deal (owner and followers fields)
Use Cases
Example 1: Hand-Off to Sales Manager
// Automation
{
stage_id: "negotiation",
action: "change_owner",
data: {
owner: salesManagerID
},
delay: 0
}
// Result: SDR's deals automatically assigned to manager at negotiation stage
Example 2: Round-Robin Assignment
// Automation (combined with external logic)
{
stage_id: "new_lead",
action: "change_owner",
data: {
owner: nextAvailableRepID // Calculated externally
},
delay: 0
}
Example 3: Specialist Assignment
// Automation
{
stage_id: "technical_evaluation",
action: "change_owner",
data: {
owner: technicalSpecialistID
},
delay: 0
}
// Result: Technical specialist takes ownership during evaluation
Follower Behavior
Before Automation
{
owner: userA,
followers: [userB, userC]
}
After Automation (new owner: userD)
{
owner: userD,
followers: [userA, userB, userC] // userA (old owner) added
}
Special Case: New Owner Already a Follower
// Before
{
owner: userA,
followers: [userB, userD] // userD already following
}
// After (new owner: userD)
{
owner: userD,
followers: [userA, userB] // userD removed from followers, userA added
}
Error Handling
Common Errors
- Owner Doesn't Exist: Invalid user ID or user not in account
- Already Owner: Deal already owned by target user
- Invalid ObjectId: Malformed owner ID
Error Response
{
deal: dealID,
owner: ownerID,
message: "Already an owner.",
additional_info: {...}
}
Business Value
Why Auto-Reassign?
- Stage-Based Specialization: Different stages require different expertise
- Workload Distribution: Distribute deals automatically
- Visibility: Old owner stays informed as follower
- Consistency: Ensures proper handoffs happen
Performance
Execution Time: 150-400ms per deal
Complexity: LOW-MEDIUM
Lines of Code: 165