Commit Graph

167 Commits

Author SHA1 Message Date
daveadmin 01a63ebf46 fix: correct Qdrant IP to 10.0.2.10 in diagnostics.php 2026-05-26 22:35:22 +02:00
daveadmin 2e2b0b45fa Full DMS: folders + ACLs, versioning, trash, bulk ops, preview, smart folders
Rebuild the dashboard as a Drive-style document management system on top of
the existing CaveauAI hybrid RAG pipeline.

Backend:
- 5 migrations (versions, trash soft-delete, saved searches, categories, audit)
- DMS helpers (folder ACL walker, disk storage, audit, version snapshot,
  XLSX/PPTX/HTML/CSV/MD extractors)
- New APIs: folders, document-versions, trash, bulk, preview, saved-searches,
  categories, diagnostics
- Extended APIs: documents (folder_id, soft-delete, ACL filter, sort),
  upload (9 file types, version-collision detection with replace/new/keep-both,
  disk persistence), chat-stream (folder scoping + graph related-documents)
- 30-day trash purge cron with Qdrant + disk + graph cleanup

Frontend:
- Drive-style two-pane browser with folder tree, drag-drop, bulk-action bar,
  right-click context menu, multi-select
- New pages: folders (tree + per-folder ACL editor), trash (restore/purge)
- Extended pages: upload (folder picker, version-collision modal, 9 file
  type chips), document (Preview/Versions/Permissions tabs with PDF.js +
  mammoth.js + audio), index (DMS KPIs + activity feed), settings (live
  diagnostics ping MariaDB/Qdrant/LiteLLM/FalkorDB/disk), chat (folder
  scope chips + related-authorities chips)
- New CSS (dms.css) + JS bundle (dms.js) exposing window.DBN_DMS
- Sidebar nav adds Folders + Trash items

All routes return HTTP 200 in local smoke test; all 32 files lint clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 22:24:56 +02:00
daveadmin b84827ecea Add Transcribe docs (about/guide/tech) + refresh Redact docs
- New: transcribe-about.php, transcribe-guide.php, transcribe-tech.php
  with full en/no/uk/pl translations (3-engine cascade, diarization, vocab)
- New: translations/transcribe-about|guide|tech.php (4-lang strings)
- New: scripts/translate-pages.php (Azure gpt-4o CLI translation helper)
- Add korr-doc-links nav to transcribe.php
- Refresh redact-about|guide|tech.php — point to assets/images/redact/
- Fix all "never written to disk" wording in redact translations
- Add Min Sak/corpus save workflow to redact guide and tech privacy section
- redact.php upload hint: correct in-memory wording

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 10:28:06 +02:00
daveadmin 234ab7278b Timeline: group same-date/actor events, clean badges, Bedrock routing
- renderTimeline(): group consecutive same-date+actor events into one card
  with a bullet list; single events keep their current layout
- Date format: YYYY-MM-DD → "1 Jun 2023" (3-letter month, international)
- Time shown in header when available
- Remove date_type badge; confidence badge replaced by amber ⚠ flag on
  low-confidence events only (high/medium border colour still shows)
- LegalTools.php: resolve azure_full/azure_mini to Bedrock Sonnet/Haiku
  when DbnBedrockGateway is active; claude_sonnet/claude_haiku also handled
- timeline.php + api/timeline.php: engine labels updated (Claude Haiku/Sonnet);
  claude_haiku + claude_sonnet added to valid engine list
- i18n engine labels updated in all 4 languages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 23:21:35 +02:00
daveadmin 25c2cf826d Remove deep legal analysis button from redact results
ask still gets the button; redact results no longer offer it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 22:13:13 +02:00
daveadmin b2e1bf268d korrespond v1 premiere: Bedrock routing, engine picker, journal auto-save + status
- KorrespondAgent: add resolveDeployment() helper; fix classify/translate to use
  Haiku via Bedrock, draft to use Haiku (quick) or Sonnet (thorough) — fixes broken
  withDeployment('gpt-4o-mini') calls when DBN_BEDROCK_ENABLED=true
- korrespond.php: add Quick/Thorough engine picker (case_toggle already present)
- korrespond.js: pass engine in request payload
- api/korrespond.php: accept user-selected engine, auto-save to case_tool_results
  for paid users after each successful run, update deployment log label
