196 lines
3.8 KiB
TypeScript
196 lines
3.8 KiB
TypeScript
/**
|
|
* Webhook Entity
|
|
*
|
|
* Represents a webhook subscription for external integrations
|
|
*/
|
|
|
|
export enum WebhookEvent {
|
|
BOOKING_CREATED = 'booking.created',
|
|
BOOKING_UPDATED = 'booking.updated',
|
|
BOOKING_CANCELLED = 'booking.cancelled',
|
|
BOOKING_CONFIRMED = 'booking.confirmed',
|
|
RATE_QUOTE_CREATED = 'rate_quote.created',
|
|
DOCUMENT_UPLOADED = 'document.uploaded',
|
|
ORGANIZATION_UPDATED = 'organization.updated',
|
|
USER_CREATED = 'user.created',
|
|
}
|
|
|
|
export enum WebhookStatus {
|
|
ACTIVE = 'active',
|
|
INACTIVE = 'inactive',
|
|
FAILED = 'failed',
|
|
}
|
|
|
|
interface WebhookProps {
|
|
id: string;
|
|
organizationId: string;
|
|
url: string;
|
|
events: WebhookEvent[];
|
|
secret: string;
|
|
status: WebhookStatus;
|
|
description?: string;
|
|
headers?: Record<string, string>;
|
|
retryCount: number;
|
|
lastTriggeredAt?: Date;
|
|
failureCount: number;
|
|
createdAt: Date;
|
|
updatedAt: Date;
|
|
}
|
|
|
|
export class Webhook {
|
|
private constructor(private readonly props: WebhookProps) {}
|
|
|
|
static create(
|
|
props: Omit<WebhookProps, 'id' | 'status' | 'retryCount' | 'failureCount' | 'createdAt' | 'updatedAt'> & { id: string },
|
|
): Webhook {
|
|
return new Webhook({
|
|
...props,
|
|
status: WebhookStatus.ACTIVE,
|
|
retryCount: 0,
|
|
failureCount: 0,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
});
|
|
}
|
|
|
|
static fromPersistence(props: WebhookProps): Webhook {
|
|
return new Webhook(props);
|
|
}
|
|
|
|
get id(): string {
|
|
return this.props.id;
|
|
}
|
|
|
|
get organizationId(): string {
|
|
return this.props.organizationId;
|
|
}
|
|
|
|
get url(): string {
|
|
return this.props.url;
|
|
}
|
|
|
|
get events(): WebhookEvent[] {
|
|
return this.props.events;
|
|
}
|
|
|
|
get secret(): string {
|
|
return this.props.secret;
|
|
}
|
|
|
|
get status(): WebhookStatus {
|
|
return this.props.status;
|
|
}
|
|
|
|
get description(): string | undefined {
|
|
return this.props.description;
|
|
}
|
|
|
|
get headers(): Record<string, string> | undefined {
|
|
return this.props.headers;
|
|
}
|
|
|
|
get retryCount(): number {
|
|
return this.props.retryCount;
|
|
}
|
|
|
|
get lastTriggeredAt(): Date | undefined {
|
|
return this.props.lastTriggeredAt;
|
|
}
|
|
|
|
get failureCount(): number {
|
|
return this.props.failureCount;
|
|
}
|
|
|
|
get createdAt(): Date {
|
|
return this.props.createdAt;
|
|
}
|
|
|
|
get updatedAt(): Date {
|
|
return this.props.updatedAt;
|
|
}
|
|
|
|
/**
|
|
* Check if webhook is active
|
|
*/
|
|
isActive(): boolean {
|
|
return this.props.status === WebhookStatus.ACTIVE;
|
|
}
|
|
|
|
/**
|
|
* Check if webhook subscribes to an event
|
|
*/
|
|
subscribesToEvent(event: WebhookEvent): boolean {
|
|
return this.props.events.includes(event);
|
|
}
|
|
|
|
/**
|
|
* Activate webhook
|
|
*/
|
|
activate(): Webhook {
|
|
return new Webhook({
|
|
...this.props,
|
|
status: WebhookStatus.ACTIVE,
|
|
updatedAt: new Date(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Deactivate webhook
|
|
*/
|
|
deactivate(): Webhook {
|
|
return new Webhook({
|
|
...this.props,
|
|
status: WebhookStatus.INACTIVE,
|
|
updatedAt: new Date(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Mark webhook as failed
|
|
*/
|
|
markAsFailed(): Webhook {
|
|
return new Webhook({
|
|
...this.props,
|
|
status: WebhookStatus.FAILED,
|
|
failureCount: this.props.failureCount + 1,
|
|
updatedAt: new Date(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Record successful trigger
|
|
*/
|
|
recordTrigger(): Webhook {
|
|
return new Webhook({
|
|
...this.props,
|
|
lastTriggeredAt: new Date(),
|
|
retryCount: this.props.retryCount + 1,
|
|
failureCount: 0, // Reset failure count on success
|
|
updatedAt: new Date(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Update webhook
|
|
*/
|
|
update(updates: {
|
|
url?: string;
|
|
events?: WebhookEvent[];
|
|
description?: string;
|
|
headers?: Record<string, string>;
|
|
}): Webhook {
|
|
return new Webhook({
|
|
...this.props,
|
|
...updates,
|
|
updatedAt: new Date(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Convert to plain object
|
|
*/
|
|
toObject(): WebhookProps {
|
|
return { ...this.props };
|
|
}
|
|
}
|