- Add BookingService with core booking management functionality - Implement mock repositories for testing booking service interactions - Create booking integration test with Jitsi room generation - Add methods for creating, retrieving, and managing bookings - Integrate Jitsi service for generating meeting room URLs - Implement schedule management within booking service - Add support for booking creation with user and schedule context - Enhance database layer to support repository retrieval Closes #TICKET_NUMBER (if applicable)
93 lines
2.6 KiB
Go
93 lines
2.6 KiB
Go
package services
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"attune-heart-therapy/internal/config"
|
|
)
|
|
|
|
// jitsiService implements the JitsiService interface
|
|
type jitsiService struct {
|
|
config *config.JitsiConfig
|
|
}
|
|
|
|
// NewJitsiService creates a new instance of JitsiService
|
|
func NewJitsiService(cfg *config.JitsiConfig) JitsiService {
|
|
return &jitsiService{
|
|
config: cfg,
|
|
}
|
|
}
|
|
|
|
// CreateMeeting creates a new Jitsi meeting room for a booking
|
|
func (j *jitsiService) CreateMeeting(bookingID uint, scheduledAt time.Time) (*JitsiMeeting, error) {
|
|
// Generate a unique room ID
|
|
roomID, err := j.generateRoomID(bookingID)
|
|
if err != nil {
|
|
log.Printf("Failed to generate room ID for booking %d: %v", bookingID, err)
|
|
return nil, fmt.Errorf("failed to generate room ID: %w", err)
|
|
}
|
|
|
|
// Generate the meeting URL
|
|
roomURL := j.GetMeetingURL(roomID)
|
|
|
|
meeting := &JitsiMeeting{
|
|
RoomID: roomID,
|
|
RoomURL: roomURL,
|
|
}
|
|
|
|
log.Printf("Created Jitsi meeting for booking %d: Room ID %s", bookingID, roomID)
|
|
return meeting, nil
|
|
}
|
|
|
|
// GetMeetingURL generates the full Jitsi meeting URL for a given room ID
|
|
func (j *jitsiService) GetMeetingURL(roomID string) string {
|
|
baseURL := j.config.BaseURL
|
|
if baseURL == "" {
|
|
// Default to meet.jit.si if no base URL is configured
|
|
baseURL = "https://meet.jit.si"
|
|
}
|
|
|
|
// Ensure the base URL doesn't end with a slash
|
|
if baseURL[len(baseURL)-1] == '/' {
|
|
baseURL = baseURL[:len(baseURL)-1]
|
|
}
|
|
|
|
return fmt.Sprintf("%s/%s", baseURL, roomID)
|
|
}
|
|
|
|
// DeleteMeeting handles cleanup of a Jitsi meeting room
|
|
// Note: Jitsi Meet doesn't require explicit room deletion as rooms are ephemeral
|
|
// This method is implemented for interface compliance and future extensibility
|
|
func (j *jitsiService) DeleteMeeting(roomID string) error {
|
|
// Jitsi Meet rooms are ephemeral and don't require explicit deletion
|
|
// However, we can log the deletion for audit purposes
|
|
log.Printf("Meeting room %s marked for cleanup", roomID)
|
|
|
|
// In the future, if using Jitsi as a Service (JaaS) or custom deployment,
|
|
// this method could make API calls to clean up resources
|
|
|
|
return nil
|
|
}
|
|
|
|
// generateRoomID creates a unique room identifier for the meeting
|
|
func (j *jitsiService) generateRoomID(bookingID uint) (string, error) {
|
|
// Generate a random component for uniqueness
|
|
randomBytes := make([]byte, 8)
|
|
_, err := rand.Read(randomBytes)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to generate random bytes: %w", err)
|
|
}
|
|
|
|
randomHex := hex.EncodeToString(randomBytes)
|
|
|
|
// Create a room ID that includes the booking ID and timestamp for uniqueness
|
|
timestamp := time.Now().Unix()
|
|
roomID := fmt.Sprintf("booking-%d-%d-%s", bookingID, timestamp, randomHex)
|
|
|
|
return roomID, nil
|
|
}
|