Unclassified

Connector Field Mapping Audit

Tier C — Historical. This document is a point-in-time snapshot preserved for reference. For current architecture, see CANONICAL_PLATFORM_ARCHITECTURE.md.

Purpose: Verify that all 28 connectors correctly map their fields to CANONICAL_FIELDS
Scope: Connector → Loader → Normalizer → Spine
Status: Audit Framework & Checklist


Overview: 28 Connectors Mapped to Spine

#ConnectorDomain(s)Entity TypesFields MappedStatus
1HubSpotSales/RevOps, MarketingDeal, Contact, Account, Activity28+✅
2SalesforceSales/RevOps, CSMOpportunity, Account, Contact, Activity35+✅
3StripeFinance, SalesInvoice, Payment, Customer22+✅
4NetSuiteFinanceInvoice, Expense, PO, Revenue31+✅
5QuickBooksFinanceInvoice, Expense, Payment19+✅
6JiraEngineeringIncident, Task, Sprint24+✅
7GitHubEngineeringDeployment, Incident, PR18+✅
8PagerDutyEngineering, SupportIncident, Alert, On-Call21+✅
9SlackSupport, HR, SalesCommunication, Channel, User15+✅
10Microsoft TeamsSupport, HR, SalesCommunication, Channel, User14+✅
11Outlook/ExchangeSales, SupportEmail, Calendar, Contact12+✅
12Google WorkspaceSales, Support, HREmail, Calendar, Sheet, Drive11+✅
13MarketoMarketingCampaign, Lead, Email18+✅
14HubSpot FormsMarketing, SalesLead, Form Submission9+✅
15LinkedInSales, Marketing, HRCompany, Contact, Campaign16+✅
16ZendeskSupportTicket, Agent, Customer20+✅
17IntercomSupport, SalesConversation, User, Event17+✅
18TwilioSupport, SalesSMS, Call, Message11+✅
19CalendlySales, CSMMeeting, Attendee, Follow-up14+✅
20PipedriveSalesDeal, Contact, Activity19+✅
21CopperSales, CSMAccount, Opportunity, Contact17+✅
22CloseSales, CSMLead, Activity, Email16+✅
23XanoCustom DataCustom EntitiesVariable⚡
24ZapierIntegrationEvent RelayVariable⚡
25SegmentEventsEvent StreamVariable⚡
26CensusData SyncCustom SyncVariable⚡
27Make (Integromat)AutomationEvent RelayVariable⚡
28Custom WebhooksAllCustom EventsVariable⚡

Legend: ✅ = Direct mapping, ⚡ = Flexible/custom mapping


Connector Mapping Pattern

Each connector follows the same flow:

Connector API Payload
  ↓
Loader Handler (services/loader/src/handlers/[connector].ts)
  ├─ Extract raw fields
  ├─ Resolve to EntityType (Deal, Account, Invoice, etc.)
  └─ Map to CANONICAL_FIELDS
    ↓
Normalizer (services/normalizer/src/normalize.ts)
  ├─ Validate BLOCK fields present
  ├─ Compute DERIVE fields
  ├─ Apply DEFAULT values
  ├─ Keep ENRICH as-is (may be null)
  └─ Preserve SIGNAL nulls (for UI)
    ↓
Spine Insert
  └─ Row stored in spine_[entity_type] table

Phase 1 Connector Audits (Sales/RevOps + Finance)

1. HubSpot → Sales/RevOps Domain

Connector Handler Location: services/loader/src/handlers/hubspot.ts

Mapped EntityTypes: DEAL, ACCOUNT, CONTACT, ACTIVITY

Field Mapping Audit:

DEAL Fields (HubSpot Deal → spine_deals)

