File size: 7,080 Bytes
419099f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Complete Reminder System Test

This script:
1. Creates a test user with profile and phone number
2. Creates a reminder that fires in the next 2-3 minutes
3. Verifies the reminder scheduler picks it up and sends SMS

Run from backend directory:
    python scripts/test_reminder_system.py
"""
import asyncio
import sys
from pathlib import Path
from datetime import datetime, timedelta
from uuid import uuid4

# Add the backend directory to path
backend_dir = Path(__file__).parent.parent
sys.path.insert(0, str(backend_dir))

# Load environment variables
from dotenv import load_dotenv
load_dotenv(backend_dir / ".env")

from sqlalchemy import select
from app.db import async_session_maker, init_db
from app.models import User, UserProfile, Reminder
from app.security import hash_password


async def create_test_user_and_reminder():
    """Create a test user with profile and a reminder that fires soon."""
    
    print("=" * 70)
    print("CO-CODE REMINDER SYSTEM TEST")
    print("=" * 70)
    
    # Initialize database
    print("\n1. Initializing database...")
    await init_db()
    print("   βœ… Database initialized")
    
    async with async_session_maker() as db:
        # Check for existing test user
        print("\n2. Creating/finding test user...")
        result = await db.execute(
            select(User).where(User.email == "reminder_test@cocode.com")
        )
        user = result.scalar_one_or_none()
        
        if user:
            print(f"   ℹ️  Found existing test user: {user.email} (ID: {user.id})")
        else:
            # Create test user
            user = User(
                id=uuid4(),
                email="reminder_test@cocode.com",
                full_name="Reminder Test User",
                password_hash=hash_password("testpass123"),
                is_active=True
            )
            db.add(user)
            await db.commit()
            await db.refresh(user)
            print(f"   βœ… Created test user: {user.email} (ID: {user.id})")
        
        # Check for profile
        print("\n3. Creating/updating user profile...")
        result = await db.execute(
            select(UserProfile).where(UserProfile.user_id == user.id)
        )
        profile = result.scalar_one_or_none()
        
        # Get phone number from environment
        import os
        phone_number = os.getenv("SMS_TEST_TO_NUMBER", "+919004281995")
        
        if profile:
            profile.phone_number = phone_number
            profile.full_name = "Reminder Test User"
            profile.age_years = 30
            print(f"   ℹ️  Updated existing profile with phone: {phone_number}")
        else:
            profile = UserProfile(
                user_id=user.id,
                full_name="Reminder Test User",
                phone_number=phone_number,
                age_years=30,
                sex_at_birth="male",
                height_cm=175,
                weight_kg=70
            )
            db.add(profile)
            print(f"   βœ… Created profile with phone: {phone_number}")
        
        await db.commit()
        await db.refresh(profile)
        
        # Delete any existing test reminders for this user
        print("\n4. Cleaning up old test reminders...")
        result = await db.execute(
            select(Reminder).where(Reminder.user_id == user.id)
        )
        old_reminders = list(result.scalars().all())
        for reminder in old_reminders:
            await db.delete(reminder)
        await db.commit()
        print(f"   βœ… Deleted {len(old_reminders)} old reminder(s)")
        
        # Create a new reminder that fires in 2 minutes
        print("\n5. Creating test reminder...")
        next_run = datetime.utcnow() + timedelta(minutes=2)
        
        reminder = Reminder(
            user_id=user.id,
            type="test",
            title="πŸ§ͺ Test Reminder",
            message=f"This is a test reminder from Co-Code! If you receive this SMS, the reminder system is working perfectly. Time: {datetime.utcnow().strftime('%H:%M:%S UTC')}",
            schedule_type="once",
            schedule_json={"time": next_run.isoformat()},
            timezone="UTC",
            channel="sms",
            is_enabled=True,
            next_run_at=next_run
        )
        
        db.add(reminder)
        await db.commit()
        await db.refresh(reminder)
        
        print(f"   βœ… Created test reminder:")
        print(f"      ID: {reminder.id}")
        print(f"      Title: {reminder.title}")
        print(f"      Next run: {next_run.strftime('%Y-%m-%d %H:%M:%S UTC')}")
        print(f"      Phone: {phone_number}")
        
        # Calculate time until reminder fires
        seconds_until = (next_run - datetime.utcnow()).total_seconds()
        minutes = int(seconds_until // 60)
        seconds = int(seconds_until % 60)
        
        print(f"\n{'=' * 70}")
        print(f"⏰ REMINDER WILL FIRE IN: {minutes} minutes and {seconds} seconds")
        print(f"{'=' * 70}")
        print(f"\nπŸ“± Watch for SMS to: {phone_number}")
        print(f"πŸ“‹ Check Docker logs: docker logs ggw-backend -f")
        print(f"πŸ” Look for: 'Reminder scheduler tick: processed'")
        print(f"\nThe reminder scheduler checks every 60 seconds.")
        print(f"Your reminder will be sent at approximately: {next_run.strftime('%H:%M:%S UTC')}")
        print(f"\n{'=' * 70}\n")
        
        return {
            "user_id": str(user.id),
            "reminder_id": str(reminder.id),
            "phone_number": phone_number,
            "next_run": next_run.isoformat(),
            "seconds_until": int(seconds_until)
        }


async def monitor_logs():
    """Monitor Docker logs for reminder processing."""
    print("\nπŸ” Monitoring logs for reminder processing...")
    print("   (Press Ctrl+C to stop)\n")
    
    import subprocess
    
    try:
        process = subprocess.Popen(
            ["docker", "logs", "ggw-backend", "-f"],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        
        for line in process.stdout:
            if any(keyword in line.lower() for keyword in ["reminder", "sms", "twilio", "processed"]):
                print(f"   {line.strip()}")
        
    except KeyboardInterrupt:
        print("\n\n   Monitoring stopped by user")
        process.kill()


if __name__ == "__main__":
    try:
        result = asyncio.run(create_test_user_and_reminder())
        
        print("\n" + "=" * 70)
        print("TEST SETUP COMPLETE!")
        print("=" * 70)
        print("\nWould you like to monitor logs? (Y/n): ", end="")
        
        choice = input().strip().lower()
        if choice in ["", "y", "yes"]:
            asyncio.run(monitor_logs())
        else:
            print("\nβœ… Setup complete. Check SMS and Docker logs in ~2 minutes.")
    
    except Exception as e:
        print(f"\n❌ ERROR: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)