backend-service/docs/PERSONALIZED_MEETING_LINKS.md
ats-tech25 04f2d02afc docs(api comprehensive API documentation for attune Heart Therapy
Add detailed API:
- Complete API documentation for In Format Usage flow diagrams for authentication and booking processes
- Comprehensive endpoint descriptions with request/response examples
- Detailed authentication and booking flow explanations
- Structured documentation for health checks, authentication, and booking endpoints
-: - Includes JWT authentication details
usage
- Provides clear API usage patterns for users and clients and administrators
system interactions
- Enhances project documentation with provides clear, structured API reference
- Improves developer and user understanding of system capabilities
2025-11-07 19:22:46 +00:00

324 lines
9.0 KiB
Markdown

# Personalized Meeting Links Implementation
## Overview
All meeting links are now personalized with the user's name and role-specific settings. This ensures users join meetings with their actual names instead of generic identifiers, and admins get appropriate moderator privileges.
## Changes Made
### 1. API Endpoints with Personalized Links
#### GET /api/bookings
Returns the authenticated user's bookings with personalized meeting links.
**Response Example:**
```json
{
"bookings": [
{
"id": 123,
"user_id": 45,
"scheduled_at": "2024-01-15T10:00:00Z",
"duration": 60,
"status": "scheduled",
"jitsi_room_id": "booking-123-1234567890-abc123",
"jitsi_room_url": "https://meet.jit.si/booking-123-1234567890-abc123",
"personalized_meeting_url": "https://meet.jit.si/booking-123-1234567890-abc123#userInfo.displayName=\"John Doe\"",
"amount": 100.00,
"payment_status": "succeeded"
}
]
}
```
**Key Fields:**
- `jitsi_room_url`: Original Jitsi room URL (kept for backward compatibility)
- `personalized_meeting_url`: User-specific URL with their name pre-filled
#### GET /api/admin/bookings
Returns all bookings with admin's personalized meeting links.
**Response Example:**
```json
{
"bookings": [
{
"id": 123,
"user_id": 45,
"scheduled_at": "2024-01-15T10:00:00Z",
"duration": 60,
"status": "scheduled",
"jitsi_room_id": "booking-123-1234567890-abc123",
"jitsi_room_url": "https://meet.jit.si/booking-123-1234567890-abc123",
"admin_meeting_url": "https://meet.jit.si/booking-123-1234567890-abc123#userInfo.displayName=\"Dr. Smith\"&config.startWithAudioMuted=false&config.startWithVideoMuted=false",
"amount": 100.00,
"payment_status": "succeeded"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
**Key Fields:**
- `admin_meeting_url`: Admin-specific URL with moderator privileges
#### GET /api/meetings/:id/link
Returns a personalized meeting link for a specific booking.
**Response Example:**
```json
{
"booking_id": 123,
"meeting_url": "https://meet.jit.si/booking-123-1234567890-abc123#userInfo.displayName=\"John Doe\"",
"display_name": "John Doe",
"is_admin": false,
"scheduled_at": "2024-01-15T10:00:00Z",
"duration": 60,
"status": "scheduled"
}
```
### 2. Email Notifications
All email notifications now include personalized meeting links:
#### Meeting Info Email (After Booking)
- Sent to: **User**
- Link includes: User's name
- Example: `https://meet.jit.si/room-id#userInfo.displayName="John Doe"`
#### Reminder Email (Before Meeting)
- Sent to: **User**
- Link includes: User's name
- Example: `https://meet.jit.si/room-id#userInfo.displayName="John Doe"`
**Note:** Admin users receive emails with admin privileges in the link if they book for themselves.
### 3. Display Name Logic
The system determines display names in this order:
1. **First Name + Last Name**: `"John Doe"`
2. **Email**: If name fields are empty, uses email address
3. **Fallback**: Email as last resort
### 4. Admin vs Regular User Differences
#### Regular User Link
```
https://meet.jit.si/room-id#userInfo.displayName="John Doe"
```
**Features:**
- Name pre-filled
- Standard participant permissions
- Default audio/video settings
#### Admin User Link
```
https://meet.jit.si/room-id#userInfo.displayName="Dr. Smith"&config.startWithAudioMuted=false&config.startWithVideoMuted=false
```
**Features:**
- Name pre-filled
- Moderator privileges
- Audio and video enabled by default
- Can manage participants
- Can start/stop recording (if configured)
## Frontend Implementation Guide
### Using Personalized Links from /api/bookings
```javascript
// Fetch user's bookings
async function fetchMyBookings() {
const response = await fetch('/api/bookings', {
headers: {
'Authorization': `Bearer ${userToken}`
}
});
const data = await response.json();
// Use personalized_meeting_url instead of jitsi_room_url
data.bookings.forEach(booking => {
if (booking.personalized_meeting_url) {
console.log(`Join link: ${booking.personalized_meeting_url}`);
}
});
}
```
### Using Admin Links from /api/admin/bookings
```javascript
// Fetch all bookings as admin
async function fetchAllBookings() {
const response = await fetch('/api/admin/bookings', {
headers: {
'Authorization': `Bearer ${adminToken}`
}
});
const data = await response.json();
// Use admin_meeting_url for admin access
data.bookings.forEach(booking => {
if (booking.admin_meeting_url) {
console.log(`Admin join link: ${booking.admin_meeting_url}`);
}
});
}
```
### React Component Example
```jsx
function BookingCard({ booking, isAdmin }) {
const getMeetingLink = () => {
if (isAdmin && booking.admin_meeting_url) {
return booking.admin_meeting_url;
}
return booking.personalized_meeting_url || booking.jitsi_room_url;
};
const handleJoinMeeting = () => {
const meetingLink = getMeetingLink();
window.open(meetingLink, '_blank');
};
return (
<div className="booking-card">
<h3>Booking #{booking.id}</h3>
<p>Scheduled: {new Date(booking.scheduled_at).toLocaleString()}</p>
{booking.status === 'scheduled' && (
<button onClick={handleJoinMeeting}>
{isAdmin ? 'Join as Moderator' : 'Join Meeting'}
</button>
)}
</div>
);
}
```
## Migration Guide
### Before (Old Implementation)
```javascript
// Direct use of jitsi_room_url
<a href={booking.jitsi_room_url} target="_blank">
Join Meeting
</a>
```
**Problems:**
- Users join as "Booking ID" or generic name
- No admin differentiation
- Same link for everyone
### After (New Implementation)
```javascript
// Use personalized_meeting_url for users
<button onClick={() => window.open(booking.personalized_meeting_url, '_blank')}>
Join Meeting
</button>
// Use admin_meeting_url for admins
<button onClick={() => window.open(booking.admin_meeting_url, '_blank')}>
Join as Moderator
</button>
```
**Benefits:**
- Users join with their actual names
- Admins get moderator privileges
- Better user experience
## Testing Checklist
### Test as Regular User
1. ✅ Login as regular user
2. ✅ Create a booking
3. ✅ Call `GET /api/bookings`
4. ✅ Verify `personalized_meeting_url` contains your name
5. ✅ Open the URL and confirm name appears in Jitsi
6. ✅ Check email notification has personalized link
### Test as Admin
1. ✅ Login as admin
2. ✅ Call `GET /api/admin/bookings`
3. ✅ Verify `admin_meeting_url` contains admin name and moderator config
4. ✅ Open the URL and confirm moderator privileges
5. ✅ Verify audio/video enabled by default
6. ✅ Check email notification has admin link (if admin books for themselves)
### Test Email Notifications
1. ✅ Create a booking
2. ✅ Check "Meeting Info" email
3. ✅ Verify "Join Meeting" button uses personalized link
4. ✅ Click link and confirm name is pre-filled
5. ✅ Wait for reminder email
6. ✅ Verify reminder also has personalized link
## Security Considerations
### Authorization
- Regular users can only access their own bookings via `/api/bookings`
- Admins can access all bookings via `/api/admin/bookings`
- `/api/meetings/:id/link` enforces ownership or admin check
### Link Sharing
- Personalized links include user-specific information
- Links are generated on-demand, not stored
- Original `jitsi_room_url` remains unchanged in database
### Token Expiration
- All endpoints require valid JWT authentication
- Expired tokens require re-authentication
- Meeting links remain valid regardless of token expiration
## Backward Compatibility
The `jitsi_room_url` field is still present in all responses for backward compatibility. However, frontends should migrate to using:
- `personalized_meeting_url` for regular users
- `admin_meeting_url` for admins
- `/api/meetings/:id/link` endpoint for dynamic link generation
## Troubleshooting
### Issue: Name still shows as "Booking ID"
**Solution:** Ensure you're using `personalized_meeting_url` or `admin_meeting_url` instead of `jitsi_room_url`
### Issue: Admin doesn't have moderator privileges
**Solution:**
1. Verify user's `is_admin` field is `true` in database
2. Check that `admin_meeting_url` includes moderator config parameters
3. Ensure using `/api/admin/bookings` endpoint, not `/api/bookings`
### Issue: Email links don't have personalized URLs
**Solution:**
1. Verify notification service is generating personalized URLs
2. Check email template uses `{{.JoinURL}}` field
3. Ensure user has valid first/last name or email
### Issue: Display name is email instead of name
**Solution:** Update user's `first_name` and `last_name` fields in the database
## Future Enhancements
Potential improvements:
1. **Custom Display Names**: Allow users to set custom display names
2. **Meeting Roles**: Support different roles beyond admin/user (e.g., observer, presenter)
3. **Link Expiration**: Add time-based expiration to meeting links
4. **Waiting Room**: Implement waiting room for participants before admin joins
5. **Custom Branding**: Add organization-specific branding to Jitsi interface