erp-core-backend-v2/src/modules/webhooks/entities/delivery.entity.ts
rckrdmrd ca07b4268d feat: Add complete module structure for ERP backend
- Add modules: ai, audit, billing-usage, biometrics, branches, dashboard,
  feature-flags, invoices, mcp, mobile, notifications, partners,
  payment-terminals, products, profiles, purchases, reports, sales,
  storage, warehouses, webhooks, whatsapp
- Add controllers, DTOs, entities, and services for each module
- Add shared services and utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 00:40:54 -06:00

98 lines
2.7 KiB
TypeScript

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<string, any>;
@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<string, string>;
@Column({ name: 'response_status', type: 'int', nullable: true })
responseStatus: number;
@Column({ name: 'response_headers', type: 'jsonb', default: {} })
responseHeaders: Record<string, string>;
@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;
}