deckhearth/migrations/1748365200000_add-scan-tables.js
Randall Stillwell b0f9a9ec71 feat(scanner): move card identification server-side (convoy #2)
Replace browser Gemini/OCR with POST /api/scan/identify, add card_submissions
review queue, remove user-writable cards INSERT, and surface disambiguation
when catalog matching is ambiguous.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 08:44:02 -05:00

52 lines
1.7 KiB
JavaScript

/**
* card_submissions + scan_attempts for server-side scan pipeline.
*
* @type {import('node-pg-migrate').ColumnDefinitions | undefined}
*/
export const shorthands = undefined;
/**
* @param {import('node-pg-migrate').MigrationBuilder} pgm
*/
export const up = (pgm) => {
pgm.sql(`
CREATE TABLE IF NOT EXISTS card_submissions (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
ocr_text TEXT,
ocr_confidence INTEGER,
scan_image_url TEXT,
candidate_card_ids JSONB DEFAULT '[]',
ocr_payload JSONB,
status VARCHAR(32) NOT NULL DEFAULT 'pending',
reviewed_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
promoted_card_id INTEGER REFERENCES cards(id) ON DELETE SET NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS scan_attempts (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
ocr_text TEXT,
ocr_confidence INTEGER,
layer INTEGER NOT NULL DEFAULT 2,
matched_card_id INTEGER REFERENCES cards(id) ON DELETE SET NULL,
result_kind VARCHAR(32) NOT NULL,
latency_ms INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_card_submissions_status
ON card_submissions (status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_scan_attempts_user_created
ON scan_attempts (user_id, created_at DESC);
`);
};
/**
* @param {import('node-pg-migrate').MigrationBuilder} pgm
*/
export const down = (pgm) => {
throw new Error('Down migration not supported for add-scan-tables');
};