feat(trash): NoteRepository.trash with pending_jobs cleanup (#4 v0.2.3)

This commit is contained in:
altair823
2026-05-01 20:38:17 +09:00
parent 3797e6c4f3
commit 13da554461
2 changed files with 41 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -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();
});
});