import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, Index, ManyToOne, JoinColumn, } from 'typeorm'; import { WebhookEndpoint } from './endpoint.entity'; export type DeliveryStatus = 'pending' | 'sending' | 'delivered' | 'failed' | 'retrying' | 'cancelled'; @Entity({ name: 'deliveries', schema: 'webhooks' }) export class WebhookDelivery { @PrimaryGeneratedColumn('uuid') id: string; @Index() @Column({ name: 'endpoint_id', type: 'uuid' }) endpointId: string; @Index() @Column({ name: 'tenant_id', type: 'uuid' }) tenantId: string; @Index() @Column({ name: 'event_type', type: 'varchar', length: 100 }) eventType: string; @Column({ name: 'event_id', type: 'uuid' }) eventId: string; @Column({ name: 'payload', type: 'jsonb' }) payload: Record; @Column({ name: 'payload_hash', type: 'varchar', length: 64, nullable: true }) payloadHash: string; @Column({ name: 'request_url', type: 'text' }) requestUrl: string; @Column({ name: 'request_method', type: 'varchar', length: 10 }) requestMethod: string; @Column({ name: 'request_headers', type: 'jsonb', default: {} }) requestHeaders: Record; @Column({ name: 'response_status', type: 'int', nullable: true }) responseStatus: number; @Column({ name: 'response_headers', type: 'jsonb', default: {} }) responseHeaders: Record; @Column({ name: 'response_body', type: 'text', nullable: true }) responseBody: string; @Column({ name: 'response_time_ms', type: 'int', nullable: true }) responseTimeMs: number; @Index() @Column({ name: 'status', type: 'varchar', length: 20, default: 'pending' }) status: DeliveryStatus; @Column({ name: 'attempt_number', type: 'int', default: 1 }) attemptNumber: number; @Column({ name: 'max_attempts', type: 'int', default: 5 }) maxAttempts: number; @Index() @Column({ name: 'next_retry_at', type: 'timestamptz', nullable: true }) nextRetryAt: Date; @Column({ name: 'error_message', type: 'text', nullable: true }) errorMessage: string; @Column({ name: 'error_code', type: 'varchar', length: 50, nullable: true }) errorCode: string; @Column({ name: 'scheduled_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' }) scheduledAt: Date; @Column({ name: 'started_at', type: 'timestamptz', nullable: true }) startedAt: Date; @Column({ name: 'completed_at', type: 'timestamptz', nullable: true }) completedAt: Date; @Index() @CreateDateColumn({ name: 'created_at', type: 'timestamptz' }) createdAt: Date; @ManyToOne(() => WebhookEndpoint, { onDelete: 'CASCADE' }) @JoinColumn({ name: 'endpoint_id' }) endpoint: WebhookEndpoint; }