---
phase: 10-agent-capabilities
plan: 03
type: execute
wave: 2
depends_on: ["10-01"]
files_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/components/nav/sidebar.tsx
  - packages/portal/lib/api.ts
autonomous: false
requirements:
  - CAP-03

must_haves:
  truths:
    - "Operators can see a Knowledge Base page in the portal navigation"
    - "Operators can upload files via drag-and-drop or file picker dialog"
    - "Operators can add URLs (web pages) and YouTube URLs for ingestion"
    - "Uploaded documents show processing status (processing, ready, error) with live polling"
    - "Operators can delete documents from the knowledge base"
    - "Operators can re-index a document"
    - "Customer operators can view the KB but not upload or delete (RBAC)"
  artifacts:
    - path: "packages/portal/app/(dashboard)/knowledge-base/page.tsx"
      provides: "KB management page with document list, upload, and URL ingestion"
      min_lines: 50
    - path: "packages/portal/components/kb/document-list.tsx"
      provides: "Document list component with status badges and action buttons"
    - path: "packages/portal/components/kb/upload-dialog.tsx"
      provides: "File upload dialog with drag-and-drop and file picker"
  key_links:
    - from: "packages/portal/app/(dashboard)/knowledge-base/page.tsx"
      to: "/api/portal/kb/{tenant_id}/documents"
      via: "TanStack Query fetch + polling"
      pattern: "useQuery.*kb.*documents"
    - from: "packages/portal/components/kb/upload-dialog.tsx"
      to: "/api/portal/kb/{tenant_id}/documents"
      via: "FormData multipart POST"
      pattern: "FormData.*upload"
---

<objective>
Build the Knowledge Base management page in the portal where operators can upload documents, add URLs, view processing status, and manage their tenant's knowledge base.

Purpose: Completes CAP-03 by providing the user-facing interface for document management. Operators need to see what's in their KB, upload new content, and monitor ingestion status.

Output: Fully functional /knowledge-base portal page with file upload, URL/YouTube ingestion, document list with status polling, delete, and re-index.
</objective>

<execution_context>
@/home/adelorenzo/.claude/get-shit-done/workflows/execute-plan.md
@/home/adelorenzo/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/10-agent-capabilities/10-CONTEXT.md
@.planning/phases/10-agent-capabilities/10-01-SUMMARY.md

<interfaces>
<!-- KB API endpoints from Plan 01 -->
POST /api/portal/kb/{tenant_id}/documents — multipart file upload, returns 201 {id, filename, status}
POST /api/portal/kb/{tenant_id}/documents/url — JSON {url, source_type}, returns 201 {id, source_url, status}
GET  /api/portal/kb/{tenant_id}/documents — returns [{id, filename, source_url, content_type, status, error_message, chunk_count, created_at}]
DELETE /api/portal/kb/{tenant_id}/documents/{document_id} — returns 204
POST /api/portal/kb/{tenant_id}/documents/{document_id}/reindex — returns 200

