package repository import ( "github.com/topfans/backend/pkg/logger" "github.com/topfans/backend/services/taskService/model" "go.uber.org/zap" "gorm.io/gorm" ) type OnboardingRepository interface { GetOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error) GetOrCreateOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error) UpdateOnboardingStatus(status *model.UserOnboardingStatus) error GetUserOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error) GetOrCreateOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error) ListActiveStageConfigs() ([]*model.OnboardingStageConfig, error) ListUserOnboardingProgressByUser(userID int64) ([]*model.UserOnboardingProgress, error) GetStageConfig(stage int) (*model.OnboardingStageConfig, error) } type onboardingRepository struct { db *gorm.DB } func NewOnboardingRepository(db *gorm.DB) OnboardingRepository { return &onboardingRepository{db: db} } func (r *onboardingRepository) GetOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error) { var status model.UserOnboardingStatus err := r.db.Where("user_id = ?", userID).First(&status).Error if err != nil { return nil, err } return &status, nil } func (r *onboardingRepository) GetOrCreateOnboardingStatus(userID int64) (*model.UserOnboardingStatus, error) { var status model.UserOnboardingStatus now := gorm.NowFunc().Unix() err := r.db.Where("user_id = ?", userID).FirstOrCreate(&status, &model.UserOnboardingStatus{ UserID: userID, CurrentStage: 0, Status: "pending", CreatedAt: now, UpdatedAt: now, }).Error if err != nil { logger.Logger.Error("Failed to GetOrCreateOnboardingStatus", zap.Int64("user_id", userID), zap.Error(err)) return nil, err } return &status, nil } func (r *onboardingRepository) UpdateOnboardingStatus(status *model.UserOnboardingStatus) error { status.UpdatedAt = gorm.NowFunc().Unix() if err := r.db.Save(status).Error; err != nil { logger.Logger.Error("Failed to UpdateOnboardingStatus", zap.Int64("user_id", status.UserID), zap.Error(err)) return err } return nil } func (r *onboardingRepository) GetUserOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error) { var progress model.UserOnboardingProgress err := r.db.Where("user_id = ? AND task_key = ?", userID, taskKey).First(&progress).Error if err != nil { return nil, err } return &progress, nil } func (r *onboardingRepository) GetOrCreateOnboardingProgress(userID int64, taskKey string) (*model.UserOnboardingProgress, error) { var progress model.UserOnboardingProgress now := gorm.NowFunc().Unix() err := r.db.Where("user_id = ? AND task_key = ?", userID, taskKey).FirstOrCreate(&progress, &model.UserOnboardingProgress{ UserID: userID, TaskKey: taskKey, Status: "pending", CreatedAt: now, UpdatedAt: now, }).Error if err != nil { logger.Logger.Error("Failed to GetOrCreateOnboardingProgress", zap.Int64("user_id", userID), zap.String("task_key", taskKey), zap.Error(err)) return nil, err } return &progress, nil } func (r *onboardingRepository) ListActiveStageConfigs() ([]*model.OnboardingStageConfig, error) { var configs []*model.OnboardingStageConfig err := r.db.Where("is_active = ?", true).Order("sort_order ASC").Find(&configs).Error if err != nil { logger.Logger.Error("Failed to ListActiveStageConfigs", zap.Error(err)) return nil, err } return configs, nil } func (r *onboardingRepository) ListUserOnboardingProgressByUser(userID int64) ([]*model.UserOnboardingProgress, error) { var progressList []*model.UserOnboardingProgress err := r.db.Where("user_id = ?", userID).Find(&progressList).Error if err != nil { logger.Logger.Error("Failed to ListUserOnboardingProgressByUser", zap.Int64("user_id", userID), zap.Error(err)) return nil, err } return progressList, nil } func (r *onboardingRepository) GetStageConfig(stage int) (*model.OnboardingStageConfig, error) { var config model.OnboardingStageConfig err := r.db.Where("stage = ? AND is_active = ?", stage, true).First(&config).Error if err != nil { return nil, err } return &config, nil }