From f6fc79a704ba5a8a21486c29c7ae6d46073e602b Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 00:25:20 +0200 Subject: [PATCH 01/10] Generate empty hanami app --- hanami_application/.bundle/config | 2 + hanami_application/.gitignore | 2 + hanami_application/.rspec | 1 + hanami_application/Gemfile | 32 ++++ hanami_application/Gemfile.lock | 180 ++++++++++++++++++ hanami_application/Guardfile | 10 + hanami_application/README.md | 5 +- hanami_application/Rakefile | 3 + hanami_application/app/action.rb | 9 + hanami_application/app/actions/.keep | 0 hanami_application/config.ru | 5 + hanami_application/config/app.rb | 8 + hanami_application/config/puma.rb | 15 ++ hanami_application/config/routes.rb | 7 + hanami_application/config/settings.rb | 9 + hanami_application/lib/ecommerce/types.rb | 11 ++ hanami_application/lib/tasks/.keep | 0 hanami_application/spec/requests/root_spec.rb | 11 ++ hanami_application/spec/spec_helper.rb | 10 + hanami_application/spec/support/requests.rb | 12 ++ hanami_application/spec/support/rspec.rb | 27 +++ 21 files changed, 355 insertions(+), 4 deletions(-) create mode 100644 hanami_application/.bundle/config create mode 100644 hanami_application/.gitignore create mode 100644 hanami_application/.rspec create mode 100644 hanami_application/Gemfile create mode 100644 hanami_application/Gemfile.lock create mode 100644 hanami_application/Guardfile create mode 100644 hanami_application/Rakefile create mode 100644 hanami_application/app/action.rb create mode 100644 hanami_application/app/actions/.keep create mode 100644 hanami_application/config.ru create mode 100644 hanami_application/config/app.rb create mode 100644 hanami_application/config/puma.rb create mode 100644 hanami_application/config/routes.rb create mode 100644 hanami_application/config/settings.rb create mode 100644 hanami_application/lib/ecommerce/types.rb create mode 100644 hanami_application/lib/tasks/.keep create mode 100644 hanami_application/spec/requests/root_spec.rb create mode 100644 hanami_application/spec/spec_helper.rb create mode 100644 hanami_application/spec/support/requests.rb create mode 100644 hanami_application/spec/support/rspec.rb diff --git a/hanami_application/.bundle/config b/hanami_application/.bundle/config new file mode 100644 index 000000000..942410fc9 --- /dev/null +++ b/hanami_application/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_JOBS: "8" diff --git a/hanami_application/.gitignore b/hanami_application/.gitignore new file mode 100644 index 000000000..f1112aba5 --- /dev/null +++ b/hanami_application/.gitignore @@ -0,0 +1,2 @@ +.env +log/* diff --git a/hanami_application/.rspec b/hanami_application/.rspec new file mode 100644 index 000000000..c99d2e739 --- /dev/null +++ b/hanami_application/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/hanami_application/Gemfile b/hanami_application/Gemfile new file mode 100644 index 000000000..52c14d24d --- /dev/null +++ b/hanami_application/Gemfile @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "hanami", "~> 2.0" +gem "hanami-router", "~> 2.0" +gem "hanami-controller", "~> 2.0" +gem "hanami-validations", "~> 2.0" + +gem "dry-types", "~> 1.0", ">= 1.6.1" +gem "puma" +gem "rake" + +group :development, :test do + gem "dotenv" +end + +group :cli, :development do + gem "hanami-reloader" +end + +group :cli, :development, :test do + gem "hanami-rspec" +end + +group :development do + gem "guard-puma", "~> 0.8" +end + +group :test do + gem "rack-test" +end diff --git a/hanami_application/Gemfile.lock b/hanami_application/Gemfile.lock new file mode 100644 index 000000000..5e3bf605b --- /dev/null +++ b/hanami_application/Gemfile.lock @@ -0,0 +1,180 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.3) + concurrent-ruby (1.2.2) + diff-lcs (1.5.0) + dotenv (2.8.1) + dry-auto_inject (1.0.1) + dry-core (~> 1.0) + zeitwerk (~> 2.6) + dry-cli (1.0.0) + dry-configurable (1.1.0) + dry-core (~> 1.0, < 2) + zeitwerk (~> 2.6) + dry-core (1.0.1) + concurrent-ruby (~> 1.0) + zeitwerk (~> 2.6) + dry-events (1.0.1) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0, < 2) + dry-files (1.0.2) + dry-inflector (1.0.0) + dry-initializer (3.1.1) + dry-logger (1.0.3) + dry-logic (1.5.0) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0, < 2) + zeitwerk (~> 2.6) + dry-monitor (1.0.1) + dry-configurable (~> 1.0, < 2) + dry-core (~> 1.0, < 2) + dry-events (~> 1.0, < 2) + dry-schema (1.13.3) + concurrent-ruby (~> 1.0) + dry-configurable (~> 1.0, >= 1.0.1) + dry-core (~> 1.0, < 2) + dry-initializer (~> 3.0) + dry-logic (>= 1.4, < 2) + dry-types (>= 1.7, < 2) + zeitwerk (~> 2.6) + dry-system (1.0.1) + dry-auto_inject (~> 1.0, < 2) + dry-configurable (~> 1.0, < 2) + dry-core (~> 1.0, < 2) + dry-inflector (~> 1.0, < 2) + dry-transformer (1.0.1) + zeitwerk (~> 2.6) + dry-types (1.7.1) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0) + dry-inflector (~> 1.0) + dry-logic (~> 1.4) + zeitwerk (~> 2.6) + dry-validation (1.10.0) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0, < 2) + dry-initializer (~> 3.0) + dry-schema (>= 1.12, < 2) + zeitwerk (~> 2.6) + ffi (1.16.3) + formatador (1.1.0) + guard (2.18.1) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.13.0) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-compat (1.2.1) + guard-puma (0.8.1) + guard (~> 2.14) + guard-compat (~> 1.2) + puma (>= 4.0, < 7) + hanami (2.0.3) + bundler (>= 1.16, < 3) + dry-configurable (~> 1.0, < 2) + dry-core (~> 1.0, < 2) + dry-inflector (~> 1.0, < 2) + dry-logger (~> 1.0, < 2) + dry-monitor (~> 1.0, >= 1.0.1, < 2) + dry-system (~> 1.0, < 2) + hanami-cli (~> 2.0) + hanami-utils (~> 2.0) + zeitwerk (~> 2.6) + hanami-cli (2.0.3) + bundler (~> 2.1) + dry-cli (~> 1.0, < 2) + dry-files (~> 1.0, >= 1.0.1, < 2) + dry-inflector (~> 1.0, < 2) + rake (~> 13.0) + zeitwerk (~> 2.6) + hanami-controller (2.0.2) + dry-configurable (~> 1.0, < 2) + dry-core (~> 1.0) + hanami-utils (~> 2.0) + rack (~> 2.0) + zeitwerk (~> 2.6) + hanami-reloader (2.0.2) + hanami-cli (~> 2.0) + zeitwerk (~> 2.6) + hanami-router (2.0.2) + mustermann (~> 3.0) + mustermann-contrib (~> 3.0) + rack (~> 2.0) + hanami-rspec (2.0.1) + hanami-cli (~> 2.0) + rake (~> 13.0) + rspec (~> 3.12) + zeitwerk (~> 2.6) + hanami-utils (2.0.3) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0, < 2) + dry-transformer (~> 1.0, < 2) + hanami-validations (2.0.1) + dry-validation (>= 1.10, < 2) + zeitwerk (~> 2.6.0) + hansi (0.2.1) + listen (3.8.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + lumberjack (1.2.9) + method_source (1.0.0) + mustermann (3.0.0) + ruby2_keywords (~> 0.0.1) + mustermann-contrib (3.0.0) + hansi (~> 0.2.0) + mustermann (= 3.0.0) + nenv (0.3.0) + nio4r (2.5.9) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + puma (6.4.0) + nio4r (~> 2.0) + rack (2.2.8) + rake (13.0.6) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.1) + ruby2_keywords (0.0.5) + shellany (0.0.1) + thor (1.2.2) + zeitwerk (2.6.12) + +PLATFORMS + arm64-darwin-20 + +DEPENDENCIES + dotenv + dry-types (~> 1.0, >= 1.6.1) + guard-puma (~> 0.8) + hanami (~> 2.0) + hanami-controller (~> 2.0) + hanami-reloader + hanami-router (~> 2.0) + hanami-rspec + hanami-validations (~> 2.0) + puma + rake + +BUNDLED WITH + 2.4.20 diff --git a/hanami_application/Guardfile b/hanami_application/Guardfile new file mode 100644 index 000000000..7c4504a63 --- /dev/null +++ b/hanami_application/Guardfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +group :server do + guard "puma", port: ENV.fetch("HANAMI_PORT", 2300) do + watch(%r{config/*}) + watch(%r{lib/*}) + watch(%r{app/*}) + watch(%r{slices/*}) + end +end diff --git a/hanami_application/README.md b/hanami_application/README.md index 1c13d671a..f77470fdb 100644 --- a/hanami_application/README.md +++ b/hanami_application/README.md @@ -1,4 +1 @@ -Coming soon, there's no obstacle to use it with ~~Rails~~ **RubyEventStore**. - -It will reimplement most, if not all, of counterpart Rails application. It will also reuse contexts from [ecommerce/](../ecommerce/) - +# Ecommerce diff --git a/hanami_application/Rakefile b/hanami_application/Rakefile new file mode 100644 index 000000000..c526f383e --- /dev/null +++ b/hanami_application/Rakefile @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "hanami/rake_tasks" diff --git a/hanami_application/app/action.rb b/hanami_application/app/action.rb new file mode 100644 index 000000000..11542af93 --- /dev/null +++ b/hanami_application/app/action.rb @@ -0,0 +1,9 @@ +# auto_register: false +# frozen_string_literal: true + +require "hanami/action" + +module Ecommerce + class Action < Hanami::Action + end +end diff --git a/hanami_application/app/actions/.keep b/hanami_application/app/actions/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/hanami_application/config.ru b/hanami_application/config.ru new file mode 100644 index 000000000..879c08584 --- /dev/null +++ b/hanami_application/config.ru @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require "hanami/boot" + +run Hanami.app diff --git a/hanami_application/config/app.rb b/hanami_application/config/app.rb new file mode 100644 index 000000000..64e23d98c --- /dev/null +++ b/hanami_application/config/app.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require "hanami" + +module Ecommerce + class App < Hanami::App + end +end diff --git a/hanami_application/config/puma.rb b/hanami_application/config/puma.rb new file mode 100644 index 000000000..814785f02 --- /dev/null +++ b/hanami_application/config/puma.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +max_threads_count = ENV.fetch("HANAMI_MAX_THREADS", 5) +min_threads_count = ENV.fetch("HANAMI_MIN_THREADS") { max_threads_count } +threads min_threads_count, max_threads_count + +port ENV.fetch("HANAMI_PORT", 2300) +environment ENV.fetch("HANAMI_ENV", "development") +workers ENV.fetch("HANAMI_WEB_CONCURRENCY", 2) + +on_worker_boot do + Hanami.shutdown +end + +preload_app! diff --git a/hanami_application/config/routes.rb b/hanami_application/config/routes.rb new file mode 100644 index 000000000..9a36f2481 --- /dev/null +++ b/hanami_application/config/routes.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Ecommerce + class Routes < Hanami::Routes + root { "Hello from Hanami" } + end +end diff --git a/hanami_application/config/settings.rb b/hanami_application/config/settings.rb new file mode 100644 index 000000000..f2e14f8cb --- /dev/null +++ b/hanami_application/config/settings.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Ecommerce + class Settings < Hanami::Settings + # Define your app settings here, for example: + # + # setting :my_flag, default: false, constructor: Types::Params::Bool + end +end diff --git a/hanami_application/lib/ecommerce/types.rb b/hanami_application/lib/ecommerce/types.rb new file mode 100644 index 000000000..efc8fe970 --- /dev/null +++ b/hanami_application/lib/ecommerce/types.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "dry/types" + +module Ecommerce + Types = Dry.Types + + module Types + # Define your custom types here + end +end diff --git a/hanami_application/lib/tasks/.keep b/hanami_application/lib/tasks/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/hanami_application/spec/requests/root_spec.rb b/hanami_application/spec/requests/root_spec.rb new file mode 100644 index 000000000..44acf66b5 --- /dev/null +++ b/hanami_application/spec/requests/root_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +RSpec.describe "Root", type: :request do + it "is successful" do + get "/" + + # Find me in `config/routes.rb` + expect(last_response).to be_successful + expect(last_response.body).to eq("Hello from Hanami") + end +end diff --git a/hanami_application/spec/spec_helper.rb b/hanami_application/spec/spec_helper.rb new file mode 100644 index 000000000..b0ce09239 --- /dev/null +++ b/hanami_application/spec/spec_helper.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "pathname" +SPEC_ROOT = Pathname(__dir__).realpath.freeze + +ENV["HANAMI_ENV"] ||= "test" +require "hanami/prepare" + +require_relative "support/rspec" +require_relative "support/requests" diff --git a/hanami_application/spec/support/requests.rb b/hanami_application/spec/support/requests.rb new file mode 100644 index 000000000..f1c8f9a19 --- /dev/null +++ b/hanami_application/spec/support/requests.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require "rack/test" + +RSpec.shared_context "Hanami app" do + let(:app) { Hanami.app } +end + +RSpec.configure do |config| + config.include Rack::Test::Methods, type: :request + config.include_context "Hanami app", type: :request +end diff --git a/hanami_application/spec/support/rspec.rb b/hanami_application/spec/support/rspec.rb new file mode 100644 index 000000000..96349835b --- /dev/null +++ b/hanami_application/spec/support/rspec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + + config.shared_context_metadata_behavior = :apply_to_host_groups + + config.filter_run_when_matching :focus + + config.disable_monkey_patching! + config.warnings = true + + if config.files_to_run.one? + config.default_formatter = "doc" + end + + config.profile_examples = 10 + + config.order = :random + Kernel.srand config.seed +end From 0cf55955746640ec06d9b0c5e9c630b72b8eb1a0 Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 14:11:53 +0200 Subject: [PATCH 02/10] WIP --- hanami_application/.env.development | 1 + hanami_application/Gemfile | 8 ++ hanami_application/Gemfile.lock | 73 +++++++++++++++++-- hanami_application/Rakefile | 11 +++ .../app/persistence/relations/events.rb | 10 +++ .../app/persistence/relations/orders.rb | 10 +++ .../persistence/relations/stream_entries.rb | 10 +++ .../app/read_models/configuration.rb | 13 ++++ hanami_application/app/repositories/orders.rb | 7 ++ .../config/providers/command_bus.rb | 8 ++ .../config/providers/event_store.rb | 16 ++++ .../config/providers/persistence.rb | 23 ++++++ .../config/providers/repositories.rb | 5 ++ hanami_application/config/routes.rb | 3 + hanami_application/config/settings.rb | 4 +- ...06000000_create_ruby_event_store_tables.rb | 51 +++++++++++++ .../migrate/20231005225237_create_orders.rb | 21 ++++++ 17 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 hanami_application/.env.development create mode 100644 hanami_application/app/persistence/relations/events.rb create mode 100644 hanami_application/app/persistence/relations/orders.rb create mode 100644 hanami_application/app/persistence/relations/stream_entries.rb create mode 100644 hanami_application/app/read_models/configuration.rb create mode 100644 hanami_application/app/repositories/orders.rb create mode 100644 hanami_application/config/providers/command_bus.rb create mode 100644 hanami_application/config/providers/event_store.rb create mode 100644 hanami_application/config/providers/persistence.rb create mode 100644 hanami_application/config/providers/repositories.rb create mode 100644 hanami_application/db/migrate/20210806000000_create_ruby_event_store_tables.rb create mode 100644 hanami_application/db/migrate/20231005225237_create_orders.rb diff --git a/hanami_application/.env.development b/hanami_application/.env.development new file mode 100644 index 000000000..74d2cf82b --- /dev/null +++ b/hanami_application/.env.development @@ -0,0 +1 @@ +DATABASE_URL=postgresql://localhost:5432/ecommerce_hanami diff --git a/hanami_application/Gemfile b/hanami_application/Gemfile index 52c14d24d..10430b757 100644 --- a/hanami_application/Gemfile +++ b/hanami_application/Gemfile @@ -11,6 +11,14 @@ gem "dry-types", "~> 1.0", ">= 1.6.1" gem "puma" gem "rake" +gem "rom" +gem "rom-sql" +gem "pg" + +gem "ruby_event_store" +gem "ruby_event_store-rom", require: "ruby_event_store/rom/sql" +gem "arkency-command_bus" + group :development, :test do gem "dotenv" end diff --git a/hanami_application/Gemfile.lock b/hanami_application/Gemfile.lock index 5e3bf605b..ccabfc0ac 100644 --- a/hanami_application/Gemfile.lock +++ b/hanami_application/Gemfile.lock @@ -1,6 +1,9 @@ GEM remote: https://rubygems.org/ specs: + arkency-command_bus (0.4.1) + concurrent-ruby + bigdecimal (3.1.4) coderay (1.1.3) concurrent-ruby (1.2.2) diff-lcs (1.5.0) @@ -12,6 +15,8 @@ GEM dry-configurable (1.1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) + dry-container (0.11.0) + concurrent-ruby (~> 1.0) dry-core (1.0.1) concurrent-ruby (~> 1.0) zeitwerk (~> 2.6) @@ -38,6 +43,11 @@ GEM dry-logic (>= 1.4, < 2) dry-types (>= 1.7, < 2) zeitwerk (~> 2.6) + dry-struct (1.6.0) + dry-core (~> 1.0, < 2) + dry-types (>= 1.7, < 2) + ice_nine (~> 0.11) + zeitwerk (~> 2.6) dry-system (1.0.1) dry-auto_inject (~> 1.0, < 2) dry-configurable (~> 1.0, < 2) @@ -73,7 +83,7 @@ GEM guard (~> 2.14) guard-compat (~> 1.2) puma (>= 4.0, < 7) - hanami (2.0.3) + hanami (2.1.0.beta2.1) bundler (>= 1.16, < 3) dry-configurable (~> 1.0, < 2) dry-core (~> 1.0, < 2) @@ -81,13 +91,13 @@ GEM dry-logger (~> 1.0, < 2) dry-monitor (~> 1.0, >= 1.0.1, < 2) dry-system (~> 1.0, < 2) - hanami-cli (~> 2.0) - hanami-utils (~> 2.0) + hanami-cli (~> 2.1.beta) + hanami-utils (~> 2.1.beta) zeitwerk (~> 2.6) - hanami-cli (2.0.3) + hanami-cli (2.1.0.beta2) bundler (~> 2.1) dry-cli (~> 1.0, < 2) - dry-files (~> 1.0, >= 1.0.1, < 2) + dry-files (~> 1.0, >= 1.0.2, < 2) dry-inflector (~> 1.0, < 2) rake (~> 13.0) zeitwerk (~> 2.6) @@ -109,7 +119,7 @@ GEM rake (~> 13.0) rspec (~> 3.12) zeitwerk (~> 2.6) - hanami-utils (2.0.3) + hanami-utils (2.1.0.beta1) concurrent-ruby (~> 1.0) dry-core (~> 1.0, < 2) dry-transformer (~> 1.0, < 2) @@ -117,6 +127,7 @@ GEM dry-validation (>= 1.10, < 2) zeitwerk (~> 2.6.0) hansi (0.2.1) + ice_nine (0.11.2) listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -132,16 +143,45 @@ GEM notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) + pg (1.5.4) pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) puma (6.4.0) nio4r (~> 2.0) rack (2.2.8) + rack-test (2.1.0) + rack (>= 1.3) rake (13.0.6) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) + rom (5.3.0) + rom-changeset (~> 5.3, >= 5.3.0) + rom-core (~> 5.3, >= 5.3.0) + rom-repository (~> 5.3, >= 5.3.0) + rom-changeset (5.3.0) + dry-core (~> 1.0) + rom-core (~> 5.3) + transproc (~> 1.0, >= 1.1.0) + rom-core (5.3.0) + concurrent-ruby (~> 1.1) + dry-configurable (~> 1.0) + dry-core (~> 1.0) + dry-inflector (~> 1.0) + dry-initializer (~> 3.0, >= 3.0.1) + dry-struct (~> 1.0) + dry-types (~> 1.6) + transproc (~> 1.0, >= 1.1.0) + rom-repository (5.3.0) + dry-core (~> 1.0) + dry-initializer (~> 3.0, >= 3.0.1) + rom-core (~> 5.3, >= 5.3.0) + rom-sql (3.6.1) + dry-core (~> 1.0) + dry-types (~> 1.0) + rom (~> 5.2, >= 5.2.1) + sequel (>= 4.49) rspec (3.12.0) rspec-core (~> 3.12.0) rspec-expectations (~> 3.12.0) @@ -156,14 +196,29 @@ GEM rspec-support (~> 3.12.0) rspec-support (3.12.1) ruby2_keywords (0.0.5) + ruby_event_store (2.12.1) + concurrent-ruby (~> 1.0, >= 1.1.6) + ruby_event_store-rom (2.2.0) + dry-container (>= 0.6) + dry-initializer (>= 3.0) + dry-types (>= 1.0) + rom-changeset (>= 5.0) + rom-repository (>= 5.0) + rom-sql (>= 3.0) + ruby_event_store (>= 2.0.0, < 3.0.0) + sequel (>= 5.11.0) + sequel (5.73.0) + bigdecimal shellany (0.0.1) thor (1.2.2) + transproc (1.1.1) zeitwerk (2.6.12) PLATFORMS arm64-darwin-20 DEPENDENCIES + arkency-command_bus dotenv dry-types (~> 1.0, >= 1.6.1) guard-puma (~> 0.8) @@ -173,8 +228,14 @@ DEPENDENCIES hanami-router (~> 2.0) hanami-rspec hanami-validations (~> 2.0) + pg puma + rack-test rake + rom + rom-sql + ruby_event_store + ruby_event_store-rom BUNDLED WITH 2.4.20 diff --git a/hanami_application/Rakefile b/hanami_application/Rakefile index c526f383e..4a7fd899a 100644 --- a/hanami_application/Rakefile +++ b/hanami_application/Rakefile @@ -1,3 +1,14 @@ # frozen_string_literal: true require "hanami/rake_tasks" +require "hanami/prepare" +require "ruby_event_store/rom/rake_task" +require "rom/sql/rake_task" + +namespace :db do + task :setup do + Ecommerce::App.prepare :persistence + config = Ecommerce::Container['persistence.config'] + ROM::SQL::RakeSupport.env = ROM.container(config) + end +end diff --git a/hanami_application/app/persistence/relations/events.rb b/hanami_application/app/persistence/relations/events.rb new file mode 100644 index 000000000..cc5be11ed --- /dev/null +++ b/hanami_application/app/persistence/relations/events.rb @@ -0,0 +1,10 @@ +module Ecommerce + module Persistence + module Relations + class Events < ROM::Relation[:sql] + schema(:event_store_events, infer: true, as: :events) do + end + end + end + end +end diff --git a/hanami_application/app/persistence/relations/orders.rb b/hanami_application/app/persistence/relations/orders.rb new file mode 100644 index 000000000..9c4f99b11 --- /dev/null +++ b/hanami_application/app/persistence/relations/orders.rb @@ -0,0 +1,10 @@ +module Ecommerce + module Persistence + module Relations + class Orders < ROM::Relation[:sql] + schema(:orders, infer: true) do + end + end + end + end +end diff --git a/hanami_application/app/persistence/relations/stream_entries.rb b/hanami_application/app/persistence/relations/stream_entries.rb new file mode 100644 index 000000000..1f0b87dd6 --- /dev/null +++ b/hanami_application/app/persistence/relations/stream_entries.rb @@ -0,0 +1,10 @@ +module Ecommerce + module Persistence + module Relations + class StreamEntries < ROM::Relation[:sql] + schema(:event_store_events_in_streams, infer: true, as: :stream_entries) do + end + end + end + end +end diff --git a/hanami_application/app/read_models/configuration.rb b/hanami_application/app/read_models/configuration.rb new file mode 100644 index 000000000..4ca0bb572 --- /dev/null +++ b/hanami_application/app/read_models/configuration.rb @@ -0,0 +1,13 @@ +module Ecommerce + module ReadModels + class Configuration + include Deps[ + event_store: "event_store.client", + ] + + def call + event_store.subscribe(SubmitOrder, to: [Ordering::OrderSubmitted]) + end + end + end +end diff --git a/hanami_application/app/repositories/orders.rb b/hanami_application/app/repositories/orders.rb new file mode 100644 index 000000000..6ea2b312e --- /dev/null +++ b/hanami_application/app/repositories/orders.rb @@ -0,0 +1,7 @@ +module Ecommerce + module Repositories + class Orders < ROM::Repository[:orders] + end + end +end + diff --git a/hanami_application/config/providers/command_bus.rb b/hanami_application/config/providers/command_bus.rb new file mode 100644 index 000000000..0e973f048 --- /dev/null +++ b/hanami_application/config/providers/command_bus.rb @@ -0,0 +1,8 @@ + +Hanami.app.register_provider :command_bus do + prepare do + require "arkency/command_bus" + + register "command_bus", Arkency::CommandBus.new + end +end diff --git a/hanami_application/config/providers/event_store.rb b/hanami_application/config/providers/event_store.rb new file mode 100644 index 000000000..c444be444 --- /dev/null +++ b/hanami_application/config/providers/event_store.rb @@ -0,0 +1,16 @@ +Hanami.app.register_provider :event_store, namespace: true do + prepare do + require "ruby_event_store" + require 'ruby_event_store/rom' + + repository = RubyEventStore::ROM::EventRepository.new( + rom: target['persistence.rom'], + serializer: RubyEventStore::NULL + ) + + client = RubyEventStore::Client.new(repository: repository) + + register "repository", repository + register "client", client + end +end diff --git a/hanami_application/config/providers/persistence.rb b/hanami_application/config/providers/persistence.rb new file mode 100644 index 000000000..e8dceb79d --- /dev/null +++ b/hanami_application/config/providers/persistence.rb @@ -0,0 +1,23 @@ +Hanami.app.register_provider :persistence, namespace: true do + prepare do + require 'rom-changeset' + require 'rom/core' + require 'rom/sql' + require 'rom-repository' + + config = + ROM::Configuration.new( + :sql, target['settings'].database_url + ) + + config.auto_registration( + target.root.join('app/persistence'), + namespace: 'Ecommerce::Persistence' + ) + + register 'config', config + register 'db', config.gateways[:default].connection + register 'rom', ROM.container(config) + end + end + \ No newline at end of file diff --git a/hanami_application/config/providers/repositories.rb b/hanami_application/config/providers/repositories.rb new file mode 100644 index 000000000..b53c8124e --- /dev/null +++ b/hanami_application/config/providers/repositories.rb @@ -0,0 +1,5 @@ +Hanami.app.register_provider :repositories, namespace: true do + prepare do + register 'orders', Ecommerce::Repositories::Orders.new(target['persistence.rom']) + end +end diff --git a/hanami_application/config/routes.rb b/hanami_application/config/routes.rb index 9a36f2481..4a00c9b6e 100644 --- a/hanami_application/config/routes.rb +++ b/hanami_application/config/routes.rb @@ -3,5 +3,8 @@ module Ecommerce class Routes < Hanami::Routes root { "Hello from Hanami" } + + slice :orders, at: "/orders" do + end end end diff --git a/hanami_application/config/settings.rb b/hanami_application/config/settings.rb index f2e14f8cb..b7d892840 100644 --- a/hanami_application/config/settings.rb +++ b/hanami_application/config/settings.rb @@ -2,8 +2,6 @@ module Ecommerce class Settings < Hanami::Settings - # Define your app settings here, for example: - # - # setting :my_flag, default: false, constructor: Types::Params::Bool + setting :database_url, constructor: Types::String end end diff --git a/hanami_application/db/migrate/20210806000000_create_ruby_event_store_tables.rb b/hanami_application/db/migrate/20210806000000_create_ruby_event_store_tables.rb new file mode 100644 index 000000000..f96263b2e --- /dev/null +++ b/hanami_application/db/migrate/20210806000000_create_ruby_event_store_tables.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + create_table? :event_store_events_in_streams do + primary_key :id, type: :Bignum, null: false + + column :stream, String, null: false + column :position, Integer + + column :event_id, :uuid, null: false + + column :created_at, + DateTime, + null: false, + type: "TIMESTAMP", + index: "index_event_store_events_in_streams_on_created_at" + + index %i[stream position], unique: true, name: "index_event_store_events_in_streams_on_stream_and_position" + index %i[created_at], name: "index_event_store_events_in_streams_on_created_at" + index %i[stream event_id], unique: true, name: "index_event_store_events_in_streams_on_stream_and_event_id" + end + + create_table? :event_store_events do + primary_key :id, type: :Bignum, null: false + + column :event_id, :uuid, null: false + + column :event_type, String, null: false + + column :metadata, :jsonb + column :data, :jsonb, null: false + + column :created_at, + DateTime, + null: false, + type: "TIMESTAMP", + index: "index_event_store_events_on_created_at" + column :valid_at, + DateTime, + null: false, + type: "TIMESTAMP", + index: "index_event_store_events_on_valid_at" + + index %i[event_id], unique: true, name: "index_event_store_events_on_event_id" + index %i[created_at], name: "index_event_store_events_on_created_at" + index %i[valid_at], name: "index_event_store_events_on_valid_at" + index %i[event_type], name: "index_event_store_events_on_event_type" + end + end +end diff --git a/hanami_application/db/migrate/20231005225237_create_orders.rb b/hanami_application/db/migrate/20231005225237_create_orders.rb new file mode 100644 index 000000000..cd57cc602 --- /dev/null +++ b/hanami_application/db/migrate/20231005225237_create_orders.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + create_table(:orders) do + primary_key :id # TODO: change to uuid + + column :number, String + column :customer, String + column :state, String + + column :percentage_discount, BigDecimal, size: [8, 2] + column :total_value, BigDecimal, size: [8, 2] + column :discounted_value, BigDecimal, size: [8, 2] + column :happy_hour_value, BigDecimal, size: [8, 2] + + column :total_value_updated_at, DateTime + column :discount_updated_at, DateTime + end + end +end From d7f0627bf415f84e5a9a2fc0008283741e3ec5cf Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 15:35:12 +0200 Subject: [PATCH 03/10] Inject event_store & command_bus into ecommerce configuration --- ecommerce/configuration.rb | 11 +++++------ rails_application/lib/configuration.rb | 2 ++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ecommerce/configuration.rb b/ecommerce/configuration.rb index 9179bc8c9..d210e18e3 100644 --- a/ecommerce/configuration.rb +++ b/ecommerce/configuration.rb @@ -12,10 +12,12 @@ module Ecommerce class Configuration - def initialize(number_generator: nil, payment_gateway: nil, available_vat_rates: []) + def initialize(number_generator: nil, payment_gateway: nil, available_vat_rates: [], event_store:, command_bus:) @number_generator = number_generator @payment_gateway = payment_gateway @available_vat_rates = available_vat_rates + @event_store = event_store + @command_bus = command_bus end def call(event_store, command_bus) @@ -24,9 +26,6 @@ def call(event_store, command_bus) end def configure_bounded_contexts - event_store = Rails.configuration.event_store - command_bus = Rails.configuration.command_bus - raise ArgumentError.new( "Neither number_generator nor payment_gateway can be null" ) if @number_generator.nil? || @payment_gateway.nil? @@ -41,11 +40,11 @@ def configure_bounded_contexts Pricing::Configuration.new, Taxes::Configuration.new(@available_vat_rates), ProductCatalog::Configuration.new, - ].each { |c| c.call(event_store, command_bus) } + ].each { |c| c.call(@event_store, @command_bus) } end def configure_processes(event_store, command_bus) - Processes::Configuration.new.call(event_store, command_bus) + Processes::Configuration.new.call(@event_store, @command_bus) end end end diff --git a/rails_application/lib/configuration.rb b/rails_application/lib/configuration.rb index 078f236c2..e30bbb62b 100644 --- a/rails_application/lib/configuration.rb +++ b/rails_application/lib/configuration.rb @@ -18,6 +18,8 @@ def call(event_store, command_bus) enable_authentication_read_model(event_store) Ecommerce::Configuration.new( + event_store: Rails.configuration.event_store, + command_bus: Rails.configuration.command_bus, number_generator: Rails.configuration.number_generator, payment_gateway: Rails.configuration.payment_gateway, available_vat_rates: [ From c1cd8cc3e4bdecee65bacae1f6767640638734fe Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 15:35:27 +0200 Subject: [PATCH 04/10] Configure ecommerce & infra --- hanami_application/Gemfile | 2 + hanami_application/Gemfile.lock | 48 ++++++++++++++++++- .../config/providers/ecommerce.rb | 23 +++++++++ hanami_application/config/providers/infra.rb | 9 ++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 hanami_application/config/providers/ecommerce.rb create mode 100644 hanami_application/config/providers/infra.rb diff --git a/hanami_application/Gemfile b/hanami_application/Gemfile index 10430b757..13fed3015 100644 --- a/hanami_application/Gemfile +++ b/hanami_application/Gemfile @@ -19,6 +19,8 @@ gem "ruby_event_store" gem "ruby_event_store-rom", require: "ruby_event_store/rom/sql" gem "arkency-command_bus" +gem "infra", path: "../infra" + group :development, :test do gem "dotenv" end diff --git a/hanami_application/Gemfile.lock b/hanami_application/Gemfile.lock index ccabfc0ac..30dd3b6f5 100644 --- a/hanami_application/Gemfile.lock +++ b/hanami_application/Gemfile.lock @@ -1,13 +1,42 @@ +PATH + remote: ../infra + specs: + infra (1.0.0) + aggregate_root (~> 2.9.0) + arkency-command_bus + dry-struct + dry-types + rake + ruby_event_store (~> 2.9.0) + ruby_event_store-transformations + sidekiq + GEM remote: https://rubygems.org/ specs: + activesupport (7.1.0) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + minitest (>= 5.1) + mutex_m + tzinfo (~> 2.0) + aggregate_root (2.9.1) + ruby_event_store (= 2.9.1) arkency-command_bus (0.4.1) concurrent-ruby + base64 (0.1.1) bigdecimal (3.1.4) coderay (1.1.3) concurrent-ruby (1.2.2) + connection_pool (2.4.1) diff-lcs (1.5.0) dotenv (2.8.1) + drb (2.1.1) + ruby2_keywords dry-auto_inject (1.0.1) dry-core (~> 1.0) zeitwerk (~> 2.6) @@ -127,17 +156,21 @@ GEM dry-validation (>= 1.10, < 2) zeitwerk (~> 2.6.0) hansi (0.2.1) + i18n (1.14.1) + concurrent-ruby (~> 1.0) ice_nine (0.11.2) listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) lumberjack (1.2.9) method_source (1.0.0) + minitest (5.20.0) mustermann (3.0.0) ruby2_keywords (~> 0.0.1) mustermann-contrib (3.0.0) hansi (~> 0.2.0) mustermann (= 3.0.0) + mutex_m (0.1.2) nenv (0.3.0) nio4r (2.5.9) notiffany (0.1.3) @@ -156,6 +189,8 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) + redis-client (0.17.0) + connection_pool rom (5.3.0) rom-changeset (~> 5.3, >= 5.3.0) rom-core (~> 5.3, >= 5.3.0) @@ -196,7 +231,7 @@ GEM rspec-support (~> 3.12.0) rspec-support (3.12.1) ruby2_keywords (0.0.5) - ruby_event_store (2.12.1) + ruby_event_store (2.9.1) concurrent-ruby (~> 1.0, >= 1.1.6) ruby_event_store-rom (2.2.0) dry-container (>= 0.6) @@ -207,11 +242,21 @@ GEM rom-sql (>= 3.0) ruby_event_store (>= 2.0.0, < 3.0.0) sequel (>= 5.11.0) + ruby_event_store-transformations (0.1.0) + activesupport (>= 5.0) + ruby_event_store (>= 2.0.0, < 3.0.0) sequel (5.73.0) bigdecimal shellany (0.0.1) + sidekiq (7.1.5) + concurrent-ruby (< 2) + connection_pool (>= 2.3.0) + rack (>= 2.2.4) + redis-client (>= 0.14.0) thor (1.2.2) transproc (1.1.1) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) zeitwerk (2.6.12) PLATFORMS @@ -228,6 +273,7 @@ DEPENDENCIES hanami-router (~> 2.0) hanami-rspec hanami-validations (~> 2.0) + infra! pg puma rack-test diff --git a/hanami_application/config/providers/ecommerce.rb b/hanami_application/config/providers/ecommerce.rb new file mode 100644 index 000000000..077b10990 --- /dev/null +++ b/hanami_application/config/providers/ecommerce.rb @@ -0,0 +1,23 @@ +Hanami.app.register_provider :ecommerce, namespace: true do + prepare do + require_relative "../../../ecommerce/configuration" + require_relative "../../../ecommerce/ordering/lib/ordering" + + event_store = target["event_store.client"] + command_bus = target["command_bus"] + + number_generator = -> { Ordering::NumberGenerator.new } + payment_gateway = -> { Payments::FakeGateway.new } + + Ecommerce::Configuration.new( + event_store: event_store, + command_bus: command_bus, + number_generator: number_generator, + payment_gateway: payment_gateway, + available_vat_rates: [ + Infra::Types::VatRate.new(code: "10", rate: 10), + Infra::Types::VatRate.new(code: "20", rate: 20) + ] + ).call(event_store, command_bus) + end +end diff --git a/hanami_application/config/providers/infra.rb b/hanami_application/config/providers/infra.rb new file mode 100644 index 000000000..613158c88 --- /dev/null +++ b/hanami_application/config/providers/infra.rb @@ -0,0 +1,9 @@ +Hanami.app.register_provider :infra, namespace: true do + prepare do + require 'infra' + + register "aggregate_root_repo", Infra::AggregateRootRepository.new( + target["event_store.client"] + ) + end +end \ No newline at end of file From 326b2b62d824d5a790a6c41e3a00d115dcc9ecfc Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 18:49:08 +0200 Subject: [PATCH 05/10] Working example --- hanami_application/.env.development | 2 +- hanami_application/.env.test | 1 + hanami_application/Gemfile | 1 + hanami_application/Gemfile.lock | 5 ++++ .../app/actions/orders/create.rb | 29 +++++++++++++++++++ .../app/event_handlers/orders/submit.rb | 18 ++++++++++++ .../app/persistence/relations/events.rb | 10 ------- .../persistence/relations/stream_entries.rb | 10 ------- hanami_application/app/repositories/orders.rb | 6 +++- .../config/providers/command_bus.rb | 2 +- .../config/providers/ecommerce.rb | 8 +++-- .../config/providers/event_store.rb | 11 +++++-- hanami_application/config/providers/infra.rb | 2 +- .../config/providers/persistence.rb | 17 +++++------ hanami_application/config/routes.rb | 3 +- .../migrate/20231005225237_create_orders.rb | 3 +- .../spec/requests/orders/submit_spec.rb | 16 ++++++++++ hanami_application/spec/spec_helper.rb | 2 ++ 18 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 hanami_application/.env.test create mode 100644 hanami_application/app/actions/orders/create.rb create mode 100644 hanami_application/app/event_handlers/orders/submit.rb delete mode 100644 hanami_application/app/persistence/relations/events.rb delete mode 100644 hanami_application/app/persistence/relations/stream_entries.rb create mode 100644 hanami_application/spec/requests/orders/submit_spec.rb diff --git a/hanami_application/.env.development b/hanami_application/.env.development index 74d2cf82b..af61f1c74 100644 --- a/hanami_application/.env.development +++ b/hanami_application/.env.development @@ -1 +1 @@ -DATABASE_URL=postgresql://localhost:5432/ecommerce_hanami +DATABASE_URL=postgresql://localhost:5432/ecommerce_hanami_dev diff --git a/hanami_application/.env.test b/hanami_application/.env.test new file mode 100644 index 000000000..ebb868824 --- /dev/null +++ b/hanami_application/.env.test @@ -0,0 +1 @@ +DATABASE_URL=postgresql://localhost:5432/ecommerce_hanami_test diff --git a/hanami_application/Gemfile b/hanami_application/Gemfile index 13fed3015..c32216b93 100644 --- a/hanami_application/Gemfile +++ b/hanami_application/Gemfile @@ -23,6 +23,7 @@ gem "infra", path: "../infra" group :development, :test do gem "dotenv" + gem "pry-byebug" end group :cli, :development do diff --git a/hanami_application/Gemfile.lock b/hanami_application/Gemfile.lock index 30dd3b6f5..284b8d83a 100644 --- a/hanami_application/Gemfile.lock +++ b/hanami_application/Gemfile.lock @@ -30,6 +30,7 @@ GEM concurrent-ruby base64 (0.1.1) bigdecimal (3.1.4) + byebug (11.1.3) coderay (1.1.3) concurrent-ruby (1.2.2) connection_pool (2.4.1) @@ -180,6 +181,9 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) + pry-byebug (3.10.1) + byebug (~> 11.0) + pry (>= 0.13, < 0.15) puma (6.4.0) nio4r (~> 2.0) rack (2.2.8) @@ -275,6 +279,7 @@ DEPENDENCIES hanami-validations (~> 2.0) infra! pg + pry-byebug puma rack-test rake diff --git a/hanami_application/app/actions/orders/create.rb b/hanami_application/app/actions/orders/create.rb new file mode 100644 index 000000000..993c3a9aa --- /dev/null +++ b/hanami_application/app/actions/orders/create.rb @@ -0,0 +1,29 @@ +module Ecommerce + module Actions + module Orders + class Create < Ecommerce::Action + include Deps[ + "command_bus", + "repositories.orders", + ] + + def handle(request, response) + submit_order(request.params[:order_id], request.params[:customer_id]) + + response.format = :json + response.body = orders.by_uuid(request.params[:order_id]) + .attributes + .slice(:uuid) + .to_json + end + + private + + def submit_order(order_id, customer_id) + command_bus.(Ordering::SubmitOrder.new(order_id: order_id)) + # command_bus.(Crm::AssignCustomerToOrder.new(order_id: order_id, customer_id: customer_id)) + end + end + end + end +end diff --git a/hanami_application/app/event_handlers/orders/submit.rb b/hanami_application/app/event_handlers/orders/submit.rb new file mode 100644 index 000000000..5764f7854 --- /dev/null +++ b/hanami_application/app/event_handlers/orders/submit.rb @@ -0,0 +1,18 @@ +module Ecommerce + module EventHandlers + module Orders + class Submit + include Deps[ + "repositories.orders", + ] + + def call(event) + orders.create( + uuid: event.data[:order_id], + order_number: event.data[:order_number] + ) + end + end + end + end +end diff --git a/hanami_application/app/persistence/relations/events.rb b/hanami_application/app/persistence/relations/events.rb deleted file mode 100644 index cc5be11ed..000000000 --- a/hanami_application/app/persistence/relations/events.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Ecommerce - module Persistence - module Relations - class Events < ROM::Relation[:sql] - schema(:event_store_events, infer: true, as: :events) do - end - end - end - end -end diff --git a/hanami_application/app/persistence/relations/stream_entries.rb b/hanami_application/app/persistence/relations/stream_entries.rb deleted file mode 100644 index 1f0b87dd6..000000000 --- a/hanami_application/app/persistence/relations/stream_entries.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Ecommerce - module Persistence - module Relations - class StreamEntries < ROM::Relation[:sql] - schema(:event_store_events_in_streams, infer: true, as: :stream_entries) do - end - end - end - end -end diff --git a/hanami_application/app/repositories/orders.rb b/hanami_application/app/repositories/orders.rb index 6ea2b312e..2c0a27c0a 100644 --- a/hanami_application/app/repositories/orders.rb +++ b/hanami_application/app/repositories/orders.rb @@ -1,7 +1,11 @@ module Ecommerce module Repositories class Orders < ROM::Repository[:orders] + commands :create + + def by_uuid(uuid) + orders.where(uuid: uuid).one + end end end end - diff --git a/hanami_application/config/providers/command_bus.rb b/hanami_application/config/providers/command_bus.rb index 0e973f048..a13cbb450 100644 --- a/hanami_application/config/providers/command_bus.rb +++ b/hanami_application/config/providers/command_bus.rb @@ -2,7 +2,7 @@ Hanami.app.register_provider :command_bus do prepare do require "arkency/command_bus" - + register "command_bus", Arkency::CommandBus.new end end diff --git a/hanami_application/config/providers/ecommerce.rb b/hanami_application/config/providers/ecommerce.rb index 077b10990..3c4cc30ac 100644 --- a/hanami_application/config/providers/ecommerce.rb +++ b/hanami_application/config/providers/ecommerce.rb @@ -5,10 +5,10 @@ event_store = target["event_store.client"] command_bus = target["command_bus"] - + number_generator = -> { Ordering::NumberGenerator.new } payment_gateway = -> { Payments::FakeGateway.new } - + Ecommerce::Configuration.new( event_store: event_store, command_bus: command_bus, @@ -19,5 +19,9 @@ Infra::Types::VatRate.new(code: "20", rate: 20) ] ).call(event_store, command_bus) + + event_store.subscribe( + target["event_handlers.orders.submit"], to: [Ordering::OrderSubmitted] + ) end end diff --git a/hanami_application/config/providers/event_store.rb b/hanami_application/config/providers/event_store.rb index c444be444..5d2bbe37a 100644 --- a/hanami_application/config/providers/event_store.rb +++ b/hanami_application/config/providers/event_store.rb @@ -3,9 +3,16 @@ require "ruby_event_store" require 'ruby_event_store/rom' + rom_config = target["persistence.config"] + rom_config.register_mapper RubyEventStore::ROM::Mappers::StreamEntryToSerializedRecord + rom_config.register_mapper RubyEventStore::ROM::Mappers::EventToSerializedRecord + + rom_config.register_relation RubyEventStore::ROM::Relations::Events + rom_config.register_relation RubyEventStore::ROM::Relations::StreamEntries + repository = RubyEventStore::ROM::EventRepository.new( - rom: target['persistence.rom'], - serializer: RubyEventStore::NULL + rom: ROM.container(rom_config), + serializer: JSON ) client = RubyEventStore::Client.new(repository: repository) diff --git a/hanami_application/config/providers/infra.rb b/hanami_application/config/providers/infra.rb index 613158c88..8cd2fde87 100644 --- a/hanami_application/config/providers/infra.rb +++ b/hanami_application/config/providers/infra.rb @@ -6,4 +6,4 @@ target["event_store.client"] ) end -end \ No newline at end of file +end diff --git a/hanami_application/config/providers/persistence.rb b/hanami_application/config/providers/persistence.rb index e8dceb79d..0670ea6fd 100644 --- a/hanami_application/config/providers/persistence.rb +++ b/hanami_application/config/providers/persistence.rb @@ -4,20 +4,19 @@ require 'rom/core' require 'rom/sql' require 'rom-repository' - + config = ROM::Configuration.new( :sql, target['settings'].database_url ) - config.auto_registration( - target.root.join('app/persistence'), - namespace: 'Ecommerce::Persistence' - ) - + config.auto_registration( + target.root.join('app/persistence'), + namespace: 'Ecommerce::Persistence::Relations' + ) + register 'config', config register 'db', config.gateways[:default].connection register 'rom', ROM.container(config) - end - end - \ No newline at end of file + end +end diff --git a/hanami_application/config/routes.rb b/hanami_application/config/routes.rb index 4a00c9b6e..720d04047 100644 --- a/hanami_application/config/routes.rb +++ b/hanami_application/config/routes.rb @@ -4,7 +4,6 @@ module Ecommerce class Routes < Hanami::Routes root { "Hello from Hanami" } - slice :orders, at: "/orders" do - end + post "/orders", to: "orders.create" end end diff --git a/hanami_application/db/migrate/20231005225237_create_orders.rb b/hanami_application/db/migrate/20231005225237_create_orders.rb index cd57cc602..5cf0c3f58 100644 --- a/hanami_application/db/migrate/20231005225237_create_orders.rb +++ b/hanami_application/db/migrate/20231005225237_create_orders.rb @@ -3,8 +3,9 @@ ROM::SQL.migration do change do create_table(:orders) do - primary_key :id # TODO: change to uuid + primary_key :id + column :uuid, :uuid column :number, String column :customer, String column :state, String diff --git a/hanami_application/spec/requests/orders/submit_spec.rb b/hanami_application/spec/requests/orders/submit_spec.rb new file mode 100644 index 000000000..c29d2ad80 --- /dev/null +++ b/hanami_application/spec/requests/orders/submit_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +RSpec.describe "Submit Order", type: :request do + it "is successful" do + order_id = SecureRandom.uuid + customer_id = SecureRandom.uuid + + post "/orders", { order_id: order_id, customer_id: customer_id} + + + response_uuid = JSON.parse(last_response.body)["uuid"] + expect(response_uuid).to eq(order_id) + + expect(last_response).to be_successful + end +end diff --git a/hanami_application/spec/spec_helper.rb b/hanami_application/spec/spec_helper.rb index b0ce09239..af984e69c 100644 --- a/hanami_application/spec/spec_helper.rb +++ b/hanami_application/spec/spec_helper.rb @@ -8,3 +8,5 @@ require_relative "support/rspec" require_relative "support/requests" + +Hanami.app.boot From 36b97d6e29158e4ec97aeed0b5c916637fb61b66 Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 19:41:11 +0200 Subject: [PATCH 06/10] Cleanup --- hanami_application/app/read_models/configuration.rb | 13 ------------- hanami_application/app/repositories/orders.rb | 2 ++ hanami_application/config/providers/ecommerce.rb | 6 ++---- hanami_application/config/providers/event_store.rb | 4 ++++ hanami_application/config/providers/infra.rb | 9 --------- hanami_application/config/providers/repositories.rb | 5 ----- hanami_application/config/routes.rb | 2 -- hanami_application/lib/ecommerce/types.rb | 11 ----------- hanami_application/spec/requests/root_spec.rb | 11 ----------- hanami_application/spec/spec_helper.rb | 2 -- hanami_application/spec/support/requests.rb | 2 +- 11 files changed, 9 insertions(+), 58 deletions(-) delete mode 100644 hanami_application/app/read_models/configuration.rb delete mode 100644 hanami_application/config/providers/infra.rb delete mode 100644 hanami_application/config/providers/repositories.rb delete mode 100644 hanami_application/lib/ecommerce/types.rb delete mode 100644 hanami_application/spec/requests/root_spec.rb diff --git a/hanami_application/app/read_models/configuration.rb b/hanami_application/app/read_models/configuration.rb deleted file mode 100644 index 4ca0bb572..000000000 --- a/hanami_application/app/read_models/configuration.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Ecommerce - module ReadModels - class Configuration - include Deps[ - event_store: "event_store.client", - ] - - def call - event_store.subscribe(SubmitOrder, to: [Ordering::OrderSubmitted]) - end - end - end -end diff --git a/hanami_application/app/repositories/orders.rb b/hanami_application/app/repositories/orders.rb index 2c0a27c0a..33a41783f 100644 --- a/hanami_application/app/repositories/orders.rb +++ b/hanami_application/app/repositories/orders.rb @@ -1,6 +1,8 @@ module Ecommerce module Repositories class Orders < ROM::Repository[:orders] + include Deps[container: "persistence.rom"] + commands :create def by_uuid(uuid) diff --git a/hanami_application/config/providers/ecommerce.rb b/hanami_application/config/providers/ecommerce.rb index 3c4cc30ac..c6c93b0f3 100644 --- a/hanami_application/config/providers/ecommerce.rb +++ b/hanami_application/config/providers/ecommerce.rb @@ -9,7 +9,7 @@ number_generator = -> { Ordering::NumberGenerator.new } payment_gateway = -> { Payments::FakeGateway.new } - Ecommerce::Configuration.new( + config = Ecommerce::Configuration.new( event_store: event_store, command_bus: command_bus, number_generator: number_generator, @@ -20,8 +20,6 @@ ] ).call(event_store, command_bus) - event_store.subscribe( - target["event_handlers.orders.submit"], to: [Ordering::OrderSubmitted] - ) + register "config", config end end diff --git a/hanami_application/config/providers/event_store.rb b/hanami_application/config/providers/event_store.rb index 5d2bbe37a..e436a375f 100644 --- a/hanami_application/config/providers/event_store.rb +++ b/hanami_application/config/providers/event_store.rb @@ -19,5 +19,9 @@ register "repository", repository register "client", client + + client.subscribe( + target["event_handlers.orders.submit"], to: [Ordering::OrderSubmitted] + ) end end diff --git a/hanami_application/config/providers/infra.rb b/hanami_application/config/providers/infra.rb deleted file mode 100644 index 8cd2fde87..000000000 --- a/hanami_application/config/providers/infra.rb +++ /dev/null @@ -1,9 +0,0 @@ -Hanami.app.register_provider :infra, namespace: true do - prepare do - require 'infra' - - register "aggregate_root_repo", Infra::AggregateRootRepository.new( - target["event_store.client"] - ) - end -end diff --git a/hanami_application/config/providers/repositories.rb b/hanami_application/config/providers/repositories.rb deleted file mode 100644 index b53c8124e..000000000 --- a/hanami_application/config/providers/repositories.rb +++ /dev/null @@ -1,5 +0,0 @@ -Hanami.app.register_provider :repositories, namespace: true do - prepare do - register 'orders', Ecommerce::Repositories::Orders.new(target['persistence.rom']) - end -end diff --git a/hanami_application/config/routes.rb b/hanami_application/config/routes.rb index 720d04047..fd569f461 100644 --- a/hanami_application/config/routes.rb +++ b/hanami_application/config/routes.rb @@ -2,8 +2,6 @@ module Ecommerce class Routes < Hanami::Routes - root { "Hello from Hanami" } - post "/orders", to: "orders.create" end end diff --git a/hanami_application/lib/ecommerce/types.rb b/hanami_application/lib/ecommerce/types.rb deleted file mode 100644 index efc8fe970..000000000 --- a/hanami_application/lib/ecommerce/types.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -require "dry/types" - -module Ecommerce - Types = Dry.Types - - module Types - # Define your custom types here - end -end diff --git a/hanami_application/spec/requests/root_spec.rb b/hanami_application/spec/requests/root_spec.rb deleted file mode 100644 index 44acf66b5..000000000 --- a/hanami_application/spec/requests/root_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "Root", type: :request do - it "is successful" do - get "/" - - # Find me in `config/routes.rb` - expect(last_response).to be_successful - expect(last_response.body).to eq("Hello from Hanami") - end -end diff --git a/hanami_application/spec/spec_helper.rb b/hanami_application/spec/spec_helper.rb index af984e69c..b0ce09239 100644 --- a/hanami_application/spec/spec_helper.rb +++ b/hanami_application/spec/spec_helper.rb @@ -8,5 +8,3 @@ require_relative "support/rspec" require_relative "support/requests" - -Hanami.app.boot diff --git a/hanami_application/spec/support/requests.rb b/hanami_application/spec/support/requests.rb index f1c8f9a19..0816b8cd4 100644 --- a/hanami_application/spec/support/requests.rb +++ b/hanami_application/spec/support/requests.rb @@ -3,7 +3,7 @@ require "rack/test" RSpec.shared_context "Hanami app" do - let(:app) { Hanami.app } + let(:app) { Hanami.app.boot } end RSpec.configure do |config| From 49e6ccd0ca5aae93770dece2147be33ee2d9e171 Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 20:33:52 +0200 Subject: [PATCH 07/10] Simplified database transaction --- hanami_application/app/actions/orders/create.rb | 7 +++++-- hanami_application/config/providers/persistence.rb | 1 + .../spec/requests/orders/submit_spec.rb | 7 ++++++- infra/lib/infra.rb | 1 + infra/lib/infra/transaction.rb | 13 +++++++++++++ 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 infra/lib/infra/transaction.rb diff --git a/hanami_application/app/actions/orders/create.rb b/hanami_application/app/actions/orders/create.rb index 993c3a9aa..3bb879ee9 100644 --- a/hanami_application/app/actions/orders/create.rb +++ b/hanami_application/app/actions/orders/create.rb @@ -5,6 +5,7 @@ class Create < Ecommerce::Action include Deps[ "command_bus", "repositories.orders", + "persistence.transaction", ] def handle(request, response) @@ -20,8 +21,10 @@ def handle(request, response) private def submit_order(order_id, customer_id) - command_bus.(Ordering::SubmitOrder.new(order_id: order_id)) - # command_bus.(Crm::AssignCustomerToOrder.new(order_id: order_id, customer_id: customer_id)) + transaction.call do + command_bus.(Ordering::SubmitOrder.new(order_id: order_id)) + command_bus.(Crm::AssignCustomerToOrder.new(order_id: order_id, customer_id: customer_id)) + end end end end diff --git a/hanami_application/config/providers/persistence.rb b/hanami_application/config/providers/persistence.rb index 0670ea6fd..26c9fad82 100644 --- a/hanami_application/config/providers/persistence.rb +++ b/hanami_application/config/providers/persistence.rb @@ -18,5 +18,6 @@ register 'config', config register 'db', config.gateways[:default].connection register 'rom', ROM.container(config) + register 'transaction', Infra::Transaction.new(container: config) end end diff --git a/hanami_application/spec/requests/orders/submit_spec.rb b/hanami_application/spec/requests/orders/submit_spec.rb index c29d2ad80..34817f284 100644 --- a/hanami_application/spec/requests/orders/submit_spec.rb +++ b/hanami_application/spec/requests/orders/submit_spec.rb @@ -2,12 +2,17 @@ RSpec.describe "Submit Order", type: :request do it "is successful" do + # Arrange order_id = SecureRandom.uuid customer_id = SecureRandom.uuid - post "/orders", { order_id: order_id, customer_id: customer_id} + Hanami.app["ecommerce.config"] + Hanami.app["command_bus"].(Crm::RegisterCustomer.new(customer_id: customer_id, name: 'Bruce Wayne')) + # Act + post "/orders", { order_id: order_id, customer_id: customer_id} + # Assert response_uuid = JSON.parse(last_response.body)["uuid"] expect(response_uuid).to eq(order_id) diff --git a/infra/lib/infra.rb b/infra/lib/infra.rb index 9791fcd80..a0c6cc7fd 100644 --- a/infra/lib/infra.rb +++ b/infra/lib/infra.rb @@ -17,4 +17,5 @@ require_relative "infra/process" require_relative "infra/types" require_relative "infra/testing" +require_relative "infra/transaction" require_relative "infra/event_handler" diff --git a/infra/lib/infra/transaction.rb b/infra/lib/infra/transaction.rb new file mode 100644 index 000000000..ab855bbd4 --- /dev/null +++ b/infra/lib/infra/transaction.rb @@ -0,0 +1,13 @@ +module Infra + class Transaction + def initialize(container:) + @container = container + end + + def call + @container.gateways[:default].transaction do + yield + end + end + end +end From 85ed6bd9e2e33720e27056cf252963533c1c0bc5 Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 20:39:26 +0200 Subject: [PATCH 08/10] Fix order parameter name --- hanami_application/app/event_handlers/orders/submit.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hanami_application/app/event_handlers/orders/submit.rb b/hanami_application/app/event_handlers/orders/submit.rb index 5764f7854..19943402a 100644 --- a/hanami_application/app/event_handlers/orders/submit.rb +++ b/hanami_application/app/event_handlers/orders/submit.rb @@ -9,7 +9,7 @@ class Submit def call(event) orders.create( uuid: event.data[:order_id], - order_number: event.data[:order_number] + number: event.data[:order_number] ) end end From a5c1c5c741ccb70001149e761f1c6a9f6f9b5a3e Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Fri, 6 Oct 2023 21:46:31 +0200 Subject: [PATCH 09/10] Fix problem with UUID primary key --- hanami_application/app/actions/orders/create.rb | 4 ++-- hanami_application/app/event_handlers/orders/submit.rb | 2 +- hanami_application/app/repositories/orders.rb | 4 ++-- .../db/migrate/20231005225237_create_orders.rb | 5 +++-- hanami_application/spec/requests/orders/submit_spec.rb | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/hanami_application/app/actions/orders/create.rb b/hanami_application/app/actions/orders/create.rb index 3bb879ee9..f96963f5f 100644 --- a/hanami_application/app/actions/orders/create.rb +++ b/hanami_application/app/actions/orders/create.rb @@ -12,9 +12,9 @@ def handle(request, response) submit_order(request.params[:order_id], request.params[:customer_id]) response.format = :json - response.body = orders.by_uuid(request.params[:order_id]) + response.body = orders.by_id(request.params[:order_id]) .attributes - .slice(:uuid) + .slice(:id) .to_json end diff --git a/hanami_application/app/event_handlers/orders/submit.rb b/hanami_application/app/event_handlers/orders/submit.rb index 19943402a..ef79a84a4 100644 --- a/hanami_application/app/event_handlers/orders/submit.rb +++ b/hanami_application/app/event_handlers/orders/submit.rb @@ -8,7 +8,7 @@ class Submit def call(event) orders.create( - uuid: event.data[:order_id], + id: event.data[:order_id], number: event.data[:order_number] ) end diff --git a/hanami_application/app/repositories/orders.rb b/hanami_application/app/repositories/orders.rb index 33a41783f..6de65503d 100644 --- a/hanami_application/app/repositories/orders.rb +++ b/hanami_application/app/repositories/orders.rb @@ -5,8 +5,8 @@ class Orders < ROM::Repository[:orders] commands :create - def by_uuid(uuid) - orders.where(uuid: uuid).one + def by_id(id) + orders.by_pk(id).one end end end diff --git a/hanami_application/db/migrate/20231005225237_create_orders.rb b/hanami_application/db/migrate/20231005225237_create_orders.rb index 5cf0c3f58..c87ec0e4d 100644 --- a/hanami_application/db/migrate/20231005225237_create_orders.rb +++ b/hanami_application/db/migrate/20231005225237_create_orders.rb @@ -2,10 +2,11 @@ ROM::SQL.migration do change do + run 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";' + create_table(:orders) do - primary_key :id + primary_key :id, :uuid, default: Sequel.function(:uuid_generate_v4) - column :uuid, :uuid column :number, String column :customer, String column :state, String diff --git a/hanami_application/spec/requests/orders/submit_spec.rb b/hanami_application/spec/requests/orders/submit_spec.rb index 34817f284..803d9bb5c 100644 --- a/hanami_application/spec/requests/orders/submit_spec.rb +++ b/hanami_application/spec/requests/orders/submit_spec.rb @@ -13,7 +13,7 @@ post "/orders", { order_id: order_id, customer_id: customer_id} # Assert - response_uuid = JSON.parse(last_response.body)["uuid"] + response_uuid = JSON.parse(last_response.body)["id"] expect(response_uuid).to eq(order_id) expect(last_response).to be_successful From 172c2acf7539beda4af3d26048977a986796b548 Mon Sep 17 00:00:00 2001 From: Norbert Nytko Date: Sat, 7 Oct 2023 00:08:36 +0200 Subject: [PATCH 10/10] Add simplified view --- hanami_application/Gemfile | 2 ++ hanami_application/Gemfile.lock | 12 ++++++++++++ hanami_application/app/actions/orders/index.rb | 11 +++++++++++ hanami_application/app/repositories/orders.rb | 4 ++++ .../app/templates/layouts/app.html.erb | 1 + .../app/templates/orders/index.html.erb | 5 +++++ hanami_application/app/view.rb | 9 +++++++++ hanami_application/app/views/orders/index.rb | 15 +++++++++++++++ .../config/providers/event_store.rb | 2 +- hanami_application/config/routes.rb | 1 + .../spec/requests/orders/index_spec.rb | 12 ++++++++++++ 11 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 hanami_application/app/actions/orders/index.rb create mode 100644 hanami_application/app/templates/layouts/app.html.erb create mode 100644 hanami_application/app/templates/orders/index.html.erb create mode 100644 hanami_application/app/view.rb create mode 100644 hanami_application/app/views/orders/index.rb create mode 100644 hanami_application/spec/requests/orders/index_spec.rb diff --git a/hanami_application/Gemfile b/hanami_application/Gemfile index c32216b93..674df2575 100644 --- a/hanami_application/Gemfile +++ b/hanami_application/Gemfile @@ -6,6 +6,7 @@ gem "hanami", "~> 2.0" gem "hanami-router", "~> 2.0" gem "hanami-controller", "~> 2.0" gem "hanami-validations", "~> 2.0" +gem "hanami-view", "~> 2.0" gem "dry-types", "~> 1.0", ">= 1.6.1" gem "puma" @@ -23,6 +24,7 @@ gem "infra", path: "../infra" group :development, :test do gem "dotenv" + gem "pry" gem "pry-byebug" end diff --git a/hanami_application/Gemfile.lock b/hanami_application/Gemfile.lock index 284b8d83a..7981da872 100644 --- a/hanami_application/Gemfile.lock +++ b/hanami_application/Gemfile.lock @@ -156,6 +156,14 @@ GEM hanami-validations (2.0.1) dry-validation (>= 1.10, < 2) zeitwerk (~> 2.6.0) + hanami-view (2.1.0.beta2) + concurrent-ruby (~> 1.0) + dry-configurable (~> 1.0) + dry-core (~> 1.0) + dry-inflector (~> 1.0, < 2) + temple (~> 0.10.0, >= 0.10.2) + tilt (~> 2.0, >= 2.0.6) + zeitwerk (~> 2.6) hansi (0.2.1) i18n (1.14.1) concurrent-ruby (~> 1.0) @@ -257,7 +265,9 @@ GEM connection_pool (>= 2.3.0) rack (>= 2.2.4) redis-client (>= 0.14.0) + temple (0.10.3) thor (1.2.2) + tilt (2.3.0) transproc (1.1.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -277,8 +287,10 @@ DEPENDENCIES hanami-router (~> 2.0) hanami-rspec hanami-validations (~> 2.0) + hanami-view (~> 2.0) infra! pg + pry pry-byebug puma rack-test diff --git a/hanami_application/app/actions/orders/index.rb b/hanami_application/app/actions/orders/index.rb new file mode 100644 index 000000000..6506025da --- /dev/null +++ b/hanami_application/app/actions/orders/index.rb @@ -0,0 +1,11 @@ +module Ecommerce + module Actions + module Orders + class Index < Ecommerce::Action + def handle(request, response) + response.render(view) + end + end + end + end +end diff --git a/hanami_application/app/repositories/orders.rb b/hanami_application/app/repositories/orders.rb index 6de65503d..b393f2cf7 100644 --- a/hanami_application/app/repositories/orders.rb +++ b/hanami_application/app/repositories/orders.rb @@ -8,6 +8,10 @@ class Orders < ROM::Repository[:orders] def by_id(id) orders.by_pk(id).one end + + def all + orders.to_a + end end end end diff --git a/hanami_application/app/templates/layouts/app.html.erb b/hanami_application/app/templates/layouts/app.html.erb new file mode 100644 index 000000000..37f0bddbd --- /dev/null +++ b/hanami_application/app/templates/layouts/app.html.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/hanami_application/app/templates/orders/index.html.erb b/hanami_application/app/templates/orders/index.html.erb new file mode 100644 index 000000000..593107c95 --- /dev/null +++ b/hanami_application/app/templates/orders/index.html.erb @@ -0,0 +1,5 @@ +

All Orders

+ +<% orders.each do |order| %> +

Order ID: <%= order.id %>

+<% end %> diff --git a/hanami_application/app/view.rb b/hanami_application/app/view.rb new file mode 100644 index 000000000..3956b64bd --- /dev/null +++ b/hanami_application/app/view.rb @@ -0,0 +1,9 @@ +# auto_register: false +# frozen_string_literal: true + +require "hanami/view" + +module Ecommerce + class View < Hanami::View + end +end diff --git a/hanami_application/app/views/orders/index.rb b/hanami_application/app/views/orders/index.rb new file mode 100644 index 000000000..30a600fa2 --- /dev/null +++ b/hanami_application/app/views/orders/index.rb @@ -0,0 +1,15 @@ +module Ecommerce + module Views + module Orders + class Index < Ecommerce::View + include Deps[ + "repositories.orders" + ] + + expose :orders do + orders.all + end + end + end + end +end diff --git a/hanami_application/config/providers/event_store.rb b/hanami_application/config/providers/event_store.rb index e436a375f..e75225f08 100644 --- a/hanami_application/config/providers/event_store.rb +++ b/hanami_application/config/providers/event_store.rb @@ -19,7 +19,7 @@ register "repository", repository register "client", client - + client.subscribe( target["event_handlers.orders.submit"], to: [Ordering::OrderSubmitted] ) diff --git a/hanami_application/config/routes.rb b/hanami_application/config/routes.rb index fd569f461..0a37891a0 100644 --- a/hanami_application/config/routes.rb +++ b/hanami_application/config/routes.rb @@ -3,5 +3,6 @@ module Ecommerce class Routes < Hanami::Routes post "/orders", to: "orders.create" + get "/", to: "orders.index" end end diff --git a/hanami_application/spec/requests/orders/index_spec.rb b/hanami_application/spec/requests/orders/index_spec.rb new file mode 100644 index 000000000..7963a74d6 --- /dev/null +++ b/hanami_application/spec/requests/orders/index_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +RSpec.describe "Submit Order", type: :request do + it "is successful" do + # Arrange + # Act + get "/" + + # Assert + expect(last_response).to be_successful + end +end