# Sofiia UI vNext — Dependency Map (D) > Generated: 2026-02-26 | Карта залежностей UI → Backend → DB → Events --- ## Легенда | Символ | Значення | |--------|----------| | ✅ | Endpoint/Model реалізований | | ⚠️ | Частково реалізований або за feature flag | | ❌ | Відсутній, потрібна реалізація | | 🔧 | Потрібне виправлення/доопрацювання | | 📄 | Тільки документований | --- ## Таблиця 1: Chat & Voice | UI Feature | Expected API/Event | Found? | Evidence | Action | |-----------|-------------------|--------|----------|--------| | Text chat | `POST /api/chat/send` | ✅ | `main.py` | — | | Voice STT (WebM) | `POST /api/voice/stt` | ✅ | `main.py` → memory-service | — | | Voice TTS | `POST /api/voice/tts` | ✅ | `main.py` (legacy + HA) | — | | Voice Phase 2 stream | `POST /api/voice/chat/stream` | ✅ | `main.py` | — | | Voice stop/abort | AbortController + `POST /api/voice/tts` cancel | ✅ | `index.html` JS | — | | TTFA telemetry | `POST /api/telemetry/voice` | ✅ | `main.py` | — | | Batch telemetry | `POST /api/telemetry/voice/batch` | ✅ | `main.py` | — | | Degradation badge | `GET /api/voice/degradation_status` | ✅ | `main.py` | — | | Remote voice badge | `X-Voice-Mode: remote` header | ✅ | `main.py` + `index.html` | — | | Model selector UI | inline models list | ✅ | `index.html` (hardcoded) | 🔧 Should come from `/api/models` | | Chat history restore | `GET /api/chat/history?session_id=` | ✅ | `docs_router.py` | — | | Session persistence | localStorage `session_id` | ✅ | `index.html` | — | | Memory status | `GET /api/memory/status` | ✅ | `main.py` | — | --- ## Таблиця 2: Projects | UI Feature | Expected API/Event | Found? | Evidence | Action | |-----------|-------------------|--------|----------|--------| | Projects list | `GET /api/projects` | ✅ | `docs_router.py` | — | | Create project | `POST /api/projects` | ✅ | `docs_router.py` | — | | Get project | `GET /api/projects/{id}` | ✅ | `docs_router.py` | — | | Update project | `PATCH /api/projects/{id}` | ✅ | `docs_router.py` | — | | Delete project | `DELETE /api/projects/{id}` | ❌ | Not found | implement | | Projects sidebar | `GET /api/projects` (on load) | ✅ | `index.html` `loadSidebarProjects()` | — | | Project switcher | localStorage `project_id` | ✅ | `index.html` | — | | **Board (Kanban)** | `GET /api/projects/{id}/tasks` | ❌ | Not found | implement or mock | | **Tasks CRUD** | `/api/projects/{id}/tasks` | ❌ | Not found | implement | | **Meetings** | `GET /api/projects/{id}/meetings` | ❌ | Not found | implement or mock | | **Meeting create** | `POST /api/meetings` | ❌ | Not found | implement | | **Meeting reminders** | NATS `meeting.reminder.*` | ❌ | Not found | Phase 2 | | Project settings | `PATCH /api/projects/{id}` | ✅ | `docs_router.py` | — | --- ## Таблиця 3: Documents DB | UI Feature | Expected API/Event | Found? | Evidence | Action | |-----------|-------------------|--------|----------|--------| | Upload file | `POST /api/files/upload` (multipart) | ✅ | `docs_router.py` | — | | List documents | `GET /api/projects/{id}/documents` | ✅ | `docs_router.py` | — | | Get document | `GET /api/projects/{id}/documents/{doc_id}` | ✅ | `docs_router.py` | — | | Download file | `GET /api/files/{file_id}/download` | ✅ | `docs_router.py` | — | | Search docs | `POST /api/projects/{id}/search` | ✅ | `docs_router.py` (SQL LIKE) | 🔧 Needs semantic search | | Delete document | `DELETE /api/projects/{id}/documents/{doc_id}` | ❌ | Not found | implement | | **Doc versioning** | `GET /docs/{id}/versions` | ❌ | Not found | implement (DDL needed) | | **Restore version** | `POST /docs/{id}/restore` | ❌ | Not found | implement | | **Doc diff** | `GET /docs/{id}/diff?from=&to=` | ❌ | Not found | Phase 2 | | **Backlinks (entity_links)** | `POST /docs/{id}/links` | ❌ | Not found | implement | | **"Index for AI" toggle** | `POST /docs/{id}/index` | ❌ | Not found (USE_EMBEDDINGS flag) | implement | | **doc_index_state** | status tracking | ❌ | Not found | implement | | **Wiki Markdown editor** | Frontend only | ❌ | Not in index.html | implement (Phase 2) | | **Docs tree navigation** | Frontend only | ❌ | Not in index.html | implement (Phase 2) | | Fabric OCR on upload | `POST /v1/capability/ocr` | ⚠️ | `USE_FABRIC_OCR=false` | enable flag | | Embeddings on upload | Qdrant ingest via Router | ⚠️ | `USE_EMBEDDINGS=false` | enable flag | | NATS event on upload | `attachment.created` | ❌ | Not published | add to upload handler | --- ## Таблиця 4: Sessions & Dialog Map | UI Feature | Expected API/Event | Found? | Evidence | Action | |-----------|-------------------|--------|----------|--------| | Sessions list | `GET /api/sessions?project_id=` | ✅ | `docs_router.py` | — | | Resume session | `GET /api/chat/history?session_id=` | ✅ | `docs_router.py` | — | | Session title update | `PATCH /api/sessions/{id}/title` | ✅ | `docs_router.py` | — | | Session fork | `POST /api/sessions/{id}/fork` | ✅ | `docs_router.py` | — | | Dialog Map (tree) | `GET /api/sessions/{id}/map` | ✅ | `docs_router.py` | — | | **Dialog Map (canvas)** | D3/Cytoscape rendering | ❌ | `
` tree only in UI | Phase 2 | | **Project-level map** | `GET /api/projects/{id}/dialog-map` | ❌ | Not found | implement (Postgres needed) | | **Node types** (task/doc/meeting) | NATS consumers | ❌ | Not found | Phase 2 | | **Edge creation UI** | `POST /api/links` | ❌ | Not found | implement | | **Pin important node** | `PATCH /api/sessions/{id}/pin/{msg_id}` | ❌ | Not found | implement | | Real-time map updates | WS `dialog_map.updated` event | ❌ | Not found | implement | | **Saved views** | `dialog_views` table | ❌ | Not found | implement | --- ## Таблиця 5: CTO Panel (Repo + Ops) | UI Feature | Expected API/Event | Found? | Evidence | Action | |-----------|-------------------|--------|----------|--------| | Ops actions (risk/backlog/etc.) | `GET /api/ops/actions` | ✅ | `main.py` | — | | Run ops action | `POST /api/ops/run` | ✅ | `main.py` + `ops.py` | — | | Node health dashboard | `GET /api/nodes/dashboard` | ✅ | `main.py` | — | | Node SSH status | `GET /api/nodes/ssh/status` | ✅ | `main.py` | — | | Add node | `POST /api/nodes/add` | ✅ | `main.py` | — | | Integrations status | `GET /api/integrations/status` | ✅ | `main.py` | — | | **Repo changesets list** | `GET /api/repo/changesets` | ❌ | Not found | implement or mock | | **Create changeset** | `POST /api/repo/changesets` | ❌ | Not found | implement | | **Add patch** | `POST /api/repo/changesets/{id}/patches` | ❌ | Not found | implement | | **Execution plan** | `POST /api/repo/changesets/{id}/plan` | ❌ | Not found | implement | | **Create PR** | `POST /api/repo/changesets/{id}/pr` | ❌ | Not found | implement | | **Run checks** | `POST /api/repo/pr/{id}/checks:run` | ❌ | Not found | implement | | **Ops runs list** | `GET /api/ops/runs` | ❌ | Not found (only one-shot dispatch) | implement | | **Ops run create** | `POST /api/ops/runs` (job-based) | ❌ | Not found | implement | | **Ops run status** | `GET /api/ops/runs/{id}` | ❌ | Not found | implement | | LangGraph runs | `POST /v1/graphs/{name}/runs` (Supervisor) | ✅ | `sofiia-supervisor` | 🔧 Not exposed via BFF | | LangGraph status | `GET /v1/runs/{id}` | ✅ | `sofiia-supervisor` | 🔧 Not exposed via BFF | | **repo_tool (read)** | via chat tools | ✅ | `tool_manager.py` | — | | **pr_reviewer_tool** | via chat tools | ✅ | `tool_manager.py` | — | --- ## Таблиця 6: Database Model Dependency | UI Screen | Required DB Table | Status | Storage | Action | |-----------|------------------|--------|---------|--------| | Chat history | `messages` | ✅ | SQLite | — | | Projects | `projects` | ✅ | SQLite | — | | Documents | `documents` | ✅ | SQLite | — | | Sessions | `sessions` | ✅ | SQLite | — | | Dialog Map (messages) | `messages.parent_msg_id` | ✅ | SQLite | — | | **Dialog Map (graph)** | `dialog_nodes` + `dialog_edges` | ❌ | None | ADD TABLES | | **Saved map views** | `dialog_views` | ❌ | None | ADD TABLE | | **Doc versions** | `docs_versions` | ❌ | None | ADD TABLE | | **Entity links** | `entity_links` | ❌ | None | ADD TABLE | | **Tasks** | `tasks` | ❌ | None | ADD TABLE | | **Meetings** | `meetings` | ❌ | None | ADD TABLE | | **Repo changesets** | `repo_changesets` | ❌ | None | ADD TABLE | | **Repo patches** | `repo_patches` | ❌ | None | ADD TABLE | | **Pull requests** | `pull_requests` | ❌ | None | ADD TABLE | | **Ops runs** | `ops_runs` | ❌ | None | ADD TABLE | | Embeddings | Qdrant `sofiia_docs_*` | ⚠️ | Qdrant (disabled) | ENABLE FLAG | | Long-term memory | Qdrant `sofiia_messages` | ✅ | Qdrant | — | | Facts | Postgres `daarion_memory` | ✅ | Postgres | — | --- ## Таблиця 7: Real-time Events (WebSocket) | Event | Direction | Status | Evidence | |-------|-----------|--------|----------| | `nodes.status` | Server → UI | ✅ | `main.py` WebSocket fan-out | | `chat.reply` | Server → UI | ✅ | `main.py` | | `voice.stt.result` | Server → UI | ✅ | `main.py` | | `voice.tts.ready` | Server → UI | ✅ | `main.py` | | `voice.stream.chunk` | Server → UI | ✅ | `main.py` | | `ops.run.status` | Server → UI | ✅ | `main.py` | | `error` | Server → UI | ✅ | `main.py` | | `dialog_map.updated` | Server → UI | ❌ | Not found | | `task.created` | Server → UI | ❌ | Not found | | `doc.updated` | Server → UI | ❌ | Not found | | `meeting.reminder` | Server → UI | ❌ | Not found | | `repo.pr.status` | Server → UI | ❌ | Not found | | `ops_run.completed` | Server → UI | ❌ | Not found | --- ## Таблиця 8: Security & Access Control | Feature | Status | Evidence | |---------|--------|----------| | API key auth (console) | ✅ | `auth.py` | | Strict auth (SSH/admin) | ✅ | `auth.py` strict mode | | Rate limiting per endpoint | ✅ | `main.py` limiters | | Upload sanitize (filename/mime) | ✅ | `docs_router.py` | | Upload size limits (env-based) | ✅ | `UPLOAD_MAX_*_MB` env | | RBAC tool allowlist | ✅ | `agent_tools_config.py` | | `mode=confidential` check | ❌ | Not in BFF or Router | | E2EE for docs | ❌ | Not implemented | | Audit log for actions | ⚠️ | Partial (router audit.py) | | 2-step Plan → Apply for risky ops | ❌ | Not implemented | | CORS config | ⚠️ | Check `main.py` | --- ## Граф залежностей (логічний) ``` [index.html SPA] │ ┌───────────────┼───────────────┐ │ │ │ [chat+voice] [projects] [ops+nodes] │ │ │ ▼ ▼ ▼ /api/chat/send /api/projects /api/ops/run /api/voice/* /api/files/* /api/nodes/* /api/telemetry /api/sessions/* /api/integrations/* │ │ │ ▼ ▼ ▼ [Router BFF] [SQLite sofiia.db] [nodes health poll] │ │ │ ▼ ▼ ▼ [Router DAGI] [Memory Service] [SSH + node-worker] /v1/agents/ /threads /events /caps /v1/tools/ /memories /facts /voice/health │ ▼ [LLM + Tools] Grok / qwen3 / DeepSeek + 20+ tools (repo/pr/kb/etc.) ``` **Відсутні зв'язки (vNext):** ``` [index.html] → [Kanban Board] ←→ /api/projects/{id}/tasks [index.html] → [Dialog Map canvas] ←→ /api/projects/{id}/dialog-map [index.html] → [CTO Repo Panel] ←→ /api/repo/changesets [index.html] → [CTO Ops Panel] ←→ /api/ops/runs (job-based) [docs_router] → NATS attachment.created [Supervisor] → BFF (not proxied) ``` --- ## Next Actions for UI Team (1–2 days) 1. **Immediate (today)**: всі фічі chat/voice/projects/sessions/dialog-tree вже працюють — deploy і тестуйте через http://localhost:8002 2. **Quick wins (1–2 дні)**: - `DELETE /api/projects/{id}` — 10 рядків коду - `DELETE /api/projects/{id}/documents/{doc_id}` — 10 рядків - BFF proxy до Supervisor: `POST /api/supervisor/runs` → `sofiia-supervisor:8080/v1/graphs/{name}/runs` 3. **Phase 2 UI (mock-first)**: - Kanban board: спочатку in-memory tasks → `tasks` table - Meetings: спочатку form → `meetings` table - Dialog Map canvas: `
` tree → D3 tree → D3 force graph 4. **CTO Panel mock**: додати mock handlers для `/api/repo/changesets` і `/api/ops/runs` 5. **Увімкнути USE_EMBEDDINGS=true**: після перевірки що Qdrant доступний 6. **Expose Supervisor API через BFF**: один proxy endpoint в main.py 7. **NATS attachment.created**: додати до upload handler у docs_router.py 8. **`dialog_nodes/edges` tables**: DDL + API + WS events (найважливіше для vNext graph) 9. **`docs_versions` table**: ALTER + endpoint (для wiki history) 10. **Перевірити WebSocket**: всі voice/ops events реально приходять до UI