# LIVE DEPLOYMENT GUIDE - Mandatory Password Change Feature

**Date**: September 1, 2026  
**Feature**: Mandatory password change on first client login  
**Status**: ✅ Ready for Production

---

## 📋 Quick Summary of Changes

| Category | Files | Changes |
|----------|-------|---------|
| **Database** | 1 file | Add `password_changed_at` column to users table |
| **Middleware** | 1 NEW file | Check if client needs password change on first login |
| **Controller** | 1 file (2 methods added) | Handle password change form display and update |
| **Model** | 1 file (2 locations) | Add fillable + casts for password_changed_at |
| **Routes** | 1 file (2 locations) | Add middleware + add password change routes |
| **View** | 1 NEW file | Beautiful password change form UI |

---

## 🚀 EXACT STEPS FOR DEPLOYMENT

### STEP 1: Copy Files to Live Server

Use SCP or your file transfer method to copy these files:

```
LOCAL -> LIVE SERVER

1. app/Http/Middleware/CheckPasswordChanged.php
   → app/Http/Middleware/CheckPasswordChanged.php

2. app/Http/Controllers/ClientController.php
   → app/Http/Controllers/ClientController.php

3. app/Models/User.php
   → app/Models/User.php

4. routes/web.php
   → routes/web.php

5. database/migrations/2026_09_01_141422_add_password_changed_to_users.php
   → database/migrations/2026_09_01_141422_add_password_changed_to_users.php

6. resources/views/client/change-password.blade.php
   → resources/views/client/change-password.blade.php
```

### STEP 2: SSH to Live Server

```bash
ssh user@your-live-server.com
cd /path/to/will
```

### STEP 3: Run Database Migration

```bash
php artisan migrate
```

**Expected Output**:
```
Migration table created successfully.
2026_09_01_141422_add_password_changed_to_users  DONE
```

### STEP 4: Clear Cache

```bash
php artisan cache:clear
php artisan config:cache
php artisan route:cache
php artisan view:clear
```

### STEP 5: Verify Deployment

```bash
# Check migration status
php artisan migrate:status

# Check routes are registered
php artisan route:list | grep change-password

# Check database column exists
mysql -u [user] -p [db_name] -e "DESC users;" | grep password_changed
```

---

## 📦 FILE-BY-FILE DEPLOYMENT DETAILS

### 1. NEW MIDDLEWARE FILE
**Path**: `app/Http/Middleware/CheckPasswordChanged.php`

