- notes 테이블 ADD COLUMN status (DEFAULT 'active'), status_changed_at, move_reason - deleted_at != NULL 노트 → status='trashed' + status_changed_at=deleted_at 로 backfill - index.ts registry 에 m004 추가 (runMigrations 자동 적용) - migrations.test.ts user_version assertion 4 로 갱신
81 lines
3.0 KiB
TypeScript
81 lines
3.0 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import Database from 'better-sqlite3';
|
|
import { up } from '../../src/main/db/migrations/m004_status.js';
|
|
|
|
describe('m004 migration — status column', () => {
|
|
let db: Database.Database;
|
|
|
|
beforeEach(() => {
|
|
db = new Database(':memory:');
|
|
// m003 baseline (notes 테이블 with deleted_at, real schema 따름)
|
|
db.exec(`
|
|
CREATE TABLE notes (
|
|
id TEXT PRIMARY KEY,
|
|
raw_text TEXT NOT NULL,
|
|
ai_title TEXT,
|
|
ai_summary TEXT,
|
|
ai_status TEXT NOT NULL
|
|
CHECK (ai_status IN ('pending','done','failed')),
|
|
ai_error TEXT,
|
|
ai_provider TEXT,
|
|
ai_generated_at TEXT,
|
|
title_edited_by_user INTEGER NOT NULL DEFAULT 0,
|
|
summary_edited_by_user INTEGER NOT NULL DEFAULT 0,
|
|
user_intent TEXT,
|
|
intent_prompted_at TEXT,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
due_date TEXT,
|
|
due_date_edited_by_user INTEGER NOT NULL DEFAULT 0,
|
|
deleted_at TEXT,
|
|
last_recalled_at TEXT,
|
|
recall_dismissed_at TEXT
|
|
);
|
|
INSERT INTO notes (id, raw_text, ai_status, created_at, updated_at, deleted_at)
|
|
VALUES ('a', 't1', 'done', '2026-05-01T00:00:00Z', '2026-05-01T00:00:00Z', NULL),
|
|
('b', 't2', 'done', '2026-05-01T00:00:00Z', '2026-05-01T00:00:00Z', '2026-05-08T00:00:00Z');
|
|
`);
|
|
});
|
|
|
|
afterEach(() => {
|
|
db.close();
|
|
});
|
|
|
|
it('adds status / status_changed_at / move_reason columns', () => {
|
|
up(db);
|
|
const cols = db.prepare(`PRAGMA table_info(notes)`).all() as Array<{ name: string }>;
|
|
const names = cols.map((c) => c.name);
|
|
expect(names).toContain('status');
|
|
expect(names).toContain('status_changed_at');
|
|
expect(names).toContain('move_reason');
|
|
});
|
|
|
|
it('default status="active" for non-deleted notes', () => {
|
|
up(db);
|
|
const a = db.prepare(`SELECT status FROM notes WHERE id=?`).get('a') as { status: string };
|
|
expect(a.status).toBe('active');
|
|
});
|
|
|
|
it('migrates deleted_at != NULL to status="trashed" + status_changed_at', () => {
|
|
up(db);
|
|
const b = db
|
|
.prepare(`SELECT status, status_changed_at FROM notes WHERE id=?`)
|
|
.get('b') as { status: string; status_changed_at: string };
|
|
expect(b.status).toBe('trashed');
|
|
expect(b.status_changed_at).toBe('2026-05-08T00:00:00Z');
|
|
});
|
|
|
|
it('move_reason NULL by default', () => {
|
|
up(db);
|
|
const a = db.prepare(`SELECT move_reason FROM notes WHERE id=?`).get('a') as {
|
|
move_reason: string | null;
|
|
};
|
|
expect(a.move_reason).toBeNull();
|
|
});
|
|
|
|
it('version exported as 4', async () => {
|
|
const mod = await import('../../src/main/db/migrations/m004_status.js');
|
|
expect(mod.version).toBe(4);
|
|
});
|
|
});
|