/** * Database Trigger Type Definitions * * Triggers are automated actions that execute in response to database events. * They integrate with Ductape primitives: storage, actions, notifications, * brokers, workflows, cache, quotas, fallbacks, and more. */ /** * Events that can trigger actions */ export declare enum TriggerEvent { /** Before a record is inserted */ BEFORE_INSERT = "beforeInsert", /** After a record is inserted */ AFTER_INSERT = "afterInsert", /** Before a record is updated */ BEFORE_UPDATE = "beforeUpdate", /** After a record is updated */ AFTER_UPDATE = "afterUpdate", /** Before a record is deleted */ BEFORE_DELETE = "beforeDelete", /** After a record is deleted */ AFTER_DELETE = "afterDelete", /** Before any write operation */ BEFORE_WRITE = "beforeWrite", /** After any write operation */ AFTER_WRITE = "afterWrite" } /** * Trigger execution timing */ export declare enum TriggerTiming { /** Execute synchronously, block until complete */ SYNC = "sync", /** Execute asynchronously, don't wait */ ASYNC = "async", /** Queue for background processing */ QUEUED = "queued" } /** * Types of actions a trigger can perform */ export declare enum TriggerActionType { DATABASE_INSERT = "database.insert", DATABASE_UPDATE = "database.update", DATABASE_DELETE = "database.delete", DATABASE_QUERY = "database.query", STORAGE_UPLOAD = "storage.upload", STORAGE_DELETE = "storage.delete", STORAGE_COPY = "storage.copy", NOTIFICATION_EMAIL = "notification.email", NOTIFICATION_SMS = "notification.sms", NOTIFICATION_PUSH = "notification.push", NOTIFICATION_CALLBACK = "notification.callback", BROKER_PUBLISH = "broker.publish", CACHE_SET = "cache.set", CACHE_INVALIDATE = "cache.invalidate", CACHE_DELETE = "cache.delete", FEATURE_EXECUTE = "feature.execute", FEATURE_DISPATCH = "feature.dispatch", ACTION_EXECUTE = "action.execute", AGENT_RUN = "agent.run", QUOTA_RUN = "quota.run", FALLBACK_RUN = "fallback.run", HEALTHCHECK_RUN = "healthcheck.run", LOG_CREATE = "log.create", SESSION_REVOKE = "session.revoke", VECTOR_UPSERT = "vector.upsert", VECTOR_DELETE = "vector.delete", CUSTOM_FUNCTION = "custom.function", CUSTOM_HTTP = "custom.http" } /** * Base configuration for all trigger actions */ export interface ITriggerActionBase { /** Action type */ type: TriggerActionType; /** Optional name for this action */ name?: string; /** Condition to evaluate before executing */ condition?: ITriggerCondition; /** Execution timing */ timing?: TriggerTiming; /** Retry configuration */ retry?: ITriggerRetry; /** Timeout in milliseconds */ timeout?: number; /** Continue to next action on failure */ continueOnError?: boolean; } /** * Database operation action */ export interface ITriggerDatabaseAction extends ITriggerActionBase { type: TriggerActionType.DATABASE_INSERT | TriggerActionType.DATABASE_UPDATE | TriggerActionType.DATABASE_DELETE | TriggerActionType.DATABASE_QUERY; /** Target database (tag) */ database?: string; /** Target table */ table: string; /** Data template (supports {{field}} placeholders) */ data?: Record | string; /** Where clause template */ where?: Record | string; } /** * Storage operation action */ export interface ITriggerStorageAction extends ITriggerActionBase { type: TriggerActionType.STORAGE_UPLOAD | TriggerActionType.STORAGE_DELETE | TriggerActionType.STORAGE_COPY; /** Storage resource tag */ storage: string; /** File path template */ path: string; /** Source path for copy operations */ sourcePath?: string; /** Data source field for upload */ dataField?: string; /** MIME type */ mimeType?: string; } /** * Notification action * * For emails: use `subject` for subject line variables and `template` for body variables * For SMS: use `body` for message body variables * For push: use `title`, `body`, and `data` for push notification payload */ export interface ITriggerNotificationAction extends ITriggerActionBase { type: TriggerActionType.NOTIFICATION_EMAIL | TriggerActionType.NOTIFICATION_SMS | TriggerActionType.NOTIFICATION_PUSH | TriggerActionType.NOTIFICATION_CALLBACK; /** Notification resource tag (format: notification_tag:message_tag) */ notification: string; /** Recipients template (supports {{field}} placeholders) - for email/SMS */ recipients?: string | string[]; /** Device tokens (for push notifications) */ device_tokens?: string | string[]; /** Subject variables for email (Record of template placeholders) */ subject?: Record; /** Template variables for email body (Record of template placeholders) */ template?: Record; /** Body variables for SMS (Record of template placeholders) */ body?: Record; /** Title variables for push notifications */ title?: Record; /** Additional data payload for push notifications */ data?: Record; /** Callback request data */ callback?: { query?: Record; headers?: Record; params?: Record; body?: Record; }; } /** * Broker publish action */ export interface ITriggerBrokerAction extends ITriggerActionBase { type: TriggerActionType.BROKER_PUBLISH; /** Event string (broker_tag:topic_tag) */ event: string; /** Message template */ message: Record | string; /** Message headers */ headers?: Record; /** Idempotency key template */ idempotencyKey?: string; } /** * Cache operation action */ export interface ITriggerCacheAction extends ITriggerActionBase { type: TriggerActionType.CACHE_SET | TriggerActionType.CACHE_INVALIDATE | TriggerActionType.CACHE_DELETE; /** Cache resource tag */ cache: string; /** Cache key template */ key: string; /** Value for set operations */ value?: any; /** TTL in seconds */ ttl?: number; /** Key pattern for invalidation */ pattern?: string; } /** * Feature action */ export interface ITriggerFeatureAction extends ITriggerActionBase { type: TriggerActionType.FEATURE_EXECUTE | TriggerActionType.FEATURE_DISPATCH; /** Feature tag */ feature: string; /** Input data template */ input?: Record | string; /** Wait for completion (execute only) */ waitForCompletion?: boolean; } /** * App action execution */ export interface ITriggerActionExecuteAction extends ITriggerActionBase { type: TriggerActionType.ACTION_EXECUTE; /** App tag */ app: string; /** Action event string */ action: string; /** Input data template */ input?: Record | string; } /** * Agent run action */ export interface ITriggerAgentAction extends ITriggerActionBase { type: TriggerActionType.AGENT_RUN; /** Agent tag */ agent: string; /** Prompt template */ prompt?: string; /** Input data template */ input?: Record | string; } /** * Resilience action (quota/fallback/healthcheck) */ export interface ITriggerResilienceAction extends ITriggerActionBase { type: TriggerActionType.QUOTA_RUN | TriggerActionType.FALLBACK_RUN | TriggerActionType.HEALTHCHECK_RUN; /** Resource tag */ tag: string; /** Input data template */ input?: Record | string; } /** * Log action */ export interface ITriggerLogAction extends ITriggerActionBase { type: TriggerActionType.LOG_CREATE; /** Log level */ level?: 'debug' | 'info' | 'warn' | 'error'; /** Message template */ message: string; /** Additional data */ data?: Record | string; } /** * Session action */ export interface ITriggerSessionAction extends ITriggerActionBase { type: TriggerActionType.SESSION_REVOKE; /** Session resource tag */ session: string; /** User ID field */ userIdField?: string; /** Session ID field */ sessionIdField?: string; } /** * Vector operation action */ export interface ITriggerVectorAction extends ITriggerActionBase { type: TriggerActionType.VECTOR_UPSERT | TriggerActionType.VECTOR_DELETE; /** Vector database tag */ vector: string; /** Namespace */ namespace?: string; /** Vector ID template */ id?: string; /** Vector data field */ vectorField?: string; /** Metadata template */ metadata?: Record | string; } /** * Custom function action */ export interface ITriggerCustomAction extends ITriggerActionBase { type: TriggerActionType.CUSTOM_FUNCTION; /** Custom handler function */ handler: (context: ITriggerContext) => Promise; } /** * Custom HTTP action */ export interface ITriggerHttpAction extends ITriggerActionBase { type: TriggerActionType.CUSTOM_HTTP; /** URL template */ url: string; /** HTTP method */ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; /** Headers template */ headers?: Record; /** Body template */ body?: Record | string; /** Query params template */ query?: Record; } /** * Union type of all trigger actions */ export type ITriggerAction = ITriggerDatabaseAction | ITriggerStorageAction | ITriggerNotificationAction | ITriggerBrokerAction | ITriggerCacheAction | ITriggerFeatureAction | ITriggerActionExecuteAction | ITriggerAgentAction | ITriggerResilienceAction | ITriggerLogAction | ITriggerSessionAction | ITriggerVectorAction | ITriggerCustomAction | ITriggerHttpAction; /** * Condition operators */ export declare enum ConditionOperator { EQUALS = "eq", NOT_EQUALS = "neq", GREATER_THAN = "gt", GREATER_THAN_OR_EQUALS = "gte", LESS_THAN = "lt", LESS_THAN_OR_EQUALS = "lte", IN = "in", NOT_IN = "notIn", CONTAINS = "contains", STARTS_WITH = "startsWith", ENDS_WITH = "endsWith", MATCHES = "matches", IS_NULL = "isNull", IS_NOT_NULL = "isNotNull", IS_EMPTY = "isEmpty", IS_NOT_EMPTY = "isNotEmpty", CHANGED = "changed", NOT_CHANGED = "notChanged", CHANGED_TO = "changedTo", CHANGED_FROM = "changedFrom" } /** * Single condition */ export interface IConditionClause { /** Field to evaluate (supports dot notation for nested fields) */ field: string; /** Comparison operator */ operator: ConditionOperator; /** Value to compare against */ value?: any; } /** * Trigger condition (can be simple or compound) */ export interface ITriggerCondition { /** AND conditions */ $and?: (IConditionClause | ITriggerCondition)[]; /** OR conditions */ $or?: (IConditionClause | ITriggerCondition)[]; /** NOT condition */ $not?: IConditionClause | ITriggerCondition; /** Simple condition */ field?: string; operator?: ConditionOperator; value?: any; /** Custom condition function */ custom?: (context: ITriggerContext) => boolean; } /** * Context passed to trigger actions */ export interface ITriggerContext { /** The triggering event */ event: TriggerEvent; /** Table/collection name */ table: string; /** Database tag */ database: string; /** Environment */ env: string; /** Product tag */ product: string; /** Current/new record data */ record: Record; /** Previous record data (for updates) */ previousRecord?: Record; /** Changed fields (for updates) */ changedFields?: string[]; /** Operation type */ operation: 'insert' | 'update' | 'delete'; /** Timestamp */ timestamp: Date; /** User/session info if available */ user?: { id?: string; email?: string; [key: string]: any; }; /** Transaction context if in transaction */ transaction?: any; /** Metadata */ metadata?: Record; } /** * Retry configuration */ export interface ITriggerRetry { /** Maximum retry attempts */ maxAttempts: number; /** Initial delay in ms */ initialDelay?: number; /** Maximum delay in ms */ maxDelay?: number; /** Backoff multiplier */ backoffMultiplier?: number; /** Retry on specific errors only */ retryOn?: string[]; } /** * Complete trigger definition */ export interface ITriggerDefinition { /** Unique trigger name/tag */ name: string; /** Human-readable description */ description?: string; /** Events that activate this trigger */ events: TriggerEvent[]; /** Tables this trigger applies to (empty = all tables) */ tables?: string[]; /** Condition to evaluate before running actions */ condition?: ITriggerCondition; /** Actions to execute */ actions: ITriggerAction[]; /** Whether trigger is enabled */ enabled?: boolean; /** Priority (lower = higher priority) */ priority?: number; /** Tags for organization */ tags?: string[]; } /** * Result of a single action execution */ export interface ITriggerActionResult { /** Action name/type */ action: string; /** Whether action succeeded */ success: boolean; /** Action result data */ result?: any; /** Error if failed */ error?: string; /** Execution duration in ms */ duration: number; /** Number of retry attempts */ retries?: number; } /** * Result of trigger execution */ export interface ITriggerResult { /** Trigger name */ trigger: string; /** Event that triggered */ event: TriggerEvent; /** Overall success */ success: boolean; /** Results of each action */ actions: ITriggerActionResult[]; /** Total execution duration in ms */ duration: number; /** Whether trigger was skipped (condition not met) */ skipped?: boolean; /** Skip reason */ skipReason?: string; } /** * Global trigger configuration */ export interface ITriggerConfig { /** Default timeout for actions (ms) */ defaultTimeout?: number; /** Default retry configuration */ defaultRetry?: ITriggerRetry; /** Whether to run triggers in parallel */ parallelExecution?: boolean; /** Max concurrent trigger executions */ maxConcurrency?: number; /** Global error handler */ onError?: (error: Error, context: ITriggerContext, trigger: ITriggerDefinition) => void; /** Before trigger hook */ beforeTrigger?: (context: ITriggerContext, trigger: ITriggerDefinition) => boolean | Promise; /** After trigger hook */ afterTrigger?: (result: ITriggerResult, context: ITriggerContext) => void; } /** * Triggers defined at schema level (stored in _ductape_triggers) */ export interface ISchemaTriggerConfig { /** Collection/table name */ collection: string; /** Triggers for this collection */ triggers: ITriggerDefinition[]; /** Whether schema triggers are enabled */ enabled: boolean; } /** * Action configuration for persisted triggers (uses config object instead of direct properties) */ export interface IPersistedTriggerAction { /** Action type (e.g., 'notification.email', 'database.insert', 'feature.execute') */ type: string; /** Action name for identification */ name?: string; /** Action configuration - structure depends on action type */ config: Record; /** Condition to evaluate before executing this action */ condition?: ITriggerCondition; /** Execution timing */ timing?: TriggerTiming; /** Retry configuration */ retry?: ITriggerRetry; /** Timeout in milliseconds */ timeout?: number; /** Continue to next action on failure */ continueOnError?: boolean; } /** * Input for creating a persisted trigger */ export interface ICreateTriggerInput { /** Unique trigger tag/identifier */ tag: string; /** Human-readable name */ name: string; /** Description of what the trigger does */ description?: string; /** Events that activate this trigger */ events: Array<'beforeInsert' | 'afterInsert' | 'beforeUpdate' | 'afterUpdate' | 'beforeDelete' | 'afterDelete' | 'beforeWrite' | 'afterWrite'>; /** Tables this trigger applies to */ tables: string[]; /** Condition to evaluate before running actions */ condition?: ITriggerCondition; /** Actions to execute */ actions: IPersistedTriggerAction[]; /** Whether trigger is enabled (default: true) */ enabled?: boolean; /** Priority (lower = higher priority, default: 100) */ priority?: number; } /** * Input for updating a persisted trigger */ export interface IUpdateTriggerInput { /** Human-readable name */ name?: string; /** Description of what the trigger does */ description?: string; /** Events that activate this trigger */ events?: Array<'beforeInsert' | 'afterInsert' | 'beforeUpdate' | 'afterUpdate' | 'beforeDelete' | 'afterDelete' | 'beforeWrite' | 'afterWrite'>; /** Tables this trigger applies to */ tables?: string[]; /** Condition to evaluate before running actions */ condition?: ITriggerCondition; /** Actions to execute */ actions?: IPersistedTriggerAction[]; /** Whether trigger is enabled */ enabled?: boolean; /** Priority (lower = higher priority) */ priority?: number; } /** * Persisted trigger record (stored in backend) */ export interface IPersistedTrigger { /** Unique trigger tag/identifier */ tag: string; /** Human-readable name */ name: string; /** Description of what the trigger does */ description?: string; /** Events that activate this trigger */ events: string[]; /** Tables this trigger applies to */ tables: string[]; /** Condition to evaluate before running actions */ condition?: ITriggerCondition; /** Actions to execute */ actions: IPersistedTriggerAction[]; /** Whether trigger is enabled */ enabled: boolean; /** Priority (lower = higher priority) */ priority: number; /** Database tag this trigger belongs to */ database: string; /** Product tag */ product: string; /** Created timestamp */ created_at?: string; /** Updated timestamp */ updated_at?: string; } /** * Options for listing triggers */ export interface IListTriggersOptions { /** Filter by table */ table?: string; /** Filter by event type */ event?: string; /** Filter by enabled status */ enabled?: boolean; } /** * Trigger manager interface for CRUD operations */ export interface ITriggerManager { /** Create a new trigger */ create(input: ICreateTriggerInput): Promise; /** List all triggers */ list(options?: IListTriggersOptions): Promise; /** Fetch a specific trigger by tag */ fetch(tag: string): Promise; /** Update a trigger */ update(tag: string, input: IUpdateTriggerInput): Promise; /** Delete a trigger */ delete(tag: string): Promise; }