/** * WebhookEndpoint Entity * Outbound webhook endpoint configuration with retry and rate limiting * Compatible with erp-core endpoint.entity * * @module Webhooks */ import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, Index, Unique, } from 'typeorm'; export type AuthType = 'none' | 'basic' | 'bearer' | 'hmac' | 'oauth2'; @Entity({ name: 'endpoints', schema: 'webhooks' }) @Unique(['tenantId', 'url']) export class WebhookEndpoint { @PrimaryGeneratedColumn('uuid') id: string; @Index() @Column({ name: 'tenant_id', type: 'uuid' }) tenantId: string; @Column({ name: 'name', type: 'varchar', length: 200 }) name: string; @Column({ name: 'description', type: 'text', nullable: true }) description: string; @Column({ name: 'url', type: 'text' }) url: string; @Column({ name: 'http_method', type: 'varchar', length: 10, default: 'POST' }) httpMethod: string; @Column({ name: 'auth_type', type: 'varchar', length: 30, default: 'none' }) authType: AuthType; @Column({ name: 'auth_config', type: 'jsonb', default: {} }) authConfig: Record; @Column({ name: 'custom_headers', type: 'jsonb', default: {} }) customHeaders: Record; @Column({ name: 'subscribed_events', type: 'text', array: true, default: [] }) subscribedEvents: string[]; @Column({ name: 'filters', type: 'jsonb', default: {} }) filters: Record; @Column({ name: 'retry_enabled', type: 'boolean', default: true }) retryEnabled: boolean; @Column({ name: 'max_retries', type: 'int', default: 5 }) maxRetries: number; @Column({ name: 'retry_delay_seconds', type: 'int', default: 60 }) retryDelaySeconds: number; @Column({ name: 'retry_backoff_multiplier', type: 'decimal', precision: 3, scale: 1, default: 2.0 }) retryBackoffMultiplier: number; @Column({ name: 'timeout_seconds', type: 'int', default: 30 }) timeoutSeconds: number; @Index() @Column({ name: 'is_active', type: 'boolean', default: true }) isActive: boolean; @Column({ name: 'is_verified', type: 'boolean', default: false }) isVerified: boolean; @Column({ name: 'verified_at', type: 'timestamptz', nullable: true }) verifiedAt: Date; @Column({ name: 'signing_secret', type: 'varchar', length: 255, nullable: true }) signingSecret: string; @Column({ name: 'total_deliveries', type: 'int', default: 0 }) totalDeliveries: number; @Column({ name: 'successful_deliveries', type: 'int', default: 0 }) successfulDeliveries: number; @Column({ name: 'failed_deliveries', type: 'int', default: 0 }) failedDeliveries: number; @Column({ name: 'last_delivery_at', type: 'timestamptz', nullable: true }) lastDeliveryAt: Date; @Column({ name: 'last_success_at', type: 'timestamptz', nullable: true }) lastSuccessAt: Date; @Column({ name: 'last_failure_at', type: 'timestamptz', nullable: true }) lastFailureAt: Date; @Column({ name: 'rate_limit_per_minute', type: 'int', default: 60 }) rateLimitPerMinute: number; @Column({ name: 'rate_limit_per_hour', type: 'int', default: 1000 }) rateLimitPerHour: number; @CreateDateColumn({ name: 'created_at', type: 'timestamptz' }) createdAt: Date; @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' }) updatedAt: Date; @Column({ name: 'created_by', type: 'uuid', nullable: true }) createdBy: string; }