- CaseResults: add korr_status to listForUser SELECT, add updateStatus() method
- result-action.php: add set_status action for correspondence journal
- account.php: show status dropdown (Draft/Sent/Reply received/Resolved) for
  korrespond entries in #analyses, wire JS change handler to result-action.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:52:09 +02:00
daveadmin c2735fa919 Simplify advocate engine options: remove GPU/dbn_legal_v3, fix time estimates
GPU and DBN Legal Agent v3 are unsuitable for advocate synthesis (4-6K token
structured JSON output at 20-30 tok/s = 3-5 min on RTX 3060, plus both fall
through to Sonnet when Bedrock is enabled anyway). Reduce to two honest options:
Haiku (~2-4 min) and Sonnet (~3-5 min), with accurate description of why
time is dominated by multi-pass question answering, not synthesis.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:27:34 +02:00
daveadmin a925415ef7 Fix advocate brief truncation: raise synthesis max_tokens to 6K
Haiku synthesis had a hard cap of 2500 tokens which truncated the
advocate JSON response (~4-6K tokens), causing decodeJsonObject() to
fail and rendering the raw JSON string as the brief.

Fix: remove the 2500-token Haiku override; introduce a per-mode limit
(6000 for advocate, 4000 for deep-research) in $opts before the engine
branch so all paths benefit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:09:01 +02:00
daveadmin 883d813f1b Fix sub-question expansion timeout + engine routing for Bedrock advocate
- expandQueries(): truncate seedDescription to 2000 chars (full uploads were
  48K+ tokens, exceeding the 35s timeout with Sonnet); switch to Haiku gateway
  when Bedrock is active (fast + adequate for sub-Q generation); timeout → 60s
- interpretSeed(): same Haiku + 60s fix for English non-advocate path
- synthesise(): add explicit azure_mini + Bedrock → Haiku branch so the fast
  engine actually uses Haiku (~20-40s) instead of falling through to Sonnet (~180s)
- advocate.php: relabel azure_mini as "Claude Haiku 4.5 (fast)" with accurate
  timing; relabel claude_sonnet as "(thorough)" to reflect the distinction

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:50:37 +02:00
daveadmin b78ab1e257 Fix Bedrock advocate synthesis: engine guard, response_format, Claude engine option
- DeepResearchAgent: engine guard now accepts dbn_legal_v3, claude_sonnet, claude_haiku
  (previously stripped these to azure_mini, breaking dbn_legal_v3 selection and
  preventing Claude engines from reaching the correct synthesis branch)
- DbnBedrockGateway: remove response_format=json_object from chat payload — LiteLLM
  converts this to a tool-use constraint for Bedrock, routing output into tool_calls
  instead of content (root cause of the {} empty brief)
- advocate.php: add Claude Sonnet 4.6 (AWS Bedrock) engine option
- account, billing, dashboard, nav, min-sak: pending UI/flow changes from prior sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:22:12 +02:00
daveadmin 8205a22205 Fix legal analysis issue extraction for long documents 2026-05-25 19:06:23 +02:00
daveadmin 190f639784 Make dbn-legal-agent-v3 checker context-aware; wire into LegalAnalysisAgent
Three fixes:
1. bootstrap.php dbnToolsRunLegalCheck(): prepend first 350 chars of synthesis text
   to the v3 user message so it validates actual content, not just general law.
2. BvjAnalyzerAgent: fix engine guard — was skipping check for claude_sonnet/haiku;
   now skips only when dbn_legal_v3 is the synthesis model (it already IS the check).
3. LegalAnalysisAgent: add post-synthesis dbnToolsRunLegalCheck() call after Pass 3;
   add 'legal_check' key to runFullAnalysis() return.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 16:45:41 +02:00
daveadmin 8a11001bff Add AWS Bedrock three-tier gateway routing (LiteLLM via Colin)
Routes AI tools across three tiers based on task complexity:
- Azure GPT-4o-mini always: redact, translate, timeline-basic, search-legal (mechanical tasks)
- Claude Haiku 4.5 (Bedrock): ask, summarize, timeline-deep, citations (Norwegian nuance)
- Claude Sonnet 4.6 (Bedrock): korrespond, legal-analysis, deep-research, barnevernet-analyze,
  discrepancy-find, advocate (public-facing legal output)

No AWS credentials in app — credentials live in LiteLLM on Colin (same as nova-lite).
Rollback: DBN_BEDROCK_ENABLED=false in .env, no code push needed.

