Spaces:
Running
Running
| # Service Professional Authentication Guide | |
| ## Overview | |
| Complete end-to-end authentication system for service professionals (spa staff, salon staff, beauticians, therapists, etc.) using OTP-based login via WhatsApp. | |
| ## Architecture | |
| ### Collection | |
| - **Database**: `cuatrolabs_db` | |
| - **Collection**: `scm_service_professionals` | |
| - **Purpose**: Stores service professional profiles | |
| ### Authentication Flow | |
| 1. Service professional requests OTP via phone number | |
| 2. System validates professional exists and is active | |
| 3. OTP generated and sent via WhatsApp (WATI) | |
| 4. OTP stored in Redis with 5-minute expiration | |
| 5. Professional verifies OTP | |
| 6. System generates JWT token with merchant context | |
| 7. Professional can access protected endpoints | |
| ## API Endpoints | |
| ### 1. Send OTP | |
| ```http | |
| POST /service-professionals/send-otp | |
| Content-Type: application/json | |
| { | |
| "phone": "+919876543210" | |
| } | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "success": true, | |
| "message": "OTP sent successfully via WhatsApp", | |
| "expires_in": 300 | |
| } | |
| ``` | |
| ### 2. Verify OTP & Login | |
| ```http | |
| POST /service-professionals/verify-otp | |
| Content-Type: application/json | |
| { | |
| "phone": "+919876543210", | |
| "otp": "123456" | |
| } | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", | |
| "token_type": "bearer", | |
| "expires_in": 86400, | |
| "professional_info": { | |
| "partner_id": "550e8400-e29b-41d4-a716-446655440001", | |
| "name": "Priya Sharma", | |
| "phone": "+919876543210", | |
| "email": "priya.sharma@example.com", | |
| "designation": "Senior Beautician", | |
| "status": "active", | |
| "user_type": "service_professional" | |
| } | |
| } | |
| ``` | |
| ### 3. Logout | |
| ```http | |
| POST /service-professionals/logout | |
| Authorization: Bearer {access_token} | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "success": true, | |
| "message": "Service professional logged out successfully" | |
| } | |
| ``` | |
| ## Sample Data | |
| ### Test Professionals | |
| #### Active Professionals (Can Login) | |
| 1. **Priya Sharma** - Senior Beautician | |
| - Phone: `+919876543210` | |
| - Skills: facial, makeup, hair_styling, manicure, pedicure | |
| 2. **Rahul Verma** - Massage Therapist | |
| - Phone: `+919876543211` | |
| - Skills: swedish_massage, deep_tissue, aromatherapy, hot_stone | |
| 3. **Anjali Patel** - Hair Stylist | |
| - Phone: `+919876543212` | |
| - Skills: hair_cut, hair_color, hair_treatment, styling, keratin | |
| 4. **Vikram Singh** - Spa Manager | |
| - Phone: `+919876543213` | |
| - Skills: management, customer_service, scheduling, training | |
| 5. **Meera Reddy** - Nail Technician | |
| - Phone: `+919876543214` | |
| - Skills: manicure, pedicure, nail_art, gel_nails, acrylic_nails | |
| 6. **Arjun Kumar** - Fitness Trainer | |
| - Phone: `+919876543215` | |
| - Skills: personal_training, yoga, pilates, strength_training, cardio | |
| #### Inactive Professionals (Cannot Login) | |
| 7. **Sneha Gupta** - Esthetician | |
| - Phone: `+919876543216` | |
| - Status: `inactive` | |
| - Skills: facials, waxing, threading, skin_analysis, chemical_peels | |
| ## Setup Instructions | |
| ### 1. Create Sample Data | |
| ```bash | |
| # Run the Python script to create sample professionals | |
| cd utils | |
| python create_sample_service_professionals.py | |
| ``` | |
| ### 2. Manual MongoDB Insert | |
| ```bash | |
| # Import JSON data directly | |
| mongoimport --db cuatrolabs_db \ | |
| --collection scm_service_professionals \ | |
| --file utils/sample_service_professionals.json \ | |
| --jsonArray | |
| ``` | |
| ### 3. Verify Data | |
| ```javascript | |
| // MongoDB shell | |
| use cuatrolabs_db | |
| db.scm_service_professionals.find().pretty() | |
| db.scm_service_professionals.countDocuments() | |
| ``` | |
| ## Testing | |
| ### Using cURL | |
| #### 1. Send OTP | |
| ```bash | |
| curl -X POST http://localhost:8002/service-professionals/send-otp \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"phone": "+919876543210"}' | |
| ``` | |
| #### 2. Verify OTP (replace with actual OTP) | |
| ```bash | |
| curl -X POST http://localhost:8002/service-professionals/verify-otp \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"phone": "+919876543210", "otp": "123456"}' | |
| ``` | |
| #### 3. Logout (replace TOKEN) | |
| ```bash | |
| curl -X POST http://localhost:8002/service-professionals/logout \ | |
| -H "Authorization: Bearer TOKEN" | |
| ``` | |
| ### Using Python | |
| ```python | |
| import requests | |
| # 1. Send OTP | |
| response = requests.post( | |
| "http://localhost:8002/service-professionals/send-otp", | |
| json={"phone": "+919876543210"} | |
| ) | |
| print(response.json()) | |
| # 2. Verify OTP | |
| response = requests.post( | |
| "http://localhost:8002/service-professionals/verify-otp", | |
| json={"phone": "+919876543210", "otp": "123456"} | |
| ) | |
| data = response.json() | |
| token = data["access_token"] | |
| print(f"Token: {token}") | |
| # 3. Logout | |
| response = requests.post( | |
| "http://localhost:8002/service-professionals/logout", | |
| headers={"Authorization": f"Bearer {token}"} | |
| ) | |
| print(response.json()) | |
| ``` | |
| ## Security Features | |
| ### OTP Security | |
| - **Expiration**: 5 minutes | |
| - **Attempts**: Maximum 3 attempts per OTP | |
| - **One-time use**: OTP deleted after successful verification | |
| - **Redis storage**: Secure temporary storage | |
| ### Status Validation | |
| - Only `active` professionals can login | |
| - Inactive/suspended accounts are rejected | |
| - Status checked at both OTP send and verify stages | |
| ### JWT Token | |
| - **Expiration**: 24 hours (configurable) | |
| - **Payload**: partner_id, user_type | |
| - **Algorithm**: HS256 | |
| - **Stateless**: No server-side session storage | |
| ## Error Handling | |
| ### Common Errors | |
| #### 404 - Professional Not Found | |
| ```json | |
| { | |
| "detail": "Service professional not found for this phone number" | |
| } | |
| ``` | |
| #### 403 - Inactive Account | |
| ```json | |
| { | |
| "detail": "Service professional account is inactive" | |
| } | |
| ``` | |
| #### 401 - Invalid OTP | |
| ```json | |
| { | |
| "detail": "Invalid OTP" | |
| } | |
| ``` | |
| #### 401 - Expired OTP | |
| ```json | |
| { | |
| "detail": "OTP has expired" | |
| } | |
| ``` | |
| #### 429 - Too Many Attempts | |
| ```json | |
| { | |
| "detail": "Too many attempts. Please request a new OTP" | |
| } | |
| ``` | |
| ## Files Created | |
| ### Schema | |
| - `app/auth/schemas/service_professional_auth.py` | |
| - Request/response models | |
| - Phone and OTP validation | |
| ### Service | |
| - `app/auth/services/service_professional_auth_service.py` | |
| - Business logic | |
| - OTP generation and verification | |
| - JWT token creation | |
| - WhatsApp integration | |
| ### Router | |
| - `app/auth/controllers/service_professional_router.py` | |
| - API endpoints | |
| - Request handling | |
| - Error responses | |
| ### Test Data | |
| - `utils/create_sample_service_professionals.py` - Python script | |
| - `utils/sample_service_professionals.json` - JSON data | |
| ## Configuration | |
| ### Environment Variables | |
| ```env | |
| # WhatsApp OTP Settings | |
| WATI_STAFF_OTP_TEMPLATE_NAME=staff_otp_template | |
| # JWT Settings | |
| SECRET_KEY=your-secret-key | |
| ALGORITHM=HS256 | |
| TOKEN_EXPIRATION_HOURS=24 | |
| # Redis Settings | |
| REDIS_HOST=localhost | |
| REDIS_PORT=6379 | |
| ``` | |
| ## Integration Points | |
| ### Dependencies | |
| - **MongoDB**: Professional data storage | |
| - **Redis**: OTP caching | |
| - **WATI**: WhatsApp OTP delivery | |
| - **JWT**: Token generation | |
| ### Related Collections | |
| - `scm_service_professionals` - Professional profiles | |
| - `scm_merchants` - Merchant information | |
| ## Monitoring & Logging | |
| ### Log Events | |
| - `service_professional_mobile_otp_login` - Successful login | |
| - `service_professional_logout` - Logout event | |
| - OTP send/verify attempts | |
| - Failed authentication attempts | |
| ### Metrics to Track | |
| - OTP delivery success rate | |
| - Login success rate | |
| - Average OTP verification time | |
| - Failed login attempts by phone | |
| ## Future Enhancements | |
| ### Potential Features | |
| 1. **Refresh tokens** for extended sessions | |
| 2. **Biometric authentication** for mobile apps | |
| 3. **Multi-factor authentication** for sensitive operations | |
| 4. **Session management** with Redis | |
| 5. **Rate limiting** per phone number | |
| 6. **Geolocation validation** for security | |
| 7. **Device fingerprinting** for fraud detection | |
| ## Support | |
| For issues or questions: | |
| - Check logs in `cuatrolabs-auth-ms/logs/` | |
| - Review Redis cache: `redis-cli KEYS "service_professional_otp:*"` | |
| - Verify MongoDB data: `db.scm_service_professionals.find()` | |