Files
edr-platform/apps/edr-payment-api/src/modules/webhooks/webhook-events.repository.ts
2026-06-11 15:25:24 +03:00

45 lines
1.3 KiB
TypeScript

import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { QueryFailedError, Repository } from "typeorm";
import { BaseRepository } from "@edr/api-common";
import { PaymentWebhookEvent } from "./entities/payment-webhook-event.entity";
const PG_UNIQUE_VIOLATION = "23505";
@Injectable()
export class WebhookEventsRepository extends BaseRepository<PaymentWebhookEvent> {
constructor(
@InjectRepository(PaymentWebhookEvent)
repository: Repository<PaymentWebhookEvent>,
) {
super(repository);
}
/**
* Insert the event, relying on the unique (provider, external_event_id) index for dedupe.
* Returns null when the event was already recorded (duplicate delivery / provider replay).
*/
async createDeduped(
data: Partial<PaymentWebhookEvent>,
): Promise<PaymentWebhookEvent | null> {
try {
return await this.create(data);
} catch (err) {
if (
err instanceof QueryFailedError &&
(err.driverError as { code?: string })?.code === PG_UNIQUE_VIOLATION
) {
return null;
}
throw err;
}
}
async markProcessed(id: string, processingError?: string): Promise<void> {
await this.update(id, {
processedAt: new Date(),
processingError: processingError ?? null,
});
}
}