Includes extended thinking support for Pro deep-research via chatWithThinking().
Claude Opus 4.7 constant added for future premium tier (needs litellm_config.yaml entry).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 15:22:48 +02:00
daveadmin 17ad54cf36 Add chunked timeline routing 2026-05-25 12:34:41 +02:00
daveadmin 75b19f1dcf Add timeline engine size routing 2026-05-25 11:33:47 +02:00
daveadmin 3ad8f4843c Harden timeline quick extraction 2026-05-25 11:14:21 +02:00
daveadmin 983c423740 Fix nova-lite JSON: drop response_format, strip markdown fences
nova-lite ignores json_object constraint and returns {} empty; without
it, it wraps output in ```json fences. Strip fences before decodeJsonObject.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 10:51:24 +02:00
daveadmin f00d3d68e5 Add Quick mode (nova-lite/Bedrock) as 3rd tier for timeline tool
Timeline now offers Quick/Standard/Deep: nova_lite routes to Amazon
Bedrock nova-lite via LiteLLM (1 credit, ~2s faster), azure_mini stays
gpt-4o-mini (1 credit), azure_full stays gpt-4o (2 credits, Pro only).
ToolModels tier rules: free→nova_lite only, plus→quick/standard,
pro→all three.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 10:26:07 +02:00
daveadmin 1d1bbeb69f Add redact doc pages; update timeline docs to remove GPU references
- New: redact-about.php, redact-guide.php, redact-tech.php with full
  two-pass pipeline docs, regional rule sets, output format comparison
- New: translations/redact-{about,guide,tech}.php (en + no)
- redact.php: add About/Guide/How-it-works doc links
- timeline-guide.php: remove GPU/cuttlefish engine row
- timeline-tech.php: remove GPU row, replace fine-tuned LLM section
  with SSE streaming + DOCX export section, stat4 3→2 engines
- timeline-about.php: replace dbn-legal-agent spotlight with
  SSE/DOCX export highlight
- translations/timeline-{about,guide,tech}.php: remove all GPU/
  cuttlefish references across all 4 languages; add stream_* and
  export_* keys; fix upload copy (5 files → 1 file)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 09:53:54 +02:00
daveadmin d47024ed67 timeline: remove GPU, add SSE status updates, DOCX export, single-file, engine-aware credits
- Remove GPU/cuttlefish engine from timeline.php, api/timeline.php, LegalTools.php, tools.js (all 4 langs)
- Add engine-aware credit cost: gpt-4o-mini=1 credit, gpt-4o=2 credits (matches redact pattern)
- Remove multiple attribute from file input (single document only)
- New api/timeline-stream.php: SSE endpoint emitting status events + final result
- New api/timeline-download.php: DOCX export of timeline events
- LegalTools::timeline() gains ?callable $onProgress for live status updates
- tools.js: spinner on run, SSE streaming fetch, Export to Word button
- Save to My Docs was already wired (showSaveResultButton at line 1136)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 09:32:28 +02:00
daveadmin 4b8b675a64 redact: unify save to single 'Save to My Docs' button; fix DOCX content type
- Remove js-save-corpus button from redact output (was failing with 'no_workspace'
  for users without a linked CaveauAI workspace)
- Single save path now goes through showSaveResultButton() → api/case/save-result.php,
  which works for all paid (Plus/Pro) users without workspace dependency
- Relabel 'Save result' → 'Save to My Docs' and update success message
- Fix DOCX: contentTypesXml() had wrong ContentType for docProps/core.xml
  (application/package/... → application/vnd.openxmlformats-package.core-properties+xml);
  Word validates this strictly and was rejecting the file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 08:40:39 +02:00
daveadmin 56cd87dd7b redact: UX overhaul — engine simplification, credits, spinner, save-to-docs, badges
- Remove GPU/regex engine options; keep only azure_mini (1 credit) and azure_full (2 credits)
- Variable credit cost: engine-aware pre-check and charge in api/redact.php; PricingCatalog base = 1
- Fix ATTORNEY not preserved when keepOfficials=true: add to LLM prompt, generic-tag, pseudonym regexes
- Replace Azure credits hint with per-engine credit cost text (all 4 languages)
- Single-file upload only (was: up to 5); simplify status messages
- Clear previous redaction output and show pulsing spinner when a new run starts
- Add "Save to My Docs" button in redact output panel (corpus-save.js path)
- corpus-save.js: capture source_doc_ids from button dataset, pass in POST payload
- api/save-to-corpus.php: accept source_doc_ids, store first as source_url=corpus-doc:{id}
- doc-picker.js: show "✂ Redacted" badge for documents saved from the redact tool
- CSS: .redact-working spinner, doc-item__badge--redact pill styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 08:18:51 +02:00
daveadmin a821d39dcd Replace landing card MCP copy pill with link to /mcp-tool.php; fix preview.php for slugs without authored content (legal-analysis, summarize, translate) 2026-05-25 06:54:04 +02:00
daveadmin 38d617bf02 Add Tool info links and MCP section to tool cards and preview pages
- Dashboard: add "Tool info" link → preview.php on every tool card footer
- Landing page: convert lt-card <a> to div+onclick, add footer with "Learn more" link and copyable MCP slug pill
- preview.php: add MCP Integration section per tool (slug, copy button, claude_desktop_config.json snippet, login note)
- CSS: lt-card__footer, lt-card__mcp-pill, lt-preview-mcp section styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 21:25:09 +02:00
daveadmin 61425d7f17 Fix footer library and MCP pricing links 2026-05-24 19:54:02 +02:00
daveadmin e7189fa882 Fix upsell status card text visibility — status-card--cta overrides redesign CSS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:01:05 +02:00
daveadmin b912ff22bc Dashboard account section, profile API, and CSS account panels
- SSO session auth gating on all protected pages
- dashboard.php: account section (profile form + workspace panel),
  onboarding prompt modal, overview bar extracted to CSS classes,
  dashboard.css linked in page head
- api/profile.php: save/dismiss endpoint for optional profile fields
- assets/css/dashboard.css: account grid, dash-account-panel,
  dash-profile-form, profile-prompt-backdrop modal, overview bar
  classes, dash-section-kicker, dash-tier-badge base styles
- includes/bootstrap.php: dbnToolsMainUserProfile,
  dbnToolsProfileNeedsPrompt, dbnToolsRequirePageAuth
- scripts/sql/004_user_profile_fields.sql: nullable phone, address,
  and profile_prompt_dismissed_at columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 18:49:34 +02:00
daveadmin 302bb44f70 Bump dashboard + pricing typography to readable desktop scale
Cards, status row, account bar, and pricing tiers were rendering at
.78–.94rem with 18–20px padding — felt microscopic on 1440+ viewports.
Lift every token ~12–15% and widen card padding so the Crimson Pro /
IBM Plex editorial character reads as intended.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 16:58:23 +02:00
daveadmin f609da6ad7 Fix dashboard tool cards min-height — cards were collapsing to ~100px
Restored min-height:200px + display:flex on .dashboard-tool-card in CSS,
and removed the conflicting min-height:0 inline overrides on each card div.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 16:33:29 +02:00
daveadmin 897771597e Overhaul dashboard: account bar, enhanced tool cards with MCP slugs, MCP quick-start, tool reference section
- Replace manifesto section with compact account overview bar (tier badge,
  credits breakdown, next refill/billing date, upgrade/manage/top-up CTAs)
- Convert tool cards from <a> to keyboard-accessible <div> with footer bar
  showing Open link, About link (advocate/timeline/korrespond), MCP slug copy button
- Add collapsible MCP quick-start section: token prefix fetch, stdio config,
  remote HTTP config, copy buttons, link to full mcp.php docs
- Add 3-column tool reference section for Advocate / Timeline / Korrespond
  with about/guide/tech links, description, and copyable MCP slug
- All new sections fully localised: en / no / uk / pl

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 15:38:30 +02:00
daveadmin c090a05644 Bump context bar font size and add it to dashboard, pricing, min-sak pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:51:55 +02:00
daveadmin 7df3b7f8d3 Replace manifesto bar with compact context bar + add privacy page
- layout.php: replace large manifesto section (eyebrow/title/sub/4 stats) with
  a slim dbn-context-bar strip linking to why-ours, pricing, MCP, and privacy
- i18n.php: add context_bar_* + footer_privacy_link + privacy_page_title keys
  to all 4 language blocks (en, no, uk, pl)
- dbn-tools-redesign.css: add .dbn-context-bar styles with mobile wrap
- privacy.php: new standalone page in 4 languages covering in-memory processing,
  metadata-only logging, My Case opt-in storage, EU data locations, and HTTPS transport
- footer.php: add Privacy link to first footer column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:44:44 +02:00
daveadmin aafe8efaa4 fix: restore white text in kdoc-hero on why-ours page
The redesign CSS was forcing .kdoc-hero__title to var(--dbn-blue) (#00205b)
— the same color as the hero background, making it invisible. The kicker
was also overridden to red, which clashed with the dark navy overlay.

Added more-specific .kdoc-hero .kdoc-hero__* overrides to restore white text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:09:32 +02:00
daveadmin b21bfb2f1d Add NOK pricing catalog, credit ledger, success-based charging, and tier-gated model routing
- PricingCatalog.php: single source of truth for plans (free/plus/pro), top-ups,
  Stripe price env keys, tool costs (0–6 credits), STT variable billing, feature limits
- FreeTier.php: monthly-first credit deduction, ledger (user_tool_credit_ledger),
  STT reservation/settle/release, monthly reset, trial logic
- StripeClient.php: canonical SKUs (plus/pro/topup_100/300/1000), legacy aliases kept
- stripe-checkout.php: subscription vs payment mode, trial gating, catalog metadata
- stripe-webhook.php: idempotent via stripe_events, handles subscription lifecycle +
  invoice.paid renewal + one-time topup credit grants
- All API tools: success-based credit deduction (check before, charge after)
- transcribe.php: file-size heuristic reservation, settle from actual provider duration
- ask.php + LegalTools.php: ToolModels engine resolution — Pro gets gpt-4o
- KorrespondAgent.php + korrespond.php: tier-gated draft deployment —
  Free/Plus gets gpt-4o-mini, Pro gets gpt-4o
- pricing.php: NOK-only, plan cards, top-up packs, Organisation contact card,
  tool cost table, separate monthly/prepaid balance display
- 003_pricing_credit_catalog.sql: ledger and STT reservation tables

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 13:42:27 +02:00
daveadmin bffc714541 Add My Docs picker to deep-research, advocate, barnevernet, korrespond, citations
- PHP: Add docPickerSection (button + chips + hidden input) to all 5 tool pages
- JS: Send doc_ids in payload for deep-research, advocate, barnevernet, korrespond
- Backend: Inject selected corpus doc content into paste_text/narrative/notes via dbnToolsInjectDocContent
- Citations: Add upload zone (file → api/extract.php → textarea) + paste textarea with live Norwegian legal reference extraction (regex) + ref chips → title search; doc picker populates titleInput via MutationObserver

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 13:04:45 +02:00
daveadmin 88555eb8a7 Fix docPickerBtn/audioPickerBtn i18n — add missing translation keys
Add doc_picker_btn/audio_picker_btn to i18n.php (en/no/uk/pl), add
docPickerBtn to REDACT_I18N + TIMELINE_I18N and audioPickerBtn to
TRANSCRIBE_I18N in tools.js. PHP-render picker labels in legal-analysis,
translate, summarize, tool_form, and layout_footer using dbnToolsT().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:41:09 +02:00
daveadmin 1eb55a8384 Fix language switcher dropping query params (e.g. ?tool= on mcp-tool.php)
Preserve all existing GET params when building lang switcher URLs so that
switching language on /mcp-tool.php?tool=dbn.redact stays on that tool.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:16:16 +02:00
daveadmin 96fbe4398a Fix gate card visibility, add 5 missing tool SVGs, update pricing to EUR 4-tier
Gate cards: remove .lt-gate__card from paper-card override so dark navy
backgrounds restore; drop blue title colour override for gate cards.

SVGs: add translate (bilingual doc), citations (citation graph), korrespond
(formal letter), summarize (doc→extracted bullets), legal-analysis (issue
sections + dbn-legal-agent-v3 badge).

Pricing: 3 NOK tiers → 4 EUR tiers (Free €0 / Light €9 / Pro €29 / Pro+ €79);
Pro+ is new; "Plus" references updated to "Light" throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:09:37 +02:00
daveadmin 1bfafa9908 Localize mcp.php + add mcp-tool.php detail pages for all 19 MCP tools
- Replace all hardcoded English strings in mcp.php with dbnToolsT() calls
- Add 44 MCP UI chrome translation keys to includes/i18n.php (en/no/uk/pl)
- Generate includes/mcp-tool-translations.php with tool names, descriptions,
  and parameter docs translated into Norwegian, Ukrainian, and Polish via Azure OpenAI
- Create mcp-tool.php: parameterized detail page (?tool=dbn.slug) with parameter
  table, example request/response JSON, and privacy section, all localized
- Add "View details →" links on tool cards in mcp.php (shown on expand)
- Add translations/mcp-chrome.php and scripts/generate-mcp-translations.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:05:07 +02:00
daveadmin e09ee62c62 Apply Do Better Norge tools brand redesign (CSS + all tool pages)
New dbn-tools-redesign.css with warm paper surface, navy tools nav, gold
accent, and per-tool themes via body[data-active-tool]. Updated all 21 tool
PHP pages, shared layout/nav/footer includes, and advocate route (new).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 11:26:39 +02:00
daveadmin c997f204b5 feat: add Do Better Norge MCP server — token system, runtime API, interactive setup page
- UserMcpTokens: per-user SHA256-hashed token mint/validate/revoke (Plus/Pro only)
- DbnMcpRuntime: 19 MCP tools (search, ask, summarize, timeline, redact, translate,
  legal_analysis, korrespond, barnevernet_analyze, advocate_brief, deep_research,
  discrepancy_find, transcribe_audio, corpus_stats, list_documents, get_document,
  citation_graph, case_workbench_plan, save_to_case)
- api/mcp/user/: session/tools/invoke HTTP endpoints with Bearer token auth
- api/mcp-tokens.php: token create/revoke/list REST API
- mcp.php: interactive setup page with token management, 5-client config tabs,
  auto-fill on token creation, tool catalog grid, privacy notice
- account.php: simplified MCP section with link to mcp.php
- nav.php: MCP nav link
- .htaccess: Authorization header passthrough, MCP route rewrite, CORS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 11:01:13 +02:00
daveadmin 0bb828fb98 fix: require AzureOpenAiGateway.php in api/translate.php 2026-05-24 10:03:00 +02:00
daveadmin effd3289b4 feat: add Legal Translation tool (translate.php)
New dedicated tool for translating Norwegian legal documents (Barnevernet
letters, court decisions, correspondence) into the user's chosen language
with legal-terminology annotations.

- translate.php: new tool page with source/target language selectors,
  4-way UI lang switcher, file upload, doc picker, streaming results
- api/translate.php: NDJSON streaming endpoint; Azure GPT-4o-mini with
  legal-aware prompt that preserves Norwegian statute refs verbatim and
  annotates terms with no target-language equivalent; 2-credit cost
- assets/js/translate.js: form handler, NDJSON stream reader, copy button
- assets/css/tools.css: .lt-* styles for translation result + annotations
- includes/i18n.php: 22 lt_* keys × 4 languages; translate entry in nav
- includes/FreeTier.php: translate → 2 credits
- includes/CaseResults.php + case-result.php: translate in eligible tools,
  toolLabel, toolIcon, deriveTitle, rendering block, rerun map

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 09:59:06 +02:00
daveadmin 21c092e0d0 Legal Analysis: full language follow-through (UI + LLM)
The tool now respects the chosen UI language end-to-end — even if the
source document is Norwegian, a user on EN/UK/PL gets the analysis in
their language. Norwegian statute references (barnevernsloven § 4-25,
EMK Art. 8) and case names (Strand Lobben mot Norge 37283/13) are kept
verbatim because they are proper nouns.

LLM (LegalAnalysisAgent.php):
- extractIssues: prompt asks for question + brief_context in user's
  language; statute refs preserved
- answerIssue: Norwegian core system prompt (keeps fine-tune precision)
  + language-coercion line for non-NO; localised context/source labels
- synthesise: overall_assessment, next_steps, disclaimer in user's
  language; explicit per-language disclaimer text
- runFullAnalysis empty-case fallback also localised
- what_to_check translated per language

UI:
- 40 new la_* translation keys in i18n.php × 4 languages (NO/EN/UK/PL)
- legal-analysis.php: 4-way lang switcher, dbnToolsT() for every label,
  emits window.DBN_LA_I18N for runtime JS strings
- legal-analysis.js: t() helper reads from window.DBN_LA_I18N
- layout_footer.php: emits window.DBN_CURRENT_LANG +
  window.DBN_ADDON_I18N so the legal-analysis add-on button works in
  the page's language no matter which tool it's invoked from
- tools.js add-on: reads from DBN_ADDON_I18N, passes DBN_CURRENT_LANG
  to /api/legal-analysis.php so server responds in same language

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 08:43:15 +02:00
daveadmin 2509a596c1 Fix file picker double-open across all remaining tools
Same defensive guard as legal-analysis + summarize, now applied to the
upload-zone and audio-zone handlers in tools.js. Affects redact,
timeline, and transcribe (which all share these zones via tools.js's
setupUpload / setupAudioUpload). Stops native label-for clicks and the
input's own click from bubbling into the zone handler that would
otherwise programmatically re-open the picker.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 08:23:58 +02:00
daveadmin 5589e891f4 Fix file picker reopening after selection on legal-analysis + summarize
The "browse" label's native for=input trigger AND the upload-zone click
handler both called uploadInput.click(), so the picker opened twice when
the user clicked the browse text. Stop propagation on the label and the
input itself, plus tighten the zone handler to recognise any label-for
descendant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 08:19:28 +02:00
daveadmin 7e6463ed22 Add Legal Analysis tool — two-pass DBN-legal pipeline
Restores the dbn-legal-agent-v3 fine-tune on ocelot (was silently aliased
to plain qwen2.5:14b in LiteLLM since the viper retirement) and ships a
new tool that uses it via a two-pass flow:

  Pass 1 (Azure 4o-mini)  → extract up to 5 distinct legal issues
  Pass 2 (ocelot v3 only) → answer each issue, ≤350 tokens, with corpus
  Pass 3 (Azure 4o-mini)  → synthesise overall assessment + next steps

The 12GB-VRAM constraint motivates the split: dbn-legal-agent-v3 stays
hot in VRAM through the 5 sequential per-issue calls because issue
extraction and synthesis run on Azure, not on ocelot.

New surface:
  - includes/LegalAnalysisAgent.php
  - api/legal-analysis.php           (NDJSON streaming endpoint)
  - legal-analysis.php               (dedicated tool page)
  - assets/js/legal-analysis.js      (streamed UI with per-issue cards)
  - Save-result + case-result.php rendering for legal-analysis output
  - Nav registration in all four UI languages

Add-on integration: a "⚖️🇳🇴 Run deep legal analysis on this text"
button now appears on Summarize, Ask, and Redact result pages and
streams the same pipeline inline below the existing result.

Existing tools relabelled: the misleading "🇳🇴 Norwegian specialist v3 "
option on advocate/deep-research/discrepancy/barnevernet is now honestly
"DBN Legal Agent" — now that the real fine-tune is actually deployed,
the label finally matches reality. The advocate.php v2 option was
removed since the v2 GGUF is retired.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 04:21:01 +02:00
daveadmin 2013648ee0 Add manual 'Save result' to all tools — replaces auto-save
All tool results can now be saved to My Case manually. Users click
'Save result', type a description, and confirm. This replaces the
previous silent auto-save on barnevernet/timeline/etc., giving users
control over what stays and what it's called (supports multiple runs
of the same tool with different titles).

- CaseResults: extend ELIGIBLE_TOOLS to include summarize, ask, redact,
  transcribe; add toolLabel/toolIcon entries; support explicit title
  via meta['title'] in save()
- api/case/save-result.php: new client-initiated save endpoint;
  accepts tool + title + input_payload + output_payload + meta
- Remove CaseResults::save() auto-save from barnevernet, deep-research,
  discrepancy, korrespond, timeline API endpoints
- tools.js: add showSaveResultButton() (exposed as window.dbnShowSaveResultButton);
  wire for ask, redact, timeline, transcribe (both file-upload and
  stored-audio paths)
- barnevernet.js: wire save button after final result render
- summarize.js: wire save button after renderFinal(); passes sumResults
  container so widget appears in the correct #sumResults div
- case-result.php: rich tool-specific rendering for summarize, ask,
  redact, transcribe, timeline; update re-run link map to include all
  new tools
- tools.css: styles for .save-result-widget and its states (idle,
  prompt, done, error)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 01:27:26 +02:00
daveadmin 0fcfed1a86 fix: allow empty text field when doc_ids supplied to all tool APIs
dbnToolsString was called with required=true (default), so it aborted
before dbnToolsInjectDocContent could inject content from the doc picker.
Now passes required=false and validates after injection so doc-only
submissions work in timeline, redact, ask, and summarize.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:39:46 +02:00
daveadmin fa42c7223a fix: remove browser-native required validation blocking doc picker submissions
Forms lacked novalidate and textareas had required, so the browser fired
HTML5 validation before tools.js could intercept — blocking submissions
where text came from the doc picker or file upload rather than the textarea.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:34:38 +02:00