검색 기본 정렬과 URL 상태 반영#17
Conversation
📝 WalkthroughWalkthroughSearchExperience now reads search state from URL query parameters on mount and keeps browser history synchronized as users modify queries, sorts, filters, and pagination. Sort logic adapts based on entry point: browsing by company uses latest-first; searching by query uses relevance-first. Browser back/forward navigation restores prior search states. ChangesSearch state URL synchronization
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds URL-backed search state and improves default sort behavior for keyword searches in the web search experience.
Changes:
- Uses
relevanceas the default sort for new non-empty searches while preserving user-selected sort across related interactions. - Syncs query, sort, page, and filter state to the URL and restores state on initial load/back-forward navigation.
- Documents the new URL query behavior and verification notes.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
apps/web/app/components/SearchExperience.tsx |
Adds URL parsing/sync helpers and wires search state restoration/history handling into the main search component. |
docs/search-design.md |
Documents default sort behavior and supported URL query parameters. |
docs/development-log.md |
Records implementation scope and manual verification results. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/app/components/SearchExperience.tsx (1)
608-661:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPrevent stale search responses from overwriting newer state.
runSearchcan run concurrently (submit/filter/page/popstate). Without request ordering/cancellation, an older response may resolve later and replace the latest UI state.💡 Proposed fix (request-sequence guard)
@@ const suggestAbortRef = useRef<AbortController | null>(null); const committedQueryRef = useRef<string | null>(null); + const searchRequestSeqRef = useRef(0); @@ async function runSearch( @@ ) { + const requestSeq = ++searchRequestSeqRef.current; const trimmedQuery = nextQuery.trim(); @@ try { @@ const data = (await response.json()) as SearchResponse; + if (requestSeq !== searchRequestSeqRef.current) { + return; + } setResult(data); @@ } catch (error) { + if (requestSeq !== searchRequestSeqRef.current) { + return; + } setResult(null); setErrorMessage(error instanceof Error ? error.message : "검색 중 오류가 발생했습니다."); } finally { - setIsLoading(false); + if (requestSeq === searchRequestSeqRef.current) { + setIsLoading(false); + } } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/app/components/SearchExperience.tsx` around lines 608 - 661, runSearch can return out-of-order results which overwrite newer UI state; add a request-sequencing guard by introducing a ref like latestRequestIdRef (increment before each fetch), capture the current id at start of runSearch, and after any await (before setResult, setCompanyFacets, setErrorMessage, setIsLoading) verify the captured id === latestRequestIdRef.current; if not, discard the response. Update runSearch (and any early returns on non-ok responses or catches) to only apply state when the sequence id matches so stale responses cannot override newer state.
🧹 Nitpick comments (1)
apps/web/app/components/SearchExperience.tsx (1)
650-654: ⚡ Quick winKeep company facets fresh when filters/query change.
Line 651 currently keeps old
companyFacetswhenever any source is selected, so facet counts/recommendation flags can become stale across subsequent searches.🔧 Proposed simplification
- setCompanyFacets((currentFacets) => - nextFilters.sources.length === 0 || currentFacets.length === 0 - ? data.facets.sources - : currentFacets, - ); + setCompanyFacets(data.facets.sources);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/app/components/SearchExperience.tsx` around lines 650 - 654, The current update to company facets uses a conditional that preserves currentFacets whenever any source is selected, which lets counts/flags become stale; change the setter to always assign the latest facets from data.facets.sources when filters or query change (i.e., replace the ternary in the setCompanyFacets call so it unconditionally returns data.facets.sources rather than currentFacets), referencing setCompanyFacets, nextFilters, and data.facets.sources.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@apps/web/app/components/SearchExperience.tsx`:
- Around line 608-661: runSearch can return out-of-order results which overwrite
newer UI state; add a request-sequencing guard by introducing a ref like
latestRequestIdRef (increment before each fetch), capture the current id at
start of runSearch, and after any await (before setResult, setCompanyFacets,
setErrorMessage, setIsLoading) verify the captured id ===
latestRequestIdRef.current; if not, discard the response. Update runSearch (and
any early returns on non-ok responses or catches) to only apply state when the
sequence id matches so stale responses cannot override newer state.
---
Nitpick comments:
In `@apps/web/app/components/SearchExperience.tsx`:
- Around line 650-654: The current update to company facets uses a conditional
that preserves currentFacets whenever any source is selected, which lets
counts/flags become stale; change the setter to always assign the latest facets
from data.facets.sources when filters or query change (i.e., replace the ternary
in the setCompanyFacets call so it unconditionally returns data.facets.sources
rather than currentFacets), referencing setCompanyFacets, nextFilters, and
data.facets.sources.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 65b9cf8c-7f9c-4efc-87cd-02370ddfc39b
📒 Files selected for processing (3)
apps/web/app/components/SearchExperience.tsxdocs/development-log.mddocs/search-design.md
승인된 내용
Refs #2
검색 결과 이해성과 탐색 흐름을 개선하는 후속 작업으로, 사용자가 명시적으로 요청한 검색 기본 정렬 전환과 검색 상태 URL 반영을 적용합니다.
변경 사항
관련도순으로 사용합니다.docs/search-design.md와docs/development-log.md에 동작 방식과 검증 기록을 남겼습니다.의도적으로 제외한 것
검증
apps/web에서npm run build성공/?q=RAG&sort=relevance직접 진입 시RAG,관련도순, 결과 목록 복원/?q=RAG&sort=relevance&page=2반영RAG클릭 시/?q=RAG&sort=relevance반영사람이 확인할 방법
/?q=RAG&sort=relevance로 직접 진입해 검색어/정렬/결과가 복원되는지 확인합니다.Summary by CodeRabbit