| 10-agent-capabilities |
03 |
ui |
| next.js |
| react |
| tanstack-query |
| shadcn-ui |
| knowledge-base |
| file-upload |
| i18n |
|
| phase |
provides |
| 10-agent-capabilities |
KB ingestion backend (POST /api/portal/kb endpoints, document processing pipeline) |
|
|
| /knowledge-base portal page with document list, file upload, and URL ingest |
| DocumentList component with live processing status polling (5s interval while processing) |
| UploadDialog component with drag-and-drop + file picker (PDF, DOCX, PPTX, XLSX, CSV, TXT, MD) |
| UrlIngestDialog with auto-YouTube detection and web/YouTube type selector |
| KB API functions in lib/api.ts |
| deleteKbDocument, reindexKbDocument, addKbUrl, uploadKbDocument |
|
| TanStack Query hooks |
| useKbDocuments, useDeleteKbDocument, useReindexKbDocument, useAddKbUrl |
|
| Knowledge Base nav item in sidebar (visible to all roles) |
| RBAC |
| customer_operator view-only; upload/delete require customer_admin or platform_admin |
|
|
| 11-future-phases |
| agents-with-kb-tools |
|
| added |
patterns |
|
|
| Conditional refetchInterval in useQuery — polls only while any document has status=processing |
| Raw fetch for multipart uploads — apiFetch always sets Content-Type |
| application/json; KB upload uses fetch directly with auth headers passed explicitly |
|
| getAuthHeaders() exported from api.ts for use in raw fetch upload calls |
|
|
| created |
modified |
| packages/portal/app/(dashboard)/knowledge-base/page.tsx |
| packages/portal/components/kb/document-list.tsx |
| packages/portal/components/kb/upload-dialog.tsx |
| packages/portal/components/kb/url-ingest-dialog.tsx |
|
| packages/portal/lib/api.ts |
| packages/portal/lib/queries.ts |
| packages/portal/components/nav.tsx |
| packages/portal/messages/en.json |
| packages/portal/messages/es.json |
| packages/portal/messages/pt.json |
|
|
| getAuthHeaders() exported from api.ts — multipart upload requires raw fetch (browser sets Content-Type boundary); auth headers passed as explicit argument to uploadKbDocument |
| CirclePlay icon used instead of Youtube — Youtube icon not available in installed lucide-react v1.0.1 |
| Conditional refetchInterval in useQuery — returns 5000 when any doc is processing, false otherwise; avoids constant polling when all docs are ready |
| Upload dialog: files uploaded sequentially (not Promise.all) to show per-file progress and handle partial failures cleanly |
|
| Raw multipart upload via exported getAuthHeaders() pattern — reusable for any future file upload endpoints |
|
|
22min |
2026-03-26 |