Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Version: 1.0.0
Created: 2026-01-24
Status: 📋 Specification
Spec Reference: specs/ce/specs/CE-07-email-integration.md

Overview

This document defines the integration contracts for CE-07 (Email Integration). CE-07 integrates with multiple internal modules (CE-01, CE-02, CE-04, PF-10, PF-11) and external services (Gmail API, Microsoft Graph API).

Integration Patterns

Pattern Summary

IntegrationPatternDirectionStatus
CE-01 (Contacts)Direct ReferenceCE-07 → CE-01✅ Implemented
CE-02 (Partners)Direct ReferenceCE-07 → CE-02✅ Implemented
CE-04 (Activities)Database TriggerCE-07 → CE-04✅ Implemented
PF-10 (Notifications)Platform Integration LayerCE-07 → PF-10✅ Implemented
PF-11 (Documents)Platform Integration LayerCE-07 → PF-11✅ Implemented
Gmail APIExternal APICE-07 ↔ Gmail⚠️ Blocked (OAuth verification)
Microsoft GraphExternal APICE-07 ↔ Outlook✅ Implemented

Internal Integrations

CE-01: Contacts Integration

Pattern: Direct Reference (Foreign Key)
Direction: CE-07 → CE-01
-- Email messages linked to contacts via foreign key
ce_email_messages.contact_idce_contacts.id
Integration Points:
  • Email matched to contact by email address
  • Contact timeline includes email tab
  • Email compose from contact detail page
API Contract:
// No API - direct database reference
// Contact lookup by email
const contact = await supabase
  .from('ce_contacts')
  .select('id, first_name, last_name, email')
  .eq('organization_id', orgId)
  .eq('email', emailAddress)
  .single();

CE-02: Partners Integration

Pattern: Direct Reference + Domain Matching
Direction: CE-07 → CE-02
-- Email messages linked to partners via foreign key
ce_email_messages.partner_idce_partners.id
Integration Points:
  • Email matched to partner by domain (e.g., @hospital.org)
  • Partner timeline includes email tab
  • Email compose from partner detail page
API Contract:
// Partner lookup by email domain
const emailDomain = email.split('@')[1];
const partner = await supabase
  .from('ce_partners')
  .select('id, name, domain')
  .eq('organization_id', orgId)
  .eq('domain', emailDomain)
  .single();

CE-04: Activities Integration

Pattern: Database Trigger (Event-Based)
Direction: CE-07 → CE-04
Trigger Contract:
-- Trigger: Auto-create activity when email synced
CREATE TRIGGER ce_email_create_activity
  BEFORE INSERT ON ce_email_messages
  FOR EACH ROW
  EXECUTE FUNCTION ce_create_activity_from_email();
Activity Created:
interface EmailActivity {
  organization_id: string;
  contact_id: string | null;
  partner_id: string | null;
  lead_id: string | null;
  activity_type: 'email';
  subject: string;
  description: 'Received email' | 'Sent email';
  status: 'completed';
  activity_date: string; // ISO timestamp
  created_by: string | null;
}

PF-10: Notifications Integration

Pattern: Platform Integration Layer
Direction: CE-07 → PF-10
Usage: Email tracking notifications (opens, clicks) Import:
import { sendNotification } from '@/platform/notifications';
Notification Types:
EventNotification TypeRecipients
Email openedemail_openedEmail sender
Link clickedemail_clickedEmail sender
Email bouncedemail_bouncedEmail sender
Notification Payload:
interface EmailNotification {
  type: 'email_opened' | 'email_clicked' | 'email_bounced';
  recipient_user_id: string;
  data: {
    email_message_id: string;
    contact_name: string;
    subject: string;
    event_timestamp: string;
    url?: string; // For click events
  };
}

PF-11: Documents Integration

Pattern: Platform Integration Layer
Direction: CE-07 → PF-11
Usage: Attachment storage and retrieval Import:
import { uploadDocument, getDocumentUrl } from '@/platform/documents';
Integration Points:
  • Attachments linked to PF-11 document storage
  • Document selection in email compose dialog
  • Attachment preview in email detail view
Note: Email attachment content NOT stored in CE-07 tables (only metadata). Full content stored in PF-11.

External Integrations

Gmail API Integration

