Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEAD-39: image-feat: add s3 repository #8

Open
wants to merge 5 commits into
base: DEAD-15
Choose a base branch
from
Open

Conversation

AlexNov03
Copy link
Collaborator

No description provided.

@AlexNov03 AlexNov03 changed the base branch from main to DEAD-15 October 26, 2024 00:27
@AlexNov03 AlexNov03 requested a review from ilyushkaaa October 26, 2024 19:41
@@ -0,0 +1,20 @@
services:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а зачем отдельный docker-compose файл под минио?

Comment on lines +14 to +15
SetAvatarImage(ctx context.Context, data *domain.ImageData, userID domain.UserID) (domain.ImageURL, error)
DeleteAvatarImage(ctx context.Context, userID domain.UserID) error
Copy link
Collaborator

@ilyushkaaa ilyushkaaa Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут можно бы назвать исключив слово Avatar: SetImage, DeleteImage. Они находятся в интерфейсе юзкейса Аватарок, соответственно и так понятно, что метод относится к ним


imageData := new(domain.ImageData)

file, fileHeader, multipartErr := utils.DecodeImage(r, h.cfg)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да можно было бы и просто  err, она тут ни с чем не пересекается. Обычно ошибкам дают какие то названия кроме err, если только назвав err перетрется ранее присвоенное в err значение, которое пригодится в дальнейшем. А тут нет такой проблемы

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

там в другом проблема, это ошибка типа restErr а ниже err определяется типа internalError, там типы перекрываются, поэтому нейминг другой

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

можно было конечно сделать

var err error 

и тогда под этот интерфейс оба типа бы подходили

Comment on lines +36 to +37
if errors.Is(err, interr.ErrNotFound) {
if errors.Is(err, interr.ErrNotFound) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

чтобы наверняка?)))

Comment on lines +16 to +17
SetFieldImage(ctx context.Context, data *domain.ImageData, fieldID domain.FieldID) (domain.ImageURL, error)
DeleteFieldImage(ctx context.Context, fieldID domain.FieldID) error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну и здесь тоже аналогично тому что выше по неймингу

Comment on lines +70 to +75
err = h.UC.FieldImage.DeleteFieldImage(r.Context(), fieldID)

if err != nil {
utils.ProcessInternalServerError(h.log, w, err)
return
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а тут у нас не может быть not found?

return nil, interr.NewInternalError(err, "unable to upload photo")
}

url, err := r.MinioAdapter.PresignedGetObject(ctx, r.BucketName, imageID, time.Second*60*60*24, nil)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

давай константыой хотя бы, а еще лучше конфигом время хранения объекта будем задавать

Comment on lines +75 to +77
} else {
return "", interr.NewInternalError(err, "error while viewing image by imageID")
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else можем опустить

Comment on lines +16 to +19
type Repository struct {
mu sync.RWMutex
Fields map[domain.FieldID]*domain.ImageID
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

уже бы хорошо такое хранить в каких либо inmemory хранилищах, например в redis. Рестартнется сервис и потеряются все записи в мапе

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а вообще, почему мы это в бд не храним просто в виде поля к блоку?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а, ну этим еще параллельно Ваня занимается. Хорошо бы это потом поправить когда его логика будет готова

func (r *Repository) GetUserInfo(ctx context.Context, userID domain.UserID) (*domain.UserInfo, error) {
q := `SELECT (registration_date, extra_info, num_subscribers, num_subscriptions,
avatar_url, first_name, last_name)
func (r *Repository) GetUserInfo(ctx context.Context, userID domain.UserID) (*domain.UserInfo, *domain.ImageID, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

хорошо бы завести вообще специальные объекты, с которыми мы будем оперировать на уровне базы- dto, чтобы туда из SQL запросов инфа о бюзере складывалась, а то странновато что мы imageID прям каким то отдельным полем возвращаем, это же тоже к юзеру относится

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну это ладно, посмотрим насколько успевать будем

Comment on lines +134 to +137
_, err := r.PG.Exec(ctx, q, avatarID, userID)
if err != nil {
return interr.NewInternalError(err, "user Repository.UpdateUserAvatarID pg.Exec")
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

то что не найден такой аккаунт хорошо б обработать

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

как и в других таких местах, по примеру как ты сделал GetUserAvatarID

Comment on lines +64 to +69
err = uc.repo.ImageRepo.DeleteImage(ctx, *imageID)
if err != nil {
return err
}

return uc.repo.UserRepo.ClearUserAvatarID(ctx, userID)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не очень нравится, что если не получилось очистить Avatar id, то мы будем на ошибки нарываться потом при получении его. Хорошо бы обработать этот момент конечно. Но ладно, посмотрим по времени

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

так он просто ошибку выше прокинет и на уровне хэндлеров мы ее обработаем, разве отличается от конструкции

if err := uc.repo.UserRepo.ClearUserAvatarID(ctx, userID); err != nil {
      return err
}
return nil 


Comment on lines +64 to +67
err = uc.repo.ImageRepo.DeleteImage(ctx, *imageID)
if err != nil {
return err
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
err = uc.repo.ImageRepo.DeleteImage(ctx, *imageID)
if err != nil {
return err
}
if err = uc.repo.ImageRepo.DeleteImage(ctx, *imageID); err != nil {
return err
}

)

func DecodeImage(r *http.Request, cfg *bootstrap.Config) (multipart.File, *multipart.FileHeader, resterr.RestErr) {
err := r.ParseMultipartForm(10 << 20)
Copy link
Collaborator

@ilyushkaaa ilyushkaaa Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это тоже хорошо бы в константу, а лучше в конфиг.

return resterr.NewBadRequestError("formfile is not valid")
}

_, _ = f.Seek(0, 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

странновато выглядит. Надо бы ошибку обработать как будто бы если возвращает

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну я не обработал потому что сдвиг курсора в начало на 0 символов по идее никогда не должен ошибки возвращать, там проблемы обычно бывают если от текущей позиции курсор сдвигаем и он перескакивает через конец содержимого

Comment on lines +43 to +47
for _, validType := range cfg.Image.ValidTypes {
if mimeType == validType {
return nil
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в конфигах можно мапы делать и в них парсить, так было бы чуть оптимальнее, за o(1) времени всегда бы здесь разбирались

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

жесткий хайлоад)))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну здесь больше 7-10 типов точно не будет, так что я не стал, по факту и так константа

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну это по факту такой цикл будет на каждый запрос связанный с картинкой. Это да, понятно, что мы не ляжем конечно же от такого. Но по сложности реализации это равноценные решения, никаких проблем в том, чтобы сделать немного оптимальнее я не вижу

Comment on lines +44 to +49
if curAvatarID != nil {
err := uc.repo.ImageRepo.DeleteImage(ctx, *curAvatarID)
if err != nil {
return "", err
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а там не получится просто обновить, без удаления?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я просто метод обновить картинку убрал из слоя репозиториев, хз сильно ли он нужен

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

с одной стороны чуть побыстрее будет, вместо двух операций одна, с другой стороны чуть побольше логики придется дописать

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну могу просто свой удаленный код вернуть и update делать

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

давай одним методом обновлять. Раз есть возможность, надо его использовать. Когда я говорил про то, что можно обновление и добавление картинки совместить, я имел в виду апи конец. Внутри на уровне репозитория конечно же CRUD должен быть

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну да, ты прав тем более здесь по идее может сильно больше времени тратиться

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants