Spaces:
Sleeping
Sleeping
File size: 20,480 Bytes
c4f38f8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | [1mdiff --git a/EMAIL_SETUP_GUIDE.md b/EMAIL_SETUP_GUIDE.md[m
[1mdeleted file mode 100644[m
[1mindex f22eac2..0000000[m
[1m--- a/EMAIL_SETUP_GUIDE.md[m
[1m+++ /dev/null[m
[36m@@ -1,137 +0,0 @@[m
[31m-# π§ Gmail Email Setup Guide[m
[31m-[m
[31m-This guide will help you set up Gmail SMTP for the password reset functionality.[m
[31m-[m
[31m-## π What You Need[m
[31m-[m
[31m-1. **Gmail Email Address** (your username)[m
[31m-2. **Gmail App Password** (16-character password)[m
[31m-[m
[31m-## π Step-by-Step Setup[m
[31m-[m
[31m-### Step 1: Get Your Gmail Username[m
[31m-- Your Gmail username is your Gmail email address[m
[31m-- **Example**: `john.doe@gmail.com`[m
[31m-[m
[31m-### Step 2: Create Gmail App Password[m
[31m-[m
[31m-#### 2.1 Enable 2-Step Verification[m
[31m-1. Go to: https://myaccount.google.com/security[m
[31m-2. Sign in with your Gmail account[m
[31m-3. Find "2-Step Verification" and click "Get started"[m
[31m-4. Follow the setup process (usually involves your phone)[m
[31m-[m
[31m-#### 2.2 Generate App Password[m
[31m-1. After enabling 2-Step Verification, go back to: https://myaccount.google.com/security[m
[31m-2. Scroll down and find "App passwords"[m
[31m-3. Click on "App passwords"[m
[31m-4. Select "Mail" as the app[m
[31m-5. Select "Other (Custom name)" as the device[m
[31m-6. Enter a name like "CPS Password Reset"[m
[31m-7. Click "Generate"[m
[31m-8. **Copy the 16-character password** (remove spaces)[m
[31m-[m
[31m-**Example App Password**: `abcd efgh ijkl mnop` β `abcdefghijklmnop`[m
[31m-[m
[31m-### Step 3: Configure Environment Variables[m
[31m-[m
[31m-#### Option A: Create .env file (Recommended)[m
[31m-Create a file named `.env` in the `cps-api-tx` directory:[m
[31m-[m
[31m-```bash[m
[31m-# Database Configuration[m
[31m-MONGODB_URL=mongodb://localhost:27017/cps_db[m
[31m-[m
[31m-# JWT Configuration[m
[31m-SECRET_KEY=your-secret-key-here[m
[31m-ALGORITHM=HS256[m
[31m-ACCESS_TOKEN_EXPIRE_MINUTES=30[m
[31m-[m
[31m-# Email Configuration (REPLACE WITH YOUR ACTUAL VALUES)[m
[31m-MAIL_USERNAME=your-email@gmail.com[m
[31m-MAIL_PASSWORD=your-16-character-app-password[m
[31m-MAIL_FROM=your-email@gmail.com[m
[31m-[m
[31m-# TxAgent Configuration[m
[31m-TXAGENT_MODE=cloud[m
[31m-TXAGENT_CLOUD_URL=https://rocketfarmstudios-txagent-api.hf.space[m
[31m-TXAGENT_LOCAL_ENABLED=false[m
[31m-[m
[31m-# CORS Configuration[m
[31m-ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8081[m
[31m-```[m
[31m-[m
[31m-#### Option B: Set Environment Variables in Terminal[m
[31m-[m
[31m-**Windows (PowerShell)**:[m
[31m-```powershell[m
[31m-$env:MAIL_USERNAME="your-email@gmail.com"[m
[31m-$env:MAIL_PASSWORD="your-16-character-app-password"[m
[31m-$env:MAIL_FROM="your-email@gmail.com"[m
[31m-```[m
[31m-[m
[31m-**Windows (Command Prompt)**:[m
[31m-```cmd[m
[31m-set MAIL_USERNAME=your-email@gmail.com[m
[31m-set MAIL_PASSWORD=your-16-character-app-password[m
[31m-set MAIL_FROM=your-email@gmail.com[m
[31m-```[m
[31m-[m
[31m-**Linux/Mac**:[m
[31m-```bash[m
[31m-export MAIL_USERNAME="your-email@gmail.com"[m
[31m-export MAIL_PASSWORD="your-16-character-app-password"[m
[31m-export MAIL_FROM="your-email@gmail.com"[m
[31m-```[m
[31m-[m
[31m-### Step 4: Test Your Configuration[m
[31m-[m
[31m-Run the test script to verify your setup:[m
[31m-[m
[31m-```bash[m
[31m-cd cps-api-tx[m
[31m-python test_email_config.py[m
[31m-```[m
[31m-[m
[31m-## π Troubleshooting[m
[31m-[m
[31m-### Common Issues:[m
[31m-[m
[31m-1. **"Username and Password not accepted"**[m
[31m- - Make sure you're using an App Password, not your regular Gmail password[m
[31m- - Ensure 2-Step Verification is enabled[m
[31m- - Check that the App Password is exactly 16 characters (no spaces)[m
[31m-[m
[31m-2. **"App passwords not available"**[m
[31m- - 2-Step Verification must be enabled first[m
[31m- - Wait a few minutes after enabling 2-Step Verification[m
[31m-[m
[31m-3. **"SMTP connection failed"**[m
[31m- - Check your internet connection[m
[31m- - Ensure Gmail SMTP is not blocked by firewall[m
[31m- - Try using port 587 (should be automatic)[m
[31m-[m
[31m-### Security Notes:[m
[31m-[m
[31m-- β
**App Passwords are secure** - they can only be used for the specific app[m
[31m-- β
**You can revoke App Passwords** anytime from Google Account settings[m
[31m-- β
**App Passwords don't expire** unless you change your main password[m
[31m-- β **Never share your App Password** with anyone[m
[31m-- β **Don't commit .env files** to version control[m
[31m-[m
[31m-## π Need Help?[m
[31m-[m
[31m-If you're still having issues:[m
[31m-[m
[31m-1. **Check Google Account Activity**: https://myaccount.google.com/notifications[m
[31m-2. **Review App Passwords**: https://myaccount.google.com/apppasswords[m
[31m-3. **Google Account Help**: https://support.google.com/accounts[m
[31m-[m
[31m-## β
Verification Checklist[m
[31m-[m
[31m-- [ ] 2-Step Verification enabled[m
[31m-- [ ] App Password generated for "Mail"[m
[31m-- [ ] 16-character App Password copied (no spaces)[m
[31m-- [ ] Environment variables set correctly[m
[31m-- [ ] Test script runs successfully[m
[31m-- [ ] Test email received in inbox[m
[1mdiff --git a/ENHANCED_APPOINTMENT_GUIDE.md b/ENHANCED_APPOINTMENT_GUIDE.md[m
[1mdeleted file mode 100644[m
[1mindex 8b13789..0000000[m
[1m--- a/ENHANCED_APPOINTMENT_GUIDE.md[m
[1m+++ /dev/null[m
[36m@@ -1 +0,0 @@[m
[31m-[m
[1mdiff --git a/PASSWORD_RESET_SETUP.md b/PASSWORD_RESET_SETUP.md[m
[1mdeleted file mode 100644[m
[1mindex 543b3ef..0000000[m
[1m--- a/PASSWORD_RESET_SETUP.md[m
[1m+++ /dev/null[m
[36m@@ -1,122 +0,0 @@[m
[31m-# Password Reset Setup Guide[m
[31m-[m
[31m-This guide explains how to set up the password reset functionality with email verification.[m
[31m-[m
[31m-## Email Configuration[m
[31m-[m
[31m-The password reset feature uses Gmail SMTP to send verification codes. You need to configure the following environment variables:[m
[31m-[m
[31m-### 1. Create a Gmail App Password[m
[31m-[m
[31m-1. Go to your Google Account settings[m
[31m-2. Navigate to Security > 2-Step Verification[m
[31m-3. Create an App Password for your application[m
[31m-4. Use this app password instead of your regular Gmail password[m
[31m-[m
[31m-### 2. Environment Variables[m
[31m-[m
[31m-Add these variables to your `.env` file or environment:[m
[31m-[m
[31m-```bash[m
[31m-# Email Configuration[m
[31m-MAIL_USERNAME=your-email@gmail.com[m
[31m-MAIL_PASSWORD=your-app-password-here[m
[31m-MAIL_FROM=your-email@gmail.com[m
[31m-```[m
[31m-[m
[31m-### 3. Install Dependencies[m
[31m-[m
[31m-Make sure you have the required packages installed:[m
[31m-[m
[31m-```bash[m
[31m-pip install fastapi-mail jinja2[m
[31m-```[m
[31m-[m
[31m-## API Endpoints[m
[31m-[m
[31m-The password reset functionality provides three endpoints:[m
[31m-[m
[31m-### 1. Request Password Reset[m
[31m-```[m
[31m-POST /auth/forgot-password[m
[31m-Content-Type: application/json[m
[31m-[m
[31m-{[m
[31m- "email": "user@example.com"[m
[31m-}[m
[31m-```[m
[31m-[m
[31m-### 2. Verify Reset Code[m
[31m-```[m
[31m-POST /auth/verify-reset-code[m
[31m-Content-Type: application/json[m
[31m-[m
[31m-{[m
[31m- "email": "user@example.com",[m
[31m- "verification_code": "123456"[m
[31m-}[m
[31m-```[m
[31m-[m
[31m-### 3. Reset Password[m
[31m-```[m
[31m-POST /auth/reset-password[m
[31m-Content-Type: application/json[m
[31m-[m
[31m-{[m
[31m- "email": "user@example.com",[m
[31m- "verification_code": "123456",[m
[31m- "new_password": "newpassword123"[m
[31m-}[m
[31m-```[m
[31m-[m
[31m-## Security Features[m
[31m-[m
[31m-- **6-digit verification codes** with 15-minute expiration[m
[31m-- **One-time use codes** - each code can only be used once[m
[31m-- **Email validation** - checks if the email exists before sending[m
[31m-- **Password validation** - minimum 6 characters required[m
[31m-- **Secure email templates** with professional styling[m
[31m-[m
[31m-## Frontend Integration[m
[31m-[m
[31m-### Web App (React)[m
[31m-The web app includes a complete password reset flow with:[m
[31m-- 3-step wizard interface[m
[31m-- Real-time validation[m
[31m-- Progress indicators[m
[31m-- Error handling[m
[31m-[m
[31m-### Mobile App (React Native)[m
[31m-The mobile app includes:[m
[31m-- Native password reset screen[m
[31m-- Progress bar and step indicators[m
[31m-- Snackbar notifications[m
[31m-- Keyboard-aware interface[m
[31m-[m
[31m-## Testing[m
[31m-[m
[31m-1. Start the backend server[m
[31m-2. Configure email settings[m
[31m-3. Test the password reset flow:[m
[31m- - Request reset for existing email[m
[31m- - Check email for verification code[m
[31m- - Verify code[m
[31m- - Set new password[m
[31m- - Sign in with new password[m
[31m-[m
[31m-## Troubleshooting[m
[31m-[m
[31m-### Email Not Sending[m
[31m-- Check Gmail app password configuration[m
[31m-- Verify SMTP settings[m
[31m-- Check firewall/network restrictions[m
[31m-[m
[31m-### Verification Code Issues[m
[31m-- Codes expire after 15 minutes[m
[31m-- Each code can only be used once[m
[31m-- Check database connection for code storage[m
[31m-[m
[31m-### Frontend Issues[m
[31m-- Verify API endpoint URLs[m
[31m-- Check CORS configuration[m
[31m-- Ensure proper error handling[m
[1mdiff --git a/api/routes/auth.py b/api/routes/auth.py[m
[1mindex 334e365..a44b00e 100644[m
[1m--- a/api/routes/auth.py[m
[1m+++ b/api/routes/auth.py[m
[36m@@ -107,7 +107,7 @@[m [masync def create_doctor([m
"license_number": data.license_number,[m
"created_at": datetime.utcnow().isoformat(),[m
"updated_at": datetime.utcnow().isoformat(),[m
[31m- "device_token": data.device_token or ""[m
[32m+[m[32m "device_token": "" # Default empty device token for doctors[m
}[m
[m
try:[m
[1mdiff --git a/check_database.py b/check_database.py[m
[1mdeleted file mode 100644[m
[1mindex e88aad6..0000000[m
[1m--- a/check_database.py[m
[1m+++ /dev/null[m
[36m@@ -1,98 +0,0 @@[m
[31m-#!/usr/bin/env python3[m
[31m-"""[m
[31m-Check database directly to see analysis data[m
[31m-"""[m
[31m-[m
[31m-import asyncio[m
[31m-import motor.motor_asyncio[m
[31m-import os[m
[31m-from datetime import datetime[m
[31m-[m
[31m-async def check_database():[m
[31m- """Check database directly for analysis data"""[m
[31m- [m
[31m- print("π Checking Database Directly")[m
[31m- print("=" * 50)[m
[31m- print(f"β° Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")[m
[31m- print()[m
[31m- [m
[31m- try:[m
[31m- # Connect to MongoDB[m
[31m- mongo_url = os.getenv('MONGODB_URL', 'mongodb://localhost:27017')[m
[31m- client = motor.motor_asyncio.AsyncIOMotorClient(mongo_url)[m
[31m- db = client.cps_database[m
[31m- [m
[31m- # Check patients collection[m
[31m- print("π Checking patients collection...")[m
[31m- patients_count = await db.patients.count_documents({})[m
[31m- print(f" β
Found {patients_count} patients")[m
[31m- [m
[31m- if patients_count > 0:[m
[31m- # Show sample patients[m
[31m- patients = await db.patients.find({}).limit(3).to_list(length=3)[m
[31m- print("\nπ Sample Patients:")[m
[31m- for i, patient in enumerate(patients):[m
[31m- print(f" Patient {i+1}: {patient.get('full_name', 'Unknown')}")[m
[31m- print(f" - ID: {patient.get('fhir_id', 'No ID')}")[m
[31m- print(f" - Email: {patient.get('email', 'No email')}")[m
[31m- print()[m
[31m- [m
[31m- # Check analysis collection[m
[31m- print("π Checking analysis collection...")[m
[31m- analysis_count = await db.patient_analysis_results.count_documents({})[m
[31m- print(f" β
Found {analysis_count} analysis results")[m
[31m- [m
[31m- if analysis_count > 0:[m
[31m- # Show sample analysis results[m
[31m- analyses = await db.patient_analysis_results.find({}).limit(3).to_list(length=3)[m
[31m- print("\nπ Sample Analysis Results:")[m
[31m- for i, analysis in enumerate(analyses):[m
[31m- print(f" Analysis {i+1}:")[m
[31m- print(f" - Patient ID: {analysis.get('patient_id', 'No ID')}")[m
[31m- print(f" - Timestamp: {analysis.get('timestamp', 'No timestamp')}")[m
[31m- [m
[31m- # Check suicide risk data[m
[31m- suicide_risk = analysis.get('suicide_risk', {})[m
[31m- if isinstance(suicide_risk, dict):[m
[31m- risk_level = suicide_risk.get('level', 'No level')[m
[31m- risk_score = suicide_risk.get('score', 0.0)[m
[31m- risk_factors = suicide_risk.get('factors', [])[m
[31m- print(f" - Risk Level: {risk_level}")[m
[31m- print(f" - Risk Score: {risk_score}")[m
[31m- print(f" - Risk Factors: {risk_factors}")[m
[31m- else:[m
[31m- print(f" - Suicide Risk: {suicide_risk}")[m
[31m- [m
[31m- # Check summary[m
[31m- summary = analysis.get('summary', '')[m
[31m- if summary:[m
[31m- print(f" - Summary: {summary[:100]}...")[m
[31m- print()[m
[31m- [m
[31m- # Check if there are any patients without analysis[m
[31m- if patients_count > 0 and analysis_count > 0:[m
[31m- print("π Checking for patients without analysis...")[m
[31m- patients_with_analysis = await db.patient_analysis_results.distinct('patient_id')[m
[31m- patients_without_analysis = patients_count - len(patients_with_analysis)[m
[31m- print(f" π Patients with analysis: {len(patients_with_analysis)}")[m
[31m- print(f" π Patients without analysis: {patients_without_analysis}")[m
[31m- [m
[31m- if patients_without_analysis > 0:[m
[31m- print(" β οΈ Some patients need analysis!")[m
[31m- print(" π‘ You may need to trigger analysis for these patients")[m
[31m- [m
[31m- client.close()[m
[31m- [m
[31m- except Exception as e:[m
[31m- print(f"β Database error: {e}")[m
[31m- print("π‘ Make sure MongoDB is running and accessible")[m
[31m- [m
[31m- print("\n" + "="*50)[m
[31m- print("β
Database check completed!")[m
[31m- print("\nπ Summary:")[m
[31m- print(" - If you see analysis results with real scores, the data exists")[m
[31m- print(" - If scores are 0.0, the analysis may need to be re-run")[m
[31m- print(" - Your mobile app should show real scores if data exists")[m
[31m-[m
[31m-if __name__ == "__main__":[m
[31m- asyncio.run(check_database())[m
[1mdiff --git a/monitor_and_trigger.py b/monitor_and_trigger.py[m
[1mdeleted file mode 100644[m
[1mindex 82df60b..0000000[m
[1m--- a/monitor_and_trigger.py[m
[1m+++ /dev/null[m
[36m@@ -1,124 +0,0 @@[m
[31m-#!/usr/bin/env python3[m
[31m-"""[m
[31m-Monitor Hugging Face Space and automatically trigger analysis when it comes online[m
[31m-"""[m
[31m-[m
[31m-import asyncio[m
[31m-import aiohttp[m
[31m-import json[m
[31m-import time[m
[31m-from datetime import datetime[m
[31m-[m
[31m-async def monitor_and_trigger():[m
[31m- """Monitor the space and trigger analysis when it comes online"""[m
[31m- [m
[31m- space_url = "https://rocketfarmstudios-cps-api-tx.hf.space"[m
[31m- [m
[31m- print("π Monitoring cps-api-tx Hugging Face Space")[m
[31m- print("=" * 60)[m
[31m- print(f"π‘ Space URL: {space_url}")[m
[31m- print(f"β° Started monitoring at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")[m
[31m- print()[m
[31m- print("π‘ Please restart your Hugging Face Space while this is running!")[m
[31m- print(" Go to: https://huggingface.co/spaces/RocketFarmStudios/cps-api-tx")[m
[31m- print()[m
[31m- [m
[31m- attempt = 1[m
[31m- while True:[m
[31m- try:[m
[31m- async with aiohttp.ClientSession() as session:[m
[31m- async with session.get(space_url, timeout=10) as response:[m
[31m- if response.status == 200:[m
[31m- print(f"β
SUCCESS! Space is now ONLINE! (Attempt {attempt})")[m
[31m- print(f"β° Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")[m
[31m- print()[m
[31m- [m
[31m- # Test the root endpoint[m
[31m- root_data = await response.text()[m
[31m- print(f"π Root endpoint response: {root_data}")[m
[31m- print()[m
[31m- [m
[31m- # Wait a moment for the space to fully initialize[m
[31m- print("β³ Waiting 30 seconds for space to fully initialize...")[m
[31m- await asyncio.sleep(30)[m
[31m- [m
[31m- # Trigger analysis[m
[31m- print("π Triggering analysis for all patients...")[m
[31m- try:[m
[31m- analyze_url = f"{space_url}/txagent/patients/analyze"[m
[31m- async with session.post(analyze_url, timeout=120) as analyze_response: # 2 minute timeout[m
[31m- if analyze_response.status == 200:[m
[31m- result_data = await analyze_response.json()[m
[31m- print("β
Analysis triggered successfully!")[m
[31m- print(f"π Results: {json.dumps(result_data, indent=2)}")[m
[31m- [m
[31m- analyzed_count = result_data.get('analyzed_count', 0)[m
[31m- total_patients = result_data.get('total_patients', 0)[m
[31m- [m
[31m- if analyzed_count > 0:[m
[31m- print(f"π Successfully analyzed {analyzed_count}/{total_patients} patients!")[m
[31m- [m
[31m- # Check results[m
[31m- print("\nπ Checking analysis results...")[m
[31m- results_url = f"{space_url}/txagent/patients/analysis-results"[m
[31m- async with session.get(results_url, timeout=10) as results_response:[m
[31m- if results_response.status == 200:[m
[31m- results_data = await results_response.json()[m
[31m- print(f"β
Found {len(results_data)} analysis results")[m
[31m- [m
[31m- if len(results_data) > 0:[m
[31m- print("\nπ Sample Results with Real Scores:")[m
[31m- for i, result in enumerate(results_data[:3]):[m
[31m- suicide_risk = result.get('suicide_risk', {})[m
[31m- |