'; echo '

400 — Invalid Document ID

'; return; } $docModel = new Document(); $document = $docModel->findById($docId); if ($document === null) { http_response_code(404); echo 'Not Found'; echo '

404 — Document Not Found

'; return; } // Page metadata (not full text) $pageModel = new Page(); $pages = $pageModel->getByDocument($docId); // Entity summary: count by entity type for this document $db = Database::getInstance(); $entities = []; try { $entities = $db->fetchAll( 'SELECT entity_type, COUNT(*)::int AS entity_count, array_agg(DISTINCT entity_text ORDER BY entity_text) AS examples FROM entities WHERE document_id = :docId GROUP BY entity_type ORDER BY entity_count DESC', ['docId' => $docId] ); } catch (\PDOException $e) { // Entities table may be empty or not fully populated } // Crisis events for this document $crisisEvents = []; try { $eventModel = new Event(); $crisisEvents = $eventModel->getForDocument($docId); } catch (\PDOException $e) { // Table may not exist yet } // Topic classifications $topics = []; try { $topics = $db->fetchAll( "SELECT feature_json FROM document_features WHERE document_id = :docId AND feature_name = 'topic_distribution'", ['docId' => $docId] ); if (!empty($topics[0]['feature_json'])) { $topicData = json_decode($topics[0]['feature_json'], true) ?: []; arsort($topicData); $topics = $topicData; } else { $topics = []; } } catch (\PDOException $e) { $topics = []; } // Keywords $keywords = []; try { $keywords = $db->fetchAll( 'SELECT keyword, score FROM document_keywords WHERE document_id = :docId AND keyword != :placeholder ORDER BY score DESC LIMIT 15', ['docId' => $docId, 'placeholder' => '_no_keywords_'] ); } catch (\PDOException $e) { $keywords = []; } // Forensic metadata, redaction summary, sentiment $forensic = []; $redactionSummary = null; $sentiment = null; try { $forensicRows = $db->fetchAll( "SELECT feature_name, feature_json FROM document_features WHERE document_id = :docId AND feature_name IN ('forensic_metadata', 'redaction_summary', 'sentiment')", ['docId' => $docId] ); foreach ($forensicRows as $row) { if ($row['feature_name'] === 'forensic_metadata') { $forensic = json_decode($row['feature_json'], true) ?: []; } elseif ($row['feature_name'] === 'redaction_summary') { $redactionSummary = json_decode($row['feature_json'], true) ?: []; } elseif ($row['feature_name'] === 'sentiment') { $sentiment = json_decode($row['feature_json'], true) ?: []; } } } catch (\PDOException $e) { // Not available yet } // PDF viewer URL $pdfUrl = '/pdf/' . $docId; $viewerUrl = '/assets/vendor/pdfjs/web/viewer.html?file=' . urlencode($pdfUrl); require __DIR__ . '/../views/document.php'; } }