<!-- Portal patterns -->
- TanStack Query for data fetching (useQuery, useMutation)
- shadcn/ui components (Button, Dialog, Badge, Table, etc.)
- Tailwind CSS for styling
- next-intl useTranslations() for i18n
- RBAC: session.user.role determines admin vs operator capabilities
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Knowledge Base page with document list, upload, and URL ingestion</name>
  <files>
    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/components/nav/sidebar.tsx
  </files>
  <action>
    1. **Add KB link to navigation** (`sidebar.tsx` or equivalent nav component):
       - Add "Knowledge Base" link to sidebar nav, visible for platform_admin and customer_admin roles
       - customer_operator can view (read-only) — add to nav but upload/delete buttons hidden
       - Icon: use a document/book icon from lucide-react

    2. **KB page** (`packages/portal/app/(dashboard)/knowledge-base/page.tsx`):
       - Server Component wrapper that renders the client KB content
       - Page title: "Knowledge Base" with subtitle showing tenant context
       - Two action buttons for admins: "Upload Files" (opens upload dialog), "Add URL" (opens URL dialog)
       - Document list component below actions
       - Use tenant_id from session/route context (same pattern as other dashboard pages)

    3. **Document list** (`packages/portal/components/kb/document-list.tsx`):
       - Client component using useQuery to fetch GET /api/portal/kb/{tenant_id}/documents
       - Poll every 5 seconds while any document has status='processing' (refetchInterval: 5000 conditional)
       - Table with columns: Name (filename or source_url), Type (file/url/youtube), Status (badge), Chunks, Date, Actions
       - Status badges: "Processing" (amber/spinning), "Ready" (green), "Error" (red with tooltip showing error_message)
       - Actions per row (admin only): Delete button, Re-index button
       - Empty state: "No documents in knowledge base yet. Upload files or add URLs to get started."
       - Delete: useMutation calling DELETE endpoint, invalidate query on success, confirm dialog before delete
       - Re-index: useMutation calling POST reindex endpoint, invalidate query on success

    4. **Upload dialog** (`packages/portal/components/kb/upload-dialog.tsx`):
       - shadcn/ui Dialog component
       - Drag-and-drop zone (onDragOver, onDrop handlers) with visual feedback
       - File picker button (input type="file" with accept for supported extensions: .pdf,.docx,.pptx,.xlsx,.csv,.txt,.md)
       - Support multiple file selection
       - Show selected files list before upload
       - Upload button: for each file, POST FormData to /api/portal/kb/{tenant_id}/documents
       - Show upload progress (file-by-file)
       - Close dialog and invalidate document list query on success
       - Error handling: show toast on failure

    5. **URL ingest dialog** (`packages/portal/components/kb/url-ingest-dialog.tsx`):
       - shadcn/ui Dialog component
       - Input field for URL
       - Radio or select for source type: "Web Page" or "YouTube Video"
       - Auto-detect: if URL contains youtube.com or youtu.be, default to YouTube
       - Submit: POST to /api/portal/kb/{tenant_id}/documents/url
       - Close dialog and invalidate document list query on success

    6. **API client updates** (`packages/portal/lib/api.ts`):
       - Add KB API functions: fetchKbDocuments, uploadKbDocument, addKbUrl, deleteKbDocument, reindexKbDocument
       - Use the same fetch wrapper pattern as existing API calls

    7. **i18n**: Add English, Spanish, and Portuguese translations for KB page strings (following existing i18n pattern with next-intl message files). Add keys like: kb.title, kb.upload, kb.addUrl, kb.empty, kb.status.processing, kb.status.ready, kb.status.error, kb.delete.confirm, etc.
  </action>
  <verify>
    <automated>cd /home/adelorenzo/repos/konstruct/packages/portal && npx next build 2>&1 | tail -5</automated>
  </verify>
  <done>Knowledge Base page exists at /knowledge-base with document list, file upload dialog (drag-and-drop + picker), URL/YouTube ingest dialog, status polling, delete, and re-index. Navigation updated. i18n strings added for all three languages. Portal builds successfully.</done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <name>Task 2: Human verification of Knowledge Base portal page</name>
  <files>packages/portal/app/(dashboard)/knowledge-base/page.tsx</files>
  <action>
    Verify the Knowledge Base management page in the portal:
    - File upload via drag-and-drop and file picker (PDF, DOCX, PPTX, XLSX, CSV, TXT, MD)
    - URL ingestion (web pages via Firecrawl, YouTube transcripts)
    - Document list with live processing status (processing/ready/error)
    - Delete and re-index actions
    - RBAC: admins can upload/delete, operators can only view

    Steps:
    1. Navigate to the portal and confirm "Knowledge Base" appears in the sidebar navigation
    2. Click Knowledge Base — verify the page loads with empty state message
    3. Click "Upload Files" — verify drag-and-drop zone and file picker appear
    4. Upload a small PDF or TXT file — verify it appears in the document list with "Processing" status
    5. Wait for processing to complete — verify status changes to "Ready" with chunk count
    6. Click "Add URL" — verify URL input dialog with web/YouTube type selector
    7. Add a URL — verify it appears in the list and processes
    8. Click delete on a document — verify confirmation dialog, then document removed
    9. If logged in as customer_operator — verify upload/delete buttons are hidden but document list is visible
  </action>
  <verify>Human verification of KB page functionality and RBAC</verify>
  <done>KB page approved by human testing — upload, URL ingest, status polling, delete, re-index, and RBAC all working</done>
</task>

</tasks>

<verification>
- Portal builds: `cd packages/portal && npx next build`
- KB page renders at /knowledge-base
- Document upload triggers backend ingestion
- Status polling shows processing -> ready transition
- RBAC enforced on upload/delete actions
</verification>

<success_criteria>
- Knowledge Base page accessible in portal navigation
- File upload works with drag-and-drop and file picker
- URL and YouTube ingestion works
- Document list shows live processing status with polling
- Delete and re-index work
- RBAC enforced (admin: full access, operator: view only)
- All three languages have KB translations
- Human verification approved
</success_criteria>

<output>
After completion, create `.planning/phases/10-agent-capabilities/10-03-SUMMARY.md`
</output>
