fix(trash): add repo.countTrashed() — fix UI 200-cap mismatch (review 회차 1)
PR #14 회차 1 review actionable — `inbox:trashCount` 와 `emptyTrash` dialog 가 `listTrashed({limit:200})` 로 카운트를 도출하면서 (a) hot path 에서 N rows + tags/media JOIN hydrate 비효율 (b) trash > 200 시 dialog message 가 실제 SQL DELETE 동작과 mismatch ('200개 영구 삭제합니다' 표시 vs 500개 실제 삭제) 발생. NoteRepository.countTrashed() — `SELECT COUNT(*) FROM notes WHERE deleted_at IS NOT NULL` 단일 쿼리. hydrate 없이 정확한 카운트만 반환. 두 IPC 핸들러를 이 메서드 호출로 교체. 테스트: 3 신규 단위 테스트 (0 trash / 부분 trash / 200 cap 초과 범위) 292 → 295 (+3). typecheck 0 errors. deferrable (v0.2.4 backlog 그대로): AiWorker race guard 강화, restore self-guard, limit 200 매직 넘버 상수화. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -269,6 +269,18 @@ export class NoteRepository {
|
||||
return rows.map((r) => this.hydrate(r));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cheap COUNT for trash UI badge / bulk-empty dialog. Does not hydrate
|
||||
* tags/media — used in hot paths (loadInitial / refreshMeta / upsertNote
|
||||
* follow-ups) where listTrashed() is wasteful.
|
||||
*/
|
||||
countTrashed(): number {
|
||||
const row = this.db
|
||||
.prepare(`SELECT COUNT(*) AS c FROM notes WHERE deleted_at IS NOT NULL`)
|
||||
.get() as { c: number };
|
||||
return row.c;
|
||||
}
|
||||
|
||||
/** @deprecated v0.2.3 #4 부터 hard delete 는 permanentDelete() 사용. soft delete 는 trash(). 본 메서드는 v0.2.4 에서 제거 예정. */
|
||||
delete(id: string): void {
|
||||
this.db.prepare('DELETE FROM notes WHERE id=?').run(id);
|
||||
|
||||
Reference in New Issue
Block a user