Potion/internal/app/service/engagement_service.go
Hayden Hargreaves bebeb25492 (DB/FEAT): Implemented toggle favorite in the backend.
The frontend is half wired up, just need to update the button. I also
want to update the recipe methods to return the favorite status. This
will follow very similar to the way I updated the tags. Another method
which can be called to attach the favorite state.
2025-07-14 21:30:45 -07:00

88 lines
3.3 KiB
Go

package service
import (
"fmt"
domain "github.com/haydenhargreaves/Potion/internal/domain/engagement"
domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
_ "github.com/lib/pq"
)
type EngagementService struct {
engagementRepository domain.EngagementRepository
recipeRepository domainRecipe.RecipeRepository
}
// Compile-time check to ensure the EngagementService implements domain.EngagementService
var _ domain.EngagementService = (*EngagementService)(nil)
// NewUserRepository creates a user repository object which is used by the user service to access
// the database. Any user related database operations will take place in this repository.
func NewEngagementService(engagementRepository domain.EngagementRepository, recipeRepository domainRecipe.RecipeRepository) domain.EngagementService {
return &EngagementService{
engagementRepository: engagementRepository,
recipeRepository: recipeRepository,
}
}
// UserViewRecipe requires a user ID and a recipe ID to create an engagement record in the database.
// A message will be generated using the recipe data and then used to add a view engagement to the
// database.
func (s *EngagementService) UserViewRecipe(userId, recipeId int) (domain.Engagement, error) {
recipe, err := s.recipeRepository.GetRecipe(recipeId)
if err != nil {
return domain.Engagement{}, err
}
message := fmt.Sprintf("Viewed \"%s\"", recipe.Title)
return s.engagementRepository.AddUserEntityEngagement(userId, recipeId, message, domain.EngagementViewed)
}
// UserFavoriteRecipe requires a user ID and a recipe ID to create an engagement record in the database.
// A message will be generated using the recipe data and then used to add a like engagement to the
// database.
func (s *EngagementService) UserFavoriteRecipe(userId, recipeId int) (domain.Engagement, error) {
recipe, err := s.recipeRepository.GetRecipe(recipeId)
if err != nil {
return domain.Engagement{}, err
}
// Update the favorites DB
liked, err := s.engagementRepository.UserFavoriteRecipeToggle(userId, recipeId)
if err != nil {
return domain.Engagement{}, err
}
// Determine if this like is a saving or unsaving
var message string
if liked {
message = fmt.Sprintf("Saved \"%s\"", recipe.Title)
} else {
message = fmt.Sprintf("Unsaved \"%s\"", recipe.Title)
}
return s.engagementRepository.AddUserEntityEngagement(userId, recipeId, message, domain.EngagementLiked)
}
// UserMakeRecipe requires a user ID and a recipe ID to create an engagement record in the database.
// A message will be generated using the recipe data and then used to add a make engagement to the
// database.
func (s *EngagementService) UserMakeRecipe(userId, recipeId int) (domain.Engagement, error) {
recipe, err := s.recipeRepository.GetRecipe(recipeId)
if err != nil {
return domain.Engagement{}, err
}
message := fmt.Sprintf("Made \"%s\"", recipe.Title)
return s.engagementRepository.AddUserEntityEngagement(userId, recipeId, message, domain.EngagementMade)
}
// GetUserEngagement returns a list of the users most recent engagement entries. The number of records
// is determined by the limit passed into this function. The results are sorted, newest-to-oldest.
func (s *EngagementService) GetUserEngagement(userId, limit int) ([]domain.Engagement, error) {
return s.engagementRepository.GetUserEngagement(userId, limit)
}