nusaibah0110 commited on
Commit
6d41c34
·
1 Parent(s): c6fefb4

fix: use structured report_json and show on-page autofill status

Browse files
Files changed (2) hide show
  1. backend/app.py +2 -1
  2. src/pages/ReportPage.tsx +29 -2
backend/app.py CHANGED
@@ -411,7 +411,8 @@ Do NOT include any other keys. Do NOT wrap in markdown. Return raw JSON only."""
411
  # Return as JSON object (not string) so it's properly encoded by FastAPI
412
  return JSONResponse({
413
  "status": "success",
414
- "report": cleaned_text, # Return the cleaned JSON string
 
415
  "model": used_model
416
  })
417
  except json.JSONDecodeError as je:
 
411
  # Return as JSON object (not string) so it's properly encoded by FastAPI
412
  return JSONResponse({
413
  "status": "success",
414
+ "report": cleaned_text, # Backward-compatible JSON string
415
+ "report_json": parsed_json, # Structured payload for robust frontend mapping
416
  "model": used_model
417
  })
418
  except json.JSONDecodeError as je:
src/pages/ReportPage.tsx CHANGED
@@ -79,6 +79,7 @@ export function ReportPage({
79
  const [showCompletionModal, setShowCompletionModal] = useState(false);
80
  const [isGenerating, setIsGenerating] = useState(false);
81
  const [aiError, setAiError] = useState<string | null>(null);
 
82
  const imageBucketsRef = useRef(imageBuckets);
83
  const reportContentRef = useRef<HTMLDivElement>(null);
84
  const patientId = sessionStore.get().patientInfo?.id;
@@ -156,6 +157,7 @@ export function ReportPage({
156
  const generateWithAI = async () => {
157
  setIsGenerating(true);
158
  setAiError(null);
 
159
 
160
  try {
161
  const session = sessionStore.get();
@@ -206,6 +208,27 @@ export function ReportPage({
206
  throw new Error('Invalid response from backend');
207
  }
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  // Get the report text - it should be a JSON string
210
  let reportText: string = String(data.report).trim();
211
  let parsed: Record<string, string> = {};
@@ -311,14 +334,15 @@ export function ReportPage({
311
  // Show success feedback
312
  if (missingKeys.length === 0) {
313
  setAiError(null);
 
314
  } else {
315
- setAiError(`Report generated! Some fields were missing: ${missingKeys.join(', ')}`);
316
  }
317
 
318
  } catch (err: any) {
319
  console.error('Gemini error:', err);
320
  const msg = err?.message || err?.toString() || 'Unknown error';
321
- setAiError(`AI generation failed: ${msg}. Please check the console logs for details.`);
322
  } finally {
323
  setIsGenerating(false);
324
  }
@@ -568,6 +592,9 @@ export function ReportPage({
568
  {aiError && (
569
  <p className="text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg px-3 py-2">{aiError}</p>
570
  )}
 
 
 
571
  </div>
572
  </div>
573
  </div>
 
79
  const [showCompletionModal, setShowCompletionModal] = useState(false);
80
  const [isGenerating, setIsGenerating] = useState(false);
81
  const [aiError, setAiError] = useState<string | null>(null);
82
+ const [aiStatus, setAiStatus] = useState<string | null>(null);
83
  const imageBucketsRef = useRef(imageBuckets);
84
  const reportContentRef = useRef<HTMLDivElement>(null);
85
  const patientId = sessionStore.get().patientInfo?.id;
 
157
  const generateWithAI = async () => {
158
  setIsGenerating(true);
159
  setAiError(null);
160
+ setAiStatus(null);
161
 
162
  try {
163
  const session = sessionStore.get();
 
208
  throw new Error('Invalid response from backend');
209
  }
210
 
211
+ // Prefer structured JSON from backend when available.
212
+ if (data.report_json && typeof data.report_json === 'object') {
213
+ const parsed = data.report_json as Record<string, string>;
214
+ const updatedFormData = {
215
+ examQuality: String(parsed.examQuality || '').trim(),
216
+ transformationZone: String(parsed.transformationZone || '').trim(),
217
+ acetowL: String(parsed.acetowL || '').trim(),
218
+ nativeFindings: String(parsed.nativeFindings || '').trim(),
219
+ aceticFindings: String(parsed.aceticFindings || '').trim(),
220
+ colposcopicFindings: String(parsed.colposcopicFindings || '').trim(),
221
+ treatmentPlan: String(parsed.treatmentPlan || '').trim(),
222
+ followUp: String(parsed.followUp || '').trim(),
223
+ biopsySites: String(parsed.biopsySites || '').trim(),
224
+ biopsyNotes: String(parsed.biopsyNotes || '').trim(),
225
+ };
226
+
227
+ setFormData(prev => ({ ...prev, ...updatedFormData }));
228
+ setAiStatus('Report generated and fields auto-filled successfully.');
229
+ return;
230
+ }
231
+
232
  // Get the report text - it should be a JSON string
233
  let reportText: string = String(data.report).trim();
234
  let parsed: Record<string, string> = {};
 
334
  // Show success feedback
335
  if (missingKeys.length === 0) {
336
  setAiError(null);
337
+ setAiStatus('Report generated and fields auto-filled successfully.');
338
  } else {
339
+ setAiStatus(`Report generated. Some fields were missing: ${missingKeys.join(', ')}`);
340
  }
341
 
342
  } catch (err: any) {
343
  console.error('Gemini error:', err);
344
  const msg = err?.message || err?.toString() || 'Unknown error';
345
+ setAiError(`AI generation failed: ${msg}`);
346
  } finally {
347
  setIsGenerating(false);
348
  }
 
592
  {aiError && (
593
  <p className="text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg px-3 py-2">{aiError}</p>
594
  )}
595
+ {aiStatus && !aiError && (
596
+ <p className="text-sm text-green-700 bg-green-50 border border-green-200 rounded-lg px-3 py-2">{aiStatus}</p>
597
+ )}
598
  </div>
599
  </div>
600
  </div>