package models import ( "errors" "time" "gorm.io/gorm" ) // BookingStatus represents the possible states of a booking type BookingStatus string const ( BookingStatusScheduled BookingStatus = "scheduled" BookingStatusCompleted BookingStatus = "completed" BookingStatusCancelled BookingStatus = "cancelled" ) // PaymentStatus represents the possible states of a payment type PaymentStatus string const ( PaymentStatusPending PaymentStatus = "pending" PaymentStatusSucceeded PaymentStatus = "succeeded" PaymentStatusFailed PaymentStatus = "failed" PaymentStatusRefunded PaymentStatus = "refunded" ) // Booking represents a scheduled meeting type Booking struct { gorm.Model UserID uint `json:"user_id" gorm:"not null;index" validate:"required"` User User `json:"user" gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` ScheduledAt time.Time `json:"scheduled_at" gorm:"not null;index" validate:"required"` Duration int `json:"duration" gorm:"default:60;check:duration > 0" validate:"min=15,max=480"` // minutes, 15min to 8hrs Status BookingStatus `json:"status" gorm:"default:'scheduled';size:20" validate:"required,oneof=scheduled completed cancelled"` JitsiRoomID string `json:"jitsi_room_id" gorm:"size:255;index"` JitsiRoomURL string `json:"jitsi_room_url" gorm:"size:500"` PaymentID string `json:"payment_id" gorm:"size:255;index"` PaymentStatus PaymentStatus `json:"payment_status" gorm:"size:20" validate:"omitempty,oneof=pending succeeded failed refunded"` Amount float64 `json:"amount" gorm:"type:decimal(10,2);check:amount >= 0" validate:"min=0"` Notes string `json:"notes" gorm:"type:text"` } // BeforeCreate is a GORM hook that runs before creating a booking record func (b *Booking) BeforeCreate(tx *gorm.DB) error { // Validate that the scheduled time is in the future if b.ScheduledAt.Before(time.Now()) { return errors.New("booking cannot be scheduled in the past") } // Set default status if not provided if b.Status == "" { b.Status = BookingStatusScheduled } // Set default duration if not provided if b.Duration == 0 { b.Duration = 60 } return nil } // BeforeUpdate is a GORM hook that runs before updating a booking record func (b *Booking) BeforeUpdate(tx *gorm.DB) error { // Prevent updating completed bookings if b.Status == BookingStatusCompleted { return errors.New("cannot modify completed bookings") } return nil } // CanBeCancelled checks if the booking can be cancelled func (b *Booking) CanBeCancelled() bool { return b.Status == BookingStatusScheduled && b.ScheduledAt.After(time.Now().Add(24*time.Hour)) } // CanBeRescheduled checks if the booking can be rescheduled func (b *Booking) CanBeRescheduled() bool { return b.Status == BookingStatusScheduled && b.ScheduledAt.After(time.Now().Add(2*time.Hour)) } // IsUpcoming checks if the booking is scheduled for the future func (b *Booking) IsUpcoming() bool { return b.Status == BookingStatusScheduled && b.ScheduledAt.After(time.Now()) }