Files
dobetternorge-tools/api/case/save-result.php
T
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

55 lines
1.8 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../../includes/bootstrap.php';
require_once __DIR__ . '/../../includes/CaseResults.php';
dbnToolsRequireMethod('POST');
dbnToolsRequireAuth();
if (!dbnToolsIsFreeTier()) {
dbnToolsError('Saved analyses are SSO-only.', 403, 'sso_only');
}
$userId = (int)($_SESSION['dbn_tools_sso_uid'] ?? 0);
if ($userId <= 0) {
dbnToolsError('Missing user id.', 401, 'no_user');
}
if (!CaseResults::isEnabled($userId)) {
dbnToolsError('Saving results requires a Plus or Pro plan.', 403, 'not_paid');
}
$input = dbnToolsJsonInput(800000);
$tool = (string)($input['tool'] ?? '');
$title = mb_substr(trim((string)($input['title'] ?? '')), 0, 200, 'UTF-8');
$inputPayload = $input['input_payload'] ?? [];
$outputPayload = $input['output_payload'] ?? [];
$meta = is_array($input['meta'] ?? null) ? $input['meta'] : [];
if (!in_array($tool, CaseResults::ELIGIBLE_TOOLS, true)) {
dbnToolsError('Unknown tool: ' . $tool, 400, 'bad_tool');
}
if (!is_array($inputPayload) || !is_array($outputPayload)) {
dbnToolsError('input_payload and output_payload must be objects.', 400, 'bad_payload');
}
if ($title !== '') {
$meta['title'] = $title;
}
// Normalise case_doc_ids from the input payload if not provided in meta.
if (empty($meta['case_doc_ids'])) {
$ids = $inputPayload['doc_ids'] ?? [];
$meta['case_doc_ids'] = is_array($ids) ? $ids : [];
}
$ownerId = CaseStore::caseResolveClientId($userId);
$resultId = CaseResults::save($userId, $ownerId, $tool, $inputPayload, $outputPayload, $meta);
if ($resultId <= 0) {
dbnToolsError('Could not save result. Check that your plan supports saved analyses.', 500, 'save_failed');
}
dbnToolsRespond(['ok' => true, 'result_id' => $resultId]);