refactor: update api and client to reference humanIds

This commit is contained in:
talksik
2026-03-24 19:08:51 -07:00
parent 3bf3f16be7
commit 57a1cbc696
24 changed files with 666 additions and 416 deletions
+76 -65
View File
@@ -15,23 +15,23 @@ var ErrInvalidName = errors.New("name cannot be empty")
var ErrCapacityExceeded = errors.New("active stream capacity exceeded")
type Service interface {
// Create creates a network and adds adminEmail as the first member. Returns ErrInvalidName if name is empty.
Create(ctx context.Context, name, adminEmail string) (*Network, error)
// Create creates a network and adds adminHumanId as the first member. Returns ErrInvalidName if name is empty.
Create(ctx context.Context, name, adminHumanId string) (*Network, error)
// GetByID returns ErrNotFound if network doesn't exist.
GetByID(ctx context.Context, id string) (*Network, error)
// SetName returns ErrNotFound or ErrInvalidName.
SetName(ctx context.Context, id, name string) error
AddMembers(ctx context.Context, networkID string, emails []string) error
RemoveMember(ctx context.Context, networkID, email string) error
ListForEmail(ctx context.Context, email string) ([]*Network, error)
IsMember(ctx context.Context, networkID, email string) (bool, error)
AddMembers(ctx context.Context, networkID string, humanIds []string) error
RemoveMember(ctx context.Context, networkID, humanId string) error
ListForHuman(ctx context.Context, humanId string) ([]*Network, error)
IsMember(ctx context.Context, networkID, humanId string) (bool, error)
// SetOpenStreamCapacity sets the max open streams for a network. Returns ErrNotFound.
SetOpenStreamCapacity(ctx context.Context, networkID string, capacity int) error
// IncrementOpenStreamCount returns ErrNotFound or ErrCapacityExceeded.
IncrementOpenStreamCount(ctx context.Context, networkID string) error
// DecrementOpenStreamCount returns ErrNotFound.
DecrementOpenStreamCount(ctx context.Context, networkID string) error
// Invitations (email-based, for users who haven't registered yet)
InviteByEmail(ctx context.Context, networkID string, emails []string) error
ListInvitationsForEmail(ctx context.Context, email string) ([]*Invitation, error)
ListInvitationsForNetwork(ctx context.Context, networkID string) ([]*Invitation, error)
AcceptInvitation(ctx context.Context, networkID, email, humanId string) error
RevokeInvitation(ctx context.Context, networkID, email string) error
}
type serviceImpl struct {
@@ -42,23 +42,18 @@ func NewService(pool *pgxpool.Pool) Service {
return &serviceImpl{repo: newRepository(pool)}
}
func (s *serviceImpl) Create(ctx context.Context, name, adminEmail string) (*Network, error) {
func (s *serviceImpl) Create(ctx context.Context, name, adminHumanId string) (*Network, error) {
name = strings.TrimSpace(name)
if name == "" {
return nil, ErrInvalidName
}
adminEmail, err := utils.NormalizeEmail(adminEmail)
network, err := s.repo.create(ctx, name, adminHumanId)
if err != nil {
return nil, err
}
network, err := s.repo.create(ctx, name, adminEmail)
if err != nil {
return nil, err
}
err = s.AddMembers(ctx, network.ID, []string{adminEmail})
err = s.AddMembers(ctx, network.ID, []string{adminHumanId})
if err != nil {
return nil, err
}
@@ -87,69 +82,85 @@ func (s *serviceImpl) SetName(ctx context.Context, id, name string) error {
return err
}
func (s *serviceImpl) AddMembers(ctx context.Context, networkID string, emails []string) error {
for _, email := range emails {
normalized, err := utils.NormalizeEmail(email)
if err != nil {
return fmt.Errorf("invalid email: %w", err)
func (s *serviceImpl) AddMembers(ctx context.Context, networkID string, humanIds []string) error {
for _, humanId := range humanIds {
if humanId == "" {
return fmt.Errorf("invalid humanId")
}
if err := s.repo.addMember(ctx, networkID, normalized); err != nil {
if err := s.repo.addMember(ctx, networkID, humanId); err != nil {
return err
}
}
return nil
}
func (s *serviceImpl) RemoveMember(ctx context.Context, networkID, email string) error {
email, err := utils.NormalizeEmail(email)
if err != nil {
return fmt.Errorf("invalid email: %w", err)
func (s *serviceImpl) RemoveMember(ctx context.Context, networkID, humanId string) error {
if humanId == "" {
return fmt.Errorf("invalid humanId")
}
return s.repo.removeMember(ctx, networkID, email)
return s.repo.removeMember(ctx, networkID, humanId)
}
func (s *serviceImpl) ListForEmail(ctx context.Context, email string) ([]*Network, error) {
email, err := utils.NormalizeEmail(email)
func (s *serviceImpl) ListForHuman(ctx context.Context, humanId string) ([]*Network, error) {
if humanId == "" {
return nil, fmt.Errorf("invalid humanId")
}
return s.repo.getNetworksForHuman(ctx, humanId)
}
func (s *serviceImpl) IsMember(ctx context.Context, networkID, humanId string) (bool, error) {
if humanId == "" {
return false, fmt.Errorf("invalid humanId")
}
return s.repo.isMember(ctx, networkID, humanId)
}
// Invitation methods
func (s *serviceImpl) InviteByEmail(ctx context.Context, networkID string, emails []string) error {
for _, email := range emails {
normalized, err := utils.NormalizeEmail(email)
if err != nil {
return fmt.Errorf("invalid email %q: %w", email, err)
}
if err := s.repo.createInvitation(ctx, networkID, normalized); err != nil {
return err
}
}
return nil
}
func (s *serviceImpl) ListInvitationsForEmail(ctx context.Context, email string) ([]*Invitation, error) {
normalized, err := utils.NormalizeEmail(email)
if err != nil {
return nil, fmt.Errorf("invalid email: %w", err)
}
return s.repo.getNetworksForEmail(ctx, email)
return s.repo.getInvitationsByEmail(ctx, normalized)
}
func (s *serviceImpl) IsMember(ctx context.Context, networkID, email string) (bool, error) {
email, err := utils.NormalizeEmail(email)
func (s *serviceImpl) ListInvitationsForNetwork(ctx context.Context, networkID string) ([]*Invitation, error) {
return s.repo.getInvitationsByNetwork(ctx, networkID)
}
func (s *serviceImpl) AcceptInvitation(ctx context.Context, networkID, email, humanId string) error {
normalized, err := utils.NormalizeEmail(email)
if err != nil {
return false, err
return fmt.Errorf("invalid email: %w", err)
}
return s.repo.isMember(ctx, networkID, email)
if humanId == "" {
return fmt.Errorf("invalid humanId")
}
if err := s.repo.deleteInvitation(ctx, networkID, normalized); err != nil {
return err
}
return s.repo.addMember(ctx, networkID, humanId)
}
func (s *serviceImpl) SetOpenStreamCapacity(ctx context.Context, networkID string, capacity int) error {
if capacity < 0 {
capacity = 0
func (s *serviceImpl) RevokeInvitation(ctx context.Context, networkID, email string) error {
normalized, err := utils.NormalizeEmail(email)
if err != nil {
return fmt.Errorf("invalid email: %w", err)
}
err := s.repo.setOpenStreamCapacity(ctx, networkID, capacity)
if errors.Is(err, errNotFound) {
return ErrNotFound
}
return err
}
func (s *serviceImpl) IncrementOpenStreamCount(ctx context.Context, networkID string) error {
err := s.repo.incrementOpenStreamCount(ctx, networkID)
if errors.Is(err, errNotFound) {
return ErrNotFound
}
if errors.Is(err, errCapacityExceeded) {
return ErrCapacityExceeded
}
return err
}
func (s *serviceImpl) DecrementOpenStreamCount(ctx context.Context, networkID string) error {
err := s.repo.decrementOpenStreamCount(ctx, networkID)
if errors.Is(err, errNotFound) {
return ErrNotFound
}
return err
return s.repo.deleteInvitation(ctx, networkID, normalized)
}