diff --git a/EMAIL_SETUP_GUIDE.md b/EMAIL_SETUP_GUIDE.md deleted file mode 100644 index f22eac2..0000000 --- a/EMAIL_SETUP_GUIDE.md +++ /dev/null @@ -1,137 +0,0 @@ -# šŸ“§ Gmail Email Setup Guide - -This guide will help you set up Gmail SMTP for the password reset functionality. - -## šŸ”‘ What You Need - -1. **Gmail Email Address** (your username) -2. **Gmail App Password** (16-character password) - -## šŸ“‹ Step-by-Step Setup - -### Step 1: Get Your Gmail Username -- Your Gmail username is your Gmail email address -- **Example**: `john.doe@gmail.com` - -### Step 2: Create Gmail App Password - -#### 2.1 Enable 2-Step Verification -1. Go to: https://myaccount.google.com/security -2. Sign in with your Gmail account -3. Find "2-Step Verification" and click "Get started" -4. Follow the setup process (usually involves your phone) - -#### 2.2 Generate App Password -1. After enabling 2-Step Verification, go back to: https://myaccount.google.com/security -2. Scroll down and find "App passwords" -3. Click on "App passwords" -4. Select "Mail" as the app -5. Select "Other (Custom name)" as the device -6. Enter a name like "CPS Password Reset" -7. Click "Generate" -8. **Copy the 16-character password** (remove spaces) - -**Example App Password**: `abcd efgh ijkl mnop` → `abcdefghijklmnop` - -### Step 3: Configure Environment Variables - -#### Option A: Create .env file (Recommended) -Create a file named `.env` in the `cps-api-tx` directory: - -```bash -# Database Configuration -MONGODB_URL=mongodb://localhost:27017/cps_db - -# JWT Configuration -SECRET_KEY=your-secret-key-here -ALGORITHM=HS256 -ACCESS_TOKEN_EXPIRE_MINUTES=30 - -# Email Configuration (REPLACE WITH YOUR ACTUAL VALUES) -MAIL_USERNAME=your-email@gmail.com -MAIL_PASSWORD=your-16-character-app-password -MAIL_FROM=your-email@gmail.com - -# TxAgent Configuration -TXAGENT_MODE=cloud -TXAGENT_CLOUD_URL=https://rocketfarmstudios-txagent-api.hf.space -TXAGENT_LOCAL_ENABLED=false - -# CORS Configuration -ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8081 -``` - -#### Option B: Set Environment Variables in Terminal - -**Windows (PowerShell)**: -```powershell -$env:MAIL_USERNAME="your-email@gmail.com" -$env:MAIL_PASSWORD="your-16-character-app-password" -$env:MAIL_FROM="your-email@gmail.com" -``` - -**Windows (Command Prompt)**: -```cmd -set MAIL_USERNAME=your-email@gmail.com -set MAIL_PASSWORD=your-16-character-app-password -set MAIL_FROM=your-email@gmail.com -``` - -**Linux/Mac**: -```bash -export MAIL_USERNAME="your-email@gmail.com" -export MAIL_PASSWORD="your-16-character-app-password" -export MAIL_FROM="your-email@gmail.com" -``` - -### Step 4: Test Your Configuration - -Run the test script to verify your setup: - -```bash -cd cps-api-tx -python test_email_config.py -``` - -## šŸ” Troubleshooting - -### Common Issues: - -1. **"Username and Password not accepted"** - - Make sure you're using an App Password, not your regular Gmail password - - Ensure 2-Step Verification is enabled - - Check that the App Password is exactly 16 characters (no spaces) - -2. **"App passwords not available"** - - 2-Step Verification must be enabled first - - Wait a few minutes after enabling 2-Step Verification - -3. **"SMTP connection failed"** - - Check your internet connection - - Ensure Gmail SMTP is not blocked by firewall - - Try using port 587 (should be automatic) - -### Security Notes: - -- āœ… **App Passwords are secure** - they can only be used for the specific app -- āœ… **You can revoke App Passwords** anytime from Google Account settings -- āœ… **App Passwords don't expire** unless you change your main password -- āŒ **Never share your App Password** with anyone -- āŒ **Don't commit .env files** to version control - -## šŸ“ž Need Help? - -If you're still having issues: - -1. **Check Google Account Activity**: https://myaccount.google.com/notifications -2. **Review App Passwords**: https://myaccount.google.com/apppasswords -3. **Google Account Help**: https://support.google.com/accounts - -## āœ… Verification Checklist - -- [ ] 2-Step Verification enabled -- [ ] App Password generated for "Mail" -- [ ] 16-character App Password copied (no spaces) -- [ ] Environment variables set correctly -- [ ] Test script runs successfully -- [ ] Test email received in inbox diff --git a/ENHANCED_APPOINTMENT_GUIDE.md b/ENHANCED_APPOINTMENT_GUIDE.md deleted file mode 100644 index 8b13789..0000000 --- a/ENHANCED_APPOINTMENT_GUIDE.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/PASSWORD_RESET_SETUP.md b/PASSWORD_RESET_SETUP.md deleted file mode 100644 index 543b3ef..0000000 --- a/PASSWORD_RESET_SETUP.md +++ /dev/null @@ -1,122 +0,0 @@ -# Password Reset Setup Guide - -This guide explains how to set up the password reset functionality with email verification. - -## Email Configuration - -The password reset feature uses Gmail SMTP to send verification codes. You need to configure the following environment variables: - -### 1. Create a Gmail App Password - -1. Go to your Google Account settings -2. Navigate to Security > 2-Step Verification -3. Create an App Password for your application -4. Use this app password instead of your regular Gmail password - -### 2. Environment Variables - -Add these variables to your `.env` file or environment: - -```bash -# Email Configuration -MAIL_USERNAME=your-email@gmail.com -MAIL_PASSWORD=your-app-password-here -MAIL_FROM=your-email@gmail.com -``` - -### 3. Install Dependencies - -Make sure you have the required packages installed: - -```bash -pip install fastapi-mail jinja2 -``` - -## API Endpoints - -The password reset functionality provides three endpoints: - -### 1. Request Password Reset -``` -POST /auth/forgot-password -Content-Type: application/json - -{ - "email": "user@example.com" -} -``` - -### 2. Verify Reset Code -``` -POST /auth/verify-reset-code -Content-Type: application/json - -{ - "email": "user@example.com", - "verification_code": "123456" -} -``` - -### 3. Reset Password -``` -POST /auth/reset-password -Content-Type: application/json - -{ - "email": "user@example.com", - "verification_code": "123456", - "new_password": "newpassword123" -} -``` - -## Security Features - -- **6-digit verification codes** with 15-minute expiration -- **One-time use codes** - each code can only be used once -- **Email validation** - checks if the email exists before sending -- **Password validation** - minimum 6 characters required -- **Secure email templates** with professional styling - -## Frontend Integration - -### Web App (React) -The web app includes a complete password reset flow with: -- 3-step wizard interface -- Real-time validation -- Progress indicators -- Error handling - -### Mobile App (React Native) -The mobile app includes: -- Native password reset screen -- Progress bar and step indicators -- Snackbar notifications -- Keyboard-aware interface - -## Testing - -1. Start the backend server -2. Configure email settings -3. Test the password reset flow: - - Request reset for existing email - - Check email for verification code - - Verify code - - Set new password - - Sign in with new password - -## Troubleshooting - -### Email Not Sending -- Check Gmail app password configuration -- Verify SMTP settings -- Check firewall/network restrictions - -### Verification Code Issues -- Codes expire after 15 minutes -- Each code can only be used once -- Check database connection for code storage - -### Frontend Issues -- Verify API endpoint URLs -- Check CORS configuration -- Ensure proper error handling diff --git a/api/routes/auth.py b/api/routes/auth.py index 334e365..a44b00e 100644 --- a/api/routes/auth.py +++ b/api/routes/auth.py @@ -107,7 +107,7 @@ async def create_doctor( "license_number": data.license_number, "created_at": datetime.utcnow().isoformat(), "updated_at": datetime.utcnow().isoformat(), - "device_token": data.device_token or "" + "device_token": "" # Default empty device token for doctors }  try: diff --git a/check_database.py b/check_database.py deleted file mode 100644 index e88aad6..0000000 --- a/check_database.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -""" -Check database directly to see analysis data -""" - -import asyncio -import motor.motor_asyncio -import os -from datetime import datetime - -async def check_database(): - """Check database directly for analysis data""" -  - print("šŸ” Checking Database Directly") - print("=" * 50) - print(f"ā° Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print() -  - try: - # Connect to MongoDB - mongo_url = os.getenv('MONGODB_URL', 'mongodb://localhost:27017') - client = motor.motor_asyncio.AsyncIOMotorClient(mongo_url) - db = client.cps_database -  - # Check patients collection - print("šŸ“Š Checking patients collection...") - patients_count = await db.patients.count_documents({}) - print(f" āœ… Found {patients_count} patients") -  - if patients_count > 0: - # Show sample patients - patients = await db.patients.find({}).limit(3).to_list(length=3) - print("\nšŸ“‹ Sample Patients:") - for i, patient in enumerate(patients): - print(f" Patient {i+1}: {patient.get('full_name', 'Unknown')}") - print(f" - ID: {patient.get('fhir_id', 'No ID')}") - print(f" - Email: {patient.get('email', 'No email')}") - print() -  - # Check analysis collection - print("šŸ“Š Checking analysis collection...") - analysis_count = await db.patient_analysis_results.count_documents({}) - print(f" āœ… Found {analysis_count} analysis results") -  - if analysis_count > 0: - # Show sample analysis results - analyses = await db.patient_analysis_results.find({}).limit(3).to_list(length=3) - print("\nšŸ“‹ Sample Analysis Results:") - for i, analysis in enumerate(analyses): - print(f" Analysis {i+1}:") - print(f" - Patient ID: {analysis.get('patient_id', 'No ID')}") - print(f" - Timestamp: {analysis.get('timestamp', 'No timestamp')}") -  - # Check suicide risk data - suicide_risk = analysis.get('suicide_risk', {}) - if isinstance(suicide_risk, dict): - risk_level = suicide_risk.get('level', 'No level') - risk_score = suicide_risk.get('score', 0.0) - risk_factors = suicide_risk.get('factors', []) - print(f" - Risk Level: {risk_level}") - print(f" - Risk Score: {risk_score}") - print(f" - Risk Factors: {risk_factors}") - else: - print(f" - Suicide Risk: {suicide_risk}") -  - # Check summary - summary = analysis.get('summary', '') - if summary: - print(f" - Summary: {summary[:100]}...") - print() -  - # Check if there are any patients without analysis - if patients_count > 0 and analysis_count > 0: - print("šŸ” Checking for patients without analysis...") - patients_with_analysis = await db.patient_analysis_results.distinct('patient_id') - patients_without_analysis = patients_count - len(patients_with_analysis) - print(f" šŸ“Š Patients with analysis: {len(patients_with_analysis)}") - print(f" šŸ“Š Patients without analysis: {patients_without_analysis}") -  - if patients_without_analysis > 0: - print(" āš ļø Some patients need analysis!") - print(" šŸ’” You may need to trigger analysis for these patients") -  - client.close() -  - except Exception as e: - print(f"āŒ Database error: {e}") - print("šŸ’” Make sure MongoDB is running and accessible") -  - print("\n" + "="*50) - print("āœ… Database check completed!") - print("\nšŸ“ Summary:") - print(" - If you see analysis results with real scores, the data exists") - print(" - If scores are 0.0, the analysis may need to be re-run") - print(" - Your mobile app should show real scores if data exists") - -if __name__ == "__main__": - asyncio.run(check_database()) diff --git a/monitor_and_trigger.py b/monitor_and_trigger.py deleted file mode 100644 index 82df60b..0000000 --- a/monitor_and_trigger.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python3 -""" -Monitor Hugging Face Space and automatically trigger analysis when it comes online -""" - -import asyncio -import aiohttp -import json -import time -from datetime import datetime - -async def monitor_and_trigger(): - """Monitor the space and trigger analysis when it comes online""" -  - space_url = "https://rocketfarmstudios-cps-api-tx.hf.space" -  - print("šŸ” Monitoring cps-api-tx Hugging Face Space") - print("=" * 60) - print(f"šŸ“” Space URL: {space_url}") - print(f"ā° Started monitoring at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print() - print("šŸ’” Please restart your Hugging Face Space while this is running!") - print(" Go to: https://huggingface.co/spaces/RocketFarmStudios/cps-api-tx") - print() -  - attempt = 1 - while True: - try: - async with aiohttp.ClientSession() as session: - async with session.get(space_url, timeout=10) as response: - if response.status == 200: - print(f"āœ… SUCCESS! Space is now ONLINE! (Attempt {attempt})") - print(f"ā° Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print() -  - # Test the root endpoint - root_data = await response.text() - print(f"šŸ“Š Root endpoint response: {root_data}") - print() -  - # Wait a moment for the space to fully initialize - print("ā³ Waiting 30 seconds for space to fully initialize...") - await asyncio.sleep(30) -  - # Trigger analysis - print("šŸš€ Triggering analysis for all patients...") - try: - analyze_url = f"{space_url}/txagent/patients/analyze" - async with session.post(analyze_url, timeout=120) as analyze_response: # 2 minute timeout - if analyze_response.status == 200: - result_data = await analyze_response.json() - print("āœ… Analysis triggered successfully!") - print(f"šŸ“Š Results: {json.dumps(result_data, indent=2)}") -  - analyzed_count = result_data.get('analyzed_count', 0) - total_patients = result_data.get('total_patients', 0) -  - if analyzed_count > 0: - print(f"šŸŽ‰ Successfully analyzed {analyzed_count}/{total_patients} patients!") -  - # Check results - print("\nšŸ“Š Checking analysis results...") - results_url = f"{space_url}/txagent/patients/analysis-results" - async with session.get(results_url, timeout=10) as results_response: - if results_response.status == 200: - results_data = await results_response.json() - print(f"āœ… Found {len(results_data)} analysis results") -  - if len(results_data) > 0: - print("\nšŸ“Š Sample Results with Real Scores:") - for i, result in enumerate(results_data[:3]): - suicide_risk = result.get('suicide_risk', {}) -