package services import ( "context" "fmt" "github.com/photoplaces/backend/internal/models" "github.com/photoplaces/backend/internal/repository" ) type PlaceService struct { placeRepo *repository.PlaceRepo } func NewPlaceService(placeRepo *repository.PlaceRepo) *PlaceService { return &PlaceService{placeRepo: placeRepo} } type CreatePlaceInput struct { OwnerID string Type string Title string Description *string Address *string Lat float64 Lng float64 CoverImage *string AccessInfo *string HourlyRate *int Currency string MinHours int Tags []models.Tag Features []models.Feature } func (s *PlaceService) Create(ctx context.Context, input CreatePlaceInput) (*models.Place, error) { place := &models.Place{ Type: input.Type, OwnerID: input.OwnerID, Title: input.Title, Description: input.Description, Address: input.Address, Lat: input.Lat, Lng: input.Lng, CoverImage: input.CoverImage, AccessInfo: input.AccessInfo, Status: "pending_moderation", HourlyRate: input.HourlyRate, Currency: input.Currency, MinHours: input.MinHours, Tags: input.Tags, Features: input.Features, } if err := s.placeRepo.Create(ctx, place); err != nil { return nil, fmt.Errorf("create place: %w", err) } return place, nil } func (s *PlaceService) GetByID(ctx context.Context, id string, fetchTags bool) (*models.Place, error) { place, err := s.placeRepo.GetByID(ctx, id) if err != nil { return nil, err } if place == nil { return nil, nil } if fetchTags { tags, err := s.placeRepo.GetTags(ctx, id) if err != nil { return nil, err } place.Tags = tags features, err := s.placeRepo.GetFeatures(ctx, id) if err != nil { return nil, err } place.Features = features } return place, nil } func (s *PlaceService) List(ctx context.Context, filter models.PlaceFilter) ([]*models.Place, error) { return s.placeRepo.List(ctx, filter) } type UpdatePlaceInput struct { ID string OwnerID string Title *string Description *string Address *string Lat *float64 Lng *float64 CoverImage *string AccessInfo *string HourlyRate *int Currency *string MinHours *int } func (s *PlaceService) Update(ctx context.Context, input UpdatePlaceInput, isModerator bool) (*models.Place, error) { place, err := s.placeRepo.GetByID(ctx, input.ID) if err != nil { return nil, err } if place == nil { return nil, nil } if input.Title != nil { place.Title = *input.Title } if input.Description != nil { place.Description = input.Description } if input.Address != nil { place.Address = input.Address } if input.Lat != nil { place.Lat = *input.Lat } if input.Lng != nil { place.Lng = *input.Lng } if input.CoverImage != nil { place.CoverImage = input.CoverImage } if input.AccessInfo != nil { place.AccessInfo = input.AccessInfo } if input.HourlyRate != nil { place.HourlyRate = input.HourlyRate } if input.Currency != nil { place.Currency = *input.Currency } if input.MinHours != nil { place.MinHours = *input.MinHours } if !isModerator { place.Status = "pending_moderation" } if err := s.placeRepo.Update(ctx, place); err != nil { return nil, err } return place, nil } func (s *PlaceService) Moderate(ctx context.Context, id, action, comment, moderatorID string) error { var status string switch action { case "approve": status = "published" case "reject": status = "rejected" default: return fmt.Errorf("unknown action: %s", action) } return s.placeRepo.UpdateStatus(ctx, id, status, comment) } func (s *PlaceService) Delete(ctx context.Context, id string) error { return s.placeRepo.SoftDelete(ctx, id) }