/**
 * FeedbackStore.ts — the data-access seam for the feedback factory.
 *
 * The ported processor logic (fingerprint / similarity / cluster / verify /
 * reopen) is pure; the *stateful* operations (read unprocessed items, read active
 * clusters, create/merge/reopen clusters, mark processed, count) live behind this
 * interface so the canonical instance's real adapter (Prisma cloud DB — the
 * blocked, credentials-gated piece) is a thin shim, while everything is buildable
 * and testable today against `InMemoryFeedbackStore`.
 *
 * This is the dependency-injection boundary called out in the migration spec:
 * front → Vercel, processor → Instar job, DB → cloud (Prisma). The interface
 * shape is driven by what the ported drivers + the composition (process.ts) need.
 */
import type { FeedbackItem, Cluster, ClusterResult } from '../processor/types.js';
import type { ReopenDecision } from '../processor/reopen.js';
import type { DispatchRecord } from '../dispatch/dispatch.js';
/** Read-only observability counters for the capture→cluster→reopen loop (spec §2.7). */
export interface FeedbackMetrics {
    captured: number;
    created: number;
    merged: number;
    reopened: number;
}
export interface FeedbackStore {
    /** Unprocessed feedback, oldest first (mirrors the reference's `status:'unprocessed'` query). */
    getUnprocessedFeedback(): FeedbackItem[];
    /** Active clusters (status != 'resolved'), the merge candidates. */
    getActiveClusters(): Cluster[];
    getCluster(clusterId: string): Cluster | undefined;
    /** Create a new cluster from an item (or bump reportCount if it already exists). */
    upsertClusterFromItem(clusterId: string, item: FeedbackItem): void;
    /** Merge an item into an existing cluster (bump reportCount). */
    mergeIntoCluster(clusterId: string, item: FeedbackItem): void;
    /** Apply an auto-reopen decision (status, recurrence bump, audit-note append). */
    applyReopen(clusterId: string, decision: ReopenDecision): void;
    /** Mark a feedback item processed + linked to its cluster. */
    markProcessed(feedbackId: string, clusterId: string): void;
    /** True if a feedback item with this feedbackId already exists (the dedup check). */
    hasFeedback(feedbackId: string): boolean;
    /** Persist a newly-received feedback item (the receiver write). */
    addFeedback(item: FeedbackItem): void;
    /** Active dispatches matching an optional since/type filter, oldest-first (the dispatch list read). */
    listDispatches(filter?: {
        since?: string;
        type?: string;
    }): DispatchRecord[];
    /** Find an existing dispatch by exact (normalized) title — the create-dedup check. */
    findDispatchByTitle(title: string): DispatchRecord | undefined;
    /** Persist a new dispatch. */
    createDispatch(record: DispatchRecord): void;
    metrics(): FeedbackMetrics;
}
/**
 * In-memory FeedbackStore — the test/reference implementation. Faithfully mirrors
 * the reference's create/merge/reopen field mutations (reportCount increment,
 * recurrenceCount bump on regression, status change, note append) so the
 * composition can be integration-tested without a database.
 */
export declare class InMemoryFeedbackStore implements FeedbackStore {
    private feedback;
    private clusters;
    private counts;
    constructor(seed?: {
        feedback?: FeedbackItem[];
        clusters?: Cluster[];
    });
    getUnprocessedFeedback(): FeedbackItem[];
    getActiveClusters(): Cluster[];
    getCluster(clusterId: string): Cluster | undefined;
    upsertClusterFromItem(clusterId: string, item: FeedbackItem): void;
    mergeIntoCluster(clusterId: string, _item: FeedbackItem): void;
    applyReopen(clusterId: string, decision: ReopenDecision): void;
    markProcessed(feedbackId: string, clusterId: string): void;
    hasFeedback(feedbackId: string): boolean;
    addFeedback(item: FeedbackItem): void;
    private dispatches;
    listDispatches(filter?: {
        since?: string;
        type?: string;
    }): DispatchRecord[];
    findDispatchByTitle(title: string): DispatchRecord | undefined;
    createDispatch(record: DispatchRecord): void;
    metrics(): FeedbackMetrics;
    /** Test helper: snapshot all clusters. */
    allClusters(): Cluster[];
}
export type { ClusterResult };
//# sourceMappingURL=FeedbackStore.d.ts.map