47 lines
2.8 KiB
Markdown
47 lines
2.8 KiB
Markdown
# Goal: Fix Source List Auto-Refresh After Adding New Source
|
|
|
|
## Issue Reference
|
|
GitHub Issue: #526
|
|
|
|
## Problem
|
|
When a user adds a new source to a notebook (via URL, file upload, or text), the source list in the notebook page does not auto-refresh. The user sees a toast notification saying "Source Queued" but must manually refresh the browser to see the new source appear in the list.
|
|
|
|
## Root Cause
|
|
The notebook page uses `useNotebookSources()` which queries with key `QUERY_KEYS.sourcesInfinite(notebookId)` = `['sources', 'infinite', notebookId]`.
|
|
|
|
However, the mutation hooks that create sources only invalidate different query keys:
|
|
- `useCreateSource` invalidates `QUERY_KEYS.sources(notebookId)` = `['sources', notebookId]`
|
|
- `useFileUpload` invalidates `QUERY_KEYS.sources(variables.notebookId)` = `['sources', notebookId]`
|
|
|
|
React Query's prefix matching does NOT cascade from `['sources', notebookId]` to `['sources', 'infinite', notebookId]` because the second element differs (`notebookId` vs `'infinite'`).
|
|
|
|
Note: Other hooks like `useDeleteSource`, `useUpdateSource`, etc. correctly use `queryClient.invalidateQueries({ queryKey: ['sources'] })` which IS a prefix of all source queries and does cascade properly.
|
|
|
|
## Fix
|
|
Add `sourcesInfinite` query key invalidation in both `useCreateSource` and `useFileUpload` hooks in `frontend/src/lib/hooks/use-sources.ts`.
|
|
|
|
### Key Files
|
|
- `frontend/src/lib/hooks/use-sources.ts` - Contains all source mutation hooks (main fix location)
|
|
- `frontend/src/lib/api/query-client.ts` - Defines `QUERY_KEYS` including `sourcesInfinite`
|
|
- `frontend/src/app/(dashboard)/notebooks/[id]/page.tsx` - Notebook page that uses `useNotebookSources`
|
|
- `frontend/src/app/(dashboard)/notebooks/components/SourcesColumn.tsx` - Source list UI component
|
|
|
|
### Implementation Details
|
|
|
|
**In `useCreateSource` (line ~89-139)**:
|
|
After each `QUERY_KEYS.sources(notebookId)` invalidation, also invalidate `QUERY_KEYS.sourcesInfinite(notebookId)`.
|
|
|
|
**In `useFileUpload` (line ~195-220)**:
|
|
After `QUERY_KEYS.sources(variables.notebookId)` invalidation, also invalidate `QUERY_KEYS.sourcesInfinite(variables.notebookId)`.
|
|
|
|
### Why This Works
|
|
- The backend creates the source record immediately (even for async processing, with title "Processing...")
|
|
- The source is linked to the notebook immediately
|
|
- So invalidating the query will refetch and show the new source
|
|
- `SourceCard` already has `useSourceStatus()` that polls every 2 seconds during processing, so the status will auto-update
|
|
|
|
### Gotchas
|
|
- No need for polling/delays - the source record exists in DB when the API returns
|
|
- No need for WebSocket/SSE - simple cache invalidation is sufficient
|
|
- The async path creates a minimal source with "Processing..." title that gets updated when processing completes
|
|
- `SourceCard` already handles status polling via `useSourceStatus()` hook
|