feat: avatars for humans (#273)

* implement avatar backend functionality

* add avatar endpoints

* typo

* implement client side avatar upload and handling

* fixes

* Update go/internal/handler/handler.go

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update js/desktop/src/lib/avatar-image.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* bug in order

* remove unused component

* fix invalid migration

* fix syntax errors

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit was merged in pull request #273.
This commit is contained in:
Arjun Patel
2026-06-11 15:30:21 -07:00
committed by GitHub
co-authored by coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
parent ca3bbf204e
commit 4facc6b371
25 changed files with 739 additions and 256 deletions
+25 -1
View File
@@ -11,7 +11,10 @@ import (
//go:generate go tool mockgen -source ./service.go -destination ./mocks/service.go
var ErrNotFound = errors.New("human not found")
var (
ErrNotFound = errors.New("human not found")
ErrInvalidParam = errors.New("invalid param")
)
type Service interface {
GetOrCreateByEmail(ctx context.Context, email string) (*Human, error)
@@ -22,6 +25,8 @@ type Service interface {
ListAll(ctx context.Context) ([]*Human, error)
UpdateEmailNotificationsEnabled(ctx context.Context, id string, enabled bool) error
UpdateLastEmailNotificationSentAt(ctx context.Context, id string, t time.Time) error
UpdateAvatar(ctx context.Context, id string, objectID string) error
DeleteAvatar(ctx context.Context, id string) error
}
type serviceImpl struct {
@@ -88,3 +93,22 @@ func (s *serviceImpl) UpdateLastEmailNotificationSentAt(ctx context.Context, id
}
return err
}
func (s *serviceImpl) UpdateAvatar(ctx context.Context, id string, objectID string) error {
if objectID == "" {
return ErrInvalidParam
}
err := s.repo.updateAvatarObjectID(ctx, id, utils.CreateOptionalString(objectID))
if errors.Is(err, errNotFound) {
return ErrNotFound
}
return err
}
func (s *serviceImpl) DeleteAvatar(ctx context.Context, id string) error {
err := s.repo.updateAvatarObjectID(ctx, id, nil)
if errors.Is(err, errNotFound) {
return ErrNotFound
}
return err
}