/**
 * Webhook delivery service.
 *
 * The backend persists the terminal event in WebhookOutbox before it performs
 * network I/O. This module deliberately keeps the outbox payload separate from
 * callback credentials: the secret is supplied to the sender at delivery time
 * and is used only as the HMAC key.
 */
import { WebhookPayload, WebhookDelivery } from '../types';
/**
 * The old `WebhookDelivery` model is retained as an append-only attempt
 * history. These fields are intentionally additive so existing worker callers
 * can continue to use `success`, `errorMessage`, and `httpStatus`.
 */
export type WebhookDeliveryStatus = 'delivered' | 'retry_wait' | 'dead';
export interface WebhookRetryMetadata {
    status: WebhookDeliveryStatus;
    attemptNumber: number;
    maxAttempts: number;
    retryable: boolean;
    nextAttemptAt?: Date;
    responseStatus?: number;
}
export type WebhookDeliveryResult = WebhookDelivery & WebhookRetryMetadata & {
    /** Stable callback identity, normally the WebhookOutbox primary key. */
    deliveryId: string;
    /** Monotonic per-job event identity when an outbox row supplied one. */
    eventSequence?: number;
};
export interface WebhookDeliveryOptions {
    /** Stable delivery identity. It must not change between retry attempts. */
    stableDeliveryId?: string;
    /** Attempt number for durable scheduling. Defaults to one. */
    attemptNumber?: number;
    /** Maximum automatic attempts. Clamped to a small bounded range. */
    maxAttempts?: number;
    /** Timestamp used for the signed request. Defaults to the current clock. */
    now?: Date | number;
    /** Event sequence echoed in the callback body. */
    eventSequence?: number;
    /** Submission identity echoed in the callback body. */
    submissionId?: string;
    /** Exact previously persisted request bytes. No reserialization is done. */
    canonicalBody?: string;
    /** Base delay used to calculate the next retry due time. */
    retryBaseDelayMs?: number;
    /** Upper bound for exponential retry delay. */
    retryMaxDelayMs?: number;
    /** Additional bounded jitter in milliseconds. Defaults to 25% of the delay. */
    jitterMs?: number;
    /** Injectable random source for deterministic scheduler tests. */
    random?: () => number;
}
export interface WebhookOutboxCreateInput {
    jobId: string;
    event: string;
    payload: WebhookPayload | Record<string, unknown>;
    deliveryId?: string;
    eventSequence?: number;
    /** Alias accepted for callers that use the database column name. */
    deliverySequence?: number;
    submissionId?: string;
    clientJobId?: string;
    refs?: readonly string[];
    results?: unknown;
    failure?: unknown;
    isFinal?: boolean;
    now?: Date;
}
export interface WebhookOutboxClaimOptions {
    now?: Date;
    leaseMs?: number;
    maxAttempts?: number;
    batchSize?: number;
}
export interface WebhookOutboxEntry {
    id: string;
    job_id: string;
    event: string;
    delivery_sequence: number;
    payload: unknown;
    status?: string;
    attempts: number;
    next_attempt_at?: Date | null;
    first_attempt_at?: Date | null;
    last_attempt_at?: Date | null;
    dead_at?: Date | null;
    response_status?: number | null;
    claimed_at?: Date | null;
    claimedAt?: Date;
    attemptNumber?: number;
    job?: {
        callback_url: string | null;
        callback_secret: string | null;
    };
}
export interface WebhookOutboxSettlement {
    entryId: string;
    claimedAt: Date;
    result: Pick<WebhookDeliveryResult, 'success' | 'status' | 'errorMessage' | 'httpStatus' | 'nextAttemptAt'>;
    now?: Date;
}
/**
 * Preserve the structured result mapper used by legacy and bulk callbacks.
 */
export declare function getStructuredWebhookResult(rawTranslation: string | null): {
    translation?: string;
    translatedTitle?: string;
    translatedExcerpt?: string;
    translatedContent?: string;
    translatedFields?: import("../utils/structuredFields").StructuredFields;
};
/**
 * Send one callback attempt.
 *
 * `stableDeliveryId` is retained as the fifth positional argument for old
 * callers. New callers may pass an options object instead. The timestamp is a
 * header-only replay nonce; it is regenerated on every call while the JSON
 * body and delivery identity remain unchanged for the same outbox row.
 */
export declare function deliverWebhook(jobId: string, payload: WebhookPayload | Record<string, unknown>, callbackUrl: string, callbackSecret: string, stableDeliveryIdOrOptions?: string | WebhookDeliveryOptions, suppliedOptions?: WebhookDeliveryOptions): Promise<WebhookDeliveryResult>;
/**
 * Persist a terminal callback event before any HTTP call. The returned primary
 * key is also the callback's stable deliveryId. When no sequence is supplied,
 * the next sequence is calculated inside the caller's transaction using the
 * latest row for this job.
 */
export declare function createWebhookOutbox(database: unknown, input: WebhookOutboxCreateInput): Promise<WebhookOutboxEntry>;
/**
 * Claim due rows using a compare-and-swap update. Stale delivery leases are
 * returned to pending before the due scan. Secrets are returned only in memory
 * to the sender and are never included in logs or database writes by this
 * module.
 */
export declare function claimDueWebhookOutbox(database?: unknown, options?: WebhookOutboxClaimOptions): Promise<WebhookOutboxEntry[]>;
/**
 * Persist the bounded result of a claimed delivery. The claimed timestamp is
 * part of the compare-and-swap predicate so a stale worker cannot settle a row
 * that has already been reclaimed by another worker.
 */
export declare function settleWebhookOutbox(database: unknown, settlement: WebhookOutboxSettlement): Promise<boolean>;
/** Reset a dead row into a fresh bounded retry window for an admin redrive. */
export declare function redriveWebhookOutbox(database: unknown, entryId: string, now?: Date): Promise<boolean>;
/**
 * Deliver a row returned by claimDueWebhookOutbox. Object payloads are
 * canonicalized once here; a caller may provide exact persisted request bytes
 * through `canonicalBody` when the storage layer has them.
 */
export declare function deliverPersistedWebhook(entry: WebhookOutboxEntry, callbackUrl: string, callbackSecret: string, options?: Omit<WebhookDeliveryOptions, 'stableDeliveryId' | 'eventSequence' | 'attemptNumber'>): Promise<WebhookDeliveryResult>;
/**
 * Retry the legacy direct-delivery path. Durable workers should prefer
 * deliverPersistedWebhook; this wrapper remains for existing queue callers and
 * uses the latest outbox identity when one exists.
 */
export declare function retryFailedWebhook(jobId: string, attemptNumber: number): Promise<WebhookDeliveryResult>;
/** Return sanitized attempt history without callback response bodies. */
export declare function getWebhookDeliveries(jobId: string): Promise<WebhookDelivery[]>;
/**
 * Check whether the latest legacy delivery is eligible for another attempt.
 * Durable outbox rows use their own status/next_attempt_at fields instead.
 */
export declare function shouldRetryWebhook(jobId: string): Promise<boolean>;
/** Return the next bounded legacy attempt number, or null after exhaustion. */
export declare function getNextRetryAttempt(jobId: string): Promise<number | null>;
//# sourceMappingURL=webhookService.d.ts.map