/**
 * Generic webhook source manager.
 *
 * Provides CRUD operations for webhook source configurations stored in
 * the generic_webhook_sources table. Each source defines verification method,
 * event type extraction rules, rate limits, and header filtering.
 */
import { type Kysely } from 'kysely';
import type { Database, GenericWebhookSource } from '../db/types.js';
import type { VerificationMethod } from '../providers/generic/verification.js';
import { type UniversalGitConfig } from '../providers/universal-git/config.js';
/**
 * Input for creating a new generic webhook source.
 */
interface CreateSourceInput {
    orgId: string;
    name: string;
    verificationMethod?: VerificationMethod;
    verificationConfig?: Record<string, unknown>;
    eventTypeHeader?: string;
    eventTypePath?: string;
    idempotencyKeyHeader?: string;
    idempotencyKeyPath?: string;
    dedupWindowSeconds?: number;
    maxPayloadBytes?: number;
    allowedEvents?: string[];
    stripHeaders?: string[];
    rateLimitRpm?: number;
    /** Provider implementation: 'generic' (default) or 'internal' (E2E/staging
     *  github-shaped payload routing through InternalWebhookNormalizer). */
    providerType?: 'generic' | 'internal';
    /** Universal-git configuration — when set, promotes this source from a
     *  payload-only generic webhook to a full git-aware source that can register
     *  workflows, fetch lock files, and be cloned by agents. Validated against
     *  `UniversalGitConfigSchema`; stored as JSONB in `generic_webhook_sources.git_config`. */
    gitConfig?: UniversalGitConfig;
}
/**
 * Input for updating an existing generic webhook source. Use `gitConfig: null`
 * to explicitly demote a universal-git source back to a plain generic webhook
 * (omitting the field leaves the existing config untouched).
 */
type UpdateSourceInput = Partial<Omit<CreateSourceInput, 'orgId' | 'gitConfig'>> & {
    gitConfig?: UniversalGitConfig | null;
};
/**
 * Generic webhook source manager.
 *
 * Manages CRUD operations for generic_webhook_sources table.
 * Sources are identified by routing keys with format `generic:<orgId>:<sourceId>`.
 */
export declare class GenericSourceManager {
    private readonly db;
    constructor(db: Kysely<Database>);
    /**
     * Create a new generic webhook source.
     * Generates a routing key in format `generic:<orgId>:<sourceId>`.
     */
    create(input: CreateSourceInput): Promise<GenericWebhookSource>;
    /**
     * Get a source by ID (excludes soft-deleted sources).
     */
    getById(id: string): Promise<GenericWebhookSource | null>;
    /**
     * Get a source by routing key (excludes soft-deleted and disabled sources).
     */
    getByRoutingKey(routingKey: string): Promise<GenericWebhookSource | null>;
    /**
     * Get a source by org ID and name (unique lookup, excludes soft-deleted).
     */
    getByOrgAndName(orgId: string, name: string): Promise<GenericWebhookSource | null>;
    /**
     * List all sources for an org.
     */
    list(orgId: string, includeDeleted?: boolean): Promise<GenericWebhookSource[]>;
    /**
     * List all enabled, non-deleted sources matching a provider type.
     *
     * Used at orchestrator startup to register provider bundles per routing key
     * (e.g. registering an InternalWebhookNormalizer bundle for every
     * provider_type='internal' source so the staging stg-ha smoke test and
     * other internal-bundle E2E harnesses can dispatch real runs through the
     * generic endpoint without a real GitHub signature).
     */
    listByProviderType(providerType: 'generic' | 'internal'): Promise<GenericWebhookSource[]>;
    /**
     * List all enabled, non-deleted sources with a non-null `git_config`
     * (universal-git sources). Used at orchestrator startup + config reload
     * to register a universal-git `ProviderBundle` under each source's
     * routing key.
     */
    listUniversalGitSources(): Promise<GenericWebhookSource[]>;
    /**
     * Update a source's configuration.
     */
    update(id: string, input: UpdateSourceInput): Promise<GenericWebhookSource | null>;
    /**
     * Soft delete a source (sets deleted_at timestamp).
     */
    softDelete(id: string): Promise<void>;
    /**
     * Hard delete a source (removes the row entirely).
     */
    hardDelete(id: string): Promise<void>;
    /**
     * Enable a source.
     */
    enable(id: string): Promise<void>;
    /**
     * Disable a source.
     */
    disable(id: string): Promise<void>;
    /**
     * Check if a request is a duplicate within the dedup window.
     * Uses the kici_events table for idempotency checking.
     *
     * @param sourceId - Source ID
     * @param idempotencyKey - Idempotency key from header or payload
     * @returns true if this is a duplicate request
     */
    checkIdempotency(sourceId: string, idempotencyKey: string): Promise<boolean>;
    /**
     * Record an idempotency marker after successful processing.
     * Inserts a `__dedup:<key>` event into kici_events so that
     * checkIdempotency can detect retries within the dedup window.
     *
     * @param sourceId - Source ID
     * @param idempotencyKey - Idempotency key from header or payload
     */
    markIdempotency(sourceId: string, idempotencyKey: string): Promise<void>;
    /**
     * Check if payload size is within the source's limit.
     *
     * @param sourceId - Source ID
     * @param bodyLength - Length of the request body in bytes
     * @returns Whether the payload is allowed and what the max is
     */
    checkPayloadSize(sourceId: string, bodyLength: number): Promise<{
        allowed: boolean;
        maxBytes: number;
    }>;
}
/**
 * Return the active (non-soft-deleted) generic_webhook_sources routing keys
 * for Platform registration. Excluding soft-deleted rows is critical — if a
 * source is recreated with the same name, Platform would otherwise see the
 * orchestrator register both the stale routing key and the fresh one, and
 * end up routing a subset of orchestrators to the wrong key. This matches
 * every other query on this table that filters `deleted_at IS NULL` (see
 * `GenericSourceManager.getById`, `.list`, `.listByProviderType`, etc.).
 *
 * Returns `provider_type` alongside the routing key so callers can decide
 * whether the local orchestrator can actually serve each row. A peer that
 * cannot serve a provider_type (e.g. an `internal` source on a peer with no
 * `KICI_INTERNAL_PROVIDER_REPO_PATH`) MUST NOT advertise that routing key
 * to Platform — otherwise Platform's least-loaded relay may pick that peer
 * and the webhook is silently dropped on a pipeline that has no working
 * lock-file fetcher.
 */
export declare function loadActiveGenericRoutingKeys(db: Kysely<Database>): Promise<Array<{
    routing_key: string;
    customer_id: string;
    provider_type: string;
    name: string;
    /** Whether the row has a non-null `git_config` (universal-git source). */
    has_git_config: boolean;
}>>;
export {};
//# sourceMappingURL=generic-sources.d.ts.map