/** * `createPostgresAuditStore` — implements the SDK's `AuditStore` contract * against the existing `intent_audit` table. * * Reuses `rowToRecord` from `replay.ts` (single source of truth for the * row→AuditRecord conversion) and translates the SDK's filter shape into * parameterized SQL. * * **Pagination is keyset, not offset.** The SDK's `cursor: string` is * opaque — we encode `(recorded_at, intent_hash)` of the last seen row * as base64url(JSON). Subsequent pages add a strict-less-than predicate * against that tuple. Result: O(log N) page latency at any depth — page * 100,000 of a 10M-row table runs in the same time as page 2. Offset * pagination would scan linearly. * * **Tiebreaker direction matches the primary sort.** ORDER BY * `recorded_at DESC, intent_hash DESC` and the cursor predicate uses * tuple < — both DESC. Mismatching directions causes row skipping * during millisecond-burst inserts (webhook fan-out is the canonical * trigger). */ import { type AuditRecord, type AuditRecordVerification } from "@adjudicate/core"; import type { AuditQuery, AuditStore } from "@adjudicate/admin-sdk"; import type { PostgresReader } from "./pg-reader.js"; /** * Thrown when a non-empty `cursor` fails to decode (malformed / truncated / * tampered). Silently restarting from page 1 — the previous behavior — hands * the caller a `nextCursor` for the SAME first page, an infinite loop for any * client that retries. The tRPC layer should map this to a `BAD_REQUEST`. */ export declare class InvalidCursorError extends Error { constructor(message?: string); } interface CursorPayload { readonly at: string; readonly hash: string; } export declare function encodeCursor(p: CursorPayload): string; export declare function decodeCursor(s: string): CursorPayload | null; interface SqlFragment { readonly clauses: readonly string[]; readonly params: readonly unknown[]; } /** * Builds the WHERE clause set from the SDK's filter shape. Parameter * indices are monotonic ($1, $2, ...). Each provided filter contributes * one clause; absent filters contribute none. AND-composed. */ export declare function buildWhereClauses(q: AuditQuery): SqlFragment; export interface CreatePostgresAuditStoreDeps { readonly reader: PostgresReader; } export declare function createPostgresAuditStore(deps: CreatePostgresAuditStoreDeps): AuditStore; /** * Read back the verify-on-read verdict attached by `createPostgresAuditStore`'s * `getByIntentHash` (092). Returns `undefined` for a record from a store that * does not verify on read (the in-memory reference) or one that crossed a wire * boundary (the Symbol slot is non-serializable). Re-verifying directly via * `verifyAuditRecord(record)` is always available as the canonical fallback. */ export declare function readVerificationSlot(record: AuditRecord): AuditRecordVerification | undefined; export {}; //# sourceMappingURL=audit-store.d.ts.map