diff --git a/server/src/routes/user_web.rs b/server/src/routes/user_web.rs index 17bcd35..0d31bf4 100644 --- a/server/src/routes/user_web.rs +++ b/server/src/routes/user_web.rs @@ -346,6 +346,12 @@ struct CasePageTemplate { /// Session CSRF token — rendered as a hidden field into every /// state-changing form on the page (close/reopen/analyze/reset/logout). csrf_token: String, + /// Admin-only debug copy bundle, pre-serialised as JSON for inline + /// embedding into a `` breakout via `<\/` substitution. + debug_copy_json: String, } #[derive(Template)] @@ -631,9 +637,12 @@ pub async fn handle_case_page( // Read document first; if it's on disk we display it regardless of what // the `analyzing` flag would otherwise say. Resolves the narrow race // where the worker finishes between flag check and template render. - let document_html = read_document(&case_dir) - .await - .map(|md| crate::analyze::render::md_to_html(&md)); + // Keep the raw markdown around for the admin debug-copy bundle so we + // don't pay a second filesystem read. + let document_md = read_document(&case_dir).await; + let document_html = document_md + .as_deref() + .map(crate::analyze::render::md_to_html); let recordings = scan_recordings(&case_dir).await; let (oneliner, oneliner_is_manual) = compute_oneliner_display(&case_dir, &recordings).await; @@ -658,6 +667,27 @@ pub async fn handle_case_page( let is_closed = crate::paths::is_closed(&case_dir).await; + // Admin debug-copy payload — only built when the viewer is an admin + // so non-admin renders skip the JSON serialisation entirely. + let debug_copy_json = if is_admin { + let transcripts: Vec<&str> = recordings + .iter() + .filter_map(|r| r.transcript.as_content()) + .collect(); + let payload = serde_json::json!({ + "transcripts": transcripts, + "document": document_md, + }); + // `` element; the inline JSON block + // would otherwise be vulnerable if a transcript or the document + // ever contained a literal ``. + serde_json::to_string(&payload) + .unwrap_or_else(|_| "{}".to_owned()) + .replace(" + + {% endif %} @@ -604,5 +613,48 @@ + {% if is_admin %} + + {% endif %}