types: Abstract inline interfaces to @plunk/types
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Activity tracking types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Activity types that can be tracked
|
||||
*/
|
||||
export enum ActivityType {
|
||||
EVENT_TRIGGERED = 'event.triggered',
|
||||
EMAIL_SENT = 'email.sent',
|
||||
EMAIL_DELIVERED = 'email.delivered',
|
||||
EMAIL_OPENED = 'email.opened',
|
||||
EMAIL_CLICKED = 'email.clicked',
|
||||
EMAIL_BOUNCED = 'email.bounced',
|
||||
CAMPAIGN_SENT = 'campaign.sent',
|
||||
CAMPAIGN_SCHEDULED = 'campaign.scheduled',
|
||||
WORKFLOW_STARTED = 'workflow.started',
|
||||
WORKFLOW_COMPLETED = 'workflow.completed',
|
||||
WORKFLOW_EMAIL_SCHEDULED = 'workflow.email.scheduled',
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified activity item
|
||||
*/
|
||||
export interface Activity {
|
||||
id: string;
|
||||
type: ActivityType;
|
||||
timestamp: Date;
|
||||
contactEmail?: string;
|
||||
contactId?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activity statistics for dashboard
|
||||
*/
|
||||
export interface ActivityStats {
|
||||
totalEvents: number;
|
||||
totalEmailsSent: number;
|
||||
totalEmailsOpened: number;
|
||||
totalEmailsClicked: number;
|
||||
totalWorkflowsStarted: number;
|
||||
openRate: number;
|
||||
clickRate: number;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Billing and usage limit types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Usage information for a specific email category
|
||||
*/
|
||||
export interface CategoryUsage {
|
||||
limit: number | null; // null = unlimited
|
||||
usage: number;
|
||||
percentage: number; // 0-100
|
||||
isWarning: boolean; // true if >= 80%
|
||||
isBlocked: boolean; // true if >= 100%
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete billing limits and usage for a project
|
||||
*/
|
||||
export interface BillingLimitsResponse {
|
||||
workflows: CategoryUsage;
|
||||
campaigns: CategoryUsage;
|
||||
transactional: CategoryUsage;
|
||||
currency: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of limit check
|
||||
*/
|
||||
export interface LimitCheckResult {
|
||||
allowed: boolean;
|
||||
warning: boolean; // true if >= 80% but < 100%
|
||||
usage: number;
|
||||
limit: number | null;
|
||||
percentage: number;
|
||||
message?: string;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Campaign service types
|
||||
*/
|
||||
|
||||
import type {CampaignAudienceType} from '@plunk/db';
|
||||
import type {FilterCondition} from '../segments/index.js';
|
||||
|
||||
/**
|
||||
* Data for creating a new campaign
|
||||
*/
|
||||
export interface CreateCampaignData {
|
||||
name: string;
|
||||
description?: string;
|
||||
subject: string;
|
||||
body: string;
|
||||
from: string;
|
||||
fromName?: string | null;
|
||||
replyTo?: string | null;
|
||||
audienceType: CampaignAudienceType;
|
||||
audienceCondition?: FilterCondition;
|
||||
segmentId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data for updating an existing campaign
|
||||
*/
|
||||
export interface UpdateCampaignData {
|
||||
name?: string;
|
||||
description?: string;
|
||||
subject?: string;
|
||||
body?: string;
|
||||
from?: string;
|
||||
fromName?: string | null;
|
||||
replyTo?: string | null;
|
||||
audienceType?: CampaignAudienceType;
|
||||
audienceCondition?: FilterCondition;
|
||||
segmentId?: string;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* API service types
|
||||
* Response and data structures for API endpoints
|
||||
*/
|
||||
|
||||
export * from './activity.js';
|
||||
export * from './billing.js';
|
||||
export * from './campaign.js';
|
||||
export * from './membership.js';
|
||||
export * from './verification.js';
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Project membership types
|
||||
*/
|
||||
|
||||
import type {Role} from '@plunk/db';
|
||||
|
||||
/**
|
||||
* Project member with user email
|
||||
*/
|
||||
export interface MemberWithEmail {
|
||||
userId: string;
|
||||
email: string;
|
||||
role: Role;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Project owner information
|
||||
*/
|
||||
export interface OwnerInfo {
|
||||
userId: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about disabled projects for a user
|
||||
*/
|
||||
export interface DisabledProjectInfo {
|
||||
hasDisabledProject: boolean;
|
||||
disabledProjectNames: string[];
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Email verification types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Result of email address verification
|
||||
*/
|
||||
export interface EmailVerificationResult {
|
||||
email: string;
|
||||
valid: boolean;
|
||||
isDisposable: boolean;
|
||||
isTypo: boolean;
|
||||
isPlusAddressed: boolean;
|
||||
domainExists: boolean;
|
||||
hasMxRecords: boolean;
|
||||
suggestedEmail?: string;
|
||||
reasons: string[];
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './pagination.js';
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Generic pagination types for the Plunk platform
|
||||
*/
|
||||
|
||||
/**
|
||||
* Offset-based pagination response
|
||||
* Used for: Templates, Workflows, and other paginated lists with fixed page sizes
|
||||
*
|
||||
* @template T - The type of items in the paginated response
|
||||
*/
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
totalPages: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cursor-based pagination response
|
||||
* Used for: Contacts, Activities, and other large datasets requiring efficient pagination
|
||||
*
|
||||
* Cursor pagination is more efficient for large datasets (1M+ rows) as it doesn't
|
||||
* require offset calculations and provides stable pagination when data changes.
|
||||
*
|
||||
* @template T - The type of items in the paginated response
|
||||
*/
|
||||
export interface CursorPaginatedResponse<T> {
|
||||
data: T[];
|
||||
cursor?: string;
|
||||
hasMore: boolean;
|
||||
total?: number; // Optional: computed on first page only for performance
|
||||
}
|
||||
+18
-87
@@ -1,94 +1,25 @@
|
||||
// Segment filter types
|
||||
export type SegmentFilterOperator =
|
||||
// Standard operators (for contact fields)
|
||||
| 'equals'
|
||||
| 'notEquals'
|
||||
| 'contains'
|
||||
| 'notContains'
|
||||
| 'greaterThan'
|
||||
| 'lessThan'
|
||||
| 'greaterThanOrEqual'
|
||||
| 'lessThanOrEqual'
|
||||
| 'exists'
|
||||
| 'notExists'
|
||||
| 'within'
|
||||
// Event-based operators
|
||||
| 'triggered' // Event/email activity occurred (any time)
|
||||
| 'triggeredWithin' // Event/email activity occurred within timeframe
|
||||
| 'notTriggered'; // Event/email activity never occurred
|
||||
/**
|
||||
* @plunk/types
|
||||
* Centralized type definitions for the Plunk platform
|
||||
*/
|
||||
|
||||
export type SegmentFilterLogic = 'AND' | 'OR';
|
||||
// Common utility types
|
||||
export * from './common/index.js';
|
||||
|
||||
export interface SegmentFilter {
|
||||
field: string;
|
||||
operator: SegmentFilterOperator;
|
||||
value?: any;
|
||||
unit?: 'days' | 'hours' | 'minutes';
|
||||
}
|
||||
// Job queue types
|
||||
export * from './jobs/index.js';
|
||||
|
||||
export interface FilterGroup {
|
||||
filters: SegmentFilter[];
|
||||
conditions?: FilterCondition;
|
||||
}
|
||||
// API service types
|
||||
export * from './api/index.js';
|
||||
|
||||
export interface FilterCondition {
|
||||
logic: SegmentFilterLogic;
|
||||
groups: FilterGroup[];
|
||||
}
|
||||
// Notification types
|
||||
export * from './notifications/index.js';
|
||||
|
||||
export interface CreateSegmentData {
|
||||
name: string;
|
||||
description?: string;
|
||||
condition: FilterCondition;
|
||||
trackMembership?: boolean;
|
||||
}
|
||||
// Extended Prisma types
|
||||
export * from './prisma/index.js';
|
||||
|
||||
export interface UpdateSegmentData {
|
||||
name?: string;
|
||||
description?: string;
|
||||
condition?: FilterCondition;
|
||||
trackMembership?: boolean;
|
||||
}
|
||||
// Segment and filter types
|
||||
export * from './segments/index.js';
|
||||
|
||||
export interface SegmentMembershipComputeResult {
|
||||
added: number;
|
||||
removed: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
// Security status types
|
||||
export interface SecurityRateData {
|
||||
total: number;
|
||||
bounces: number;
|
||||
complaints: number;
|
||||
bounceRate: number;
|
||||
complaintRate: number;
|
||||
}
|
||||
|
||||
export interface SecurityStatus {
|
||||
projectId: string;
|
||||
isHealthy: boolean;
|
||||
shouldDisable: boolean;
|
||||
sevenDay: SecurityRateData;
|
||||
allTime: SecurityRateData;
|
||||
violations: string[];
|
||||
warnings: string[];
|
||||
}
|
||||
|
||||
export interface SecurityThresholds {
|
||||
MIN_EMAILS_FOR_ENFORCEMENT: number;
|
||||
BOUNCE_7DAY_WARNING: number;
|
||||
BOUNCE_7DAY_CRITICAL: number;
|
||||
BOUNCE_ALLTIME_WARNING: number;
|
||||
BOUNCE_ALLTIME_CRITICAL: number;
|
||||
COMPLAINT_7DAY_WARNING: number;
|
||||
COMPLAINT_7DAY_CRITICAL: number;
|
||||
COMPLAINT_ALLTIME_WARNING: number;
|
||||
COMPLAINT_ALLTIME_CRITICAL: number;
|
||||
}
|
||||
|
||||
export interface ProjectSecurityMetrics {
|
||||
status: SecurityStatus;
|
||||
thresholds: SecurityThresholds;
|
||||
isDisabled: boolean;
|
||||
}
|
||||
// Security types
|
||||
export * from './security/index.js';
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Campaign queue job data types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Job data for processing a batch of campaign recipients
|
||||
* Used by: campaignQueue worker
|
||||
*/
|
||||
export interface CampaignBatchJobData {
|
||||
campaignId: string;
|
||||
batchNumber: number;
|
||||
offset: number;
|
||||
limit: number;
|
||||
cursor?: string; // For cursor-based pagination
|
||||
}
|
||||
|
||||
/**
|
||||
* Job data for sending a scheduled campaign
|
||||
* Used by: scheduledQueue worker
|
||||
*/
|
||||
export interface ScheduledCampaignJobData {
|
||||
campaignId: string;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Email queue job data types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Job data for sending a single email
|
||||
* Used by: emailQueue worker
|
||||
*/
|
||||
export interface SendEmailJobData {
|
||||
emailId: string;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Import and bulk operation queue job data types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Job data for importing contacts from CSV
|
||||
* Used by: importQueue worker
|
||||
*/
|
||||
export interface ContactImportJobData {
|
||||
projectId: string;
|
||||
csvData: string; // Base64 encoded CSV content
|
||||
filename: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Job data for bulk contact actions (subscribe, unsubscribe, delete)
|
||||
* Used by: bulkContactQueue worker
|
||||
*/
|
||||
export interface BulkContactActionJobData {
|
||||
projectId: string;
|
||||
contactIds: string[];
|
||||
operation: 'subscribe' | 'unsubscribe' | 'delete';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Queue job data types
|
||||
* Centralized type definitions for all BullMQ job payloads
|
||||
*/
|
||||
|
||||
export * from './email.js';
|
||||
export * from './campaign.js';
|
||||
export * from './workflow.js';
|
||||
export * from './import.js';
|
||||
export * from './maintenance.js';
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Maintenance and background task queue job data types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Job data for updating segment membership counts
|
||||
* Used by: segmentCountQueue worker
|
||||
*/
|
||||
export interface SegmentCountJobData {
|
||||
projectId?: string; // Optional: if provided, only update this project's segments
|
||||
}
|
||||
|
||||
/**
|
||||
* Job data for domain verification checks
|
||||
* Used by: domainVerificationQueue worker
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
export interface DomainVerificationJobData {
|
||||
// Empty for now - processes all domains
|
||||
}
|
||||
|
||||
/**
|
||||
* Job data for cleaning up old API request logs
|
||||
* Used by: apiRequestCleanupQueue worker
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
export interface ApiRequestCleanupJobData {
|
||||
// Empty - cleans up old API request logs
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Workflow queue job data types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Job data for executing a workflow step
|
||||
* Used by: workflowQueue worker
|
||||
*/
|
||||
export interface WorkflowStepJobData {
|
||||
executionId: string;
|
||||
stepId: string;
|
||||
type?: 'process-step' | 'timeout'; // Job type for different handling
|
||||
stepExecutionId?: string; // For timeout jobs, reference to the step execution
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './ntfy.js';
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Notification types for ntfy.sh integration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Priority levels for ntfy notifications
|
||||
* Based on ntfy.sh documentation
|
||||
*/
|
||||
export enum NtfyPriority {
|
||||
MIN = 1, // No vibration/sound, relegated to "Other notifications"
|
||||
LOW = 2, // No vibration/sound, hidden until drawer opened
|
||||
DEFAULT = 3, // Short vibration and sound (standard)
|
||||
HIGH = 4, // Long vibration, pop-over notification
|
||||
MAX = 5, // Long vibration bursts, pop-over notification
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags for ntfy notifications (emoji shortcuts)
|
||||
*/
|
||||
export enum NtfyTag {
|
||||
WARNING = 'warning',
|
||||
ERROR = 'rotating_light',
|
||||
SUCCESS = 'white_check_mark',
|
||||
MONEY = 'money_with_wings',
|
||||
SHIELD = 'shield',
|
||||
ROCKET = 'rocket',
|
||||
BELL = 'bell',
|
||||
CHART = 'chart_with_upwards_trend',
|
||||
SKULL = 'skull',
|
||||
INFO = 'information_source',
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification payload for ntfy
|
||||
*/
|
||||
export interface NtfyNotification {
|
||||
title: string;
|
||||
message: string;
|
||||
priority?: NtfyPriority;
|
||||
tags?: NtfyTag[];
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Extended Prisma types
|
||||
* Types that extend Prisma models with additional relations or computed fields
|
||||
*/
|
||||
|
||||
import type {
|
||||
Workflow,
|
||||
WorkflowExecution,
|
||||
WorkflowStep,
|
||||
WorkflowStepExecution,
|
||||
WorkflowTransition,
|
||||
Template,
|
||||
Contact,
|
||||
Prisma,
|
||||
} from '@plunk/db';
|
||||
|
||||
/**
|
||||
* Workflow with all steps, transitions, and template details
|
||||
* Used for workflow editor and detailed workflow views
|
||||
*/
|
||||
export interface WorkflowWithDetails extends Workflow {
|
||||
steps: Array<
|
||||
WorkflowStep & {
|
||||
template?: {id: string; name: string} | null;
|
||||
outgoingTransitions: WorkflowTransition[];
|
||||
incomingTransitions: WorkflowTransition[];
|
||||
}
|
||||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workflow execution with full context
|
||||
* Used for execution details and monitoring
|
||||
*/
|
||||
export interface WorkflowExecutionWithDetails extends WorkflowExecution {
|
||||
workflow: Workflow;
|
||||
contact: {id: string; email: string};
|
||||
currentStep?: WorkflowStep | null;
|
||||
stepExecutions: WorkflowStepExecution[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Workflow execution with all relations loaded
|
||||
* Used internally by workflow execution engine
|
||||
*/
|
||||
export type WorkflowExecutionWithRelations = WorkflowExecution & {
|
||||
contact: Contact;
|
||||
workflow: Workflow;
|
||||
};
|
||||
|
||||
/**
|
||||
* Workflow step with optional template
|
||||
* Used by step execution logic
|
||||
*/
|
||||
export type WorkflowStepWithTemplate = WorkflowStep & {
|
||||
template?: Template | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Workflow step with outgoing transitions loaded
|
||||
* Used for flow control and navigation
|
||||
*/
|
||||
export type WorkflowStepWithTransitions = WorkflowStep & {
|
||||
outgoingTransitions?: Array<{
|
||||
id: string;
|
||||
condition: Prisma.JsonValue;
|
||||
priority: number;
|
||||
toStep: WorkflowStep;
|
||||
}>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Step configuration (JSON value)
|
||||
* Type-safe alias for workflow step config
|
||||
*/
|
||||
export type StepConfig = Prisma.JsonValue;
|
||||
|
||||
/**
|
||||
* Step execution result
|
||||
* Generic key-value result from step execution
|
||||
*/
|
||||
export type StepResult = Record<string, unknown>;
|
||||
@@ -0,0 +1 @@
|
||||
export * from './extended.js';
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Security and project health types
|
||||
*/
|
||||
|
||||
export interface SecurityRateData {
|
||||
total: number;
|
||||
bounces: number;
|
||||
complaints: number;
|
||||
bounceRate: number;
|
||||
complaintRate: number;
|
||||
}
|
||||
|
||||
export interface SecurityStatus {
|
||||
projectId: string;
|
||||
isHealthy: boolean;
|
||||
shouldDisable: boolean;
|
||||
sevenDay: SecurityRateData;
|
||||
allTime: SecurityRateData;
|
||||
violations: string[];
|
||||
warnings: string[];
|
||||
}
|
||||
|
||||
export interface SecurityThresholds {
|
||||
MIN_EMAILS_FOR_ENFORCEMENT: number;
|
||||
BOUNCE_7DAY_WARNING: number;
|
||||
BOUNCE_7DAY_CRITICAL: number;
|
||||
BOUNCE_ALLTIME_WARNING: number;
|
||||
BOUNCE_ALLTIME_CRITICAL: number;
|
||||
COMPLAINT_7DAY_WARNING: number;
|
||||
COMPLAINT_7DAY_CRITICAL: number;
|
||||
COMPLAINT_ALLTIME_WARNING: number;
|
||||
COMPLAINT_ALLTIME_CRITICAL: number;
|
||||
}
|
||||
|
||||
export interface ProjectSecurityMetrics {
|
||||
status: SecurityStatus;
|
||||
thresholds: SecurityThresholds;
|
||||
isDisabled: boolean;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Segment and filter types
|
||||
*/
|
||||
|
||||
// Segment filter types
|
||||
export type SegmentFilterOperator =
|
||||
// Standard operators (for contact fields)
|
||||
| 'equals'
|
||||
| 'notEquals'
|
||||
| 'contains'
|
||||
| 'notContains'
|
||||
| 'greaterThan'
|
||||
| 'lessThan'
|
||||
| 'greaterThanOrEqual'
|
||||
| 'lessThanOrEqual'
|
||||
| 'exists'
|
||||
| 'notExists'
|
||||
| 'within'
|
||||
// Event-based operators
|
||||
| 'triggered' // Event/email activity occurred (any time)
|
||||
| 'triggeredWithin' // Event/email activity occurred within timeframe
|
||||
| 'notTriggered'; // Event/email activity never occurred
|
||||
|
||||
export type SegmentFilterLogic = 'AND' | 'OR';
|
||||
|
||||
export interface SegmentFilter {
|
||||
field: string;
|
||||
operator: SegmentFilterOperator;
|
||||
value?: any;
|
||||
unit?: 'days' | 'hours' | 'minutes';
|
||||
}
|
||||
|
||||
export interface FilterGroup {
|
||||
filters: SegmentFilter[];
|
||||
conditions?: FilterCondition;
|
||||
}
|
||||
|
||||
export interface FilterCondition {
|
||||
logic: SegmentFilterLogic;
|
||||
groups: FilterGroup[];
|
||||
}
|
||||
|
||||
export interface CreateSegmentData {
|
||||
name: string;
|
||||
description?: string;
|
||||
condition: FilterCondition;
|
||||
trackMembership?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateSegmentData {
|
||||
name?: string;
|
||||
description?: string;
|
||||
condition?: FilterCondition;
|
||||
trackMembership?: boolean;
|
||||
}
|
||||
|
||||
export interface SegmentMembershipComputeResult {
|
||||
added: number;
|
||||
removed: number;
|
||||
total: number;
|
||||
}
|
||||
Reference in New Issue
Block a user