feat(dashboard): add corpus dashboard at /dashboard/

Full private corpus dashboard for tools.dobetternorge.no users — each SSO
account gets an auto-provisioned CaveauAI tenant (clients row, corpus) on
first visit. Includes upload (file/paste/URL), RAG chat with SSE streaming
and citation chips, document CRUD, FalkorDB graph relations tab, and
improved save-from-tool flow with tag/preview support.

- dashboard/{index,documents,document,upload,chat,settings}.php
- api/dashboard/{corpus-init,documents,upload,ingest-status,chat-stream,
  save-from-tool,graph}.php
- includes/{CorpusProvision,layout_dashboard,layout_dashboard_footer}.php
- assets/css/dashboard.css  assets/js/corpus-save.js (routing upgrade)
- includes/{bootstrap,layout}.php extended for dashboard provisioning

Migration 141 (clients.dbn_sso_uid + import_method enum) applied on chloe.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 17:15:40 +02:00
parent 83fc71414f
commit 06d01a3bce
20 changed files with 2632 additions and 28 deletions
+65
View File
@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
$dashboardPage = 'settings';
$dashboardTitle = 'Innstillinger';
$dashboardLead = 'Innstillinger for ditt private korpus.';
require_once __DIR__ . '/../includes/layout_dashboard.php';
?>
<section class="dash-card">
<div class="dash-card__head">
<h2>Konto</h2>
</div>
<dl style="display:grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1.5rem; font-size:0.92rem;">
<dt style="color:rgba(22,19,15,0.55);">Klient-ID</dt>
<dd><code id="setClientId">—</code></dd>
<dt style="color:rgba(22,19,15,0.55);">Korpus-ID</dt>
<dd><code id="setCorpusId">—</code></dd>
<dt style="color:rgba(22,19,15,0.55);">Bruker-ID</dt>
<dd><code id="setUserId">—</code></dd>
</dl>
</section>
<section class="dash-card">
<div class="dash-card__head">
<h2>RAG-pipeline</h2>
</div>
<dl style="display:grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1.5rem; font-size:0.92rem;">
<dt style="color:rgba(22,19,15,0.55);">Chunking</dt>
<dd>600 ord pr. passasje, 75 ords overlapp, heading-aware</dd>
<dt style="color:rgba(22,19,15,0.55);">Embedding-modell</dt>
<dd><code>nomic-embed-text</code> (768-dim) via LiteLLM på Colin</dd>
<dt style="color:rgba(22,19,15,0.55);">Vector DB</dt>
<dd><code>bnl_client_chunks</code> i Qdrant (Colin Docker)</dd>
<dt style="color:rgba(22,19,15,0.55);">Søkemetode</dt>
<dd>Hybrid (vector + keyword), reciprocal rank fusion, private boost 1.5×</dd>
<dt style="color:rgba(22,19,15,0.55);">Graf-database</dt>
<dd><code>bnl_legal</code> i FalkorDB (Colin) — siterings-edges</dd>
</dl>
</section>
<section class="dash-card">
<div class="dash-card__head">
<h2>Personvern</h2>
</div>
<p style="margin-top:0; max-width:64ch; line-height:1.6;">
Alt du laster opp eller lagrer her holdes til din konto. Andre brukere kan ikke se eller søke i dine dokumenter.
Felles-pakken <code>family-legal</code> (~220K passasjer av norsk lovverk og rettspraksis) er delt og brukes
for å berike svar med autoritative kilder, men du eier alt du selv legger inn.
</p>
<p style="max-width:64ch; line-height:1.6;">
Slett enkelt-dokumenter fra <a href="/dashboard/documents.php">Dokumenter</a>. Trenger du å slette hele
kontoen, kontakt support.
</p>
</section>
<script>
(function () {
'use strict';
const d = window.DBN_DASHBOARD || {};
document.getElementById('setClientId').textContent = d.clientId || '—';
document.getElementById('setCorpusId').textContent = d.corpusId || '—';
document.getElementById('setUserId').textContent = d.clientUserId || '—';
})();
</script>
<?php require_once __DIR__ . '/../includes/layout_dashboard_footer.php'; ?>