package users import ( "context" "encoding/json" "fmt" "net/http" "reflect" "strings" "time" "fr.latosa-escrima/core" "fr.latosa-escrima/core/models" ) type UpdateUserArgs struct { FirstName *string `json:"firstname,omitempty"` LastName *string `json:"lastname,omitempty"` Email *string `json:"email,omitempty"` Password *string `json:"password,omitempty"` Phone *string `json:"phone,omitempty"` Attributes *models.UserAttributes `json:"attributes"` } func HandleUpdate(w http.ResponseWriter, r *http.Request) { var updateArgs UpdateUserArgs err := json.NewDecoder(r.Body).Decode(&updateArgs) if err != nil { core.JSONError{ Status: core.Error, Message: err.Error(), }.Respond(w, http.StatusInternalServerError) return } var user models.User updateQuery := core.DB.NewUpdate().Model(&user) val := reflect.ValueOf(updateArgs) typ := reflect.TypeOf(updateArgs) for i := 0; i < val.NumField(); i++ { field := val.Field(i) fieldname := typ.Field(i).Name tag := typ.Field(i).Tag.Get("bun") if tag == "" { tag = typ.Field(i).Tag.Get("json") } // Only add fields that are non-nil and non-zero if field.IsValid() && !field.IsNil() && !field.IsZero() { if fieldname == "Password" { updateQuery.Set(fmt.Sprintf("%s = crypt(?, gen_salt('bf'))", strings.Split(tag, ",")[0]), field.Interface()) } else { updateQuery.Set(fmt.Sprintf("%s = ?", strings.Split(tag, ",")[0]), field.Interface()) } } } // Always update the `updated_at` field updateQuery.Set("updated_at = ?", time.Now()) uuid := r.PathValue("user_uuid") _, err = updateQuery. Where("user_id = ?", uuid). Returning("*"). Exec(context.Background()) if err != nil { core.JSONError{ Status: core.Error, Message: err.Error(), }.Respond(w, http.StatusInternalServerError) return } user.Password = "" core.JSONSuccess{ Status: core.Success, Message: "User updated.", Data: user, }.Respond(w, http.StatusOK) }