PSA/shared/interfaces/inbound-email.interfaces.ts
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

230 lines
6.0 KiB
TypeScript

// Email provider interfaces for inbound email processing
export interface EmailProviderConfig {
id: string;
tenant: string;
name: string;
provider_type: 'microsoft' | 'google' | 'imap';
mailbox: string;
folder_to_monitor: string; // Defaults to 'Inbox'
active: boolean;
// Common webhook fields as real columns
webhook_notification_url: string;
webhook_subscription_id?: string;
webhook_verification_token?: string;
webhook_expires_at?: string; // ISO date
last_subscription_renewal?: string; // ISO date
// Connection status fields
connection_status: 'connected' | 'disconnected' | 'error';
last_connection_test?: string; // ISO date
connection_error_message?: string;
// Provider-specific configuration (OAuth scopes, etc.)
provider_config?: {
// Microsoft-specific
tenantId?: string;
scopes?: string[];
// Google-specific (camelCase for interface compatibility)
projectId?: string;
pubsubTopic?: string;
// Common OAuth settings
clientId?: string; // Usually from environment, but could be per-provider
// Database field names (snake_case) - for Gmail adapter compatibility
project_id?: string;
pubsub_topic_name?: string;
pubsub_subscription_name?: string;
client_id?: string;
client_secret?: string;
access_token?: string;
refresh_token?: string;
token_expires_at?: string;
history_id?: string;
watch_expiration?: string;
customScopes?: string[];
// Gmail-specific processing configuration
label_filters?: string[]; // names of labels to include (user-defined)
auto_process_emails?: boolean;
max_emails_per_sync?: number;
// IMAP-specific configuration
host?: string;
port?: number;
secure?: boolean;
allow_starttls?: boolean;
auth_type?: 'password' | 'oauth2';
username?: string;
password?: string;
folder_filters?: string[];
oauth_authorize_url?: string;
oauth_token_url?: string;
oauth_client_id?: string;
oauth_client_secret?: string;
oauth_scopes?: string;
// Note: access_token, refresh_token, token_expires_at are defined above (shared with Gmail OAuth)
uid_validity?: string;
last_uid?: string;
folder_state?: Record<string, { uid_validity?: string; last_uid?: string; last_seen_at?: string }>;
last_processed_message_id?: string;
server_capabilities?: string;
lease_owner?: string;
lease_expires_at?: string;
connection_timeout_ms?: number;
socket_keepalive?: boolean;
last_seen_at?: string;
last_sync_at?: string;
last_error?: string;
};
created_at: string; // ISO date
updated_at: string; // ISO date
}
export interface EmailIngressSkipReason {
type: 'attachment' | 'raw_mime';
reason:
| 'attachment_over_max_bytes'
| 'attachment_count_exceeded'
| 'attachment_total_bytes_exceeded'
| 'raw_mime_over_max_bytes';
attachmentId?: string;
attachmentName?: string;
size: number;
cap: number;
}
export interface EmailMessage {
id: string;
provider: 'microsoft' | 'google' | 'imap';
providerId: string;
tenant: string;
receivedAt: string;
from: {
email: string;
name?: string;
};
to: Array<{
email: string;
name?: string;
}>;
cc?: Array<{
email: string;
name?: string;
}>;
subject: string;
body: {
text: string;
html?: string;
};
attachments?: Array<{
id: string;
name: string;
contentType: string;
size: number;
contentId?: string;
isInline?: boolean;
content?: string;
}>;
threadId?: string;
references?: string[];
inReplyTo?: string;
rawMime?: string;
rawMimeBase64?: string;
sourceMimeBase64?: string;
rawSourceBase64?: string;
ingressSkipReasons?: EmailIngressSkipReason[];
}
export interface EmailMessageDetails extends EmailMessage {
// Additional details that might be available when fetching full message
headers?: Record<string, string>;
messageSize?: number;
importance?: 'low' | 'normal' | 'high';
sensitivity?: 'normal' | 'personal' | 'private' | 'confidential';
}
export interface InboundEmailEvent {
event_type: 'INBOUND_EMAIL_RECEIVED';
payload: {
emailId: string;
tenant: string;
providerId: string;
emailData: EmailMessage;
matchedClient?: {
clientId: string;
clientName: string;
contactId?: string;
contactName?: string;
};
};
}
export interface EmailConnectionStatus {
connected: boolean;
status: 'connected' | 'disconnected' | 'error';
clientName?: string;
providerId?: string;
errorMessage?: string;
lastConnectionTest?: string;
}
export type UnifiedInboundEmailProvider = 'microsoft' | 'google' | 'imap';
export interface UnifiedInboundQueueJobBase {
jobId: string;
schemaVersion: 1;
tenantId: string;
providerId: string;
provider: UnifiedInboundEmailProvider;
enqueuedAt: string;
attempt: number;
maxAttempts: number;
}
export interface MicrosoftInboundEmailPointer {
subscriptionId: string;
messageId: string;
resource?: string;
changeType?: string;
}
export interface GoogleInboundEmailPointer {
historyId: string;
emailAddress: string;
pubsubMessageId?: string;
discoveredMessageIds?: string[];
}
export interface ImapInboundEmailPointer {
mailbox: string;
uid: string;
uidValidity?: string;
messageId?: string;
}
export type UnifiedInboundEmailQueueJob =
| (UnifiedInboundQueueJobBase & {
provider: 'microsoft';
pointer: MicrosoftInboundEmailPointer;
})
| (UnifiedInboundQueueJobBase & {
provider: 'google';
pointer: GoogleInboundEmailPointer;
})
| (UnifiedInboundQueueJobBase & {
provider: 'imap';
pointer: ImapInboundEmailPointer;
});
export interface EmailQueueJob {
id: string;
tenant: string;
provider: 'microsoft' | 'google' | 'imap' | 'mailhog-test-provider';
messageId: string;
providerId: string;
webhookData: any;
attempt: number;
maxRetries: number;
createdAt: string;
// Optional email data for cases where we already have the email content (e.g., MailHog)
emailData?: EmailMessage;
}