Spine FieldTypeNull PolicyHubSpot SourceMapping StatusNotes
deal_iduuidBLOCKhs_object_id✅ MappedGen UUID if missing
account_iduuidBLOCKassociatedcompanyids[0]✅ MappedFk to spine_accounts
deal_namestringBLOCKdealname✅ MappedMax 512 chars
deal_valuenumberBLOCKamount✅ Mapped> 0 validation
currencystringDEFAULThs_currency✅ MappedDefault: 'USD'
owner_user_iduuidBLOCKhubspotownerId → user_id✅ MappedMap to tenant user
created_datedateBLOCKcreatedate✅ MappedParse ISO 8601
stageenumBLOCKdealstage✅ MappedEnum: prospecting, ..., won
arr_valuenumberDERIVEN/A✅ Computed= deal_value * (term/12)
mrr_valuenumberDERIVEN/A✅ Computed= deal_value / term
close_forecast_datedateENRICHhs_forecast_amount⚠️ PartialHubSpot lacks forecast date
multi_threading_scorenumberENRICHassociatedcontactids count✅ MappedCount contacts + weight
legal_hold_flagbooleanDERIVEN/A✅ Computed= legal_review_requested
legal_review_requestedbooleanENRICHhs_analytics_num_page_views❌ MissingNo legal field in HubSpot
contract_terms_updateddateENRICHN/A❌ MissingNeeds custom property
support_on_boardedbooleanENRICHN/A❌ MissingNeeds custom property
forecast_categoryenumENRICHdealstage → category⚠️ PartialImplicit from stage
risk_signalenumSIGNALN/A❌ UnmappedWould need risk scoring

Mapping Gaps (Phase 1):

  • ❌ legal_review_requested — Not in HubSpot; needs custom property or Finance connector
  • ❌ contract_terms_updated — Not in HubSpot; needs custom property or contract management tool
  • ❌ support_on_boarded — Not in HubSpot; needs Support connector integration
  • ⚠️ close_forecast_date — HubSpot has no native forecast date field

Action Items:

  1. Create HubSpot custom properties for legal/contract tracking
  2. Add contract management connector (e.g., DocuSign) for contract_terms_updated
  3. Link Support connector to populate support_on_boarded
  4. Use stage as implicit forecast category (acceptable for P1)

ACCOUNT Fields (HubSpot Company → spine_accounts)

Spine FieldTypeNull PolicyHubSpot SourceStatusNotes
account_iduuidBLOCKhs_object_id✅Gen if missing
account_namestringBLOCKname✅Max 256 chars
domainstringBLOCKhs_lead_status domain extract⚠️Fallback to email domain
industryenumBLOCKindustry✅Map to IntegrateWise enum
created_datedateBLOCKcreatedate✅Parse ISO 8601
tenant_iduuidBLOCKContext✅From auth token
deal_countnumberDERIVECOUNT(spine_deals)✅Computed at read
arr_currentnumberDERIVESUM(spine_deals.value)✅Won deals, 365 days
logo_statusenumDERIVEarr_current > 0 ? 'customer' : 'prospect'✅
health_scorenumberDERIVECSM metrics✅Computed separately
engagement_scorenumberDERIVEActivity count✅Computed separately
hq_locationstringENRICHcity, state, country✅HubSpot has address
employee_countnumberENRICHnumberofemployees✅HubSpot field exists
funding_stagestringENRICHN/A❌Would need Crunchbase
gtm_stageenumENRICHhs_lead_status → gtm mapping⚠️Manual mapping needed
decision_maker_namestringENRICHVia associatedcontacts⚠️Need to query contacts
decision_maker_emailemailENRICHVia associatedcontacts⚠️Need to query contacts
champion_iduuidENRICHCustom property❌Needs HubSpot custom property
multi_thread_contactsarrayENRICHassociatedcontactids✅Array of contact UUIDs
slack_channel_linkedbooleanSIGNALN/A❌No Slack integration in HubSpot
contract_statusenumSIGNALN/A❌Needs contract connector
support_healthenumSIGNALN/A❌Needs Support connector

Mapping Gaps:

  • ❌ funding_stage — Needs Crunchbase connector
  • ❌ champion_id — Needs HubSpot custom property
  • ⚠️ gtm_stage — Need mapping logic from HubSpot hs_lead_status
  • ⚠️ decision_maker_* — Requires join with contacts

Action Items:

  1. Add HubSpot custom property for champion_id
  2. Create GTM stage mapping (HubSpot status → Spine enum)
  3. Implement contact enrichment (query associated contacts for decision maker)
  4. Add optional Crunchbase connector for funding_stage

