{"id":19483461,"url":"https://github.com/librity/nlw4_elixir","last_synced_at":"2026-05-17T07:37:46.627Z","repository":{"id":99704532,"uuid":"342637591","full_name":"librity/nlw4_elixir","owner":"librity","description":"Rocket Seat - Next Level Week 4 - Elixir - RocketPay - Payments backend.","archived":false,"fork":false,"pushed_at":"2022-02-25T12:04:57.000Z","size":43,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-08T07:38:03.216Z","etag":null,"topics":["elixir","nlw-4","phoenix-framework","rocketseat","rocketseat-nlw"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/librity.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-26T16:40:55.000Z","updated_at":"2021-04-19T01:58:59.000Z","dependencies_parsed_at":"2023-07-31T13:17:30.156Z","dependency_job_id":null,"html_url":"https://github.com/librity/nlw4_elixir","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fnlw4_elixir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fnlw4_elixir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fnlw4_elixir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fnlw4_elixir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/librity","download_url":"https://codeload.github.com/librity/nlw4_elixir/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240718936,"owners_count":19846482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","nlw-4","phoenix-framework","rocketseat","rocketseat-nlw"],"created_at":"2024-11-10T20:15:13.109Z","updated_at":"2025-11-20T07:02:50.570Z","avatar_url":"https://github.com/librity.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Next Level Week - RocketPay\n\nA payments backend using Elixir, Phoenix and Ecto.\n\n## Endpoints\n\nBuilt-in\n\n- `GET` http://localhost:4000/dashboard/home\n\n`WelocomeController`\n\n- `GET` http://localhost:4000/api/\n- `GET` http://localhost:4000/api/total/:filename\n\n`UsersController`\n\n- `POST` http://localhost:4000/api/users\n\n`AccountsController`\n\n- `POST` http://localhost:4000/api/accounts/:id/deposit\n- `POST` http://localhost:4000/api/accounts/:id/withdraw\n- `POST` http://localhost:4000/api/accounts/transaction\n\n## External Docs\n\n- https://elixir-lang.org/docs.html\n- https://elixir-lang.org/getting-started/basic-types.html\n- https://elixir-lang.org/getting-started/debugging.html\n\n- https://hexdocs.pm/elixir/Kernel.html\n- https://hexdocs.pm/elixir/master/Task.html\n- https://hexdocs.pm/iex/IEx.Helpers.html\n- https://hexdocs.pm/phoenix/Phoenix.html\n- https://hexdocs.pm/ecto/Ecto.html\n- https://hexdocs.pm/decimal/readme.html\n- https://hexdocs.pm/excoveralls/readme.html\n- https://github.com/rrrene/credo/\n\n## Random Tutorials and Questions\n\n- https://www.tutorialspoint.com/elixir/elixir_lists_and_tuples.htm\n- https://www.frankelydiaz.com/blog/i-learned-today-elixir-pipe-operator-calling-a-function-with-more-than-1-parameter\n- https://stackoverflow.com/questions/66379509/elixir-decimal-cast-and-dont-allow-negative-numbers\n- https://stackoverflow.com/questions/31990134/how-to-convert-map-keys-from-strings-to-atoms-in-elixir\n- https://stackoverflow.com/questions/28594646/getting-the-current-date-and-or-time-in-elixir\n- https://stackoverflow.com/questions/47818241/concise-way-to-run-code-0-to-n-times-in-elixir\n\n## Postgres\n\nCreate a new docker container with:\n\n```bash\n$ docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres\n```\n\n## Bash Commands\n\n```bash\n# Install Phoenix\n$ mix archive.install hex phx_new 1.5.7\n\n# Create a Phoenix API (like rails new)\n$ mix phx.new rocketpay --no-webpack --no-html\n\n# Setup Ecto (database wrapper and query generator) and check database connection (like rails db:setup)\n$ mix ecto.setup\n\n# Install dependencies (like bundle install)\n$ mix deps.get\n\n# Create config file for credo (linter, like rubocop)\n$ mix credo gen.config\n\n# Run credo\n$ mix credo\n\n# Start the server (like rails s)\n$ mix phx.server\n\n# Interactive Elixir console (like irb)\n$ iex\n\n# Phoenix app console (like rails c)\n$ iex -S mix\n\n# Runs tests (like bundle exec rspec)\n$ mix test\n\n# Create a migration\n$ mix ecto.gen.migration create_user_table\n\n# Migrate database\n$ mix ecto.migrate\n\n# Drop database\n$ mix ecto.drop\n\n# Create database\n$ mix ecto.create\n\n# Generate code coverage report\n$ mix test --cover\n\n# Generate an HTML code coverage report (just like the coveralls gem)\n$ mix coveralls.html\n```\n\n## Elixir Commands\n\n```elixir\n# Calling a function from a module\n\u003e Rocketpay.Numbers.sum_from_file(\"numbers\")\n{:ok, \"1,2,3,4,8,9,10\"}\n# ^^^ In Elixir tuples are a arrays on a continous block of memory (faster)\n\u003e Rocketpay.Numbers.sum_from_file(\"snuffleupagus\")\n{:error, :enoent}\n\n# = is a pattern matcher, not an attributor\n\u003e {:ok, file} = File.read(\"numbers.csv\")\n{:ok, \"1,2,3,4,8,9,10\"}\n\u003e file\n\"1,2,3,4,8,9,10\"\n\u003e {:ok, file} = File.read(\"snuffleupagus.csv\")\n** (MatchError) no match of right hand side value: {:error, :enoent}\n\u003e [a,b,c,d] = [1,2,3,4]\n[1, 2, 3, 4]\n\u003e [a,b] = [1,2,3,4]\n** (MatchError) no match of right hand side value: [1, 2, 3, 4]\n\n\u003e recompile\nCompiling 1 file (.ex)\n:ok\n\u003e Rocketpay.Numbers.sum_from_file(\"numbers\")\n\"1,2,3,4,8,9,10\"\n\u003e Rocketpay.Numbers.sum_from_file(\"snuffleupagus\")\n{:error, \"Invalid file!\"}\n\n# Pipe operator (like bash |)\n\u003e \"numbers.csv\" |\u003e File.read()\n{:ok, \"1,2,3,4,8,9,10\"}\n\u003e \"snuffleupagus.csv\" |\u003e File.read()\n{:error, :enoent}\n\n# h before a function to read the documentation\n\u003e h String.split\n(...)\n# Tab-complete works the same as bash\n\u003e String.\\t\n(...)\n\n\u003e list = String.split(\"1,2,3,4,8,9,10\", \",\")\n[\"1\", \"2\", \"3\", \"4\", \"8\", \"9\", \"10\"]\n# Immutability == Security\n\u003e number_list = Enum.map(list, fn number_string -\u003e String.to_integer(number_string) end)\n[1, 2, 3, 4, 8, 9, 10]\n\u003e total = Enum.sum(number_list)\n37\n\n# Enum isn't lazy\n\u003e \"1,2,3,4,8,9,10\" |\u003e\n    String.split(\",\") |\u003e\n    Enum.map(fn number_string -\u003e String.to_integer(number_string) end) |\u003e\n    Enum.sum()\n37\n# Stream is lazy\n\u003e \"1,2,3,4,8,9,10\" |\u003e\n    String.split(\",\") |\u003e\n    Stream.map(fn number_string -\u003e String.to_integer(number_string) end) |\u003e\n    Enum.sum()\n# We should use Stream between enums: the compiler then knows to do it all at\n# once and optimizes it.\n\n\u003e recompile\n\u003e Rocketpay.Numbers.sum_from_file(\"numbers\")\n37\n\n# Maps (hashes in ruby)\n\u003e my_map = %{result: :ok, total: 37}\n\u003e my_map[:result]\n:ok\n\u003e my_map.total\n37\n\n\u003e alias Rocketpay.Numbers\n\u003e Numbers.sum_from_file(\"numbers\")\n{:ok, %{total: 37}}\n\u003e alias Rocketpay.Numbers, as: Snuffleupagus\n\u003e Snuffleupagus.sum_from_file(\"numbers\")\n{:ok, %{total: 37}}\n\n\u003e %{filename: whatever} = %{filename: \"numbers\", value: 7}\n\u003e whatever\n\"numbers\"\n\n# Similiar to \"  RaFaEl  \".strip.downcase\n\u003e \"  RaFaEl  \" |\u003e String.trim() |\u003e String.downcase()\n\"rafael\"\n\n\u003e Ecto.UUID.generate\n\"04980ee4-6b82-4523-966f-f4600a2631e9\"\n\n\u003e :this_is_an_atom\n\u003e :this_is_not_a_symbol\n\n\u003e Bcrypt.add_hash(\"dasda\")\n%{password_hash: \"$2b$12$SgkYtcvmDSlkOv86tsCxVOp8e9SAShSuqd1fEmYhMbOrtsdVNTwum\"}\n\n# Like Model.attributes\n\u003e %Rocketpay.User{}\n\u003e params = %{name: \"Luisito\", nickname: \"luisito\", email: \"luisito@gmail.com\",\n                password: \"dsadsadsadas ad\", age: 87}\n# Like Model.new({attributes: attr})\n\u003e Rocketpay.User.changeset(params)\n# Like Model.create({attributes: attr})\n\u003e Rocketpay.Users.Create.call(params)\n# With delegate\n\u003e Rocketpay.create_user(params)\n\n\u003e Rocketpay.Repo.all(Rocketpay.User)\n\u003e Rocketpay.Repo.all(Rocketpay.User) |\u003e Rocketpay.Repo.preload(:account)\n\n\u003e Base.encode64(\"foobar:123456\")\n\"Zm9vYmFyOjEyMzQ1Ng==\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrity%2Fnlw4_elixir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibrity%2Fnlw4_elixir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrity%2Fnlw4_elixir/lists"}