conversation-columns.ts5.4 KBView on GitHub /**
* Default CRM Conversation column configuration.
*
* ── FE ↔ BE field parity ─────────────────────────────────────────────────────────────────────
* The backend has a canonical field registry at
* `apps/server/src/services/crm/conversation-fields.ts` that is the source of truth for what
* each conversation field can do (filter / sort / return) and derives the flexible_query filter
* enum, sort map, and returnable-`extraFields` map from one place. There is no shared FE/BE
* package, so this file MIRRORS it — the column `id`s here are the frontend/column_filters
* aliases, recorded on the backend side as each field's `frontendId`.
*
* A few ids intentionally differ from the backend canonical key (kept because stored canvases
* reference these ids); keep both sides in sync when adding/removing a column:
* FE column id → backend canonical key
* 'lastMeetingTime' → 'lastMeetingAt'
* 'lastOutboundEmailTime' → 'lastOutboundEmailAt'
* 'lastInboundEmailTime' → 'lastInboundAt'
* 'primaryUser' → 'ownerId'
* 'type' → 'aopName'
* 'primaryCompany' → 'primaryCompanyName' / 'name'
* The backend parity test (`conversation-fields.parity.test.ts`) mirrors the id list below and
* fails if a column here lacks a backend `frontendId` mapping — update both together.
*/
import { DEFAULT_CRM_SYNCED_OPTIONS, DEFAULT_HISTORY_OPTIONS } from '../field-enums';
import type { CRMColumnMetadata } from '../store/crmSlice';
/**
* Default columns shown in agent canvas mode.
* These provide the most relevant context for agent-driven batch operations.
* The agent can override these by specifying visibleColumns in findCRMConversationsTool.
*/
export const AGENT_CANVAS_DEFAULT_COLUMNS = ['primaryCompany', 'status', 'currentAction'] as const;
export const conversationColumnsConfig: CRMColumnMetadata[] = [
{
id: 'primaryCompany',
name: 'Company',
type: 'company-combined',
description: 'Primary company and conversation name',
isFixed: true,
},
{
id: 'nextStepDate',
name: 'Next Step Date',
type: 'date',
description: 'Planned next action date',
},
{
id: 'nextSteps',
name: 'Next Steps',
type: 'text',
description: 'Planned next actions',
},
{
// Sits immediately after Next Steps by design: "is a meeting already booked?" is the
// first thing you ask about a next step, so the two read as one unit. This array's
// order is the fallback column order for any canvas that doesn't pin an explicit
// `order` in its columnConfiguration (see use-canvas-configuration.ts).
id: 'hasFutureCalendar',
name: 'Upcoming Meeting',
type: 'date',
description: 'Date of next upcoming calendar event',
enumOptions: [
{ value: 'true', label: 'Has meeting', color: 'blue', enumOrder: 0 },
{ value: 'false', label: 'No meeting', color: 'gray', enumOrder: 1 },
],
},
{
id: 'dealValue',
name: 'Deal Size',
type: 'number',
description: 'Monetary value of the deal',
},
{
id: 'status',
name: 'Stage',
type: 'status-badge',
description: 'Current deal stage',
enumOptions: [], // Will be populated from AOP or show all unique values
},
{
id: 'statusOverview',
name: 'Status Overview',
type: 'text',
description: 'Status overview text',
},
{
id: 'lastContactedAt',
name: 'Last Contact',
type: 'date',
description: 'Date of last contact',
},
{
id: 'priority',
name: 'Priority',
type: 'select',
description: 'Priority level',
enumOptions: [], // Will be populated from AOP or show all unique values
},
{
id: 'risk',
name: 'Risk',
type: 'select',
description: 'Risk level',
enumOptions: [], // Will be populated from AOP or show all unique values
},
{
id: 'type',
name: 'Type',
type: 'aop-type',
description: 'Type of conversation (derived from AOP)',
},
{
id: 'history',
name: 'Recent Activity',
type: 'timeline',
description: 'Recent events and interactions',
enumOptions: DEFAULT_HISTORY_OPTIONS,
},
{
id: 'activityOverview',
name: 'Activity Timeline',
type: 'activity-overview',
description: 'Visual timeline of activity over time',
},
{
id: 'workingMemory',
name: 'Custom Fields',
type: 'working-memory',
description: 'Agent custom fields',
},
{
id: 'crmSynced',
name: 'CRM Synced',
type: 'crm-synced',
description: 'Whether synced to an external CRM',
enumOptions: DEFAULT_CRM_SYNCED_OPTIONS,
},
{
id: 'currentAction',
name: 'Suggested Action',
type: 'current-action',
description: 'Most overdue task or last activity if no tasks',
},
{
id: 'lastMeetingTime',
name: 'Last Meeting',
type: 'date',
description: 'Date of last meeting',
},
{
id: 'lastOutboundEmailTime',
name: 'Last Email Sent',
type: 'date',
description: 'Date of last outbound email sent',
},
{
id: 'lastInboundEmailTime',
name: 'Last Email Received',
type: 'date',
description: 'Date of last inbound email received from prospect',
},
{
id: 'primaryUser',
name: 'Owner',
type: 'user',
description: 'The team member who owns this conversation',
},
];