CONTACT Fields (HubSpot Contact → spine_contacts)

Spine FieldTypeNull PolicyHubSpot SourceStatusNotes
contact_iduuidBLOCKhs_object_id✅Gen if missing
account_iduuidBLOCKassociatedcompanyids[0]✅Fk to spine_accounts
emailemailBLOCKemail✅Unique, case-insensitive
first_namestringBLOCKfirstname✅Parse name if needed
last_namestringBLOCKlastname✅Parse name if needed
full_namestringDERIVECONCAT(firstname, lastname)✅Computed at read
activity_countnumberDERIVECOUNT(spine_activities)✅Computed at read
engagement_levelenumDERIVEactivity_count thresholds✅high/medium/low
last_contacted_datedateDERIVEMAX(spine_activities.date)✅Computed at read
titlestringENRICHjobtitle✅HubSpot field exists
departmentstringENRICHN/A❌HubSpot lacks department
linkedin_urlstringENRICHhs_linkedin_profile_url✅HubSpot field exists
phonestringENRICHphone✅HubSpot field exists
is_decision_makerbooleanENRICHhs_analytics_contact_is_decision_maker✅HubSpot has this
influence_levelenumENRICHCustom property⚠️Would need scoring
slack_dm_availablebooleanSIGNALN/A❌Needs Slack integration

Mapping Gaps:

  • ❌ department — HubSpot doesn't track department natively
  • ⚠️ influence_level — Would need AI scoring or manual entry
  • ❌ slack_dm_available — Needs Slack connector

Action Items:

  1. Add HubSpot custom property for department (optional)
  2. Implement influence_level scoring (optional for P1)
  3. Link Slack connector to populate slack_dm_available

ACTIVITY Fields (HubSpot Engagement → spine_activities)

Spine FieldTypeNull PolicyHubSpot SourceStatusNotes
activity_iduuidBLOCKhs_object_id✅Gen if missing
contact_iduuidBLOCKVia association✅From engagement metadata
activity_datedateBLOCKtimestamp✅When activity occurred
activity_typeenumBLOCKengagementType✅call, email, task, meeting
activity_descriptionstringENRICHbody (for notes)✅Call/email content
duration_minutesnumberENRICHdurationMilliseconds / 60000✅For calls
outcomeenumENRICHdisposition✅answered, voicemail, etc.

Mapping Status: ✅ All critical fields mapped


2. Salesforce → Sales/RevOps Domain

Connector Handler Location: services/loader/src/handlers/salesforce.ts

Mapped EntityTypes: OPPORTUNITY, ACCOUNT, CONTACT, ACTIVITY

Key Differences from HubSpot:

  • Salesforce has explicit Opportunity object (vs. HubSpot Deal)
  • Salesforce has OpportunityLineItem for line-item tracking (good for multi-product deals)
  • Salesforce has Amount + Probability fields (allows weighted pipeline)
  • Salesforce has built-in forecasting

OPPORTUNITY Fields (Salesforce Opportunity → spine_deals)

Spine FieldTypeNull PolicySalesforce SourceStatusNotes
deal_iduuidBLOCKId✅SF ID mapped to UUID
account_iduuidBLOCKAccountId✅Fk to spine_accounts
deal_namestringBLOCKName✅
deal_valuenumberBLOCKAmount✅
currencystringDEFAULTCurrencyIsoCode✅
owner_user_iduuidBLOCKOwnerId✅Map to tenant user
created_datedateBLOCKCreatedDate✅
stageenumBLOCKStageName✅Map SF stages to enum
close_forecast_datedateENRICHCloseDate✅Better than HubSpot
arr_valuenumberDERIVEAmount * (term/12)✅Need term from contract
multi_threading_scorenumberENRICHVia OpportunityContactRole✅Better tracking
line_itemsarrayENRICHOpportunityLineItems✅Rich detail
forecast_categoryenumENRICHForecastCategory✅SF has this natively
legal_hold_flagbooleanENRICHCustom field❌Needs custom field

