Files
Snip/backend/internal/adapter/memory/user_repo.go
T
2026-06-15 21:25:57 +07:00

61 lines
1.2 KiB
Go

package memory
import (
"context"
"crypto/rand"
"sync"
"github.com/snip/backend/internal/domain"
)
type UserRepo struct {
mu sync.RWMutex
byID map[string]*domain.User
byKey map[string]string // provider|subject -> id
}
func NewUserRepo() *UserRepo {
return &UserRepo{byID: make(map[string]*domain.User), byKey: make(map[string]string)}
}
func (r *UserRepo) Upsert(_ context.Context, u *domain.User) (*domain.User, error) {
r.mu.Lock()
defer r.mu.Unlock()
key := u.Provider + "|" + u.Subject
if id, ok := r.byKey[key]; ok {
existing := r.byID[id]
existing.Email = u.Email
existing.Name = u.Name
cp := *existing
return &cp, nil
}
id := randomID()
u.ID = id
r.byID[id] = u
r.byKey[key] = id
cp := *u
return &cp, nil
}
func (r *UserRepo) GetByID(_ context.Context, id string) (*domain.User, error) {
r.mu.RLock()
defer r.mu.RUnlock()
u, ok := r.byID[id]
if !ok {
return nil, domain.ErrNotFound
}
cp := *u
return &cp, nil
}
func randomID() string {
const hex = "0123456789abcdef"
b := make([]byte, 16)
_, _ = rand.Read(b)
out := make([]byte, 16)
for i := range out {
out[i] = hex[int(b[i])%16]
}
return "u_" + string(out)
}