Add read-only production runtime audit

This commit is contained in:
2026-08-17 11:17:40 +07:00
parent 057d4ed9dc
commit a1de4715a4
106 changed files with 6869 additions and 1782 deletions
+24 -1
View File
@@ -1,7 +1,7 @@
"use client";
import { useEffect, useState } from "react";
import type { ChatMessage, Citation } from "@duoc-thu/shared-types";
import type { ChatMessage, Citation, MonographPickerState } from "@duoc-thu/shared-types";
import { ChatPanel } from "./_components/ChatPanel";
import { Sidebar, ChatSession } from "./_components/Sidebar";
import { EvidencePanel } from "./_components/EvidencePanel";
@@ -39,6 +39,7 @@ export default function ChatPage() {
const [currentSessionId, setCurrentSessionId] = useState<string>("");
const [messagesBySession, setMessagesBySession] = useState<Record<string, ChatMessage[]>>({});
const [queryOverride, setQueryOverride] = useState<{ text: string; token: number } | null>(null);
const [monographPicker, setMonographPicker] = useState<MonographPickerState | null>(null);
useEffect(() => {
const stored = loadStoredSessions();
@@ -106,6 +107,7 @@ export default function ChatPage() {
setQueryOverride(null);
setCitations([]);
setActiveCitationIndex(null);
setMonographPicker(null);
setShowMobileSidebar(false);
};
@@ -114,6 +116,7 @@ export default function ChatPage() {
setQueryOverride(null);
setCitations([]);
setActiveCitationIndex(null);
setMonographPicker(null);
setShowMobileSidebar(false);
};
@@ -162,6 +165,7 @@ export default function ChatPage() {
// must replace the panel's state, not just the index into a stale one.
setCitations(allCitations);
setActiveCitationIndex(index);
setMonographPicker(null);
setShowMobileEvidence(true);
};
@@ -179,6 +183,16 @@ export default function ChatPage() {
// coordinates are computed fresh.
};
const handleToggleSection = (sectionKey: string) => {
setMonographPicker((current) => {
if (!current) return current;
const selected = current.selectedSectionKeys.includes(sectionKey)
? current.selectedSectionKeys.filter((key) => key !== sectionKey)
: [...current.selectedSectionKeys, sectionKey];
return { ...current, selectedSectionKeys: selected };
});
};
return (
<div className="flex flex-1 w-full h-[calc(100vh-6.5rem)] overflow-hidden bg-app relative">
{/* Mobile Header Bar Controls */}
@@ -210,6 +224,7 @@ export default function ChatPage() {
onNewChat={handleNewChat}
onDeleteSession={handleDeleteSession}
onQuickQuery={handleQuickQuery}
historyRefreshKey={currentMessages.length}
className="hidden lg:flex"
/>
@@ -228,6 +243,7 @@ export default function ChatPage() {
onNewChat={handleNewChat}
onDeleteSession={handleDeleteSession}
onQuickQuery={handleQuickQuery}
historyRefreshKey={currentMessages.length}
className="w-full h-full border-r-0"
/>
</div>
@@ -246,6 +262,9 @@ export default function ChatPage() {
onCitationClick={handleCitationClick}
onCitationsLoaded={handleCitationsLoaded}
activeCitationIndex={activeCitationIndex}
monographPicker={monographPicker}
onMonographChange={setMonographPicker}
onToggleSection={handleToggleSection}
className="w-full max-w-4xl h-full"
/>
</main>
@@ -256,6 +275,8 @@ export default function ChatPage() {
citations={citations}
activeCitationIndex={activeCitationIndex}
onSelectCitation={(citation, index) => setActiveCitationIndex(index)}
monographPicker={monographPicker}
onToggleSection={handleToggleSection}
onClose={() => setShowEvidenceDesktop(false)}
className="hidden lg:flex"
/>
@@ -275,6 +296,8 @@ export default function ChatPage() {
onSelectCitation={(citation, index) => {
setActiveCitationIndex(index);
}}
monographPicker={monographPicker}
onToggleSection={handleToggleSection}
onClose={() => setShowMobileEvidence(false)}
className="w-full h-full border-l-0"
/>