|
|
6d38b793f4
|
Add Fetch Request pipeline UI with real-time SSEs (#8)
## Summary
Add Fetch Request pipeline UI with real-time SSE progress tracking, ambiguity resolution, list page with filtering/retry, and detail page with stepper/event feed.
## Changes
### New files
- **`src/FetchRequestDetail.tsx`** (+675 lines) — Full detail page for a single fetch request with:
- SSE connection for real-time pipeline progress (`/fetch-requests/:id/events`)
- 4-step stepper (Extract → Raw Expense → Enrich → Save) with active/completed/failed/paused states
- Granular progress bar (10% Extract, 20% Raw Expense, 50% Enrich, 20% Save)
- Progress event feed with auto-scroll and deduplication (only latest `progress` per step, hides `started` when terminal event follows)
- Ambiguity resolution cards with candidate selection buttons
- Retry support with retry-count progress bar
- Failure/success snackbar notifications
- Error display for failed fetch requests
### Modified files
- **`react-openapi/api/client.ts`** — added `api.patch()` method for PATCH requests
- **`react-openapi/hooks/useResource.ts`** — added `usePatch()` mutation hook for partial updates with cache invalidation
- **`src/FetchRequests.tsx`** (+347/−73 lines) — Major list page rewrite:
- Row-level actions: retry (failed <3 retries), navigate to detail (paused), delete with confirmation dialog
- Filter bar: status multi-select, account text filter, file/email source toggle
- Account name autocomplete from API
- Format dropdown driven by `resourceOverrides` config
- Date pickers (changed from `datetime-local` to `date`)
- Copy fingerprint button, retry count display, date range column
- Row click navigates to detail, sorted by `created_at` desc
- `pause` status support in `statusColors`
- 409 conflict handling on duplicate fingerprint
- `formatApiError()` for 422 validation error display
- **`src/features/fetch-requests/fetch-requests.models.ts`** — Added types:
- `paused` to `FetchRequestStatus`
- `FetchRequestUpdate` interface
- `retry_count` to `FetchRequest` interface
- `raw_lines`, `txn_blocks`, `txn_dicts`, `txn_dict_count`/`txn_dicts_count` to source types
- `PendingAmbiguity`, `AmbiguityCandidate`, `ResolveAmbiguityPayload`
- `SSEEvent`, `SSEEventStep`, `SSEEventStatus`, `ProgressMessage`
- `FetchRequestFilters`
- `formatApiError()` helper for FastAPI 422 error parsing
- `RETRY_MAX = 3` constant
- **`src/features/fetch-requests/index.ts`** — Barrel exports for all new types, hooks, and helpers
- **`src/features/fetch-requests/useFetchRequests.ts`** — Added hooks:
- `useUpdateFetchRequest()` — PATCH via `usePatch`
- `useFetchRequestAmbiguities(id)` — queries `/fetch-requests/:id/ambiguities`
- `useResolveAmbiguity()` — posts to `/ambiguities/:id/resolve` with cache invalidation
- **`src/main.jsx`** — Added route `/fetch-requests/:id` → `FetchRequestDetail`
## Key decisions
- SSE event stream is the single source of truth for progress; REST is only fallback for page load
- Stepper shows granular ratio-based progress counts (e.g. `150/246` for enrich)
- `pipeline/failed` SSE event triggers refetch + error snackbar
- `load_content` events excluded from event feed entirely
- Enrich/Save progress counts come only from SSE (no REST fallback since those phases don't pause)
Reviewed-on: #8
Co-authored-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
Co-committed-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
|
2026-05-30 15:58:48 +00:00 |
|