package services import ( "errors" "gauth-central/internal/database" "gauth-central/internal/models" "gorm.io/gorm" ) type ResumeService struct{} func NewResumeService() *ResumeService { return &ResumeService{} } // CreateResume creates a new resume configuration. func (s *ResumeService) CreateResume(title, titleSub, education, experience, codingSkills, knowledge string, isActive bool) (*models.Resume, error) { item := models.Resume{ Title: title, TitleSub: titleSub, Education: education, Experience: experience, CodingSkills: codingSkills, Knowledge: knowledge, IsActive: isActive, } err := database.DB.Transaction(func(tx *gorm.DB) error { if isActive { // Deactivate all other resumes if err := tx.Model(&models.Resume{}).Where("is_active = ?", true).Update("is_active", false).Error; err != nil { return err } } if err := tx.Create(&item).Error; err != nil { return err } return nil }) if err != nil { return nil, err } return s.GetResumeByID(item.ID.String()) } // GetAllResumes retrieves all resumes. Use onlyActive to filter public data. // For admin (onlyActive=false), it returns basic info. // For public (onlyActive=true), it preloads all related data (Educations, Experiences, etc.) func (s *ResumeService) GetAllResumes(onlyActive bool) ([]models.Resume, error) { var items []models.Resume query := database.DB.Order("created_at desc") if onlyActive { query = query.Where("is_active = ?", true). Preload("Educations", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("created_at desc") }). Preload("Experiences", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("created_at desc") }). Preload("Skills", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("degree desc") }). Preload("Knowledges", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("created_at desc") }) } if err := query.Find(&items).Error; err != nil { return nil, err } return items, nil } // GetFirstActiveResume returns the single active resume with all relations preloaded. func (s *ResumeService) GetFirstActiveResume() (*models.Resume, error) { var item models.Resume query := database.DB.Where("is_active = ?", true).Order("created_at desc"). Preload("Educations", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("created_at desc") }). Preload("Experiences", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("created_at desc") }). Preload("Skills", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("degree desc") }). Preload("Knowledges", func(db *gorm.DB) *gorm.DB { return db.Where("is_active = ?", true).Order("created_at desc") }) if err := query.First(&item).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errors.New("resume not found") } return nil, err } return &item, nil } // GetResumeByID retrieves a resume by ID. func (s *ResumeService) GetResumeByID(id string) (*models.Resume, error) { var item models.Resume if err := database.DB.Where("id = ?", id). Preload("Educations"). Preload("Experiences"). Preload("Skills"). Preload("Knowledges"). First(&item).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errors.New("resume not found") } return nil, err } return &item, nil } // UpdateResume updates an existing resume entry. func (s *ResumeService) UpdateResume(id string, title, titleSub, education, experience, codingSkills, knowledge *string, isActive *bool) (*models.Resume, error) { item, err := s.GetResumeByID(id) if err != nil { return nil, err } updates := map[string]interface{}{} if title != nil { updates["title"] = *title } if titleSub != nil { updates["title_sub"] = *titleSub } if education != nil { updates["education"] = *education } if experience != nil { updates["experience"] = *experience } if codingSkills != nil { updates["coding_skills"] = *codingSkills } if knowledge != nil { updates["knowledge"] = *knowledge } if isActive != nil { updates["is_active"] = *isActive } if len(updates) > 0 { err := database.DB.Transaction(func(tx *gorm.DB) error { if isActive != nil && *isActive { // Deactivate all other resumes except the current one if err := tx.Model(&models.Resume{}).Where("id != ? AND is_active = ?", id, true).Update("is_active", false).Error; err != nil { return err } } if err := tx.Model(item).Updates(updates).Error; err != nil { return err } return nil }) if err != nil { return nil, err } } return s.GetResumeByID(id) } // DeleteResume deletes a resume by ID. func (s *ResumeService) DeleteResume(id string) error { result := database.DB.Delete(&models.Resume{}, "id = ?", id) if result.Error != nil { return result.Error } if result.RowsAffected == 0 { return errors.New("resume not found") } return nil }