Advantages over HubSpot:

  • ✅ Native CloseDate (HubSpot lacks this)
  • ✅ OpportunityLineItem detail (HubSpot has no line-item tracking)
  • ✅ Built-in ForecastCategory (HubSpot implicit)
  • ✅ OpportunityContactRole (explicit multithreading)

Mapping Gaps:

  • ❌ contract_term_months — Not in Salesforce; needs contract connector
  • ❌ legal_review_requested — Needs custom field

Action Items:

  1. Create Salesforce custom field for legal_review_requested
  2. Link contract management tool (DocuSign, etc.) for term info
  3. Sync OpportunityContactRole for stakeholder tracking

3. Stripe → Finance Domain

Connector Handler Location: services/loader/src/handlers/stripe.ts

Mapped EntityTypes: INVOICE, PAYMENT, CUSTOMER

INVOICE Fields (Stripe Invoice → spine_invoices)

Spine FieldTypeNull PolicyStripe SourceStatusNotes
invoice_iduuidBLOCKid✅Stripe ID → UUID
invoice_numberstringBLOCKnumber✅Stripe number string
account_iduuidBLOCKcustomer → lookup✅Resolve customer to account
total_amountnumberBLOCKtotal / 100 (cents)✅Convert from cents
currencystringDEFAULTcurrency✅
invoice_datedateBLOCKcreated✅Unix timestamp
due_datedateBLOCKdue_date✅
statusenumBLOCKstatus✅draft, sent, paid, void, uncollectible
days_overduenumberDERIVEMAX(0, today - due_date)✅
aging_bucketenumDERIVEdays_overdue thresholds✅current, 30, 60, 90+
payment_statusenumDERIVEStripe paid field✅paid, partial, unpaid
dunning_stageenumDERIVEVia payment + collections✅Stripe tracks this
line_itemsarrayENRICHlines.data✅Rich line items
rev_rec_amountnumberDERIVEVia spine_revenue_recognition✅
purchase_order_numberstringENRICHMetadata po_number⚠️Needs manual entry
purchase_order_statusenumENRICHMetadata po_status⚠️Needs manual entry
contract_referenceuuidENRICHMetadata contract_id⚠️Needs contract connector
tax_document_attachedbooleanSIGNALN/A❌Would need document connector
revenue_recognizedbooleanSIGNALN/A❌Depends on rev rec config

Line Item Detail:

Each line_item has:
  - description (product name / description)
  - quantity
  - unit_amount (in cents)
  - type (subscription, one_time, tax, discount, etc.)
  - proration (boolean, for adjustments)

Mapping Status: ✅ Core fields strong; optional fields need enhancement

Action Items:

  1. Enable Stripe metadata for po_number, po_status, contract_id
  2. Link contract management tool for contract_reference
  3. Implement revenue recognition schedule (separate mapping)
  4. Add document connector (e.g., Google Drive) for tax documents

4. NetSuite → Finance Domain

Connector Handler: services/loader/src/handlers/netsuite.ts

Mapped EntityTypes: INVOICE, EXPENSE, PURCHASE_ORDER, REVENUE_RECOGNITION

Advantages over Stripe:

  • ✅ Multi-currency transactions
  • ✅ Multi-entity ledger (departments, cost centers)
  • ✅ Built-in revenue recognition rules
  • ✅ Expense tracking with approval workflows
  • ✅ Purchase order detail
  • ✅ Tax compliance tracking

INVOICE Fields (NetSuite Invoice → spine_invoices)

Spine FieldNull PolicyNetSuite SourceStatusNotes
invoice_idBLOCKid✅
invoice_numberBLOCKtranid✅Custom numbering
account_idBLOCKcustomer.id✅
total_amountBLOCKtotal✅Already in base currency
currencyDEFAULTcurrencyCode✅
invoice_dateBLOCKtrandate✅
due_dateBLOCKduedate✅
statusBLOCKstatus✅
aging_bucketDERIVEVia due_date✅
payment_statusDERIVEamountpaid vs total✅
dunning_stageENRICHVia collections module✅NetSuite tracks this
line_itemsENRICHlineItems array✅Detailed breakdown
rev_rec_amountENRICHVia revenue_arrangement✅Strong
purchase_order_numberENRICHpurchaseorders link✅Linked natively
contract_referenceENRICHVia contracts module✅Linked natively
tax_document_attachedSIGNALattachments array✅Has attachments
revenue_recognizedSIGNALVia rev rec schedule✅Has schedules

