/** * Store for the data-programs primitive: CRUD on the `dataPrograms` ownable * resource (via Drizzle) plus a raw-DDL run-result cache * (`data_program_runs`) mirroring `../provider-api/staged-datasets-store.ts`. * * Follows the boot-DDL pattern from `../extensions/store.ts`: a memoized * init promise, Postgres probe-then-guarded-DDL via `ensureTableExists` / * `ensureIndexExists`, and a plain create-then-catch on SQLite. */ import { type AccessContext } from "../sharing/access.js"; export declare const MAX_PROGRAM_ROWS = 10000; export declare const MAX_PROGRAM_RESULT_BYTES: number; export declare const MAX_ACTIVE_PROGRAMS_PER_APP = 200; export declare const MIN_REFRESH_TTL_MS = 60000; export declare function ensureDataProgramTables(): Promise; export declare function registerDataProgramsShareable(): void; /** Test-only: reset the memoized init promise. */ export declare function _resetDataProgramInitPromiseForTests(): void; export type DataProgramRefreshMode = "manual" | "ttl"; export interface DataProgramRow { id: string; appId: string; name: string; title: string; description: string; code: string; paramsSchema: string | null; defaultParams: string | null; outputColumns: string | null; refreshMode: DataProgramRefreshMode; refreshTtlMs: number; background: boolean; createdAt: string; updatedAt: string; archivedAt: string | null; ownerEmail: string; orgId: string | null; visibility: "private" | "org" | "public"; } export interface UpsertDataProgramInput { id?: string; appId: string; name: string; title: string; description?: string; code: string; paramsSchema?: string | null; defaultParams?: string | null; outputColumns?: string | null; refreshMode?: DataProgramRefreshMode; refreshTtlMs?: number; background?: boolean; ownerEmail: string; orgId?: string | null; } /** * Create or update a data program. When `id` is omitted, checks for an * existing program with the same (appId, ownerEmail, name) slug and updates * it in place (upsert-by-slug); otherwise creates a new row. Enforces * MAX_ACTIVE_PROGRAMS_PER_APP on create. */ export declare function upsertDataProgram(input: UpsertDataProgramInput): Promise; /** * Look up a program by id. Pass `appId` to scope the lookup to the calling * app — in a shared-database multi-app deployment, a program created in one * app must not be readable/runnable from another app's agent chat just * because the caller otherwise has row-level (owner/org/share) access to it. * `appId` is optional only because a handful of internal call sites * (`upsertDataProgram`'s existing-row lookup, tests) look up a program they * already know is scoped correctly by construction. */ export declare function getDataProgram(id: string, appId?: string): Promise; export declare function getDataProgramByName(appId: string, name: string, ownerEmail: string): Promise; export interface ListDataProgramsOptions { includeArchived?: boolean; } /** List programs scoped to `appId`, filtered through the sharing access rules. */ export declare function listDataPrograms(appId: string, ctx: AccessContext, options?: ListDataProgramsOptions): Promise; /** Soft-archive: sets `archivedAt`. NEVER hard-deletes — panels/history may still reference the id. */ export declare function archiveDataProgram(id: string, appId?: string): Promise; export type DataProgramRunStatus = "queued" | "running" | "succeeded" | "failed" | "timed_out"; export interface DataProgramRunRow { id: string; programId: string; paramsHash: string; paramsJson: string; status: DataProgramRunStatus; rowsJson: string | null; schemaJson: string | null; truncated: boolean; rowCount: number; byteSize: number; errorCode: string | null; errorMessage: string | null; logsTail: string | null; executionId: string | null; triggeredBy: string; startedAt: number; finishedAt: number | null; durationMs: number | null; } export interface RecordDataProgramRunInput { programId: string; paramsHash: string; paramsJson: string; status: DataProgramRunStatus; rowsJson?: string | null; schemaJson?: string | null; truncated?: boolean; rowCount?: number; byteSize?: number; errorCode?: string | null; errorMessage?: string | null; logsTail?: string | null; executionId?: string | null; triggeredBy: string; startedAt?: number; finishedAt?: number | null; durationMs?: number | null; /** How many run rows to keep per (programId, paramsHash) after this write. */ keep?: number; } /** Insert a new run row (typically `status: "running"` or `"queued"` first, finalized via `updateDataProgramRun`). */ export declare function recordDataProgramRun(input: RecordDataProgramRunInput): Promise; export interface UpdateDataProgramRunInput { status?: DataProgramRunStatus; rowsJson?: string | null; schemaJson?: string | null; truncated?: boolean; rowCount?: number; byteSize?: number; errorCode?: string | null; errorMessage?: string | null; logsTail?: string | null; executionId?: string | null; finishedAt?: number | null; durationMs?: number | null; /** How many run rows to keep per (programId, paramsHash) after this write. */ keep?: number; } /** Finalize an existing run row (e.g. a background execution completing). */ export declare function updateDataProgramRun(runId: string, updates: UpdateDataProgramRunInput): Promise; export declare function getLatestSuccessfulRun(programId: string, paramsHash: string): Promise; export declare function getLatestRun(programId: string, paramsHash: string): Promise; /** * Return the latest queued/running run row for (programId, paramsHash), if * any, so callers can dedupe concurrent executions instead of racing. */ export declare function getActiveRun(programId: string, paramsHash: string): Promise; /** * Delete all but the `keep` most-recent run rows for (programId, paramsHash). * Called on every write (prune-on-write, no sweep job). Fetches all ids * ordered newest-first and slices in TypeScript rather than `LIMIT ... OFFSET` * so the query stays byte-identical across SQLite and Postgres (SQLite's * `LIMIT -1 OFFSET n` idiom has no direct Postgres equivalent). */ export declare function pruneDataProgramRuns(programId: string, paramsHash: string, keep?: number): Promise; //# sourceMappingURL=store.d.ts.map