Yimaru-BackEnd/internal/services/learnernotifications/service.go
2026-06-09 05:11:16 -07:00

109 lines
3.8 KiB
Go

package learnernotifications
import (
"context"
"fmt"
"time"
"Yimaru-Backend/internal/domain"
notificationservice "Yimaru-Backend/internal/services/notification"
)
// Service sends learner-facing in-app and push notifications.
type Service struct {
notifications *notificationservice.Service
}
func New(notifications *notificationservice.Service) *Service {
return &Service{notifications: notifications}
}
func (s *Service) NotifyWelcome(userID int64) {
s.send(userID, domain.NOTIFICATION_TYPE_USER_WELCOME, domain.NotificationLevelSuccess,
"Welcome to Yimaru Academy",
"Your account is ready. Start learning and track your progress across programs and courses.")
}
func (s *Service) NotifyModuleCompleted(userID int64, moduleName string) {
s.send(userID, domain.NOTIFICATION_TYPE_MODULE_COMPLETED, domain.NotificationLevelSuccess,
"Module completed",
fmt.Sprintf("Great work! You completed the module \"%s\".", moduleName))
}
func (s *Service) NotifyCourseCompleted(userID int64, courseName string) {
s.send(userID, domain.NOTIFICATION_TYPE_COURSE_COMPLETED, domain.NotificationLevelSuccess,
"Course completed",
fmt.Sprintf("Congratulations! You completed the course \"%s\".", courseName))
}
func (s *Service) NotifyProgramCompleted(userID int64, programName string) {
s.send(userID, domain.NOTIFICATION_TYPE_PROGRAM_COMPLETED, domain.NotificationLevelSuccess,
"Program completed",
fmt.Sprintf("Amazing achievement! You completed the program \"%s\".", programName))
}
func (s *Service) NotifyLearnPackageSubscribed(userID int64, planName string) {
s.send(userID, domain.NOTIFICATION_TYPE_SUBSCRIPTION_ACTIVATED, domain.NotificationLevelSuccess,
"Subscription active",
fmt.Sprintf("Your \"%s\" Learn English package is now active. Enjoy your learning journey!", planName))
}
func (s *Service) NotifyLearnPackageExpiringSoon(userID int64, planName string, expiresAt time.Time) {
s.send(userID, domain.NOTIFICATION_TYPE_SUBSCRIPTION_EXPIRING, domain.NotificationLevelWarning,
"Subscription expiring soon",
fmt.Sprintf("Your \"%s\" package expires on %s. Renew to keep uninterrupted access.", planName, expiresAt.Format("Jan 2, 2006")))
}
func (s *Service) MaybeNotifyLearnPackageSubscribed(userID int64, planCategory, planName string) {
if planCategory == string(domain.SubscriptionCategoryLearnEnglish) {
s.NotifyLearnPackageSubscribed(userID, planName)
}
}
func (s *Service) NotifyLMSPracticeMilestones(userID int64, result domain.LMSPracticeCompletionResult) {
if result.ModuleCompleted != nil {
s.NotifyModuleCompleted(userID, result.ModuleCompleted.Name)
}
if result.CourseCompleted != nil {
s.NotifyCourseCompleted(userID, result.CourseCompleted.Name)
}
if result.ProgramCompleted != nil {
s.NotifyProgramCompleted(userID, result.ProgramCompleted.Name)
}
}
func (s *Service) SendLearnPackageExpiryReminders(reminders []domain.SubscriptionExpiryReminder) {
for _, r := range reminders {
s.NotifyLearnPackageExpiringSoon(r.UserID, r.PlanName, r.ExpiresAt)
}
}
func (s *Service) send(userID int64, notifType domain.NotificationType, level domain.NotificationLevel, headline, message string) {
if s == nil || s.notifications == nil || userID == 0 {
return
}
go func() {
ctx := context.Background()
for _, channel := range []domain.DeliveryChannel{
domain.DeliveryChannelInApp,
domain.DeliveryChannelPush,
} {
notification := &domain.Notification{
RecipientID: userID,
ReceiverType: domain.ReceiverTypeUser,
Type: notifType,
Level: level,
Reciever: domain.NotificationRecieverSideCustomer,
DeliveryChannel: channel,
DeliveryStatus: domain.DeliveryStatusPending,
IsRead: false,
Payload: domain.NotificationPayload{
Headline: headline,
Message: message,
},
}
_ = s.notifications.SendNotification(ctx, notification)
}
}()
}