diff --git a/gqlgen.yml b/gqlgen.yml index 8ec8478..bd51335 100755 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -15,6 +15,8 @@ resolver: package: resolvers filename_template: "{name}.go" +nullable_input_omittable: true + autobind: - github.com/avptp/brain/internal/generated/data diff --git a/internal/api/arguments/main.go b/internal/api/arguments/main.go deleted file mode 100644 index 10b30bb..0000000 --- a/internal/api/arguments/main.go +++ /dev/null @@ -1,25 +0,0 @@ -package arguments - -import ( - "context" - - "github.com/99designs/gqlgen/graphql" -) - -func GetFields(ctx context.Context, name string) []string { - fieldContext := graphql.GetFieldContext(ctx) - - names := []string{} - - for _, arg := range fieldContext.Field.Arguments { - if arg.Name != name { - continue - } - - for _, child := range arg.Value.Children { - names = append(names, child.Name) - } - } - - return names -} diff --git a/internal/api/resolvers/person.go b/internal/api/resolvers/person.go index 8c54e9a..34d5812 100755 --- a/internal/api/resolvers/person.go +++ b/internal/api/resolvers/person.go @@ -9,7 +9,6 @@ import ( "entgo.io/contrib/entgql" "github.com/alexedwards/argon2id" - "github.com/avptp/brain/internal/api/arguments" "github.com/avptp/brain/internal/api/reporting" "github.com/avptp/brain/internal/auth" "github.com/avptp/brain/internal/generated/api" @@ -29,15 +28,19 @@ func (r *mutationResolver) CreatePerson(ctx context.Context, input api.CreatePer d := data.FromContext(ctx) // transactional data client for mutations allowCtx := privacy.DecisionContext(ctx, privacy.Allow) - p, err := d.Person. + create := d.Person. Create(). SetEmail(input.Email). SetPassword(input.Password). SetTaxID(input.TaxID). SetFirstName(input.FirstName). - SetNillableLastName(input.LastName). - SetLanguage(input.Language). - Save(allowCtx) + SetLanguage(input.Language) + + if input.LastName.IsSet() { + create.SetNillableLastName(input.LastName.Value()) + } + + p, err := create.Save(allowCtx) if err != nil { return nil, err @@ -53,77 +56,91 @@ func (r *mutationResolver) UpdatePerson(ctx context.Context, input api.UpdatePer d := data.FromContext(ctx) // transactional data client for mutations update := d.Person.UpdateOneID(input.ID) - // This is not clean, but it is an option until "gqlgen" makes it - // possible to distinguish between undefined and null fields. - // See: https://github.com/99designs/gqlgen/issues/1416 - fields := arguments.GetFields(ctx, "input") - - for _, key := range fields { - switch key { - case "email": - if v := input.Email; v != nil { - update.SetEmail(*v) - } - case "phone": - if v := input.Phone; v != nil { - update.SetPhone(*v) - } else { - update.ClearPhone() - } - case "taxId": - if v := input.TaxID; v != nil { - update.SetTaxID(*v) - } - case "firstName": - if v := input.FirstName; v != nil { - update.SetFirstName(*v) - } - case "lastName": - if v := input.LastName; v != nil { - update.SetLastName(*v) - } else { - update.ClearLastName() - } - case "language": - if v := input.Language; v != nil { - update.SetLanguage(*v) - } - case "birthdate": - if v := input.Birthdate; v != nil { - update.SetBirthdate(*v) - } else { - update.ClearBirthdate() - } - case "gender": - if v := input.Gender; v != nil { - update.SetGender(*v) - } else { - update.ClearGender() - } - case "address": - if v := input.Address; v != nil { - update.SetAddress(*v) - } else { - update.ClearAddress() - } - case "postalCode": - if v := input.PostalCode; v != nil { - update.SetPostalCode(*v) - } else { - update.ClearPostalCode() - } - case "city": - if v := input.City; v != nil { - update.SetCity(*v) - } else { - update.ClearCity() - } - case "country": - if v := input.Country; v != nil { - update.SetCountry(*v) - } else { - update.ClearCountry() - } + if input.Email.IsSet() { + if v := input.Email.Value(); v != nil { + update.SetEmail(*v) + } + } + + if input.Phone.IsSet() { + if v := input.Phone.Value(); v != nil { + update.SetPhone(*v) + } else { + update.ClearPhone() + } + } + + if input.TaxID.IsSet() { + if v := input.TaxID.Value(); v != nil { + update.SetTaxID(*v) + } + } + + if input.FirstName.IsSet() { + if v := input.FirstName.Value(); v != nil { + update.SetFirstName(*v) + } + } + + if input.LastName.IsSet() { + if v := input.LastName.Value(); v != nil { + update.SetLastName(*v) + } else { + update.ClearLastName() + } + } + + if input.Language.IsSet() { + if v := input.Language.Value(); v != nil { + update.SetLanguage(*v) + } + } + + if input.Birthdate.IsSet() { + if v := input.Birthdate.Value(); v != nil { + update.SetBirthdate(*v) + } else { + update.ClearBirthdate() + } + } + + if input.Gender.IsSet() { + if v := input.Gender.Value(); v != nil { + update.SetGender(*v) + } else { + update.ClearGender() + } + } + + if input.Address.IsSet() { + if v := input.Address.Value(); v != nil { + update.SetAddress(*v) + } else { + update.ClearAddress() + } + } + + if input.PostalCode.IsSet() { + if v := input.PostalCode.Value(); v != nil { + update.SetPostalCode(*v) + } else { + update.ClearPostalCode() + } + } + + if input.City.IsSet() { + if v := input.City.Value(); v != nil { + update.SetCity(*v) + } else { + update.ClearCity() + } + } + + if input.Country.IsSet() { + if v := input.Country.Value(); v != nil { + update.SetCountry(*v) + } else { + update.ClearCountry() } } diff --git a/internal/generated/api/exec.go b/internal/generated/api/exec.go index e8c12d6..65e7fa6 100644 --- a/internal/generated/api/exec.go +++ b/internal/generated/api/exec.go @@ -5286,7 +5286,7 @@ func (ec *executionContext) unmarshalInputCreatePersonInput(ctx context.Context, if err != nil { return it, err } - it.LastName = data + it.LastName = graphql.OmittableOf(data) case "language": var err error @@ -5418,7 +5418,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.Email = data + it.Email = graphql.OmittableOf(data) case "phone": var err error @@ -5427,7 +5427,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.Phone = data + it.Phone = graphql.OmittableOf(data) case "taxId": var err error @@ -5436,7 +5436,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.TaxID = data + it.TaxID = graphql.OmittableOf(data) case "firstName": var err error @@ -5445,7 +5445,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.FirstName = data + it.FirstName = graphql.OmittableOf(data) case "lastName": var err error @@ -5454,7 +5454,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.LastName = data + it.LastName = graphql.OmittableOf(data) case "language": var err error @@ -5463,7 +5463,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.Language = data + it.Language = graphql.OmittableOf(data) case "birthdate": var err error @@ -5472,7 +5472,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.Birthdate = data + it.Birthdate = graphql.OmittableOf(data) case "gender": var err error @@ -5481,7 +5481,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.Gender = data + it.Gender = graphql.OmittableOf(data) case "address": var err error @@ -5490,7 +5490,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.Address = data + it.Address = graphql.OmittableOf(data) case "postalCode": var err error @@ -5499,7 +5499,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.PostalCode = data + it.PostalCode = graphql.OmittableOf(data) case "city": var err error @@ -5508,7 +5508,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.City = data + it.City = graphql.OmittableOf(data) case "country": var err error @@ -5517,7 +5517,7 @@ func (ec *executionContext) unmarshalInputUpdatePersonInput(ctx context.Context, if err != nil { return it, err } - it.Country = data + it.Country = graphql.OmittableOf(data) } } diff --git a/internal/generated/api/model.go b/internal/generated/api/model.go index 261f601..c0db10a 100644 --- a/internal/generated/api/model.go +++ b/internal/generated/api/model.go @@ -5,6 +5,7 @@ package api import ( "time" + "github.com/99designs/gqlgen/graphql" "github.com/avptp/brain/internal/generated/data" "github.com/avptp/brain/internal/generated/data/person" "github.com/google/uuid" @@ -20,13 +21,13 @@ type CreateAuthenticationPayload struct { } type CreatePersonInput struct { - Email string `json:"email"` - Password string `json:"password"` - TaxID string `json:"taxId"` - FirstName string `json:"firstName"` - LastName *string `json:"lastName,omitempty"` - Language string `json:"language"` - Captcha string `json:"captcha"` + Email string `json:"email"` + Password string `json:"password"` + TaxID string `json:"taxId"` + FirstName string `json:"firstName"` + LastName graphql.Omittable[*string] `json:"lastName,omitempty"` + Language string `json:"language"` + Captcha string `json:"captcha"` } type CreatePersonPayload struct { @@ -52,19 +53,19 @@ type DeletePersonPayload struct { } type UpdatePersonInput struct { - ID uuid.UUID `json:"id"` - Email *string `json:"email,omitempty"` - Phone *string `json:"phone,omitempty"` - TaxID *string `json:"taxId,omitempty"` - FirstName *string `json:"firstName,omitempty"` - LastName *string `json:"lastName,omitempty"` - Language *string `json:"language,omitempty"` - Birthdate *time.Time `json:"birthdate,omitempty"` - Gender *person.Gender `json:"gender,omitempty"` - Address *string `json:"address,omitempty"` - PostalCode *string `json:"postalCode,omitempty"` - City *string `json:"city,omitempty"` - Country *string `json:"country,omitempty"` + ID uuid.UUID `json:"id"` + Email graphql.Omittable[*string] `json:"email,omitempty"` + Phone graphql.Omittable[*string] `json:"phone,omitempty"` + TaxID graphql.Omittable[*string] `json:"taxId,omitempty"` + FirstName graphql.Omittable[*string] `json:"firstName,omitempty"` + LastName graphql.Omittable[*string] `json:"lastName,omitempty"` + Language graphql.Omittable[*string] `json:"language,omitempty"` + Birthdate graphql.Omittable[*time.Time] `json:"birthdate,omitempty"` + Gender graphql.Omittable[*person.Gender] `json:"gender,omitempty"` + Address graphql.Omittable[*string] `json:"address,omitempty"` + PostalCode graphql.Omittable[*string] `json:"postalCode,omitempty"` + City graphql.Omittable[*string] `json:"city,omitempty"` + Country graphql.Omittable[*string] `json:"country,omitempty"` } type UpdatePersonPasswordInput struct {