fix(docs): PR #301 Gemini review medium 3건 (bracket escape + empty dir + stale meta)#302
Conversation
status/날짜 필터로 자식이 전부 걸러진 디렉터리를 null 반환해 숨긴다. 원래부터 비어 있던 dir 은 그대로 유지 (필터로 빈 것만 숨김). 회귀 테스트 3건 추가. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…badges (gemini PR #301, T3) 이전엔 plan 메타가 projectKey 변경 시 1회만 로드 → plan status 변경·새 plan 생성이 사이드바 배지·필터에 미반영 (stale). window focus / visibilitychange 복귀 시 refreshTick 증가 → docs 스캔 + plan 메타 동시 재로드. 타이머 polling 없이 사용자가 창으로 돌아오는 자연스러운 시점에만 재fetch (과도한 re-fetch 회피). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces markdown escaping for brackets in plan titles, implements a window focus and visibility change listener to refresh stale sidebar plan metadata, and refines directory filtering to hide directories that become empty after filtering while keeping originally empty ones. Feedback on these changes suggests adding a throttling mechanism to the window focus and visibility event handlers to prevent duplicate triggers and redundant backend requests.
| useEffect(() => { | ||
| const bump = () => setRefreshTick((n) => n + 1); | ||
| const onVisibility = () => { | ||
| if (document.visibilityState === "visible") bump(); | ||
| }; | ||
| window.addEventListener("focus", bump); | ||
| document.addEventListener("visibilitychange", onVisibility); | ||
| return () => { | ||
| window.removeEventListener("focus", bump); | ||
| document.removeEventListener("visibilitychange", onVisibility); | ||
| }; | ||
| }, []); |
There was a problem hiding this comment.
Window focus 이벤트와 visibilitychange 이벤트는 사용자가 탭을 전환하거나 다른 창에서 돌아올 때 거의 동시에 발생할 수 있습니다. 이로 인해 bump 함수가 짧은 시간 내에 두 번 호출되어 refreshTick이 2번 증가하게 되고, 결과적으로 scanDocs 및 loadPlanMeta와 같은 비동기 백엔드 요청이 중복으로 발생하여 불필요한 IPC 오버헤드와 리렌더링을 유발합니다.
이를 방지하기 위해 마지막으로 업데이트된 시간을 기록하는 간단한 스로틀링(Throttling) 로직을 추가하여, 1초 이내의 중복 호출을 방지하는 것을 권장합니다.
useEffect(() => {
let lastBumpTime = 0;
const bump = () => {
const now = Date.now();
if (now - lastBumpTime > 1000) {
lastBumpTime = now;
setRefreshTick((n) => n + 1);
}
};
const onVisibility = () => {
if (document.visibilityState === "visible") bump();
};
window.addEventListener("focus", bump);
document.addEventListener("visibilitychange", onVisibility);
return () => {
window.removeEventListener("focus", bump);
document.removeEventListener("visibilitychange", onVisibility);
};
}, []);
매니페스트 4 곳 + Cargo.lock bump. CHANGELOG entry 추가. 핵심 (PR #301 + #302): - docs/plans 가상 필터 (status/날짜) + 상태 배지 (DB plan join, 경로 불변) - regenerate_plans_index command (마커 기반 부분 갱신) - stale 배지 / index 링크 escape / 빈 dir / shallow copy fix 다모앙 커뮤니티 사용자 요청. Phase 2 (archive 물리 이동) 는 검증 후 별도. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#302) (#303) 탭 복귀 시 window focus + visibilitychange 가 거의 동시 발생해 bump (refreshTick 증가) 가 2회 호출되어 scanDocs/loadPlanMeta IPC 가 중복 실행되던 문제 수정. effect closure 변수 lastBumpTime 으로 마지막 bump 시각을 기록해 1초 이내 중복 호출을 무시한다. empty deps 이므로 변수는 effect lifetime 동안 1회만 생성되고 re-render 시 reset 되지 않는다. focus/visibilitychange 재로드 동작과 cleanup 은 그대로 보존. Co-authored-by: dghong <d9ng@outlook.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #301 (
feat(docs): docs/plans 가상 필터 + index 자동 생성 + #300 shallow copy (Phase 1)) 의 Gemini 코드 리뷰 medium 3건 후속 fix. 단일 PR / 3 commit.변경 (task 별)
src-tauri/src/commands/plans.rs— index.md 자동 생성 시 plan title 의[/]가 markdown link[title](path)를 깨뜨리는 문제. 기존|escape 에[/]추가 (+6/-1). 회귀 테스트 1건.src/components/tunaflow/sidebar/planDocsFilter.ts— status/날짜 필터로 자식이 전부 걸러진 dir 을 숨김(null). 원래부터 빈 dir 은 유지. 회귀 테스트 3건 (docsPlansFilter.test.ts).src/components/tunaflow/sidebar/DocsSection.tsx— plan 메타가 projectKey 변경 시 1회만 로드되어 plan status 변경·새 plan 이 사이드바 배지·필터에 미반영(stale)되던 문제. windowfocus/visibilitychange→visible복귀 시refreshTick증가 → docs 스캔 + plan 메타 동시 재로드. 타이머 polling 없이 사용자가 창으로 돌아오는 자연스러운 시점에만 재fetch (과도한 re-fetch 회피).Verification (PASS)
cargo check --message-format=short— Finished (OK)cargo test --lib— 662 passed (baseline 661 + T1 1건)tsc --noEmit— exit 0vitest run— 516 passed (baseline 513 + T2 3건)회귀 가드 (위반 0)
git diff src-tauri -- ':!.../plans.rs'→ (none)git diff src -- ':!.../sidebar/' ':!.../docsPlansFilter.test.ts'→ (none)rg "replace\('\['" plans.rs→ 존재 (T1 bracket escape 확인)🤖 Generated with Claude Code