Skip to content

Phone Number Assignment ​

Overview ​

Phone number assignments control which organizations and customers can use which numbers and in which direction. The system enforces a strict hierarchy with cascading rules.

PhoneNumberAssignment Model ​

typescript
{
  assignmentUID: string,       // Unique identifier
  phoneUID: string,            // Reference to PhoneNumber
  number: string,              // Denormalized phone number (for quick lookups)
  orgUID: string,              // Organization the number is assigned to
  customerUID: string,         // Customer within the org (optional for org-level)
  direction: "outbound" | "inbound" | "both",
  status: "active" | "inactive",
  inboundConfig: {             // Present only when direction includes inbound
    dispatchRuleId: string,    // LiveKit dispatch rule ID
    defaultAgentId: string,    // Agent linked for inbound calls
    isActive: boolean          // Whether inbound is currently active
  }
}

Assignment Hierarchy ​

Superadmin (owns phone numbers)
  └── Org (assigned by superadmin)
       └── Customer (assigned by org admin)

Assignments flow downward. An org must have access before a customer within that org can be assigned.

One Doc Per Combination ​

There is ONE assignment document per unique combination of phoneUID + orgUID + customerUID. Duplicates are never created.

Merge Behavior ​

When assigning a direction that already has a partial assignment:

  • Phone assigned as "outbound" to Org A
  • Later assigned as "inbound" to Org A
  • Result: existing doc upgraded to "both" (not a new doc)

This merge ensures the one-doc-per-combination invariant is maintained.

Direction Enforcement ​

Direction enforcement is hierarchical each level cannot exceed the level above:

PhoneNumber.direction >= Org Assignment.direction >= Customer Assignment.direction
ScenarioResult
Phone is "outbound" only, try to assign inbound to org❌ Rejected
Phone is "both", org assigned "outbound", customer wants "inbound"❌ Rejected (org doesn't have inbound)
Phone is "both", org assigned "both", customer wants "inbound"✅ Allowed

Inbound Exclusivity ​

Only one customer per phone number globally can have inbound access.

  • If Customer A in Org X has inbound for number +1555..., no other customer in any org can get inbound for that number
  • Outbound has no such exclusivity constraint multiple customers can share outbound access to the same number

Cascading Behavior ​

Revoking Org Access ​

When an org's assignment is revoked or downgraded, all customer assignments under that org are affected:

Full revocation (delete org assignment):

  • All customer assignments for that org + phone are deleted

Direction downgrade on org (e.g., "both" → "outbound"):

  • Customer assignments that only had the removed direction → deleted
  • Customer assignments that had "both" → downgraded to match

Downgrade Behavior for "both" ​

When a "both" assignment is downgraded:

Revoked DirectionResult
Revoking inboundAssignment becomes "outbound"
Revoking outboundAssignment becomes "inbound"
Revoking bothAssignment is deleted

Cascade Examples ​

Before: Org has "both", Customer has "both"
Action: Revoke inbound from Org
After:  Org has "outbound", Customer has "outbound"

Before: Org has "both", Customer has "inbound"  
Action: Revoke inbound from Org
After:  Org has "outbound", Customer assignment DELETED (can't keep inbound)

Before: Org has "both", Customer has "outbound"
Action: Revoke inbound from Org
After:  Org has "outbound", Customer still "outbound" (unaffected)

Last updated: