25 * 1024 * 1024) { dbnToolsError('Filen må være mellom 1 byte og 25 MB.', 413, 'bad_size'); } // Validate it's actually a PDF (magic number check) $fh = @fopen($tmp, 'rb'); if ($fh === false) { dbnToolsError('Kunne ikke lese filen.', 500, 'read_fail'); } $head = (string)fread($fh, 5); fclose($fh); if (strncmp($head, '%PDF-', 5) !== 0) { dbnToolsError('Filen er ikke en gyldig PDF.', 415, 'not_pdf'); } try { $doc = CaseStore::registerUpload($userId, $name, $tmp, $size); CaseStore::caseEnqueueIngest((int)$doc['doc_id'], $userId); } catch (Throwable $e) { dbnToolsError($e->getMessage(), 400, 'upload_failed'); } // Dual-write to CaveauAI corpus (best-effort — never fails the upload) $caveauDocId = null; $clientId = (int)($_SESSION['dbn_tools_client_id'] ?? 0); if ($clientId > 0 && !empty($doc['storage_path'])) { try { dbnToolsBootCaveau(); $aiPortalRoot = dbnToolsAiPortalRoot(); $textExtractFile = $aiPortalRoot . '/platform/includes/text_extract.php'; if (is_file($textExtractFile)) { require_once $textExtractFile; $content = extractPdfText($doc['storage_path']); if ($content !== '' && strlen($content) > 30) { $caveauDb = getDb(); $corpusSt = $caveauDb->prepare( 'SELECT id FROM client_corpora WHERE client_id = ? AND is_default = 1 LIMIT 1' ); $corpusSt->execute([$clientId]); $corpusId = (int)($corpusSt->fetchColumn() ?: 0); if ($corpusId > 0) { $title = pathinfo($doc['filename'], PATHINFO_FILENAME); $caveauDb->prepare(" INSERT INTO client_documents (client_id, corpus_id, title, source_type, content, category, import_method, word_count, status) VALUES (?, ?, ?, 'pdf', ?, 'user-upload', 'dbn_upload', ?, 'pending') ")->execute([$clientId, $corpusId, $title, $content, str_word_count($content)]); $caveauDocId = (int)$caveauDb->lastInsertId(); $rag = new ClientRagPipeline($clientId); $rag->ingestDocument($caveauDocId); } } } } catch (Throwable $e) { // Non-fatal: log and continue error_log('[upload] CaveauAI dual-write failed for doc ' . ($doc['doc_id'] ?? '?') . ': ' . $e->getMessage()); } } dbnToolsRespond([ 'ok' => true, 'doc_id' => $doc['doc_id'], 'filename' => $doc['filename'], 'caveau_doc_id' => $caveauDocId, ]);