Skip to content

Commit

Permalink
FEAT: Adding logic for Get Account Resolvers" (#32)
Browse files Browse the repository at this point in the history
* feat: adding graphql service for accounts

* feat: adding support for accounts-graphql schema

* fix: scale machines to 0

* fix: fly.toml

* fix: internal port 8080 in production

* fix: change back to port 3000

* fix: move graph into internal

* feat: code generation for gql

* fix: models

* fix: models

* feat: resolvers are fixed

* feat: updating resolver path

* feat: move schemas into their own directory

* fix: moving models to a package

* feat: adding proper generated files package

* feat: adding apollo router locally for dev

* feat: logged todos resolver is called

* fix: empty resolvers

* fix: moving schema configs to dev

* fix: moving schema configs to dev

* feat: adding apolo router

* feat: super graph dev and prod setup

* feat: remove the custom metrics

* fix: deployment for apollo router

* fix: delete older files

* feat: updating dockerfile for router

* fix: remove homepage

* fix: disable homepage

* fix: disable homepage

* fix: router config

* fix: config

* fix: apollo router config

* fix: dockerfile

* fix: dockerfile slashes

* fix: apollo router prod

* fix: prod

* fix: http service for accounts graphql

* fix: revert back to public prod url

* fix: graphql schema

* feat: account model generation

* feat: update prod graph

* fix: use internal routing

* feat: adding accounts internal

* feat: hide accounts-graphql behind VPC

* feat: graphql service generator

* feat: cleanup graphql files

* fix: file generation

* fix: further cleanup

* fix: remove unwanted package in go workspace

* feat: calling accounts api from accounts graph

* feat: updating supergraph schema with prod

* refactor: change name to account_service handler

* feat: adding uuid validation for account

* fix: models to query by commonID

* feat: abstracting lru cache and other caches to their own package

* fix: move data center deployments closer to US-East

* feat: supporting get account by commonID or Email gRPC

* feat: updating graphs
  • Loading branch information