Pattern: External API (OAuth 2.0)
Direction: Bi-directional
OAuth Configuration:
const GMAIL_SCOPES = [
  'https://www.googleapis.com/auth/gmail.readonly',
  'https://www.googleapis.com/auth/gmail.send',
  'https://www.googleapis.com/auth/gmail.modify',
];
API Endpoints Used:
OperationEndpointMethod
Get messages/gmail/v1/users/me/messagesGET
Get message/gmail/v1/users/me/messages/{id}GET
Send message/gmail/v1/users/me/messages/sendPOST
Get profile/gmail/v1/users/me/profileGET
Watch inbox/gmail/v1/users/me/watchPOST
Edge Functions:
  • gmail-oauth/index.ts - OAuth flow (authorize, callback, refresh)
  • email-sync-gmail/index.ts - Message sync

Microsoft Graph API Integration

Pattern: External API (OAuth 2.0)
Direction: Bi-directional
OAuth Configuration:
const OUTLOOK_SCOPES = [
  'Mail.Read',
  'Mail.Send',
  'Mail.ReadWrite',
  'offline_access',
];
API Endpoints Used:
OperationEndpointMethod
Get messages/v1.0/me/messagesGET
Get message/v1.0/me/messages/{id}GET
Send message/v1.0/me/sendMailPOST
Get user/v1.0/meGET
Delta sync/v1.0/me/mailFolders/inbox/messages/deltaGET
Edge Functions:
  • outlook-oauth/index.ts - OAuth flow (authorize, callback, refresh)
  • email-sync-outlook/index.ts - Message sync

Event Contracts

Email Synced Event

Event Name: ce.email.synced
Publisher: CE-07
Subscribers: CE-04 (Activity creation)
Payload Schema:
interface EmailSyncedEvent {
  event_type: 'ce.email.synced';
  organization_id: string;
  email_message_id: string;
  direction: 'inbound' | 'outbound';
  contact_id: string | null;
  partner_id: string | null;
  timestamp: string;
}

Email Tracking Event

Event Name: ce.email.tracking
Publisher: CE-07 (tracking Edge Function)
Subscribers: PF-10 (Notifications)
Payload Schema:
interface EmailTrackingEvent {
  event_type: 'ce.email.tracking';
  organization_id: string;
  email_message_id: string;
  tracking_event: 'open' | 'click';
  url?: string; // For click events
  timestamp: string;
  ip_address: string;
  user_agent: string;
}

Security Considerations

OAuth Token Security

  • Tokens encrypted at rest via Supabase Vault (pgsodium)
  • Refresh tokens stored separately from access tokens
  • Token refresh handled server-side only
  • No tokens exposed in client-side code

Email Content Security

  • Email content stored in org-isolated tables
  • RLS policies enforce organization boundaries
  • No email content in application logs
  • PHI/PII detection warnings (optional)

Tracking Pixel Security

  • Tracking endpoints validate organization context
  • Rate limiting on tracking endpoints
  • No sensitive data in tracking URLs

Module Settings

Settings stored in ce_module_settings:
SettingTypeDefaultDescription
email_sync_history_daysINTEGER30Days of history to sync (7-90)
email_body_size_limit_kbINTEGER500Max email body size in KB (100-2000)
email_sync_interval_minutesINTEGER15Polling interval for sync fallback (5-60)
email_tracking_enabledBOOLEANtrueEnable open/click tracking
email_custom_tracking_domainTEXTnullCustom tracking domain (Phase 2)

Implementation Status

ComponentStatusNotes
Database schema✅ Implemented4 tables created with RLS
CE-01 (Contacts) integration✅ ImplementedDirect reference via foreign key
CE-02 (Partners) integration✅ ImplementedDirect reference + domain matching
CE-04 (Activities) integration✅ ImplementedDatabase trigger creates activity records
PF-10 (Notifications) integration✅ ImplementedPlatform Integration Layer
PF-11 (Documents) integration✅ ImplementedPlatform Integration Layer
Microsoft Graph (Outlook) OAuth✅ ImplementedOAuth flow and sync operational
Gmail OAuth⚠️ BlockedRequires Google app verification
Email sync✅ ImplementedMicrosoft Graph sync operational; Gmail blocked
Activity trigger✅ ImplementedTrigger creates CE-04 activity records
Tracking📋 PlannedPhase 3

References


Last Updated: 2026-01-24