| # TB-Guard-XAI: Integration Checklist for Detailed Reports | |
| ## CHANGES REQUIRED ACROSS THE SYSTEM | |
| ### 1. **Backend Changes (backend.py)** | |
| #### ✅ ALREADY DONE: | |
| - [x] Accept `report_type` parameter in AnalysisRequest (schemas.py updated) | |
| - [x] Accept patient metadata fields (mrn, patient_name, age, sex, institution) | |
| #### ⚠️ NEEDS TO BE DONE: | |
| - [ ] Pass `report_type` to explainer.explain() | |
| - [ ] Pass `patient_metadata` dict to explainer.explain() | |
| - [ ] Build patient_metadata from request fields | |
| **Code Location:** backend.py line ~430 in `/analyze` endpoint | |
| **Change Required:** | |
| ```python | |
| # Current: | |
| result = explainer.explain( | |
| image_path=image_path, | |
| symptoms=symptoms, | |
| threshold=threshold, | |
| age_group=age_group, | |
| force_offline=force_offline | |
| ) | |
| # Change To: | |
| patient_metadata = { | |
| "mrn": request.mrn, | |
| "name": request.patient_name, | |
| "age": request.age, | |
| "sex": request.sex, | |
| "study_date": datetime.utcnow().isoformat(), | |
| "institution": request.institution, | |
| } | |
| result = explainer.explain( | |
| image_path=image_path, | |
| symptoms=symptoms, | |
| threshold=threshold, | |
| age_group=age_group, | |
| force_offline=force_offline, | |
| patient_metadata=patient_metadata | |
| ) | |
| ``` | |
| --- | |
| ### 2. **Mistral Explainer Changes (mistral_explainer.py)** | |
| #### ✅ ALREADY DONE: | |
| - [x] `generate_offline_explanation()` updated to detailed format | |
| - [x] Accepts `patient_metadata` parameter | |
| - [x] Generates detailed offline reports with 10 sections | |
| - [x] Includes disclaimers, red flags, limitations | |
| #### ⚠️ NEEDS TO BE DONE: | |
| - [ ] Update `generate_explanation()` to pass `report_type` to Mistral | |
| - [ ] Add `report_type` parameter to `explain()` method signature | |
| - [ ] Handle online mode to generate concise reports | |
| **Current Status:** | |
| - Offline: Detailed (10-section) format ✓ | |
| - Online: Still using old 7-section Mistral format | |
| **Change Required:** Online reports should stay 7-section (concise for hospital), but Mistral prompt should respect this. | |
| --- | |
| ### 3. **UI Changes (templates/index.html)** | |
| #### ✅ ALREADY DONE: | |
| - None yet - UI still shows basic form | |
| #### ⚠️ NEEDS TO BE DONE: | |
| - [ ] Add patient metadata form fields: | |
| - [ ] MRN input | |
| - [ ] Patient name input | |
| - [ ] Age input (numeric) | |
| - [ ] Sex dropdown (M/F) | |
| - [ ] Institution name input | |
| - [ ] Add report type selector: | |
| - [ ] Radio button: "Clinical (Hospital)" - Concise format | |
| - [ ] Radio button: "Detailed (Patient)" - Educational format | |
| - [ ] Display patient metadata in report output | |
| - [ ] Format report output based on report_type | |
| **Current:** Shows only basic analysis request form | |
| **Add Form Fields:** | |
| ```html | |
| <!-- Patient Metadata Section --> | |
| <div class="form-section"> | |
| <h3>Patient Information (Optional)</h3> | |
| <input type="text" name="mrn" placeholder="MRN" maxlength="50"> | |
| <input type="text" name="patient_name" placeholder="Patient Name" maxlength="100"> | |
| <input type="number" name="age" placeholder="Age" min="0" max="150"> | |
| <select name="sex"> | |
| <option value="">Sex</option> | |
| <option value="M">Male</option> | |
| <option value="F">Female</option> | |
| <option value="O">Other</option> | |
| </select> | |
| <input type="text" name="institution" placeholder="Hospital/Institution" maxlength="200"> | |
| </div> | |
| <!-- Report Type Selection --> | |
| <div class="form-section"> | |
| <h3>Report Format</h3> | |
| <label> | |
| <input type="radio" name="report_type" value="clinical" checked> | |
| Clinical (Hospital/Concise) | |
| </label> | |
| <label> | |
| <input type="radio" name="report_type" value="detailed"> | |
| Detailed (Patient/Educational) | |
| </label> | |
| </div> | |
| ``` | |
| --- | |
| ### 4. **API Request/Response Changes** | |
| #### Request (POST /analyze): | |
| ```json | |
| { | |
| "file": <binary>, | |
| "symptoms": "persistent cough, fever", | |
| "threshold": 0.5, | |
| "age_group": "Adult (18-64)", | |
| "force_offline": false, | |
| "mrn": "MED-2026-45821", | |
| "patient_name": "Rajesh Kumar", | |
| "age": 48, | |
| "sex": "M", | |
| "institution": "Apollo Hospitals", | |
| "report_type": "detailed" | |
| } | |
| ``` | |
| #### Response (AnalysisResponse): | |
| Same structure, but `clinical_synthesis` field will contain: | |
| - **If report_type="clinical"**: Concise 7-section report (1 page) | |
| - **If report_type="detailed"**: Detailed 10-section report (3-4 pages) | |
| --- | |
| ### 5. **UI Output Display Changes** | |
| #### Current: | |
| Shows just the explanation text in textarea | |
| #### Needs: | |
| - [ ] Display patient metadata at top (if provided) | |
| - [ ] Format report with proper sections and headings | |
| - [ ] Color code important sections (red flags, disclaimers) | |
| - [ ] Render differently for clinical vs detailed format | |
| **Example HTML Structure:** | |
| ```html | |
| <div class="report-output"> | |
| <!-- Patient Header --> | |
| <div class="patient-header"> | |
| <p>MRN: {mrn} | Name: {name} | Age: {age} | Sex: {sex}</p> | |
| <p>Institution: {institution} | Study Date: {study_date}</p> | |
| </div> | |
| <!-- Report Content --> | |
| <div class="report-content"> | |
| <h1>TB-GUARD XAI CLINICAL REPORT</h1> | |
| <!-- Formatted sections --> | |
| </div> | |
| <!-- Red Flags (if detailed format) --> | |
| <div class="red-flags" style="background-color: #ffe6e6;"> | |
| <h3>🚨 When to Seek Immediate Medical Attention</h3> | |
| <!-- Red flags list --> | |
| </div> | |
| </div> | |
| ``` | |
| --- | |
| ### 6. **Schema Updates (schemas.py)** | |
| #### ✅ ALREADY DONE: | |
| - [x] Added `report_type` field to AnalysisRequest | |
| - [x] Added patient metadata fields to AnalysisRequest | |
| #### Status: Complete ✓ | |
| --- | |
| ## IMPLEMENTATION SUMMARY | |
| | Component | Current | Needed | Status | | |
| |-----------|---------|--------|--------| | |
| | **Backend** | Accepts basic params | Pass report_type + metadata | ⚠️ 50% | | |
| | **Mistral Explainer** | Detailed offline format | Already done | ✅ 100% | | |
| | **UI Form** | Basic fields only | Add metadata + report type | ⚠️ 0% | | |
| | **UI Output** | Text only | Formatted sections | ⚠️ 0% | | |
| | **Schemas** | Basic fields | Updated with new fields | ✅ 100% | | |
| | **API Contract** | Minimal | Extended | ✅ 100% | | |
| --- | |
| ## QUICK IMPLEMENTATION GUIDE | |
| ### Step 1: Backend (15 min) | |
| In `backend.py` line ~430, modify `/analyze` endpoint: | |
| ```python | |
| # Build patient metadata dict | |
| patient_metadata = { | |
| "mrn": getattr(request, 'mrn', None), | |
| "name": getattr(request, 'patient_name', None), | |
| "age": getattr(request, 'age', None), | |
| "sex": getattr(request, 'sex', None), | |
| "study_date": datetime.utcnow().isoformat(), | |
| "institution": getattr(request, 'institution', None), | |
| } | |
| # Pass to explainer | |
| result = explainer.explain( | |
| image_path=image_path, | |
| symptoms=symptoms, | |
| threshold=threshold, | |
| age_group=age_group, | |
| force_offline=force_offline, | |
| patient_metadata=patient_metadata | |
| ) | |
| ``` | |
| ### Step 2: UI Form (20 min) | |
| In `templates/index.html`, add after current form fields: | |
| ```html | |
| <!-- Patient Metadata --> | |
| <div id="patient-section"> | |
| <h3>Patient Information (Optional)</h3> | |
| <input type="text" id="mrn" placeholder="MRN" maxlength="50"> | |
| <input type="text" id="patient_name" placeholder="Patient Name" maxlength="100"> | |
| <input type="number" id="age" placeholder="Age" min="0" max="150"> | |
| <select id="sex"> | |
| <option value="">Sex</option> | |
| <option value="M">Male</option> | |
| <option value="F">Female</option> | |
| </select> | |
| <input type="text" id="institution" placeholder="Institution" maxlength="200"> | |
| </div> | |
| <!-- Report Type --> | |
| <div id="report-type-section"> | |
| <h3>Report Format</h3> | |
| <label><input type="radio" name="report_type" value="clinical" checked> Clinical (Concise)</label> | |
| <label><input type="radio" name="report_type" value="detailed"> Detailed (Educational)</label> | |
| </div> | |
| ``` | |
| ### Step 3: UI JavaScript (15 min) | |
| Update form submission to include new fields: | |
| ```javascript | |
| const formData = new FormData(); | |
| formData.append('file', file); | |
| formData.append('symptoms', document.getElementById('symptoms').value); | |
| formData.append('mrn', document.getElementById('mrn').value); | |
| formData.append('patient_name', document.getElementById('patient_name').value); | |
| formData.append('age', document.getElementById('age').value); | |
| formData.append('sex', document.getElementById('sex').value); | |
| formData.append('institution', document.getElementById('institution').value); | |
| formData.append('report_type', document.querySelector('input[name="report_type"]:checked').value); | |
| // Send to backend | |
| const response = await fetch('/analyze', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| ``` | |
| ### Step 4: UI Output Display (20 min) | |
| Format report output: | |
| ```javascript | |
| // In response handler | |
| const report = response.clinical_synthesis; | |
| // Display patient info if available | |
| if (response.patient_metadata) { | |
| const patientInfo = ` | |
| <div class="patient-header"> | |
| <p>MRN: ${response.patient_metadata.mrn} | Name: ${response.patient_metadata.name}</p> | |
| </div> | |
| `; | |
| document.getElementById('output').innerHTML = patientInfo + report; | |
| } else { | |
| document.getElementById('output').innerHTML = report; | |
| } | |
| // Style based on report_type | |
| if (response.report_type === 'detailed') { | |
| document.getElementById('output').classList.add('detailed-report'); | |
| } else { | |
| document.getElementById('output').classList.add('clinical-report'); | |
| } | |
| ``` | |
| --- | |
| ## TOTAL WORK ESTIMATE | |
| | Task | Time | Priority | | |
| |------|------|----------| | |
| | Backend integration | 15 min | HIGH | | |
| | UI form fields | 20 min | HIGH | | |
| | UI JavaScript | 15 min | HIGH | | |
| | UI output formatting | 20 min | MEDIUM | | |
| | Testing | 30 min | HIGH | | |
| | **TOTAL** | **100 min** | - | | |
| --- | |
| ## CURRENT STATE | |
| ✅ **Backend ready** (schemas + explainer) | |
| ✅ **Report templates ready** (detailed offline format) | |
| ⚠️ **UI needs update** (form + output display) | |
| **Next Steps:** | |
| 1. Update `templates/index.html` with patient metadata fields | |
| 2. Update form submission JavaScript | |
| 3. Update output display formatting | |
| 4. Test with both clinical and detailed report types | |
| 5. Verify metadata appears in reports | |
| **Estimated completion: 2 hours of UI work** | |