import type { SqliteDatabase } from '../sqlite/sqlite-driver.js'; import { type CrystallizationEvent, type CrystallizationEventInput, type CrystallizationEventStatus } from './crystallization-types.js'; /** * Low-level SQLite access for the `crystallization_event` table. * The migration is registered with the existing `openStateDb()` * pipeline via * `src/services/skillhub/migrations/006-crystallization-event.sql` * and is applied in lexicographic order alongside the other * skillhub migrations. The function `ensureCrystallizationEventTable` * below is a belt-and-suspenders re-applier for callers that pass a * database they built themselves (e.g. tests). * * Defense in depth: * - All JSON columns are stored as TEXT and parsed at the * boundary. No big JSON BLOB at the SQLite layer — the row * stays small and queryable. * - The migration is idempotent (CREATE TABLE IF NOT EXISTS, * CREATE INDEX IF NOT EXISTS) so re-running it is safe. * - The 4-section brief guard and any other business rule is * enforced at the SERVICE layer (not the DB); the DB stores * the persisted, validated row. */ declare const SCHEMA_VERSION: "peaks.crystallization/1"; /** * Re-apply the crystallization_event table migration against an * already-open database. Used by tests that build their own DB * without the openStateDb pipeline. Idempotent. */ export declare function ensureCrystallizationEventTable(db: SqliteDatabase): void; /** * Insert a CrystallizationEvent row. The row's `schema_version` is * taken from the input (must equal `peaks.crystallization/1`); * `id` and `created_at` are stamped here so callers cannot backdate * a row. * * The Zod schema (parse boundary) re-asserts the 4-section brief * guard: a missing-section event is rejected before the SQL INSERT. * * Returns the persisted row. */ export declare function insertCrystallizationEvent(db: SqliteDatabase, row: CrystallizationEventInput): CrystallizationEvent; /** Read a single CrystallizationEvent row by id; returns undefined if absent. */ export declare function getCrystallizationEvent(db: SqliteDatabase, id: string): CrystallizationEvent | undefined; /** * List CrystallizationEvent rows. Filter by `lifecycle_status` and/or * any of the optional FK pointers. When ALL filters are omitted, lists * every event (newest-first by `created_at`). */ export declare function listCrystallizationEvents(db: SqliteDatabase, opts?: { lifecycle_status?: CrystallizationEventStatus; created_loop_release_id?: string; updated_loop_release_id?: string; created_bee_release_id?: number; updated_bee_release_id?: number; }): CrystallizationEvent[]; /** * Update the lifecycle_status of an existing CrystallizationEvent row. * Returns the updated row, or undefined if absent. * * Lifecycle transitions are NOT validated here; the service layer * decides whether `stable` requires a user_confirmation_pointer or * other evidence (mirroring the evolution-store design). */ export declare function updateCrystallizationEventStatus(db: SqliteDatabase, id: string, next: CrystallizationEventStatus): CrystallizationEvent | undefined; /** * Test seam: produce a fresh id for a CrystallizationEvent row. * Format: `crys-` (12 hex chars). Matches the Zod * `^crys-[0-9a-f]{8,}$` pattern in CrystallizationEventSchema. */ export declare function newCrystallizationId(): string; /** * Test seam: re-export the schema version so the service layer has a * single source of truth. */ export { SCHEMA_VERSION as CRYSTALLIZATION_SCHEMA_VERSION };