{"slug":"architecture/ENTITY360_V2_MODEL","title":"Entity360 V2 — Cross-Tool Rich Composition Model","section":"architecture","sectionLabel":"Architecture","status":"unclassified","type":"document","path":"architecture/ENTITY360_V2_MODEL.mdx","bytes":13768,"description":null,"updated":null,"source":"integratewise/Integratewise-docs-wiki","content":"\n> **Status:** Canonical data model  \n> **Date:** July 12, 2026  \n> **Authority:** Nirmal (Founder)  \n> **Canonical Reference:** [CANONICAL_PLATFORM_ARCHITECTURE.md](./CANONICAL_PLATFORM_ARCHITECTURE.md)  \n> **Reconciles:** Document 1 (flat Entity360) and Document 3 (cross-tool rich Entity 360)  \n> **Cross-Reference:** [PLANE_LAYER_CROSS_REFERENCE.md](./PLANE_LAYER_CROSS_REFERENCE.md)\n\n---\n\n## The Problem\n\nTwo Entity360 models exist:\n\n1. **Document 1 (Flat Struct):**\n\n```typescript\ninterface Entity360 {\n  id: string;\n  type: string;\n  tenantId: string;\n  properties: Record<string, unknown>;\n  traits: Trait[];\n  timeline: TimelineEvent[];\n  projections: ProjectedView[];\n  provenance: ProvenanceRecord[];\n}\n```\n\n2. **Document 3 (Rich Cross-Tool):**\n   > \"CRM account fields + Support ticket history + Product usage deltas + Billing status + Recent communication + Project milestones + Renewal memory + Relevant decisions + Authorized capabilities.\"\n\nThe flat struct cannot support the richness described in Document 3. The rich model needs a structured composition that preserves type safety while supporting lazy loading.\n\n---\n\n## The Unified Model\n\n```typescript\n// ═══════════════════════════════════════════════════════════════\n// ENTITY360 V2 — Canonical Cross-Tool Entity Model\n// ═══════════════════════════════════════════════════════════════\n\ninterface Entity360 {\n  // ─── Core Identity (always present, always fast) ──────────\n  id: string;\n  type: CanonicalEntityType;\n  tenantId: string;\n  createdAt: string;\n  updatedAt: string;\n\n  // ─── Flat Properties (fast lookup, always loaded) ─────────\n  properties: Record<string, unknown>;\n\n  // ─── Traits (behavioral characteristics) ──────────────────\n  traits: Trait[];\n\n  // ─── Timeline (temporal events) ───────────────────────────\n  timeline: TimelineEvent[];\n\n  // ─── Provenance (source tracking) ─────────────────────────\n  provenance: ProvenanceRecord[];\n\n  // ─── Cross-Tool Composition (lazy-loaded per Workbench) ───\n  composition?: EntityComposition;\n\n  // ─── Governance (authority and sync) ──────────────────────\n  governance: EntityGovernance;\n}\n\n// ═══════════════════════════════════════════════════════════════\n// COMPOSITION — Lazy-loaded cross-tool views\n// ═══════════════════════════════════════════════════════════════\n\ninterface EntityComposition {\n  // Each view is loaded only when the Workbench needs it\n  crm?: CrmEntityView;\n  support?: SupportEntityView;\n  billing?: BillingEntityView;\n  product?: ProductEntityView;\n  communication?: CommunicationEntityView;\n  projects?: ProjectEntityView;\n  engineering?: EngineeringEntityView;\n  finance?: FinanceEntityView;\n  hiring?: HiringEntityView;\n  legal?: LegalEntityView;\n  operations?: OperationsEntityView;\n\n  // Cross-tool relationships\n  relationships?: EntityRelationship[];\n\n  // Memory and decisions\n  memory?: MemoryEntityView;\n  decisions?: DecisionEntityView;\n\n  // Available capabilities\n  capabilities?: CapabilityView[];\n}\n\n// ═══════════════════════════════════════════════════════════════\n// TOOL-SPECIFIC VIEWS — Typed per provider\n// ═══════════════════════════════════════════════════════════════\n\ninterface CrmEntityView {\n  provider: \"salesforce\" | \"hubspot\" | \"pipedrive\" | \"zoho\";\n  accountId?: string;\n  contacts?: ContactSummary[];\n  opportunities?: OpportunitySummary[];\n  activities?: ActivitySummary[];\n  healthScore?: number;\n  lastActivity?: string;\n  customFields?: Record<string, unknown>;\n}\n\ninterface SupportEntityView {\n  provider: \"zendesk\" | \"intercom\" | \"freshdesk\" | \"servicenow\";\n  tickets?: TicketSummary[];\n  openTickets?: number;\n  avgResolutionTime?: number;\n  satisfactionScore?: number;\n  escalations?: EscalationSummary[];\n  lastTicket?: string;\n}\n\ninterface BillingEntityView {\n  provider: \"stripe\" | \"chargebee\" | \"zuora\" | \"quickbooks\";\n  mrr?: number;\n  arr?: number;\n  subscriptionStatus?: string;\n  nextBillingDate?: string;\n  invoices?: InvoiceSummary[];\n  paymentFailures?: number;\n  lifetimeValue?: number;\n}\n\ninterface ProductEntityView {\n  provider: \"amplitude\" | \"mixpanel\" | \"segment\" | \"posthog\";\n  activeUsers?: number;\n  featureUsage?: FeatureUsageSummary[];\n  adoptionRate?: number;\n  churnRisk?: number;\n  lastActivity?: string;\n  usageTrend?: TrendSummary;\n}\n\ninterface CommunicationEntityView {\n  provider: \"slack\" | \"email\" | \"teams\" | \"discord\";\n  recentConversations?: ConversationSummary[];\n  sentiment?: SentimentSummary;\n  responseTime?: number;\n  openThreads?: number;\n  keyMentions?: MentionSummary[];\n}\n\ninterface ProjectEntityView {\n  provider: \"jira\" | \"asana\" | \"linear\" | \"github\";\n  activeIssues?: IssueSummary[];\n  milestones?: MilestoneSummary[];\n  velocity?: number;\n  blockers?: IssueSummary[];\n  lastDeploy?: string;\n  sprintProgress?: SprintSummary;\n}\n\n// ═══════════════════════════════════════════════════════════════\n// RELATIONSHIPS — Cross-tool entity links\n// ═══════════════════════════════════════════════════════════════\n\ninterface EntityRelationship {\n  id: string;\n  sourceEntityId: string;\n  targetEntityId: string;\n  type: RelationshipType;\n  source: string; // which tool created this relationship\n  confidence: number; // how certain is this link\n  properties?: Record<string, unknown>;\n}\n\ntype RelationshipType =\n  | \"owns\" // Account owns Contact\n  | \"has_ticket\" // Account has Support Ticket\n  | \"has_invoice\" // Account has Invoice\n  | \"uses_product\" // Account uses Product\n  | \"communicates\" // Account communicates via Channel\n  | \"works_on\" // Account works on Project\n  | \"decided\" // Account made Decision\n  | \"related_to\" // Generic relationship\n  | string; // Extensible\n\n// ═══════════════════════════════════════════════════════════════\n// MEMORY AND DECISIONS — Organizational continuity\n// ═══════════════════════════════════════════════════════════════\n\ninterface MemoryEntityView {\n  keyDecisions?: DecisionSummary[];\n  contextNotes?: NoteSummary[];\n  renewalMemory?: RenewalMemory;\n  riskSignals?: RiskSignal[];\n  opportunities?: OpportunitySignal[];\n}\n\ninterface DecisionEntityView {\n  recentDecisions?: DecisionSummary[];\n  pendingDecisions?: DecisionSummary[];\n  decisionTrail?: DecisionTrailEntry[];\n}\n\n// ═══════════════════════════════════════════════════════════════\n// CAPABILITIES — What can be done with this entity\n// ═══════════════════════════════════════════════════════════════\n\ninterface CapabilityView {\n  capabilityId: string;\n  name: string;\n  description: string;\n  available: boolean; // is this capability available for this entity?\n  requiresApproval: boolean;\n  estimatedImpact: string;\n}\n\n// ═══════════════════════════════════════════════════════════════\n// GOVERNANCE — Authority and sync policy\n// ═══════════════════════════════════════════════════════════════\n\ninterface EntityGovernance {\n  sourceOwnership: string; // which tool owns the canonical source\n  writeAuthority: string; // who can write to this entity\n  syncPolicy: SyncPolicy;\n  consumerScope: string[]; // which Workbenches can consume this\n}\n\ninterface SyncPolicy {\n  mode: \"immediate\" | \"deferred\" | \"batch\" | \"scheduled\" | \"event-driven\";\n  interval?: string; // for scheduled mode\n  lastSync?: string;\n  nextSync?: string;\n  pendingMutations?: number;\n}\n```\n\n---\n\n## How Composition Loading Works\n\n### 1. Workbench Requests Entity360\n\n```\nUser opens Account Success Workbench\n  → Selects account \"Acme Corp\"\n  → Workbench requests Entity360 for Acme Corp\n```\n\n### 2. Core Entity Loaded (Fast)\n\n```typescript\n// Always loaded — flat properties + traits + timeline\nconst entity = await spine.getEntity360(\"acct_123\");\n// entity.properties = { name: \"Acme Corp\", industry: \"SaaS\", ... }\n// entity.traits = [...]\n// entity.timeline = [...]\n```\n\n### 3. Composition Loaded Based on Workbench Role\n\n```typescript\n// Role: CSM → loads CRM, Support, Billing, Communication views\nconst composition = await spine.loadComposition(\"acct_123\", {\n  role: \"csm\",\n  department: \"customer_success\",\n  activeContext: \"renewal_review\",\n});\n\n// composition.crm = { provider: 'salesforce', healthScore: 82, ... }\n// composition.support = { openTickets: 3, satisfactionScore: 4.2, ... }\n// composition.billing = { mrr: 12000, subscriptionStatus: 'active', ... }\n```\n\n### 4. Lazy Loading by Need\n\n```typescript\n// If user clicks into Product Usage tab\nconst productView = await spine.loadCompositionView(\"acct_123\", \"product\");\n// composition.product = { activeUsers: 45, adoptionRate: 0.72, ... }\n```\n\n### 5. Cross-Tool Relationships Resolved\n\n```typescript\n// Relationships are resolved during Creamy Load / Delta Load\nconst relationships = await spine.getRelationships(\"acct_123\");\n// [\n//   { type: 'has_ticket', target: 'tkt_456', source: 'zendesk' },\n//   { type: 'has_invoice', target: 'inv_789', source: 'stripe' },\n//   { type: 'uses_product', target: 'prod_012', source: 'amplitude' },\n// ]\n```\n\n---\n\n## Workbench Composition Example\n\n### Customer Success Workbench for \"Acme Corp\"\n\n```typescript\nconst workbench = await composeWorkbench({\n  entity: 'acct_123',\n  role: 'csm',\n  department: 'customer_success',\n  activeContext: 'q3_renewal_review',\n});\n\n// Result:\n{\n  // Core entity\n  entity: { id: 'acct_123', type: 'ACCOUNT', properties: { name: 'Acme Corp', ... } },\n\n  // Composed views (loaded based on role)\n  composition: {\n    crm: { healthScore: 82, lastActivity: '2026-07-10', contacts: [...] },\n    support: { openTickets: 3, avgResolutionTime: '4.2h', escalations: [...] },\n    billing: { mrr: 12000, nextBillingDate: '2026-08-01', invoices: [...] },\n    communication: { sentiment: 'positive', recentConversations: [...] },\n    memory: { keyDecisions: [...], renewalMemory: { renewalDate: '2026-09-15', riskLevel: 'medium' } },\n    decisions: { recentDecisions: [...], pendingDecisions: [...] },\n    capabilities: [\n      { capabilityId: 'cs.renewal draft', name: 'Draft Renewal Proposal', available: true },\n      { capabilityId: 'cs.escalation create', name: 'Create Escalation', available: true },\n      { capabilityId: 'cs.email send', name: 'Send Follow-up Email', available: true, requiresApproval: true },\n    ],\n  },\n\n  // Relationships\n  relationships: [\n    { type: 'has_ticket', target: 'tkt_456', source: 'zendesk' },\n    { type: 'has_invoice', target: 'inv_789', source: 'stripe' },\n  ],\n\n  // Governance\n  governance: {\n    sourceOwnership: 'salesforce',\n    writeAuthority: 'csm_team',\n    syncPolicy: { mode: 'deferred' },\n    consumerScope: ['customer_success', 'finance', 'executive'],\n  },\n}\n```\n\n---\n\n## Migration Path\n\n### Phase 1: Backward Compatibility (Current)\n\n- Document 1's flat Entity360 continues to work\n- `composition` field is optional (undefined = not loaded)\n- Existing services consume `properties` as before\n\n### Phase 2: Composition Loading\n\n- Implement `loadComposition()` in spine service\n- Add composition views per tool provider\n- Workbench components consume composition\n\n### Phase 3: Rich Cross-Tool\n\n- Implement relationship resolution during Creamy/Delta Load\n- Add memory and decision views\n- Add capability views per entity\n\n### Phase 4: Full Network Effect\n\n- Implement cross-tool entity resolution\n- Add conflict detection for cross-tool writes\n- Implement Spine Network Effect (N × M → T)\n\n---\n\n## Implementation Priorities\n\n1. **P0:** Define Entity360 V2 interface (this document)\n2. **P1:** Implement composition loading in spine service\n3. **P1:** Define tool-specific view types (CRM, Support, Billing, etc.)\n4. **P2:** Implement lazy loading in Workbench components\n5. **P2:** Implement relationship resolution during load\n6. **P3:** Implement cross-tool entity resolution\n7. **P3:** Implement conflict detection for cross-tool writes\n"}