• altair823 released this 2026-05-09 15:53:17 +00:00 | 113 commits to main since this release

    v0.2.11 — Cut D (FTS5 search + 회고 view)

    recall 핵심 가치 도달 cut. F19 의 6 옵션 중 A (FTS5 search) + D (일/주/월 회고 view) 적용. B/C/E/F 는 v0.3+ deferred.

    주요 변경

    • F19-A FTS5 search: SQLite FTS5 가상 테이블 notes_fts (note_id UNINDEXED + raw_text + ai_title + ai_summary + tags + tokenize='unicode61'). m007 마이그레이션 + AFTER INSERT/UPDATE/DELETE 트리거 3개 (notes 컬럼 자동 sync). 기존 status != 'trashed' 노트 backfill (note_tags JOIN GROUP_CONCAT). 헤더 SearchBox (200ms debounce) + clearSearch on empty + inbox view 결과 렌더 분기. 빈 query → 기본 list. multi-token = implicit AND. FTS5 special char ("*():) sanitize.
    • F19-D 일/주/월 회고 view: useInbox.view'review-daily' | 'review-weekly' | 'review-monthly' 추가. reviewAggregate(period, now) (totalCount + recentNotes(50) + tagCounts(DESC) + dueProgress(passed/pending KST today 기준)). computeCutoff 가 KST 자정 ISO 반환. ReviewView 컴포넌트 (period 라벨 + tag bar + due progress + 최근 NoteCard) + 헤더 <select> dropdown 진입.
    • NoteRepository.search(query, opts): sanitizeFtsQuery + notes_fts MATCH + ORDER BY rank + LIMIT cap (1..200). default status != 'trashed', opts.status 명시 시 해당 status 만.
    • single write path 강제 (Cut C 도입 + Cut D 보강): notes_fts.tags 컬럼은 트리거 자동 sync 안 함 — rebuildFtsTagsForNote(noteId) private 헬퍼가 single write path. note_tags INSERT/DELETE 하는 모든 path (updateAiResult / updateUserAiFields / importNote) 가 transaction 끝에서 헬퍼 호출. final review 단계에서 importNote 누락 발견 → 패치 (735d549).
    • AI 정책 무변: AiWorker findById(id).rawText source 코드 무수정. raw_text 가변 (Cut C) 의 trigger AFTER UPDATE 가 자동 sync.

    테스트 / 빌드

    • 단위: 569 → 608 pass (+39):
      • m007 마이그레이션 6
      • rebuildFtsTagsForNote (updateAiResult / updateUserAiFields) 2
      • ftsHelpers (sanitize + computeCutoff) 7
      • search 6
      • reviewAggregate 5
      • IPC handlers 3
      • store 3
      • SearchBox 2
      • ReviewView 3
      • importNote tags sync (final review fix) 2
    • typecheck: 0 errors
    • e2e: 세션 내 미수행 (worktree node_modules 비어 있어 prebuild path 실패; UI 변경 = 헤더 SearchBox + 회고 dropdown + ReviewView 만, capture/onboarding/banner 무관 — main 머지 후 검증)
    • 산출물: Inkling-Setup-0.2.11.exe (Windows NSIS x64, signed)
    • (macOS dmg / Linux AppImage + deb 차후 추가)

    Schema 마이그레이션

    • m007: notes_fts FTS5 가상 테이블 + 트리거 3개 (raw_text/ai_title/ai_summary 자동 sync) + 기존 status != 'trashed' 노트 backfill (note_tags JOIN GROUP_CONCAT). transaction 안 단일 exec (runMigrations wrap). 외래키 안전 (FTS5 가상 테이블은 FK 없음, trigger 의 OLD/NEW 만 사용)

    메모리 정책 갱신 (Cut D 머지 후 적용)

    • search source = notes.raw_text / ai_title / ai_summary / tags csv (FTS5 인덱스 latest only — Cut C revision X). raw_text 가변 정책과 일관
    • single write path 강제 (Cut D 보강): tags 변경 path = updateAiResult / updateUserAiFields / importNote 3곳, 모두 rebuildFtsTagsForNote 호출 보장 — invariant 검증 완료
    • 회고 cutoff = KST 자정 ISO (computeCutoff). dueProgress 비교 = KST today (kstTodayIso)
    • trashed 노트 FTS row 잔존 + query-level 필터 (별도 cleanup 안 함 — YAGNI)
    • regression 회귀 검사 패턴 (Cut D 확립): spec 단계에서 invariant 강제 항목 listing → implementation 단계 모든 entry point 점검 → final review 단계 spec invariant 항목 별 검증. importNote 같은 secondary path 누락 회귀 방지 (Cut C 의 capture revision 누락, Cut D 의 tags sync 누락 — 동일 패턴)

    다음 (Cut E)

    v0.3.0 Cut E: F21 양방향 sync + Configure UI + conflict. dogfood 1주 soak 후 진입.

    Downloads