package service import ( "errors" "dating-app/internal/models" "dating-app/internal/repository" ) const MaxPhotosPerUser = 6 var ( ErrTooManyPhotos = errors.New("حداکثر تعداد عکس مجاز رو داری") ErrPhotoNotOwned = errors.New("این عکس متعلق به تو نیست") ErrInvalidImage = errors.New("فرمت فایل باید jpg، png یا webp باشه") ErrImageTooLarge = errors.New("حجم عکس نباید بیشتر از ۵ مگابایت باشه") ) const MaxPhotoSizeBytes = 5 * 1024 * 1024 type ProfileService struct { photoRepo *repository.PhotoRepository userRepo *repository.UserRepository storage PhotoStorage } func NewProfileService(photoRepo *repository.PhotoRepository, userRepo *repository.UserRepository, storage PhotoStorage) *ProfileService { return &ProfileService{photoRepo: photoRepo, userRepo: userRepo, storage: storage} } var allowedImageExts = map[string]bool{ ".jpg": true, ".jpeg": true, ".png": true, ".webp": true, } func (s *ProfileService) UploadPhoto(userID uint, ext string, data []byte) (*models.Photo, error) { if !allowedImageExts[ext] { return nil, ErrInvalidImage } if len(data) > MaxPhotoSizeBytes { return nil, ErrImageTooLarge } count, err := s.photoRepo.CountByUser(userID) if err != nil { return nil, err } if count >= MaxPhotosPerUser { return nil, ErrTooManyPhotos } url, err := s.storage.Save(userID, ext, data) if err != nil { return nil, err } photo := &models.Photo{UserID: userID, URL: url, SortOrder: int(count)} if err := s.photoRepo.Create(photo); err != nil { return nil, err } return photo, nil } func (s *ProfileService) DeletePhoto(userID, photoID uint) error { photo, err := s.photoRepo.FindByID(photoID) if err != nil { return err } if photo.UserID != userID { return ErrPhotoNotOwned } if err := s.photoRepo.Delete(photoID); err != nil { return err } return s.storage.Delete(photo.URL) } // DeletePhotoAdmin مثل DeletePhoto ولی بدون چک مالکیت؛ برای نظارت محتوایی // ادمین که باید بتونه هر عکسی رو صرف‌نظر از صاحبش حذف کنه. func (s *ProfileService) DeletePhotoAdmin(photoID uint) error { photo, err := s.photoRepo.FindByID(photoID) if err != nil { return err } if err := s.photoRepo.Delete(photoID); err != nil { return err } return s.storage.Delete(photo.URL) } func (s *ProfileService) ListPhotos(userID uint) ([]models.Photo, error) { return s.photoRepo.ListByUser(userID) } func (s *ProfileService) UpdateLocation(user *models.User, lat, lng float64) error { return s.userRepo.UpdateFields(user, map[string]interface{}{ "latitude": lat, "longitude": lng, }) }