UNPKG

business-as-code

Version:

Primitives for expressing business logic and processes as code

989 lines 26.1 kB
/** * Customer Entity Types (Nouns) * * Customer and relationship management: Customer, Account, Contact, Segment, Persona. * * @packageDocumentation */ // ============================================================================= // Customer // ============================================================================= /** * Customer entity * * Represents a customer (individual or company). */ export const Customer = { singular: 'customer', plural: 'customers', description: 'A customer (individual or company)', properties: { // Identity name: { type: 'string', description: 'Customer name', }, email: { type: 'string', optional: true, description: 'Primary email', }, phone: { type: 'string', optional: true, description: 'Primary phone', }, // Type type: { type: 'string', description: 'Customer type', examples: ['individual', 'company', 'nonprofit', 'government'], }, // Classification tier: { type: 'string', optional: true, description: 'Customer tier', examples: ['free', 'starter', 'pro', 'business', 'enterprise', 'strategic'], }, segment: { type: 'string', optional: true, description: 'Customer segment', }, industry: { type: 'string', optional: true, description: 'Industry', }, // Lifecycle stage: { type: 'string', description: 'Customer lifecycle stage', examples: ['prospect', 'trial', 'onboarding', 'active', 'at-risk', 'churned', 'won-back'], }, source: { type: 'string', optional: true, description: 'Acquisition source', examples: ['organic', 'paid', 'referral', 'partner', 'outbound', 'event'], }, referredBy: { type: 'string', optional: true, description: 'Referrer ID or name', }, // Dates firstContactAt: { type: 'datetime', optional: true, description: 'First contact date', }, convertedAt: { type: 'datetime', optional: true, description: 'Conversion date', }, churnedAt: { type: 'datetime', optional: true, description: 'Churn date', }, // Value lifetimeValue: { type: 'number', optional: true, description: 'Customer lifetime value', }, mrr: { type: 'number', optional: true, description: 'Monthly recurring revenue', }, arr: { type: 'number', optional: true, description: 'Annual recurring revenue', }, currency: { type: 'string', optional: true, description: 'Currency code', }, // Health healthScore: { type: 'number', optional: true, description: 'Customer health score (0-100)', }, nps: { type: 'number', optional: true, description: 'Net Promoter Score (-100 to 100)', }, lastActivityAt: { type: 'datetime', optional: true, description: 'Last activity date', }, // Location country: { type: 'string', optional: true, description: 'Country', }, region: { type: 'string', optional: true, description: 'Region', }, timezone: { type: 'string', optional: true, description: 'Timezone', }, // Company info (for B2B) companySize: { type: 'string', optional: true, description: 'Company size', examples: ['1-10', '11-50', '51-200', '201-500', '501-1000', '1000+'], }, annualRevenue: { type: 'number', optional: true, description: 'Annual revenue', }, website: { type: 'url', optional: true, description: 'Website URL', }, // Tags tags: { type: 'string', array: true, optional: true, description: 'Tags', }, // Status status: { type: 'string', description: 'Customer status', examples: ['active', 'inactive', 'suspended', 'deleted'], }, }, relationships: { account: { type: 'Account', required: false, description: 'Parent account (for B2B)', }, contacts: { type: 'Contact[]', description: 'Associated contacts', }, owner: { type: 'Worker', required: false, description: 'Account owner/CSM', }, segment: { type: 'Segment', required: false, description: 'Customer segment', }, subscriptions: { type: 'Subscription[]', description: 'Active subscriptions', }, contracts: { type: 'Contract[]', description: 'Contracts', }, deals: { type: 'Deal[]', description: 'Sales deals', }, interactions: { type: 'Interaction[]', description: 'Interaction history', }, }, actions: [ 'create', 'update', 'qualify', 'convert', 'onboard', 'upgrade', 'downgrade', 'renew', 'markAtRisk', 'churn', 'winBack', 'merge', 'archive', ], events: [ 'created', 'updated', 'qualified', 'converted', 'onboarded', 'upgraded', 'downgraded', 'renewed', 'markedAtRisk', 'churned', 'wonBack', 'merged', 'archived', ], }; // ============================================================================= // Account // ============================================================================= /** * Account entity * * Represents a company account (B2B). */ export const Account = { singular: 'account', plural: 'accounts', description: 'A company account (B2B)', properties: { // Identity name: { type: 'string', description: 'Account/company name', }, legalName: { type: 'string', optional: true, description: 'Legal entity name', }, domain: { type: 'string', optional: true, description: 'Primary domain', }, website: { type: 'url', optional: true, description: 'Website URL', }, // Classification type: { type: 'string', optional: true, description: 'Account type', examples: ['prospect', 'customer', 'partner', 'competitor'], }, tier: { type: 'string', optional: true, description: 'Account tier', examples: ['smb', 'mid-market', 'enterprise', 'strategic'], }, industry: { type: 'string', optional: true, description: 'Industry', }, // Size employees: { type: 'number', optional: true, description: 'Employee count', }, annualRevenue: { type: 'number', optional: true, description: 'Annual revenue', }, // Location headquarters: { type: 'string', optional: true, description: 'Headquarters location', }, country: { type: 'string', optional: true, description: 'Country', }, region: { type: 'string', optional: true, description: 'Region', }, // Relationship parentAccountId: { type: 'string', optional: true, description: 'Parent account (for subsidiaries)', }, // Value totalContractValue: { type: 'number', optional: true, description: 'Total contract value', }, arr: { type: 'number', optional: true, description: 'Annual recurring revenue', }, currency: { type: 'string', optional: true, description: 'Currency code', }, // Health healthScore: { type: 'number', optional: true, description: 'Account health score', }, // IDs crmId: { type: 'string', optional: true, description: 'External CRM ID', }, // Status status: { type: 'string', description: 'Account status', examples: ['active', 'inactive', 'churned', 'archived'], }, }, relationships: { owner: { type: 'Worker', required: false, description: 'Account owner', }, contacts: { type: 'Contact[]', description: 'Account contacts', }, customers: { type: 'Customer[]', description: 'Associated customers', }, deals: { type: 'Deal[]', description: 'Sales deals', }, contracts: { type: 'Contract[]', description: 'Contracts', }, parent: { type: 'Account', required: false, description: 'Parent account', }, subsidiaries: { type: 'Account[]', description: 'Subsidiary accounts', }, }, actions: [ 'create', 'update', 'merge', 'assignOwner', 'updateTier', 'addContact', 'removeContact', 'archive', ], events: [ 'created', 'updated', 'merged', 'ownerAssigned', 'tierUpdated', 'contactAdded', 'contactRemoved', 'archived', ], }; // ============================================================================= // Contact // ============================================================================= /** * Contact entity * * Represents a person/contact at a customer or account. */ export const Contact = { singular: 'contact', plural: 'contacts', description: 'A person/contact at a customer or account', properties: { // Identity firstName: { type: 'string', description: 'First name', }, lastName: { type: 'string', description: 'Last name', }, email: { type: 'string', description: 'Email address', }, phone: { type: 'string', optional: true, description: 'Phone number', }, // Role title: { type: 'string', optional: true, description: 'Job title', }, department: { type: 'string', optional: true, description: 'Department', }, role: { type: 'string', optional: true, description: 'Role in buying process', examples: ['decision-maker', 'influencer', 'champion', 'blocker', 'end-user', 'economic-buyer', 'technical-buyer'], }, seniority: { type: 'string', optional: true, description: 'Seniority level', examples: ['c-level', 'vp', 'director', 'manager', 'individual-contributor'], }, // Contact preferences preferredChannel: { type: 'string', optional: true, description: 'Preferred contact channel', examples: ['email', 'phone', 'linkedin', 'slack'], }, timezone: { type: 'string', optional: true, description: 'Timezone', }, // Social linkedinUrl: { type: 'url', optional: true, description: 'LinkedIn URL', }, twitterHandle: { type: 'string', optional: true, description: 'Twitter handle', }, // Engagement lastContactedAt: { type: 'datetime', optional: true, description: 'Last contacted date', }, lastRespondedAt: { type: 'datetime', optional: true, description: 'Last response date', }, // Opt-in marketingOptIn: { type: 'boolean', optional: true, description: 'Marketing opt-in', }, salesOptIn: { type: 'boolean', optional: true, description: 'Sales opt-in', }, // Tags tags: { type: 'string', array: true, optional: true, description: 'Tags', }, // Status status: { type: 'string', description: 'Contact status', examples: ['active', 'inactive', 'bounced', 'unsubscribed', 'archived'], }, }, relationships: { account: { type: 'Account', required: false, description: 'Parent account', }, customer: { type: 'Customer', required: false, description: 'Associated customer', }, owner: { type: 'Worker', required: false, description: 'Contact owner', }, deals: { type: 'Deal[]', description: 'Associated deals', }, interactions: { type: 'Interaction[]', description: 'Interaction history', }, }, actions: [ 'create', 'update', 'merge', 'assignOwner', 'optIn', 'optOut', 'markBounced', 'archive', ], events: [ 'created', 'updated', 'merged', 'ownerAssigned', 'optedIn', 'optedOut', 'bounced', 'archived', ], }; // ============================================================================= // Segment // ============================================================================= /** * Segment entity * * Represents a customer segment. */ export const Segment = { singular: 'segment', plural: 'segments', description: 'A customer segment', properties: { // Identity name: { type: 'string', description: 'Segment name', }, description: { type: 'string', optional: true, description: 'Segment description', }, // Type type: { type: 'string', optional: true, description: 'Segment type', examples: ['demographic', 'behavioral', 'firmographic', 'technographic', 'psychographic'], }, // Criteria criteria: { type: 'json', optional: true, description: 'Segment criteria/filters', }, criteriaDescription: { type: 'string', optional: true, description: 'Human-readable criteria', }, // Size size: { type: 'number', optional: true, description: 'Number of customers in segment', }, // Value totalRevenue: { type: 'number', optional: true, description: 'Total revenue from segment', }, avgRevenue: { type: 'number', optional: true, description: 'Average revenue per customer', }, avgLTV: { type: 'number', optional: true, description: 'Average lifetime value', }, // Behavior avgChurnRate: { type: 'number', optional: true, description: 'Average churn rate', }, avgNPS: { type: 'number', optional: true, description: 'Average NPS', }, // Dynamic isDynamic: { type: 'boolean', optional: true, description: 'Auto-updates based on criteria', }, lastCalculatedAt: { type: 'datetime', optional: true, description: 'Last calculation time', }, // Status status: { type: 'string', description: 'Segment status', examples: ['active', 'inactive', 'archived'], }, }, relationships: { customers: { type: 'Customer[]', description: 'Customers in segment', }, campaigns: { type: 'Campaign[]', description: 'Targeted campaigns', }, persona: { type: 'Persona', required: false, description: 'Associated persona', }, }, actions: [ 'create', 'update', 'refresh', 'addCustomer', 'removeCustomer', 'archive', ], events: [ 'created', 'updated', 'refreshed', 'customerAdded', 'customerRemoved', 'archived', ], }; // ============================================================================= // Persona // ============================================================================= /** * Persona entity * * Represents a buyer or user persona. */ export const Persona = { singular: 'persona', plural: 'personas', description: 'A buyer or user persona', properties: { // Identity name: { type: 'string', description: 'Persona name', }, description: { type: 'string', optional: true, description: 'Persona description', }, avatarUrl: { type: 'url', optional: true, description: 'Avatar image URL', }, // Type type: { type: 'string', optional: true, description: 'Persona type', examples: ['buyer', 'user', 'influencer', 'decision-maker'], }, // Demographics jobTitle: { type: 'string', optional: true, description: 'Typical job title', }, department: { type: 'string', optional: true, description: 'Typical department', }, seniority: { type: 'string', optional: true, description: 'Seniority level', }, companySize: { type: 'string', optional: true, description: 'Typical company size', }, industry: { type: 'string', optional: true, description: 'Typical industry', }, // Psychographics goals: { type: 'string', array: true, optional: true, description: 'Goals and objectives', }, challenges: { type: 'string', array: true, optional: true, description: 'Pain points and challenges', }, motivations: { type: 'string', array: true, optional: true, description: 'Motivations', }, objections: { type: 'string', array: true, optional: true, description: 'Common objections', }, // Behavior preferredChannels: { type: 'string', array: true, optional: true, description: 'Preferred communication channels', }, contentPreferences: { type: 'string', array: true, optional: true, description: 'Content format preferences', }, buyingProcess: { type: 'string', optional: true, description: 'Typical buying process', }, // Messaging valueProposition: { type: 'string', optional: true, description: 'Value proposition for this persona', }, messagingGuidelines: { type: 'string', optional: true, description: 'Messaging guidelines', }, keywords: { type: 'string', array: true, optional: true, description: 'Keywords/phrases that resonate', }, // Status status: { type: 'string', description: 'Persona status', examples: ['active', 'draft', 'archived'], }, }, relationships: { segments: { type: 'Segment[]', description: 'Associated segments', }, products: { type: 'Product[]', description: 'Relevant products', }, content: { type: 'Content[]', description: 'Content for this persona', }, campaigns: { type: 'Campaign[]', description: 'Targeted campaigns', }, }, actions: [ 'create', 'update', 'validate', 'archive', ], events: [ 'created', 'updated', 'validated', 'archived', ], }; // ============================================================================= // Interaction // ============================================================================= /** * Interaction entity * * Represents a customer interaction/touchpoint. */ export const Interaction = { singular: 'interaction', plural: 'interactions', description: 'A customer interaction or touchpoint', properties: { // Type type: { type: 'string', description: 'Interaction type', examples: ['email', 'call', 'meeting', 'chat', 'support-ticket', 'demo', 'webinar', 'event', 'social'], }, direction: { type: 'string', optional: true, description: 'Interaction direction', examples: ['inbound', 'outbound'], }, // Content subject: { type: 'string', optional: true, description: 'Subject/title', }, description: { type: 'string', optional: true, description: 'Description/notes', }, // Timing occurredAt: { type: 'datetime', description: 'When it occurred', }, duration: { type: 'number', optional: true, description: 'Duration in minutes', }, // Outcome outcome: { type: 'string', optional: true, description: 'Interaction outcome', examples: ['positive', 'neutral', 'negative', 'no-response'], }, sentiment: { type: 'string', optional: true, description: 'Customer sentiment', examples: ['very-positive', 'positive', 'neutral', 'negative', 'very-negative'], }, nextSteps: { type: 'string', optional: true, description: 'Next steps', }, // Channel channel: { type: 'string', optional: true, description: 'Channel used', }, // Attribution campaignId: { type: 'string', optional: true, description: 'Associated campaign', }, }, relationships: { customer: { type: 'Customer', required: false, description: 'Customer', }, contact: { type: 'Contact', required: false, description: 'Contact', }, account: { type: 'Account', required: false, description: 'Account', }, createdBy: { type: 'Worker', required: false, description: 'Who logged it', }, deal: { type: 'Deal', required: false, description: 'Associated deal', }, }, actions: [ 'log', 'update', 'delete', ], events: [ 'logged', 'updated', 'deleted', ], }; // ============================================================================= // Exports // ============================================================================= export const CustomerEntities = { Customer, Account, Contact, Segment, Persona, Interaction, }; export const CustomerCategories = { customers: ['Customer', 'Account', 'Contact'], segmentation: ['Segment', 'Persona'], engagement: ['Interaction'], }; //# sourceMappingURL=customers.js.map