**Deployment**: COPY THIS FILE (NEW - doesn't exist on live)

**Action on Live**:
```bash
# Verify file was copied
ls -la app/Http/Middleware/CheckPasswordChanged.php
```

---

### 2. DATABASE MIGRATION
**Path**: `database/migrations/2026_09_01_141422_add_password_changed_to_users.php`

**Deployment**: COPY THIS FILE (NEW)

**Action on Live**:
```bash
php artisan migrate
```

**Verify**:
```bash
mysql -u [user] -p [db_name] -e "DESC users;" | grep password_changed_at
```

Should show:
```
password_changed_at | timestamp | YES | | NULL
```

---

### 3. UPDATED USER MODEL
**Path**: `app/Models/User.php`

**Deployment**: COPY UPDATED FILE

**Verify**:
```bash
# Check if password_changed_at is in fillable
grep -A 30 "protected \$fillable" app/Models/User.php | grep password_changed_at

# Check if password_changed_at is in casts
grep -A 15 "protected function casts" app/Models/User.php | grep password_changed_at
```

---

### 4. UPDATED ROUTES FILE
**Path**: `routes/web.php`

**Deployment**: COPY UPDATED FILE

**Verify**:
```bash
# Check middleware is registered
grep "CheckPasswordChanged" routes/web.php

# Check routes are registered
php artisan route:list | grep change-password
```

Should show:
```
GET|HEAD   /client/change-password              client.change-password
POST       /client/change-password              client.update-password
```

---

### 5. UPDATED CONTROLLER
**Path**: `app/Http/Controllers/ClientController.php`

**Deployment**: COPY UPDATED FILE

**Verify**:
```bash
# Check methods exist
grep -A 5 "public function showChangePassword\|public function updatePassword" app/Http/Controllers/ClientController.php
```

---

### 6. NEW VIEW FILE
**Path**: `resources/views/client/change-password.blade.php`

**Deployment**: COPY THIS FILE (NEW)

**Verify**:
```bash
ls -la resources/views/client/change-password.blade.php
```

---

## ✅ POST-DEPLOYMENT VERIFICATION CHECKLIST

Run these commands to verify everything worked:

```bash
#!/bin/bash
# Save as verify_deployment.sh

echo "🔍 Checking Deployment..."
echo ""

# 1. Check migration
echo "1️⃣ Migration Status:"
php artisan migrate:status | grep 2026_09_01_141422

# 2. Check database column
echo ""
echo "2️⃣ Database Column:"
mysql -u [user] -p [db_name] -e "DESC users\G" | grep -A 2 password_changed_at

# 3. Check routes
echo ""
echo "3️⃣ Routes Registered:"
php artisan route:list | grep change-password

# 4. Check middleware
echo ""
echo "4️⃣ Middleware in Routes:"
grep "CheckPasswordChanged" routes/web.php

# 5. Check file permissions
echo ""
echo "5️⃣ File Permissions:"
ls -la app/Http/Middleware/CheckPasswordChanged.php
ls -la resources/views/client/change-password.blade.php

# 6. Check for PHP errors
echo ""
echo "6️⃣ PHP Syntax Check:"
php -l app/Http/Controllers/ClientController.php
php -l app/Models/User.php
php -l routes/web.php

echo ""
echo "✅ Verification Complete!"
```

**Run it**:
```bash
chmod +x verify_deployment.sh
./verify_deployment.sh
```

---

## 🧪 MANUAL TESTING

After deployment, test the feature:

1. **Create Test Client** (via agent portal)
   - Name: Test Client
   - Email: testclient@example.com
   - IC: 123456789012

2. **Log In as Client**
   - URL: `https://your-live-server.com/client/login`
   - Email: testclient@example.com
   - Password: 123456789012 (IC number)

3. **Verify Redirect**
   - Should redirect to `/client/change-password`
   - Should show yellow warning alert

4. **Change Password**
   - Enter current password: 123456789012
   - Enter new password: TestPass123
   - Confirm: TestPass123
   - Click "Change Password"

5. **Verify Success**
   - Should redirect to dashboard
   - Should show success message
   - Check database: `password_changed_at` should have timestamp

6. **Test Subsequent Login**
   - Log out
   - Log in with new password (TestPass123)
   - Should NOT redirect to change password page
   - Should have full portal access

---

## 🆘 TROUBLESHOOTING

### Issue: "Migration fails"
```bash
# Check if migration was already run
php artisan migrate:status | grep 2026_09_01_141422

# If already run, skip and continue
# If column exists, migration already applied
mysql -u [user] -p [db_name] -e "DESC users\G" | grep password_changed_at
```

### Issue: "Routes not showing"
```bash
# Clear and rebuild route cache
php artisan route:clear
php artisan route:cache
php artisan route:list | grep change-password
```

### Issue: "Middleware not intercepting"
```bash
# Check middleware is in routes file
grep "CheckPasswordChanged" routes/web.php

# Check middleware file exists
ls -la app/Http/Middleware/CheckPasswordChanged.php

# Clear cache again
php artisan cache:clear
```

### Issue: "View not rendering"
```bash
# Check view file exists
ls -la resources/views/client/change-password.blade.php

# Check for syntax errors
php artisan view:clear
```

### Issue: "Password validation failing"
```bash
# Check controller has methods
grep -c "public function updatePassword" app/Http/Controllers/ClientController.php
# Should return 1

# Check validation rules in method
grep -A 10 "public function updatePassword" app/Http/Controllers/ClientController.php
```

---

## 📊 DEPLOYMENT MONITORING

Monitor these logs after deployment:

```bash
# Laravel application logs
tail -f storage/logs/laravel.log

# Watch for errors
grep -i "error\|exception" storage/logs/laravel.log

# Check specific errors
grep -A 5 "CheckPasswordChanged" storage/logs/laravel.log
```

---

## 🔄 ROLLBACK PROCEDURE (If Needed)

If something goes wrong, rollback is simple:

### Quick Rollback:

```bash
# 1. Rollback database
php artisan migrate:rollback --step=1

# 2. Remove files
rm app/Http/Middleware/CheckPasswordChanged.php
rm resources/views/client/change-password.blade.php

# 3. Restore original files from backup
# Get previous versions of:
# - app/Http/Controllers/ClientController.php
# - app/Models/User.php
# - routes/web.php

# 4. Clear cache
php artisan cache:clear
php artisan route:cache
php artisan view:clear
```

### Verify Rollback:

```bash
php artisan migrate:status
php artisan route:list | grep change-password
# Should show 0 routes
```

---

## 📝 DEPLOYMENT RECORD

Create a record of deployment:

```markdown
## Deployment Record - Mandatory Password Change Feature

**Date**: [Today's Date]
**Environment**: Production
**Server**: [Your Server]
**Deployed By**: [Your Name]

### Changes Applied:
- [ ] Database migration run
- [ ] 6 files copied to live server
- [ ] Cache cleared
- [ ] Routes verified
- [ ] Middleware verified
- [ ] Manual testing completed

### Test Results:
- [ ] New client redirected to change password
- [ ] Password change form works
- [ ] Password updated in database
- [ ] Subsequent login works
- [ ] Existing clients unaffected

### Issues Encountered:
None

### Notes:
All tests passed. Feature ready for production use.
```

---

## 📞 SUPPORT & CONTACTS

If issues arise during deployment:

1. Check logs: `storage/logs/laravel.log`
2. Verify file permissions
3. Ensure cache is cleared
4. Test with test client
5. Check database structure with `DESC users;`

Contact development team if unable to resolve.

---

## 🎯 SUCCESS CRITERIA

Deployment is successful when:

✅ Migration runs without errors  
✅ All 6 files are on live server  
✅ Routes show both change-password routes  
✅ Middleware is registered  
✅ New client redirected on first login  
✅ Password change form displays correctly  
✅ Password validation works  
✅ `password_changed_at` column populated after change  
✅ Subsequent login doesn't redirect  
✅ Existing clients unaffected  
✅ No errors in Laravel logs  

---

