Contact
Introduction
The Contact entity is a polymorphic aggregate root that represents all business relationships in the system - customers, carriers, vendors, employees, agents, and more. Unlike most entities that represent a single concept, Contact uses the ContactType enum to differentiate between 15 distinct business roles, each with specific behaviors and validation rules.
Contact supports hierarchical relationships (parent/child contacts), multi-division access control, contact linking (representing relationships between contacts), address management, payment terms, credit limits, and extensible custom properties. Contacts can have associated system users for portal access, carrier equipment for logistics tracking, and discounts for pricing.
Entity Structure
Properties
| Property Name | Type | Required | Description |
|---|---|---|---|
| ContactId | int | Yes | Primary key - unique contact identifier |
| Name | string | Yes | Company or individual name |
| ContactType | ContactType | Yes | Type of contact (Customer, Carrier, Vendor, etc.) |
| OrganizationId | int | Yes | Organization owning this contact (multi-tenancy) |
| DivisionId | int | Yes | Primary division for this contact |
| Division | Division | No | Navigation property to primary division |
| AccountNumber | string? | No | Customer/vendor account number |
| ContactFirstName | string? | No | First name of primary contact person |
| ContactLastName | string? | No | Last name of primary contact person |
| EmailAddress | string? | No | Primary email address |
| PhoneNumber | string? | No | Primary phone number (required for most types) |
| MobilePhoneNumber | string? | No | Mobile phone number |
| FaxNumber | string? | No | Fax number |
| Website | string? | No | Company website URL |
| IdNumber | string? | No | Tax ID, EIN, DUNS, or passport number |
| IdNumberType | IDNumberType? | No | Type of ID number (EIN, DUNS, ForeignEntityId, Other) |
| CreditLimit | decimal? | No | Credit limit for customers |
| PaymentTermId | int? | No | Default payment terms (Net 30, etc.) |
| PaymentTerm | PaymentTerm | No | Navigation property to payment terms |
| PaidAs | PaidAs? | No | Prepaid or Collect (freight payment method) |
| IsACorporation | bool? | No | Whether contact is a corporation |
| IsDeleted | bool | Yes | Soft delete flag (default: false) |
| ParentContactId | int? | No | Parent contact for hierarchical relationships |
| ContactStatusId | int? | No | Current status of contact |
| ContactStatus | ContactStatus | No | Navigation property to status |
| EntityTypeId | int? | No | Custom entity type classification |
| EntityType | EntityType | No | Navigation property to entity type |
| CustomValues | Dictionary<string, object?> | No | Extensible custom properties dictionary |
| Tags | List<string> | No | Tag list for categorization |
| SearchVector | NpgsqlTsVector | No | Full-text search vector (managed by database) |
| Created | DateTime | Yes | Creation timestamp (inherited from AuditableEntity) |
| CreatedBy | string | Yes | User ID who created the contact (inherited) |
| LastModified | DateTime | Yes | Last modification timestamp (inherited) |
| LastModifiedBy | string | Yes | User ID who last modified (inherited) |
ContactType Enum
The ContactType determines validation rules, available features, and business logic:
| Value | Description | Can Have Accounting | Can Have Equipment | Can Have User | Must Have Phone |
|---|---|---|---|---|---|
| Customer | Customer receiving services | Yes | No | Yes (portal) | Yes |
| Carrier | Transportation carrier | Yes | Yes | No | Yes |
| Vendor | Supplier of services | No | No | No | Yes |
| Contact | Individual contact (must link to another contact) | No | No | No | No |
| Driver | Truck driver or operator | No | No | No | Yes |
| Employee | Company employee | No | No | Yes (internal) | Yes |
| SalesPerson | Sales representative | No | No | No | Yes |
| ForwardingAgent | Freight forwarder or agent | No | No | No | Yes |
| FactoringCompany | Factoring/financing company | No | No | No | Yes |
| Lead | Potential customer | No | No | No | No |
| PoolPoint | Freight pool or cross-dock | No | No | Yes | No |
| DistributionCenter | Distribution center | No | No | No | No |
| Store | Retail store or location | No | No | Yes | No |
| ContactUser | User associated with contact | No | No | No | No |
| USPPI | US Principal Party in Interest (export) | No | No | No | No |
IDNumberType Enum
| Value | Description |
|---|---|
| EIN | Employer Identification Number (US tax ID) |
| DUNS | D-U-N-S Number (Dun & Bradstreet) |
| ForeignEntityId | Foreign entity identifier (e.g., passport number) |
| Other | Other identification number type |
PaidAs Enum
| Value | Description |
|---|---|
| Prepaid | Freight charges paid by shipper |
| Collect | Freight charges paid by consignee |
Relationships (Navigation Properties)
| Relationship | Type | Description |
|---|---|---|
| ContactAddresses | ICollection<ContactAddress> | Addresses for this contact (billing, shipping, physical) |
| ContactLinks | ICollection<ContactLink> | Links from this contact to other contacts |
| LinkToContactLinks | ICollection<ContactLink> | Links to this contact from other contacts |
| Contacts | ICollection<Contact> | Contacts linked to this contact |
| LinksToContacts | ICollection<Contact> | Contacts this contact is linked to |
| Orders | ICollection<Order> | Orders associated with this contact |
| OrderEntities | ICollection<OrderEntity> | Dynamic role assignments (shipper, consignee, etc.) |
| OrderCarriers | ICollection<OrderCarrier> | Carrier assignments on orders |
| Rates | ICollection<Rate> | Rates applicable to this contact |
| Discounts | ICollection<Discount> | Discounts through ContactDiscount junction |
| ContactDiscounts | ICollection<ContactDiscount> | Junction table for contact-discount relationships |
| AdditionalDivisions | ICollection<Division> | Additional divisions this contact can access |
| ContactDivisions | ICollection<ContactDivision> | Junction table for multi-division access |
| UserEmployee | AspNetUserEmployee | User account for portal/employee access |
| EquipmentTypes | ICollection<EquipmentType> | Equipment types (for Carrier contacts) |
| CarrierEquipments | ICollection<CarrierEquipment> | Carrier equipment tracking (for Carrier contacts) |
| Division | Division | Primary division |
| PaymentTerm | PaymentTerm | Default payment terms |
| ContactStatus | ContactStatus | Current status |
| EntityType | EntityType | Custom classification |
YAML Configuration
Creating a Customer Contact
# Create a new customer with billing address
- task: Contact/Create@1
name: createCustomer
inputs:
organizationId: ${organizationId}
contact:
name: "Acme Manufacturing Inc."
contactType: Customer
divisionId: ${divisionId}
accountNumber: "CUST-2025-001"
contactFirstName: "John"
contactLastName: "Smith"
emailAddress: "[email protected]"
phoneNumber: "+1-555-0123"
mobilePhoneNumber: "+1-555-0124"
website: "https://www.acme.com"
idNumber: "12-3456789"
idNumberType: EIN
creditLimit: 50000.00
paymentTermId: ${net30TermId}
paidAs: Prepaid
isACorporation: true
tags:
- "preferred-customer"
- "west-coast"
- "manufacturing"
customValues:
industryCode: "NAICS-332"
accountManager: "Sarah Johnson"
preferredCarrier: "FedEx"
outputs:
- contact: customer
# Add billing address
- task: ContactAddress/Create@1
name: addBillingAddress
inputs:
organizationId: ${organizationId}
contactAddress:
contactId: ${customer.contactId}
addressType: Billing
addressLine: "123 Industrial Blvd"
addressLine2: "Suite 200"
cityName: "Los Angeles"
stateCode: "CA"
postalCode: "90001"
countryCode: "US"
Creating a Carrier Contact with Equipment
# Create carrier contact
- task: Contact/Create@1
name: createCarrier
inputs:
organizationId: ${organizationId}
contact:
name: "Coast to Coast Trucking LLC"
contactType: Carrier
divisionId: ${divisionId}
accountNumber: "CARR-500"
emailAddress: "[email protected]"
phoneNumber: "+1-555-TRUCK"
website: "https://coasttrucking.com"
idNumber: "98-7654321"
idNumberType: EIN
paymentTermId: ${net15TermId}
isACorporation: true
tags:
- "LTL"
- "refrigerated"
customValues:
dotNumber: "1234567"
mcNumber: "MC-987654"
insuranceCoverage: 1000000
safetyRating: "Satisfactory"
outputs:
- contact: carrier
# Assign equipment to carrier
- task: Contact/Update@1
name: assignCarrierEquipment
inputs:
organizationId: ${organizationId}
contactId: ${carrier.contactId}
contact:
carrierEquipments:
- equipmentTypeId: ${truck53ftId}
equipmentNumber: "TRUCK-001"
year: 2023
- equipmentTypeId: ${reeferTrailerId}
equipmentNumber: "TRAILER-R01"
year: 2024
Creating an Employee Contact with User Access
# Create employee contact
- task: Contact/Create@1
name: createEmployee
inputs:
organizationId: ${organizationId}
contact:
name: "Martinez, Carlos"
contactType: Employee
divisionId: ${divisionId}
contactFirstName: "Carlos"
contactLastName: "Martinez"
emailAddress: "[email protected]"
phoneNumber: "+1-555-0199"
mobilePhoneNumber: "+1-555-0198"
tags:
- "operations"
- "manager"
customValues:
department: "Operations"
title: "Operations Manager"
hireDate: "2020-01-15"
employeeId: "EMP-1234"
outputs:
- contact: employee
# Assign user account for system access
- task: Contact/Update@1
name: assignUserAccount
inputs:
organizationId: ${organizationId}
contactId: ${employee.contactId}
contact:
userId: ${aspNetUserId}
Hierarchical Contacts - Parent/Child Relationship
# Create parent company
- task: Contact/Create@1
name: createParentCompany
inputs:
organizationId: ${organizationId}
contact:
name: "Global Logistics Corporation"
contactType: Customer
divisionId: ${divisionId}
accountNumber: "CUST-PARENT-001"
phoneNumber: "+1-555-0100"
outputs:
- contact: parentCompany
# Create subsidiary
- task: Contact/Create@1
name: createSubsidiary
inputs:
organizationId: ${organizationId}
contact:
name: "Global Logistics - West Coast Division"
contactType: Customer
divisionId: ${divisionId}
parentContactId: ${parentCompany.contactId}
accountNumber: "CUST-SUB-001"
phoneNumber: "+1-555-0101"
customValues:
billingConsolidation: "parent"
region: "West"
outputs:
- contact: subsidiary
Contact Linking - Representing Relationships
# Create primary decision maker contact
- task: Contact/Create@1
name: createDecisionMaker
inputs:
organizationId: ${organizationId}
contact:
name: "Jane Doe"
contactType: Contact # Generic contact type
divisionId: ${divisionId}
contactFirstName: "Jane"
contactLastName: "Doe"
emailAddress: "[email protected]"
phoneNumber: "+1-555-0150"
outputs:
- contact: decisionMaker
# Link this contact to the customer company
- task: Contact/Update@1
name: linkToCustomer
inputs:
organizationId: ${organizationId}
contactId: ${decisionMaker.contactId}
contact:
contactLinks:
- linkedContactId: ${customer.contactId}
relationshipType: "Decision Maker"
Multi-Division Access Control
# Give customer access to multiple divisions
- task: Contact/Update@1
name: assignMultipleDivisions
inputs:
organizationId: ${organizationId}
contactId: ${customer.contactId}
contact:
contactDivisions:
- divisionId: ${eastCoastDivisionId}
- divisionId: ${westCoastDivisionId}
- divisionId: ${centralDivisionId}
Assigning Discounts to Contact
# Apply volume discounts to customer
- task: Contact/Update@1
name: assignDiscounts
inputs:
organizationId: ${organizationId}
contactId: ${customer.contactId}
contact:
contactDiscounts:
- discountId: ${volumeDiscount10PercentId}
- discountId: ${earlyPaymentDiscount2PercentId}
- discountId: ${preferredCustomerDiscountId}
Querying Contact with All Relationships
# Query customer with complete data using GraphQL
- task: Query/GraphQL
name: getCustomerWithRelationships
inputs:
organizationId: ${organizationId}
query: |
query GetContact($contactId: ID!) {
contact(id: $contactId) {
contactId
name
contactType
accountNumber
emailAddress
phoneNumber
creditLimit
contactAddresses { addressType addressLine cityName stateCode }
contactLinks { linkedContact { name } relationshipType }
division { divisionName }
contactDivisions { division { divisionName } }
paymentTerm { termName }
contactStatus { statusName }
userEmployee { user { userName email } }
contactDiscounts { discount { name percentage } }
orders { orderNumber orderStatus { statusName } }
rates { originPort { name } destinationPort { name } amount }
}
}
variables:
contactId: ${customerId}
outputs:
- response.contact: fullCustomer
Updating Contact Properties
# Update customer credit limit, payment terms, and contact information
- task: Contact/Update@1
name: updateCustomerInfo
inputs:
organizationId: ${organizationId}
contactId: ${customerId}
contact:
creditLimit: 100000.00
paymentTermId: ${net45TermId}
emailAddress: "[email protected]"
Working with Custom Values and Tags
# Update custom values and tags
- task: Contact/Update@1
name: updateCustomData
inputs:
organizationId: ${organizationId}
contactId: ${customerId}
contact:
customValues:
salesRepId: ${repId}
preferredShippingDay: "Tuesday"
specialInstructions: "Requires 24hr advance notice"
lastReviewDate: "2025-01-15"
creditCheckDate: "2025-01-01"
tags:
- "preferred-customer"
- "high-volume"
- "west-coast"
- "temperature-sensitive"
Key Methods
The Contact entity provides extensive methods for managing the aggregate:
Property Updates (Basic Information)
ChangeName(string)- Update contact nameChangeAccountNumber(string?)- Update account numberChangeContactFirstName(string?)- Update first nameChangeContactLastName(string?)- Update last nameChangeEmailAddress(string?)- Update email addressChangePhoneNumber(string?)- Update phone numberChangeMobilePhoneNumber(string?)- Update mobile numberChangeFaxNumber(string?)- Update fax numberChangeWebsite(string?)- Update website URL
Contact Type and Classification
ChangeContactType(ContactType)- Change contact type (Customer, Carrier, etc.)ChangeIdNumber(string?)- Update ID number (EIN, DUNS, etc.)ChangeIdNumberType(IDNumberType?)- Update ID number typeChangeIsACorporation(bool?)- Set corporation flagChangeContactStatusId(int?)- Update contact status
Financial Settings
ChangeCreditLimit(decimal?)- Update credit limitChangePaymentTermId(int?)- Update payment termsChangePaymentTerm(PaymentTerm)- Set payment term objectChangePaidAs(PaidAs?)- Set prepaid or collect
Organizational Structure
ChangeDivisionId(int)- Change primary divisionChangeDivision(Division)- Set division objectChangeAdditionalDivisions(List<DivisionObjectId>?)- Set multi-division access (publishes ContactChangedDivisions event)ChangeParentContactId(int?)- Set parent contact for hierarchy
Address and Contact Management
ChangeContactAddresses(IEnumerable<ContactAddress>?)- Manage addresses (merge logic: updates existing, adds new)ChangeContactLinks(IEnumerable<ContactLink>)- Set contact links (relationships to other contacts)ChangeLinksToContacts(IEnumerable<Contact>)- Set linked contactsChangeContacts(ICollection<Contact>)- Set contact collection
User and Access Management
AssignUserId(string)- Create user account for employee or customer portalChangeUserEmployee(AspNetUserEmployee?)- Set user employee mapping
Carrier-Specific Features
ChangeEquipmentTypes(ICollection<EquipmentType>)- Set equipment types (for carriers)ChangeCarrierEquipments(ICollection<CarrierEquipment>)- Manage carrier equipment
Pricing and Discounts
ChangeDiscounts(List<DiscountObjectId>)- Set applicable discounts (publishes ContactChangedDiscounts event)
Extensibility
ChangeCustomValues(Dictionary<string, object?>?)- Update custom properties (merges with existing)ChangeTags(List<string>?)- Update tag list
Order Relationships (Internal Use)
ChangeOrders(IEnumerable<Order>)- Set order collectionChangeOrderCarriers(IEnumerable<OrderCarrier>)- Set order carrier assignments
Soft Delete
ChangeIsDeleted(bool)- Soft delete or restore contact
Helper Methods
GetBillingAddressId()- Retrieve billing address ID
Static Validation Methods
These methods determine what features are available based on ContactType:
CanHaveAccounting(ContactType)- Returns true for Carrier, CustomerCanHaveLinkedContact(ContactType)- Returns true for Contact, Carrier, Employee, Customer, LeadMustHaveLinkedContact(ContactType)- Returns true for Contact type onlyMustHavePhoneNumber(ContactType)- Returns true for most contact typesCanHaveUserEmployee(ContactType)- Returns true for Employee, Customer, PoolPoint, StoreCanHaveEquipments(ContactType)- Returns true for Carrier only
Domain Events
The Contact entity publishes two domain events:
ContactChangedDiscounts
Published when ChangeDiscounts() is called. Allows discount assignment logic to be handled asynchronously (e.g., updating junction table, recalculating pricing).
Event Properties:
_Contact- The contact being updatedDiscountIds- List of discount IDs to associate with this contact
ContactChangedDivisions
Published when ChangeAdditionalDivisions() is called. Allows multi-division access control to be managed asynchronously (e.g., updating junction table, propagating permissions).
Event Properties:
_Contact- The contact being updatedDivisionIds- List of division IDs this contact can access
Use Cases
1. Customer Onboarding with Complete Profile
# Create customer with full profile
- task: Contact/Create@1
name: onboardNewCustomer
inputs:
organizationId: ${organizationId}
contact:
name: "Tech Innovations LLC"
contactType: Customer
divisionId: ${divisionId}
accountNumber: "CUST-${autoIncrement}"
contactFirstName: "Michael"
contactLastName: "Chen"
emailAddress: "[email protected]"
phoneNumber: "+1-555-TECH"
website: "https://techinnovations.com"
idNumber: "45-6789012"
idNumberType: EIN
creditLimit: 75000.00
paymentTermId: ${net30TermId}
isACorporation: true
customValues:
salesRepName: "Jessica Martinez"
industryVertical: "Technology Hardware"
annualRevenue: 5000000
accountTier: "Gold"
outputs:
- contact: newCustomer
# Add multiple addresses
- task: ContactAddress/Create@1
name: addBillingAddress
inputs:
organizationId: ${organizationId}
contactAddress:
contactId: ${newCustomer.contactId}
addressType: Billing
addressLine: "500 Tech Center Dr"
cityName: "San Jose"
stateCode: "CA"
postalCode: "95110"
countryCode: "US"
- task: ContactAddress/Create@1
name: addShippingAddress
inputs:
organizationId: ${organizationId}
contactAddress:
contactId: ${newCustomer.contactId}
addressType: Shipping
addressLine: "1000 Warehouse Way"
cityName: "Fremont"
stateCode: "CA"
postalCode: "94538"
countryCode: "US"
- task: ContactAddress/Create@1
name: addPhysicalAddress
inputs:
organizationId: ${organizationId}
contactAddress:
contactId: ${newCustomer.contactId}
addressType: Physical
addressLine: "500 Tech Center Dr"
cityName: "San Jose"
stateCode: "CA"
postalCode: "95110"
countryCode: "US"
# Apply customer discounts
- task: Contact/Update@1
name: applyDiscounts
inputs:
organizationId: ${organizationId}
contactId: ${newCustomer.contactId}
contact:
contactDiscounts:
- discountId: ${goldTierDiscountId}
- discountId: ${volumeDiscount15PercentId}
2. Carrier Network Management
# Create carrier with DOT/MC numbers
- task: Contact/Create@1
name: createCarrierProfile
inputs:
organizationId: ${organizationId}
contact:
name: "Nationwide Freight Services"
contactType: Carrier
divisionId: ${divisionId}
accountNumber: "CARR-${sequence}"
phoneNumber: "+1-800-FREIGHT"
emailAddress: "[email protected]"
website: "https://nationwidefreight.com"
idNumber: "11-2233445"
idNumberType: EIN
paymentTermId: ${quickPayTermId}
customValues:
dotNumber: "7654321"
mcNumber: "MC-123456"
scacCode: "NWFS"
insuranceProvider: "Truckers Insurance Co"
insurancePolicyNumber: "POL-987654"
insuranceExpiry: "2026-12-31"
safetyRating: "Satisfactory"
serviceArea: ["CA", "NV", "AZ", "OR", "WA"]
outputs:
- contact: carrier
# Track carrier equipment
- task: Contact/Update@1
name: assignCarrierFleet
inputs:
organizationId: ${organizationId}
contactId: ${carrier.contactId}
contact:
carrierEquipments:
- equipmentTypeId: ${dryVan53ftId}
equipmentNumber: "TRL-001"
year: 2023
make: "Great Dane"
vin: "1GRAA06285P123456"
- equipmentTypeId: ${dryVan53ftId}
equipmentNumber: "TRL-002"
year: 2024
make: "Wabash"
- equipmentTypeId: ${tractorId}
equipmentNumber: "TRAC-100"
year: 2022
make: "Freightliner"
3. Employee Directory with Portal Access
# Create employee
- task: Contact/Create@1
name: createSalesRep
inputs:
organizationId: ${organizationId}
contact:
name: "Johnson, Emily"
contactType: Employee
divisionId: ${salesDivisionId}
contactFirstName: "Emily"
contactLastName: "Johnson"
emailAddress: "[email protected]"
phoneNumber: "+1-555-0188"
mobilePhoneNumber: "+1-555-0189"
customValues:
employeeId: "EMP-5678"
department: "Sales"
title: "Senior Account Executive"
hireDate: "2018-03-15"
manager: "Robert Smith"
commissionRate: 0.05
outputs:
- contact: salesRep
# Grant system access and multi-division permissions
- task: Contact/Update@1
name: configureEmployeeAccess
inputs:
organizationId: ${organizationId}
contactId: ${salesRep.contactId}
contact:
userId: ${ejohnsonUserId}
contactDivisions:
- divisionId: ${eastDivisionId}
- divisionId: ${westDivisionId}
Best Practices
1. Contact Type Selection
- Choose the appropriate ContactType based on business role
- Customer, Carrier types enable accounting transactions
- Employee type enables internal system access
- Contact type (generic) must always link to another contact
2. Phone Number Validation
- Most ContactTypes require a phone number (use static
MustHavePhoneNumber()to check) - Provide PhoneNumber for Carrier, Customer, Driver, Employee, FactoringCompany, ForwardingAgent, SalesPerson, Vendor
3. Address Management
- Use
ChangeContactAddresses()for address updates - it intelligently merges existing addresses - Provide AddressType (Billing, Shipping, Physical) for proper classification
- Billing address is critical for invoicing - use
GetBillingAddressId()helper
4. Hierarchical Contacts
- Use ParentContactId for corporate hierarchies (parent company → subsidiaries)
- Enable consolidated billing, reporting, and credit management at parent level
- Store region or division-specific data in child contact CustomValues
5. Contact Linking
- Use ContactLink for representing relationships between contacts (decision makers, authorized signers, etc.)
- Generic Contact type is designed specifically for individuals linked to companies
- ContactLinks are directional - consider creating bidirectional links when needed
6. Multi-Division Access
- Use
ChangeAdditionalDivisions()for contacts that span multiple divisions - Primary DivisionId is mandatory, additional divisions are optional
- Event-driven architecture ensures junction table updates are handled consistently
7. Carrier-Specific Features
- Only Carrier type can have equipment (enforced by
CanHaveEquipments()) - Store DOT number, MC number, SCAC code, insurance info in CustomValues
- Track carrier equipment for capacity planning and dispatch
8. User Portal Access
- Use
AssignUserId()for employees or customer portal users - Only Employee, Customer, PoolPoint, Store types can have user access (see
CanHaveUserEmployee()) - Portal access enables self-service tracking, booking, document download
9. Custom Values Strategy
- Use CustomValues for industry-specific fields (DOT numbers, NAICS codes, etc.)
- Store extended contact information that doesn't fit standard fields
- CustomValues support complex objects - use for storing arrays, nested data
10. Discount and Pricing Management
- Apply customer-specific discounts using
ChangeDiscounts() - Domain event architecture ensures discount changes trigger pricing recalculations
- Combine contact discounts with other discount types (mode, product, etc.) for flexible pricing
11. Tags for Categorization
- Use Tags for flexible categorization ("preferred-customer", "high-volume", "temperature-sensitive")
- Tags enable filtering and reporting without rigid schema changes
- Tags are searchable - use meaningful, consistent tag names
12. Soft Delete Over Hard Delete
- Use
ChangeIsDeleted(true)instead of deleting contact records - Preserves historical data for audit trails and reporting
- Soft-deleted contacts can be filtered in queries while maintaining referential integrity
Related Topics
- ContactAddress Entity - Address management for contacts
- ContactLink Entity - Contact-to-contact relationships
- ContactStatus Entity - Status definitions for contacts
- ContactDiscount Entity - Junction table for contact discounts
- ContactDivision Entity - Junction table for multi-division access
- Division Entity - Organizational divisions
- PaymentTerm Entity - Payment terms (Net 30, etc.)
- Order Entity - Orders associated with contacts
- OrderEntity Entity - Dynamic role assignments (shipper, consignee, etc.)
- CarrierEquipment Entity - Carrier equipment tracking
- EquipmentType Entity - Equipment type definitions
- Discount Entity - Discount definitions
- AspNetUserEmployee Entity - User-employee mapping for system access
- Entity System Overview - Aggregate root patterns and multi-tenancy architecture