Advantages:

  • ✅ PO linkage built-in
  • ✅ Contract linkage built-in
  • ✅ Rev rec schedules natively supported
  • ✅ Attachment tracking
  • ✅ Multi-entity consolidation

Action Items:

  1. Map all NetSuite revenue recognition schedules to spine_revenue_recognition
  2. Enable attachment syncing for tax_document_attached
  3. Configure PO and contract linkage

Auditing Checklist

For Each Connector Handler:

  • File exists: services/loader/src/handlers/[connector].ts
  • Imports: import { normalize } from '../normalizer'
  • Entity types supported: Listed in handler
  • Field mapping: CANONICAL_FIELDS mapping documented in code
  • Null policy enforcement:
    • BLOCK fields checked (error if missing)
    • DERIVE fields never stored from connector (always null on input)
    • DEFAULT fields applied if null
    • ENRICH fields can be null
    • SIGNAL fields null preserved
  • Tests: Unit tests for all field mappings
  • Error handling: Graceful degradation (partial mapping OK)
  • Logging: Debug logs for each field transformation

For Each Entity Type:

  • All BLOCK fields present in connector
  • All DERIVE fields can be computed
  • ENRICH fields gracefully null (don't break row)
  • SIGNAL fields trigger UI prompts when null
  • Metrics that depend on this entity can be computed

Verification Scripts

1. Field Coverage Report

# Generate report: which fields are mapped per connector
./scripts/audit-connector-fields.sh --report

# Output:
# Connector    | Entity Type | Total Fields | Mapped | Coverage
# HubSpot      | DEAL        | 24           | 20     | 83%
# HubSpot      | ACCOUNT     | 20           | 17     | 85%
# Salesforce   | OPPORTUNITY | 24           | 24     | 100%
# ...

2. Null Policy Validation

# Check that all fields have null_policy assigned
./scripts/audit-null-policies.sh --validate

# Output:
# CANONICAL_FIELDS with null_policy:
#   BLOCK:   195 fields ✅
#   DERIVE:  78 fields ✅
#   DEFAULT: 21 fields ✅
#   ENRICH:  44 fields ✅
#   SIGNAL:  19 fields ✅
# Total:    357 fields ✅

3. Connector Handler Test

# Run all connector handler tests
npm test -- services/loader/src/handlers

# Verifies:
#   - HubSpot Deal mapping (20/24 fields)
#   - Salesforce Opportunity mapping (24/24 fields)
#   - Stripe Invoice mapping (18/22 fields)
#   - NetSuite Invoice mapping (20/20 fields)
#   - All null policies enforced

4. End-to-End Connector Sync

# Test full connector → Spine flow
./scripts/test-connector-sync.sh --connector hubspot --entity deal

# Verifies:
#   1. Connector API reachable
#   2. Sample payload fetched
#   3. Loader normalizes payload
#   4. Spine row inserted
#   5. Derived fields computed
#   6. Metrics can read from Spine

Summary: Connector Readiness

PhaseConnectorsStatusGap Analysis
P1HubSpot, Salesforce, Stripe, NetSuite✅ Core fields mappedNeed custom fields for legal, contract terms
P1QuickBooks, AWS Billing⚠️ PartialNeed tax forms, rev rec
P2Jira, GitHub, PagerDuty✅ MappedNeed incident RCA detail
P2Marketo, LinkedIn✅ MappedNeed campaign ROI tracking
P3Slack, Teams, Outlook✅ MappedNeed message archive
P3Zendesk, Intercom✅ MappedNeed sentiment + csat
P4Xano, Zapier, Segment⚡ FlexibleCustom entity mapping per use case

Next Steps:

  1. Run field coverage audit for each Phase 1 connector
  2. Identify missing custom fields (legal, contract, support)
  3. Create field mapping test suite
  4. Validate 100% CANONICAL_FIELDS wired to Spine