From 13da554461157733c88bd3db9bc197b838ed628e Mon Sep 17 00:00:00 2001 From: altair823 Date: Fri, 1 May 2026 20:38:17 +0900 Subject: [PATCH] feat(trash): NoteRepository.trash with pending_jobs cleanup (#4 v0.2.3) --- src/main/repository/NoteRepository.ts | 10 +++++++++ tests/unit/NoteRepository.test.ts | 31 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/main/repository/NoteRepository.ts b/src/main/repository/NoteRepository.ts index 8541b60..d863777 100644 --- a/src/main/repository/NoteRepository.ts +++ b/src/main/repository/NoteRepository.ts @@ -221,6 +221,16 @@ export class NoteRepository { .run(date, now, id); } + trash(id: string, deletedAt: string): void { + const tx = this.db.transaction(() => { + this.db + .prepare(`UPDATE notes SET deleted_at = ?, updated_at = ? WHERE id = ?`) + .run(deletedAt, deletedAt, id); + this.db.prepare(`DELETE FROM pending_jobs WHERE note_id = ?`).run(id); + }); + tx(); + } + delete(id: string): void { this.db.prepare('DELETE FROM notes WHERE id=?').run(id); } diff --git a/tests/unit/NoteRepository.test.ts b/tests/unit/NoteRepository.test.ts index 5fde31d..2aa2579 100644 --- a/tests/unit/NoteRepository.test.ts +++ b/tests/unit/NoteRepository.test.ts @@ -215,3 +215,34 @@ describe('NoteRepository', () => { expect(n).toBeGreaterThanOrEqual(0); }); }); + +describe('NoteRepository.trash', () => { + let db: Database.Database; + let repo: NoteRepository; + + beforeEach(() => { + db = new Database(':memory:'); + runMigrations(db); + repo = new NoteRepository(db); + }); + + it('sets deleted_at and removes pending_jobs row atomically', () => { + const { id } = repo.create({ rawText: 'x' }); + expect(db.prepare('SELECT COUNT(*) AS c FROM pending_jobs WHERE note_id=?').get(id)).toMatchObject({ c: 1 }); + repo.trash(id, '2026-05-01T12:00:00.000Z'); + const note = repo.findById(id)!; + expect(note.deletedAt).toBe('2026-05-01T12:00:00.000Z'); + expect(db.prepare('SELECT COUNT(*) AS c FROM pending_jobs WHERE note_id=?').get(id)).toMatchObject({ c: 0 }); + }); + + it('updates updated_at to deletedAt timestamp', () => { + const { id } = repo.create({ rawText: 'x' }); + repo.trash(id, '2026-05-01T12:00:00.000Z'); + const note = repo.findById(id)!; + expect(note.updatedAt).toBe('2026-05-01T12:00:00.000Z'); + }); + + it('is no-op when note does not exist', () => { + expect(() => repo.trash('nonexistent', '2026-05-01T12:00:00.000Z')).not.toThrow(); + }); +});