- Add new `app` package to manage application initialization and lifecycle - Refactor `main.go` to use new application management approach - Implement graceful shutdown with context timeout and signal handling - Add dependency injection container initialization - Enhance logging with configurable log levels and structured logging - Update configuration loading and server initialization process - Modify Jitsi configuration in `.env` for custom deployment - Improve error handling and logging throughout application startup - Centralize application startup and shutdown logic in single package Introduces a more robust and flexible application management system with improved initialization, logging, and shutdown capabilities.
140 lines
3.7 KiB
Go
140 lines
3.7 KiB
Go
package jobs
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// ReminderConfig represents the configuration for reminder scheduling
|
|
type ReminderConfig struct {
|
|
// Default reminder times before the meeting (in minutes)
|
|
DefaultReminders []int `json:"default_reminders"`
|
|
|
|
// Maximum number of reminders per booking
|
|
MaxReminders int `json:"max_reminders"`
|
|
|
|
// Minimum time before meeting to send reminder (in minutes)
|
|
MinReminderTime int `json:"min_reminder_time"`
|
|
|
|
// Whether reminders are enabled globally
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
// DefaultReminderConfig returns the default reminder configuration
|
|
func DefaultReminderConfig() *ReminderConfig {
|
|
return &ReminderConfig{
|
|
DefaultReminders: []int{1440, 60, 15}, // 24 hours, 1 hour, 15 minutes before
|
|
MaxReminders: 3,
|
|
MinReminderTime: 5, // Don't send reminders less than 5 minutes before
|
|
Enabled: true,
|
|
}
|
|
}
|
|
|
|
// ReminderScheduler handles the scheduling of reminder notifications
|
|
type ReminderScheduler struct {
|
|
config *ReminderConfig
|
|
jobScheduler *JobScheduler
|
|
}
|
|
|
|
// NewReminderScheduler creates a new reminder scheduler
|
|
func NewReminderScheduler(config *ReminderConfig, jobScheduler *JobScheduler) *ReminderScheduler {
|
|
if config == nil {
|
|
config = DefaultReminderConfig()
|
|
}
|
|
|
|
return &ReminderScheduler{
|
|
config: config,
|
|
jobScheduler: jobScheduler,
|
|
}
|
|
}
|
|
|
|
// ScheduleRemindersForBooking schedules all reminders for a booking
|
|
func (rs *ReminderScheduler) ScheduleRemindersForBooking(bookingID uint, userID uint, meetingTime time.Time) error {
|
|
if !rs.config.Enabled {
|
|
return nil
|
|
}
|
|
|
|
now := time.Now()
|
|
scheduledCount := 0
|
|
|
|
for _, reminderMinutes := range rs.config.DefaultReminders {
|
|
if scheduledCount >= rs.config.MaxReminders {
|
|
break
|
|
}
|
|
|
|
reminderTime := meetingTime.Add(-time.Duration(reminderMinutes) * time.Minute)
|
|
|
|
// Skip if reminder time is in the past
|
|
if reminderTime.Before(now) {
|
|
continue
|
|
}
|
|
|
|
// Skip if reminder is too close to the meeting
|
|
if meetingTime.Sub(reminderTime).Minutes() < float64(rs.config.MinReminderTime) {
|
|
continue
|
|
}
|
|
|
|
// Schedule the reminder job
|
|
rs.jobScheduler.ScheduleReminderJob(bookingID, userID, reminderTime)
|
|
scheduledCount++
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CancelRemindersForBooking cancels all scheduled reminders for a booking
|
|
func (rs *ReminderScheduler) CancelRemindersForBooking(bookingID uint) error {
|
|
// In a production system, this would mark the reminders as cancelled in a persistent store
|
|
// For now, we'll just log the cancellation
|
|
// The actual implementation would depend on how jobs are persisted
|
|
return nil
|
|
}
|
|
|
|
// UpdateReminderConfig updates the reminder configuration
|
|
func (rs *ReminderScheduler) UpdateReminderConfig(config *ReminderConfig) {
|
|
rs.config = config
|
|
}
|
|
|
|
// GetReminderConfig returns the current reminder configuration
|
|
func (rs *ReminderScheduler) GetReminderConfig() *ReminderConfig {
|
|
return rs.config
|
|
}
|
|
|
|
// GetNextReminderTime calculates the next reminder time for a meeting
|
|
func (rs *ReminderScheduler) GetNextReminderTime(meetingTime time.Time) *time.Time {
|
|
if !rs.config.Enabled {
|
|
return nil
|
|
}
|
|
|
|
now := time.Now()
|
|
|
|
for _, reminderMinutes := range rs.config.DefaultReminders {
|
|
reminderTime := meetingTime.Add(-time.Duration(reminderMinutes) * time.Minute)
|
|
|
|
if reminderTime.After(now) {
|
|
return &reminderTime
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// IsReminderTimeValid checks if a reminder time is valid
|
|
func (rs *ReminderScheduler) IsReminderTimeValid(reminderTime, meetingTime time.Time) bool {
|
|
if !rs.config.Enabled {
|
|
return false
|
|
}
|
|
|
|
// Check if reminder is in the future
|
|
if reminderTime.Before(time.Now()) {
|
|
return false
|
|
}
|
|
|
|
// Check if reminder is not too close to the meeting
|
|
timeDiff := meetingTime.Sub(reminderTime).Minutes()
|
|
if timeDiff < float64(rs.config.MinReminderTime) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|