2025-11-23 00:19:26 +00:00
|
|
|
from rest_framework.decorators import api_view, permission_classes
|
|
|
|
|
from rest_framework.response import Response
|
|
|
|
|
from rest_framework.permissions import AllowAny
|
|
|
|
|
|
|
|
|
|
@api_view(['GET'])
|
|
|
|
|
@permission_classes([AllowAny])
|
|
|
|
|
def api_root(request, format=None):
|
|
|
|
|
base_url = request.build_absolute_uri('/api/')
|
|
|
|
|
|
|
|
|
|
endpoints = {
|
|
|
|
|
'authentication': {
|
|
|
|
|
'description': 'User authentication and management endpoints',
|
|
|
|
|
'base_path': '/api/auth/',
|
|
|
|
|
'endpoints': {
|
|
|
|
|
'register': {
|
|
|
|
|
'description': 'Register a new user and send verification OTP',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/register/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['email', 'first_name', 'last_name', 'password', 'password2'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'email': 'user@example.com',
|
|
|
|
|
'first_name': 'John',
|
|
|
|
|
'last_name': 'Doe',
|
|
|
|
|
'phone_number': '+1234567890',
|
|
|
|
|
'password': 'SecurePassword123',
|
|
|
|
|
'password2': 'SecurePassword123'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'verify_otp': {
|
|
|
|
|
'description': 'Verify email address using OTP',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/verify-otp/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['email', 'otp'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'email': 'user@example.com',
|
|
|
|
|
'otp': '123456'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'login': {
|
|
|
|
|
'description': 'Authenticate user and return JWT tokens',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/login/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['email', 'password'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'email': 'user@example.com',
|
|
|
|
|
'password': 'SecurePassword123'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'resend_otp': {
|
|
|
|
|
'description': 'Resend OTP for email verification or password reset',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/resend-otp/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['email'],
|
|
|
|
|
'optional_fields': ['context (registration/password_reset)'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'email': 'user@example.com',
|
|
|
|
|
'context': 'registration'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'forgot_password': {
|
|
|
|
|
'description': 'Initiate password reset process',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/forgot-password/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['email'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'email': 'user@example.com'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'verify_password_reset_otp': {
|
|
|
|
|
'description': 'Verify OTP for password reset',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/verify-password-reset-otp/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['email', 'otp'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'email': 'user@example.com',
|
|
|
|
|
'otp': '123456'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'reset_password': {
|
|
|
|
|
'description': 'Reset password after OTP verification',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/reset-password/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['email', 'otp', 'new_password', 'confirm_password'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'email': 'user@example.com',
|
|
|
|
|
'otp': '123456',
|
|
|
|
|
'new_password': 'NewSecurePassword123',
|
|
|
|
|
'confirm_password': 'NewSecurePassword123'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'token_refresh': {
|
|
|
|
|
'description': 'Refresh access token using refresh token',
|
|
|
|
|
'url': request.build_absolute_uri('/api/auth/token/refresh/'),
|
|
|
|
|
'methods': ['POST'],
|
|
|
|
|
'required_fields': ['refresh'],
|
|
|
|
|
'example_request': {
|
|
|
|
|
'refresh': 'your_refresh_token_here'
|
|
|
|
|
}
|
2025-11-23 13:55:04 +00:00
|
|
|
},
|
|
|
|
|
"update_profile": {
|
|
|
|
|
"description": "Update user profile (Authenticated users only)",
|
|
|
|
|
"url": request.build_absolute_uri("/api/auth/profile/update/"),
|
|
|
|
|
"methods": ["PATCH"],
|
|
|
|
|
"authentication": "Required (Authenticated users only)",
|
|
|
|
|
"required_fields": ["first_name", "last_name", "phone_number"],
|
|
|
|
|
"example_request": {
|
|
|
|
|
"first_name": "John",
|
|
|
|
|
"last_name": "Doe",
|
|
|
|
|
"phone_number": "+1234567890"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"get_profile": {
|
|
|
|
|
"description": "Get user profile (Authenticated users only)",
|
|
|
|
|
"url": request.build_absolute_uri("/api/auth/profile/"),
|
|
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required (Authenticated users only)",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"user": "User object"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"all-users": {
|
|
|
|
|
"description": "Get all users (Admin only)",
|
|
|
|
|
"url": request.build_absolute_uri("/api/auth/all-users/"),
|
|
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required (Admin users only)",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"users": "List of user objects"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"activate-deactivate-user": {
|
|
|
|
|
"description": "Activate or deactivate a user (Admin only)",
|
|
|
|
|
"url": request.build_absolute_uri("/api/auth/activate-deactivate-user/<uuid:pk>/"),
|
|
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required (Admin users only)",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"user": "User object"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"delete-user": {
|
|
|
|
|
"description": "Delete a user (Admin only)",
|
|
|
|
|
"url": request.build_absolute_uri("/api/auth/delete-user/<uuid:pk>/"),
|
|
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required (Admin users only)",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"user": "User object"
|
|
|
|
|
}
|
2025-11-23 00:19:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"appointments": {
|
|
|
|
|
"description": "Appointment request and management system with Jitsi video meetings",
|
|
|
|
|
"base_path": "/api/meetings/",
|
|
|
|
|
"endpoints": {
|
|
|
|
|
"admin_availability": {
|
|
|
|
|
"description": "Get or update admin weekly availability (Admin only)",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/admin/availability/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["GET", "PUT", "PATCH"],
|
|
|
|
|
"authentication": "Required (Staff users only)",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"available_days": "List of weekday numbers (0-6) when appointments are accepted",
|
|
|
|
|
"available_days_display": "Human-readable day names"
|
|
|
|
|
},
|
|
|
|
|
"example_request": {
|
|
|
|
|
"available_days": [0, 1, 2, 3, 4]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"available_dates": {
|
|
|
|
|
"description": "Get available appointment dates for the next 30 days (Public)",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/available-dates/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "None required",
|
|
|
|
|
"response": "List of available dates in YYYY-MM-DD format"
|
|
|
|
|
},
|
|
|
|
|
"create_appointment": {
|
|
|
|
|
"description": "Create a new appointment request (Public)",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/create/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["POST"],
|
2025-11-23 13:55:04 +00:00
|
|
|
"authentication": "Required (User only)",
|
2025-11-23 00:19:26 +00:00
|
|
|
"required_fields": [
|
|
|
|
|
"first_name", "last_name", "email",
|
|
|
|
|
"preferred_dates", "preferred_time_slots"
|
|
|
|
|
],
|
|
|
|
|
"optional_fields": ["phone", "reason"],
|
|
|
|
|
"example_request": {
|
|
|
|
|
"first_name": "John",
|
|
|
|
|
"last_name": "Doe",
|
|
|
|
|
"email": "john@example.com",
|
|
|
|
|
"phone": "+1234567890",
|
|
|
|
|
"reason": "Initial consultation for anxiety",
|
|
|
|
|
"preferred_dates": ["2024-01-15", "2024-01-16"],
|
|
|
|
|
"preferred_time_slots": ["morning", "afternoon"]
|
|
|
|
|
},
|
|
|
|
|
"validation": "Preferred dates must be within admin available days"
|
|
|
|
|
},
|
|
|
|
|
"list_appointments": {
|
|
|
|
|
"description": "List appointment requests (Admin sees all, users see their own)",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required",
|
|
|
|
|
"query_parameters": {
|
|
|
|
|
"email": "For non-authenticated user lookup (simplified approach)"
|
|
|
|
|
},
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"jitsi_meet_url": "Jitsi meeting URL (only for scheduled appointments)",
|
|
|
|
|
"jitsi_room_id": "Jitsi room ID",
|
|
|
|
|
"has_jitsi_meeting": "Boolean indicating if meeting is created",
|
|
|
|
|
"can_join_meeting": "Boolean indicating if meeting can be joined now",
|
|
|
|
|
"meeting_status": "Current meeting status"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"appointment_detail": {
|
|
|
|
|
"description": "Get detailed information about a specific appointment",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/<uuid:pk>/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required",
|
|
|
|
|
"url_parameter": "pk (UUID of the appointment)",
|
|
|
|
|
"response_includes": "Jitsi meeting information for scheduled appointments"
|
|
|
|
|
},
|
|
|
|
|
"user_appointments": {
|
|
|
|
|
"description": "Get appointments for the authenticated user",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/user/appointments/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required",
|
|
|
|
|
"response": "List of user's appointment requests with Jitsi meeting details"
|
|
|
|
|
},
|
|
|
|
|
"schedule_appointment": {
|
|
|
|
|
"description": "Schedule an appointment and automatically create Jitsi meeting (Admin only)",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/<uuid:pk>/schedule/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["POST"],
|
|
|
|
|
"authentication": "Required (Staff users only)",
|
|
|
|
|
"required_fields": ["scheduled_datetime"],
|
|
|
|
|
"optional_fields": ["scheduled_duration"],
|
|
|
|
|
"prerequisites": "Appointment must be in 'pending_review' status",
|
|
|
|
|
"example_request": {
|
|
|
|
|
"scheduled_datetime": "2024-01-15T10:00:00Z",
|
|
|
|
|
"scheduled_duration": 60
|
|
|
|
|
},
|
|
|
|
|
"side_effects": [
|
|
|
|
|
"Updates status to 'scheduled'",
|
|
|
|
|
"Automatically generates Jitsi meeting room",
|
|
|
|
|
"Creates unique Jitsi room ID and URL",
|
|
|
|
|
"Sends confirmation email to user with meeting link",
|
|
|
|
|
"Clears rejection reason if any"
|
|
|
|
|
],
|
|
|
|
|
"response_includes": {
|
|
|
|
|
"jitsi_meet_url": "Generated Jitsi meeting URL",
|
|
|
|
|
"jitsi_room_id": "Unique Jitsi room ID",
|
|
|
|
|
"has_jitsi_meeting": "true"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"reject_appointment": {
|
|
|
|
|
"description": "Reject an appointment request (Admin only)",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/<uuid:pk>/reject/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["POST"],
|
|
|
|
|
"authentication": "Required (Staff users only)",
|
|
|
|
|
"optional_fields": ["rejection_reason"],
|
|
|
|
|
"prerequisites": "Appointment must be in 'pending_review' status",
|
|
|
|
|
"example_request": {
|
|
|
|
|
"rejection_reason": "No availability for preferred dates"
|
|
|
|
|
},
|
|
|
|
|
"side_effects": [
|
|
|
|
|
"Updates status to 'rejected'",
|
|
|
|
|
"Clears Jitsi meeting information",
|
|
|
|
|
"Sends rejection email to user",
|
|
|
|
|
"Clears scheduled datetime if any"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
"jitsi_meeting_info": {
|
|
|
|
|
"description": "Get Jitsi meeting information for a scheduled appointment",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/<uuid:pk>/jitsi-meeting/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required",
|
|
|
|
|
"prerequisites": "Appointment must be in 'scheduled' status",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"meeting_url": "Jitsi meeting URL",
|
|
|
|
|
"room_id": "Jitsi room ID",
|
|
|
|
|
"scheduled_time": "Formatted scheduled datetime",
|
|
|
|
|
"duration": "Meeting duration display",
|
|
|
|
|
"can_join": "Boolean indicating if meeting can be joined now",
|
|
|
|
|
"meeting_status": "Current meeting status",
|
|
|
|
|
"join_instructions": "Instructions for joining the meeting"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"appointment_stats": {
|
|
|
|
|
"description": "Get appointment statistics and analytics (Admin only)",
|
2025-11-23 12:20:05 +00:00
|
|
|
"url": request.build_absolute_uri("/api/meetings/appointments/stats/"),
|
2025-11-23 00:19:26 +00:00
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required (Staff users only)",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"total_requests": "Total number of appointment requests",
|
|
|
|
|
"pending_review": "Number of pending review requests",
|
|
|
|
|
"scheduled": "Number of scheduled appointments",
|
|
|
|
|
"rejected": "Number of rejected requests",
|
|
|
|
|
"completion_rate": "Percentage of requests that were scheduled"
|
|
|
|
|
}
|
2025-11-23 23:06:17 +00:00
|
|
|
},
|
2025-11-24 11:55:42 +00:00
|
|
|
"user_appointment_stats": {
|
|
|
|
|
"description": "Get appointment statistics and analytics for the authenticated user",
|
|
|
|
|
"url": request.build_absolute_uri("/api/meetings/user/appointments/stats/"),
|
|
|
|
|
"methods": ["GET"],
|
|
|
|
|
"authentication": "Required",
|
|
|
|
|
"response_fields": {
|
|
|
|
|
"total_requests": "Total number of appointment requests",
|
|
|
|
|
"pending_review": "Number of pending review requests",
|
|
|
|
|
"scheduled": "Number of scheduled appointments",
|
|
|
|
|
"rejected": "Number of rejected requests",
|
|
|
|
|
"completed": "Number of completed appointments",
|
|
|
|
|
"completion_rate": "Percentage of requests that were scheduled"
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-11-23 23:06:17 +00:00
|
|
|
|
2025-11-23 00:19:26 +00:00
|
|
|
},
|
|
|
|
|
"jitsi_integration": {
|
|
|
|
|
"description": "Automatic Jitsi video meeting integration",
|
|
|
|
|
"features": [
|
|
|
|
|
"Automatic meeting room generation when appointment is scheduled",
|
|
|
|
|
"Unique room IDs for each therapy session",
|
|
|
|
|
"No setup required for clients - just click and join",
|
|
|
|
|
"Meeting availability based on scheduled time",
|
|
|
|
|
"Secure, encrypted video sessions"
|
|
|
|
|
],
|
|
|
|
|
"meeting_lifecycle": {
|
|
|
|
|
"pending": "No Jitsi meeting created",
|
|
|
|
|
"scheduled": "Jitsi meeting automatically generated with unique URL",
|
|
|
|
|
"active": "Meeting can be joined 10 minutes before scheduled time",
|
|
|
|
|
"completed": "Meeting ends 15 minutes after scheduled duration"
|
|
|
|
|
},
|
|
|
|
|
"join_conditions": [
|
|
|
|
|
"Appointment must be in 'scheduled' status",
|
|
|
|
|
"Current time must be within 10 minutes before to 15 minutes after scheduled end",
|
|
|
|
|
"Both client and therapist can join using the same URL"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Response({
|
|
|
|
|
'message': 'Therapy Appointment API',
|
|
|
|
|
'version': '1.0.0',
|
|
|
|
|
'base_url': base_url,
|
|
|
|
|
'project_structure': {
|
|
|
|
|
'admin': '/admin/ - Django admin interface',
|
|
|
|
|
'authentication': '/api/auth/ - User authentication and management',
|
|
|
|
|
'appointments': '/api/meetings/ - Appointment booking system'
|
|
|
|
|
},
|
|
|
|
|
'endpoints': endpoints,
|
|
|
|
|
|
|
|
|
|
'appointment_workflows': {
|
|
|
|
|
'client_booking_flow': [
|
|
|
|
|
'1. GET /api/meetings/appointments/available-dates/ - Check available dates',
|
|
|
|
|
'2. POST /api/meetings/appointments/create/ - Submit appointment request',
|
|
|
|
|
'3. GET /api/meetings/user/appointments/ - Track request status',
|
|
|
|
|
'4. Receive email notification when scheduled/rejected'
|
|
|
|
|
],
|
|
|
|
|
'admin_management_flow': [
|
|
|
|
|
'1. PUT /api/meetings/admin/availability/ - Set weekly availability',
|
|
|
|
|
'2. GET /api/meetings/appointments/ - Review pending requests',
|
|
|
|
|
'3. POST /api/meetings/appointments/{id}/schedule/ - Schedule appointment OR',
|
|
|
|
|
'4. POST /api/meetings/appointments/{id}/reject/ - Reject with reason',
|
|
|
|
|
'5. GET /api/meetings/appointments/stats/ - Monitor performance'
|
|
|
|
|
],
|
|
|
|
|
'status_lifecycle': [
|
|
|
|
|
'pending_review → scheduled (with datetime)',
|
|
|
|
|
'pending_review → rejected (with optional reason)'
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'authentication_flows': {
|
|
|
|
|
'registration_flow': [
|
|
|
|
|
'1. POST /api/auth/register/ - Register user and send OTP',
|
|
|
|
|
'2. POST /api/auth/verify-otp/ - Verify email with OTP',
|
|
|
|
|
'3. POST /api/auth/login/ - Login with credentials'
|
|
|
|
|
],
|
|
|
|
|
'password_reset_flow': [
|
|
|
|
|
'1. POST /api/auth/forgot-password/ - Request password reset OTP',
|
|
|
|
|
'2. POST /api/auth/verify-password-reset-otp/ - Verify OTP',
|
|
|
|
|
'3. POST /api/auth/reset-password/ - Set new password'
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'quick_start': {
|
|
|
|
|
'for_users': [
|
|
|
|
|
'1. Register: POST /api/auth/register/',
|
|
|
|
|
'2. Verify email: POST /api/auth/verify-otp/',
|
|
|
|
|
'3. Login: POST /api/auth/login/',
|
|
|
|
|
'4. Check availability: GET /api/meetings/appointments/available-dates/',
|
|
|
|
|
'5. Book appointment: POST /api/meetings/appointments/create/'
|
|
|
|
|
],
|
|
|
|
|
'for_admins': [
|
|
|
|
|
'1. Login to Django admin: /admin/',
|
|
|
|
|
'2. Set availability: PUT /api/meetings/admin/availability/',
|
|
|
|
|
'3. Manage appointments: GET /api/meetings/appointments/',
|
|
|
|
|
'4. Schedule/Reject: Use specific appointment endpoints'
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'data_specifications': {
|
|
|
|
|
'appointment': {
|
|
|
|
|
'status_choices': [
|
|
|
|
|
'pending_review - Initial state, awaiting admin action',
|
|
|
|
|
'scheduled - Approved with specific date/time',
|
|
|
|
|
'rejected - Not accepted, with optional reason'
|
|
|
|
|
],
|
|
|
|
|
'time_slot_choices': [
|
|
|
|
|
'morning - 9AM to 12PM',
|
|
|
|
|
'afternoon - 1PM to 5PM',
|
|
|
|
|
'evening - 6PM to 9PM'
|
|
|
|
|
],
|
|
|
|
|
'preferred_dates_format': 'YYYY-MM-DD (array of strings)',
|
|
|
|
|
'encrypted_fields': [
|
|
|
|
|
'first_name', 'last_name', 'email', 'phone',
|
|
|
|
|
'reason', 'rejection_reason'
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
'availability': {
|
|
|
|
|
'day_format': '0=Monday, 1=Tuesday, ..., 6=Sunday',
|
|
|
|
|
'example': '[0, 1, 2, 3, 4] for Monday-Friday'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'authentication_notes': {
|
|
|
|
|
'token_usage': 'Include JWT token in Authorization header: Bearer <token>',
|
|
|
|
|
'token_refresh': 'Use refresh token to get new access token when expired',
|
|
|
|
|
'permissions': {
|
|
|
|
|
'public_endpoints': 'No authentication required',
|
|
|
|
|
'user_endpoints': 'Valid JWT token required',
|
|
|
|
|
'admin_endpoints': 'Staff user with valid JWT token required'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|