# 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()`