/** * pgvector + cards.embedding for Layer-0 visual catalog search. * * Neon prod: CREATE EXTENSION vector succeeds for the project owner. * Homelab CI (`deckhearth_ci`, non-superuser): extension create may fail; * we skip embedding DDL so migrate still passes — L0 escalates until * an operator enables pgvector on CT 102 or runs backfill on Neon. * * @type {import('node-pg-migrate').ColumnDefinitions | undefined} */ export const shorthands = undefined; /** Must match lib/card-embed.js EMBED_DIMENSION. */ const EMBED_DIMENSION = 1024; /** * @param {import('node-pg-migrate').MigrationBuilder} pgm */ export const up = (pgm) => { pgm.sql(` DO $do$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'vector') THEN CREATE EXTENSION vector; END IF; EXCEPTION WHEN insufficient_privilege OR OTHERS THEN RAISE NOTICE 'vector extension unavailable on this database (%). Skipping embedding DDL.', SQLERRM; RETURN; END $do$; DO $do$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'vector') THEN RAISE NOTICE 'vector extension not installed — skipping cards.embedding columns'; RETURN; END IF; ALTER TABLE cards ADD COLUMN IF NOT EXISTS embedding vector(${EMBED_DIMENSION}), ADD COLUMN IF NOT EXISTS embedded_at TIMESTAMP; CREATE INDEX IF NOT EXISTS idx_cards_embedding_hnsw ON cards USING hnsw (embedding vector_cosine_ops) WHERE embedding IS NOT NULL; END $do$; `); }; /** * @param {import('node-pg-migrate').MigrationBuilder} pgm */ export const down = (pgm) => { throw new Error('Down migration not supported for add-card-embeddings'); };