ericzorn93 authored Jan 4, 2025
1 parent 3d4afb7 commit 4dada06
Show file tree
Hide file tree
Showing 25 changed files with 955 additions and 243 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@ func (r *RegistrationServiceHandler) CreateAccount(
ctx context.Context,
req *connect.Request[accountsapiv1.CreateAccountRequest],
) (*connect.Response[accountsapiv1.CreateAcountResponse], error) {
commonID, err := valueobjects.NewCommonIDFromString(req.Msg.CommonId)
if err != nil {
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid common ID: %w", err))
}
commonID := valueobjects.NewCommonIDFromString(req.Msg.CommonId)
emailAddress := valueobjects.NewEmailAddress(req.Msg.EmailAddress)

// Convert to user domain type
user := entities.NewUser(
entities.WithCommonID(commonID),
entities.WithEmailAddress(req.Msg.EmailAddress),
entities.WithEmailAddress(emailAddress),
entities.WithUserUsername(req.Msg.Username),
)

Expand All @@ -62,21 +60,29 @@ func (r *RegistrationServiceHandler) GetAccount(
ctx context.Context,
req *connect.Request[accountsapiv1.GetAccountRequest],
) (*connect.Response[accountsapiv1.GetAccountResponse], error) {
commonID, err := valueobjects.NewCommonIDFromString(req.Msg.CommonId)
if err != nil {
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid common ID: %w", err))

// Parse the commonID vs emailAddress, depending on which one is passed
var commonID valueobjects.CommonID
var emailAddress valueobjects.EmailAddress

if req.Msg.CommonId != nil {
commonID = valueobjects.NewCommonIDFromString(*req.Msg.CommonId)
}

if req.Msg.EmailAddress != nil {
emailAddress = valueobjects.NewEmailAddress(*req.Msg.EmailAddress)
}

// Get the user from the database
user, err := r.App.RegistrationService.GetUser(ctx, commonID)
user, err := r.App.RegistrationService.GetUser(ctx, commonID, emailAddress)
if err != nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("user not found: %w", err))
}

// Convert to proto types
account := &accountsDomain.Account{
CommonId: user.CommonID.String(),
EmailAddress: user.EmailAddress,
EmailAddress: user.EmailAddress.String(),
Username: user.Username,
CreatedAt: timestamppb.New(user.CreatedAt),
UpdatedAt: timestamppb.New(user.UpdatedAt),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (r AccountRepository) CreateAccount(ctx context.Context, user userEntities.
// Create account
account := &models.Account{
CommonID: user.CommonID.Value(),
EmailAddress: user.EmailAddress,
EmailAddress: user.EmailAddress.String(),
UserName: user.Username,
}

Expand All @@ -50,8 +50,8 @@ func (r AccountRepository) CreateAccount(ctx context.Context, user userEntities.
return nil
}

// GetAccount gets an account from the database by commonID
func (r AccountRepository) GetAccount(ctx context.Context, commonID userValueObjects.CommonID) (userEntities.User, error) {
// GetAccountByCommonID gets an account from the database by commonID
func (r AccountRepository) GetAccountByCommonID(ctx context.Context, commonID userValueObjects.CommonID) (userEntities.User, error) {
r.Logger.Info("Getting account", slog.String("commonID", commonID.String()))

account := &models.Account{}
Expand All @@ -61,13 +61,33 @@ func (r AccountRepository) GetAccount(ctx context.Context, commonID userValueObj
return userEntities.User{}, errors.New("account not found")
}

return r.convertAccountToUser(account), nil
}

// GetAccountByEmailAddress gets an account from the database by email address
func (r AccountRepository) GetAccountByEmailAddress(ctx context.Context, emailAdress userValueObjects.EmailAddress) (userEntities.User, error) {
r.Logger.Info("Getting account", slog.String("emailAdress", emailAdress.String()))

account := &models.Account{}
r.Database.First(account, "email_address = ?", emailAdress.Value())

if account.ID == uuid.Nil {
return userEntities.User{}, errors.New("account not found")
}

return r.convertAccountToUser(account), nil
}

// convertAccountToUser converts an account to a user
func (r AccountRepository) convertAccountToUser(account *models.Account) userEntities.User {
parsedCommonID := userValueObjects.NewCommonIDFromUUID(account.CommonID)
parsedEmailAddress := userValueObjects.NewEmailAddress(account.EmailAddress)

return userEntities.NewUser(
userEntities.WithCommonID(parsedCommonID),
userEntities.WithEmailAddress(account.EmailAddress),
userEntities.WithEmailAddress(parsedEmailAddress),
userEntities.WithUserUsername(account.UserName),
userEntities.WithCreatedAt(account.CreatedAt),
userEntities.WithUpdatedAt(account.UpdatedAt),
), nil
)
}
4 changes: 2 additions & 2 deletions apps/services/accounts-api/internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "apps/services/accounts-api/internal/app/ports"
// App is the application struct
type App struct {
// RegistrationService is the registration service
RegistrationService ports.RegistrationService
RegistrationService ports.AccountService
}

// AppOption is the option for the application
Expand All @@ -23,7 +23,7 @@ func NewApp(opts ...AppOption) App {
}

// WithRegistrationService sets the registration service in the application
func WithRegistrationService(service ports.RegistrationService) AppOption {
func WithRegistrationService(service ports.AccountService) AppOption {
return func(a *App) {
a.RegistrationService = service
}
Expand Down
7 changes: 5 additions & 2 deletions apps/services/accounts-api/internal/app/ports/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ type AccountRepository interface {
// CreateAccount creates an account in the database
CreateAccount(context.Context, userEntities.User) error

// GetAccount gets an account from the database by commonID
GetAccount(context.Context, userValueObjects.CommonID) (userEntities.User, error)
// GetAccountByCommonID gets an account from the database by commonID
GetAccountByCommonID(context.Context, userValueObjects.CommonID) (userEntities.User, error)

// GetAccountByEmailAddress gets an account from the database by email address
GetAccountByEmailAddress(context.Context, userValueObjects.EmailAddress) (userEntities.User, error)
}
6 changes: 3 additions & 3 deletions apps/services/accounts-api/internal/app/ports/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
userValueObjects "libs/backend/domain/user/valueobjects"
)

// RegistrationService is the interface for the registration service
type RegistrationService interface {
// AccountService is the interface for the registration service
type AccountService interface {
// RegisterUser registers a user in the system and the database
RegisterUser(ctx context.Context, user userEntities.User) error

// GetUser gets a user from the system
GetUser(ctx context.Context, commonID userValueObjects.CommonID) (userEntities.User, error)
GetUser(ctx context.Context, commonID userValueObjects.CommonID, emailAddress userValueObjects.EmailAddress) (userEntities.User, error)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package services
import (
"apps/services/accounts-api/internal/app/ports"
"context"
"errors"
"libs/backend/boot"
userEntities "libs/backend/domain/user/entities"
userValueObjects "libs/backend/domain/user/valueobjects"
Expand Down Expand Up @@ -40,13 +41,27 @@ func (s RegistrationService) RegisterUser(ctx context.Context, user userEntities
}

// GetUser gets a user from the system
func (s RegistrationService) GetUser(ctx context.Context, commonID userValueObjects.CommonID) (userEntities.User, error) {
func (s RegistrationService) GetUser(ctx context.Context, commonID userValueObjects.CommonID, emailAddress userValueObjects.EmailAddress) (userEntities.User, error) {
var err error

s.Logger.Info("Getting user", slog.String("commonID", commonID.String()))

// Get account from the repository
user, err := s.AccountRepository.GetAccount(ctx, commonID)
if err != nil {
return userEntities.NewEmptyUser(), err
// Get account from the repository by commonID or email address
var user userEntities.User

switch {
case !commonID.IsEmpty():
user, err = s.AccountRepository.GetAccountByCommonID(ctx, commonID)
if err != nil {
return userEntities.NewEmptyUser(), err
}
case !emailAddress.IsEmpty():
user, err = s.AccountRepository.GetAccountByEmailAddress(ctx, emailAddress)
if err != nil {
return userEntities.NewEmptyUser(), err
}
default:
return userEntities.NewEmptyUser(), errors.New("commonID or emailAddress must be provided")
}

return user, nil
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4dada06

Please sign in to comment.