feat: Legal Tools v1 — multilingual landing, dashboard, SSO bridge

- Public landing page at / for unauthenticated users (EN/NO/UK/PL)
- Authenticated / shows Case Workbench dashboard with manifesto strip,
  stats, and launched-tool grid (Transcribe, Timeline, BVJ, Advocate,
  Deep Research, Corpus)
- Added includes/i18n.php with full 4-language translation layer
- Extended layout.php to Case Workbench shell with tool rail, lang switcher
- AI output language normalization extended to en/no/uk/pl in PHP agents
- SSO token validation in bootstrap.php / index.php (dobetternorge.no bridge)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-15 22:53:27 +02:00
parent ba6c197f1b
commit a3d46f9756
19 changed files with 1149 additions and 238 deletions
+10 -7
View File
@@ -38,7 +38,7 @@ final class DbnDeepResearchAgent
$seedQuery = trim($seedQuery);
$pastedText = trim($pastedText);
$engine = in_array($engine, ['azure_mini', 'azure_full', 'gpu'], true) ? $engine : 'azure_mini';
$language = in_array($language, ['en', 'no'], true) ? $language : 'en';
$language = dbnToolsNormalizeUiLanguage($language);
$controls = $this->normalizeControls($controls);
@@ -444,7 +444,7 @@ final class DbnDeepResearchAgent
private function interpretSeed(string $seedDescription, string $language, string $advocateRole = '', ?array $priorContext = null, string $branchNotes = ''): array
{
$locale = $language === 'no' ? 'Norwegian' : 'English';
$locale = dbnToolsLanguageName($language);
$rolePrefix = $advocateRole !== ''
? "You are preparing a case-research brief for: {$advocateRole}. Frame your interpretation to identify the strongest legal angles for this party.\n\n"
: '';
@@ -511,7 +511,7 @@ PROMPT;
private function expandQueries(string $seedDescription, string $brief, int $targetCount, string $language, string $advocateRole = ''): array
{
$locale = $language === 'no' ? 'Norwegian' : 'English';
$locale = dbnToolsLanguageName($language);
if ($advocateRole !== '') {
$prompt = <<<PROMPT
@@ -942,14 +942,17 @@ PROMPT;
?array $priorContext = null,
string $branchNotes = ''
): array {
$locale = $language === 'no' ? 'Norwegian' : 'English';
$locale = dbnToolsLanguageName($language);
if (empty($numberedSources)) {
return [
'json' => [
'brief_markdown' => $language === 'no'
? 'Jeg fant ikke tilstrekkelig kildestøtte i korpuset til å gi et grunnlagsbasert svar.'
: 'I did not find enough source support in the corpus to give a grounded answer.',
'brief_markdown' => match (dbnToolsNormalizeUiLanguage($language)) {
'no' => 'Jeg fant ikke tilstrekkelig kildestøtte i korpuset til å gi et grunnlagsbasert svar.',
'uk' => 'Я не знайшов достатньої підтримки джерел у корпусі, щоб дати обґрунтовану відповідь.',
'pl' => 'Nie znalazłem wystarczającego wsparcia źródłowego w korpusie, aby udzielić ugruntowanej odpowiedzi.',
default => 'I did not find enough source support in the corpus to give a grounded answer.',
},
'what_we_found' => 'No retrieved sources passed the similarity threshold.',
'what_remains_uncertain' => ['No corpus evidence retrieved for the given query and slice selection.'],
'next_practical_step' => 'Try widening slice selection or rephrasing with more specific statutory or party terms.',