-
Notifications
You must be signed in to change notification settings - Fork 0
feat: alter create user to also create an account with 1000 as amount #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,32 @@ | ||
| defmodule BankingAPI.Accounts.Schemas.Account do | ||
| @moduledoc """ | ||
| The entity of Account. | ||
| Account entity. | ||
|
|
||
| 1 user (id) - N accounts (FK user_id) | ||
| 1 account (FK user_id) -> 1 user (id) | ||
| """ | ||
| use Ecto.Schema | ||
|
|
||
| import Ecto.Changeset | ||
|
|
||
| alias BankingAPI.Users.Schemas.User | ||
|
|
||
| @derive {Jason.Encoder, except: [:__meta__]} | ||
| @required [:amount] | ||
|
|
||
| @primary_key {:id, :binary_id, autogenerate: true} | ||
| @foreign_key_type :binary_id | ||
| schema "accounts" do | ||
| belongs_to(:user, User) | ||
| field(:account_number, :integer, read_after_writes: true) | ||
| field(:amount, :integer) | ||
|
|
||
| timestamps() | ||
| end | ||
|
|
||
| def changeset(model \\ %__MODULE__{}, params) do | ||
| model | ||
| |> cast(params, @required) | ||
| |> validate_required(@required) | ||
| |> validate_number(:amount, greater_than_or_equal_to: 0) | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,24 +2,24 @@ defmodule BankingAPI.Users do | |
| @moduledoc """ | ||
| Domain public functions for users context | ||
| """ | ||
| require Logger | ||
|
|
||
| alias BankingAPI.Repo | ||
| alias BankingAPI.Users.Inputs | ||
| alias BankingAPI.Users.Schemas.User | ||
|
|
||
| require Logger | ||
|
|
||
| @doc """ | ||
| Given a VALID changeset it attempts to insert a new user. | ||
| It might fail due to email unique index and we transform that return | ||
| into an error tuple. | ||
| """ | ||
| @spec create(Inputs.Create.t()) :: | ||
| {:ok, User.t()} | {:error, Ecto.Changeset.t() | :email_conflict} | ||
| {:ok, User.t()} | {:error, Ecto.Changeset.t()} | ||
| def create(%Inputs.Create{} = input) do | ||
| Logger.info("Inserting new user") | ||
|
|
||
| params = %{name: input.name, email: input.email} | ||
| new_account = %{amount: 1000} | ||
| params = %{name: input.name, email: input.email, account: new_account} | ||
|
|
||
| params | ||
| |> User.changeset() | ||
|
|
@@ -29,10 +29,6 @@ defmodule BankingAPI.Users do | |
| Logger.info("User successfully inserted", email: inspect(user.email)) | ||
| {:ok, user} | ||
|
|
||
| {:error, %{errors: [email: {"has already been taken", _}]}} -> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Osh, esse caso de erro ainda pode acontecer, não?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Provavelmente o erro vai estourar no controller qnd acontecer
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Siimm, vou refazer o controller namoral agora |
||
| Logger.info("Email already taken") | ||
| {:error, :email_conflict} | ||
|
|
||
| {:error, changeset} -> | ||
| Logger.error("Error while inserting new user", error: inspect(changeset)) | ||
| {:error, changeset} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,12 +4,25 @@ defmodule BankingAPI.Repo.Migrations.CreateAccount do | |
| def change do | ||
| create table(:accounts, primary_key: false) do | ||
| add(:id, :uuid, primary_key: true) | ||
| add(:user_id, references(:users, type: :uuid)) | ||
| add(:amount, :integer) | ||
| add(:user_id, references(:users, type: :uuid), null: false) | ||
| add(:account_number, :serial, null: false) | ||
| add(:amount, :integer, null: false) | ||
|
|
||
| timestamps() | ||
| end | ||
|
|
||
| create( | ||
| constraint(:accounts, "account_number_must_be_between_10000_and_99999", | ||
| check: "account_number >= 10000 and account_number <= 99999" | ||
| ) | ||
| ) | ||
|
|
||
| create(unique_index(:accounts, [:account_number])) | ||
|
|
||
| execute "ALTER SEQUENCE accounts_account_number_seq START with 10000 RESTART" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tem um problema em expor numeros sequenciais publicamente q eh revelar coisas como: quantidade de contas no banco e velocidade em que elas são abertas. No geral, é preferível usar números aleatórios mas não precisa mudar
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eu pensei nisso, mas fiquei com duvida de como faria isso na aplicação. Pois se gerar um número randomico que já exista no banco, ele iria ficar tentando várias vezes até conseguir um número vago (isso quando tiver muitos registros de account number). Tem alguma sugestão para isso?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hoje acontece conflito e a gente retenta e tem resolvido so far. Com 6 digitos são 1 milhão de contas, demora atéo conflito virar um problema. Mas temos uma todo pra resolver isso inclusive. O jeito que pensei é gerar tds os numeros possiveis (até x digitos) e subtrair os existentes numa query (da pra fzr no postgres essa geracao e subtracao), cachear esses numeros e ir tirando aleatoriamente da lista. O cache pode durar alguns minutos pra nao precisar ir no banco toda vez gerar essa lista. Se o cache for numa storage externa tipo redis nem precisa ir no banco de novo, só usar ele pra armazenar essa pool de contas disponiveis
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. É nois, Vou tentar gerar um novo concorrente de peso aqui então. |
||
|
|
||
| create(constraint(:accounts, "ammount_must_be_0_or_positive", check: "amount >= 0")) | ||
|
|
||
| create(index(:accounts, [:user_id])) | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| defmodule BankingAPIWeb.UserView do | ||
| @moduledoc """ | ||
| User view | ||
| """ | ||
| use BankingAPIWeb, :view | ||
|
|
||
| def render("show.json", %{user: user}) do | ||
| %{ | ||
| name: user.name, | ||
| email: user.email, | ||
| account: %{account_number: user.account.account_number, amount: user.account.amount} | ||
| } | ||
| end | ||
| end |
Uh oh!
There was an error while loading. Please reload this page.