From f311a3fe4a78fcc52877d4935f61ae90fe1a4e48 Mon Sep 17 00:00:00 2001 From: lukaszreszke Date: Tue, 6 Aug 2024 18:56:17 +0200 Subject: [PATCH] RAILS WAY mhm future prices work --- ecommerce/authentication/.mutant.yml | 10 - ecommerce/authentication/Gemfile | 4 - ecommerce/authentication/Gemfile.lock | 119 ------ ecommerce/authentication/Makefile | 10 - ecommerce/authentication/README.md | 7 - .../authentication/lib/authentication.rb | 25 -- .../lib/authentication/account.rb | 47 -- .../lib/authentication/account_service.rb | 49 --- .../commands/connect_account_to_client.rb | 7 - .../commands/register_account.rb | 6 - .../lib/authentication/commands/set_login.rb | 7 - .../commands/set_password_hash.rb | 7 - .../events/account_connected_to_client.rb | 6 - .../events/account_registered.rb | 5 - .../lib/authentication/events/login_set.rb | 6 - .../events/password_hash_set.rb | 6 - .../test/connect_account_to_client_test.rb | 20 - .../test/register_account_test.rb | 32 -- .../authentication/test/set_login_test.rb | 19 - .../test/set_password_hash_test.rb | 20 - ecommerce/authentication/test/test_helper.rb | 19 - ecommerce/configuration.rb | 50 --- ecommerce/crm/.mutant.yml | 11 - ecommerce/crm/Gemfile | 4 - ecommerce/crm/Gemfile.lock | 119 ------ ecommerce/crm/Makefile | 10 - ecommerce/crm/README.md | 9 - ecommerce/crm/lib/crm.rb | 22 - .../crm/commands/assign_customer_to_order.rb | 7 - .../crm/commands/promote_customer_to_vip.rb | 6 - .../crm/lib/crm/commands/register_customer.rb | 7 - ecommerce/crm/lib/crm/customer.rb | 40 -- ecommerce/crm/lib/crm/customer_service.rb | 27 -- .../crm/events/customer_assigned_to_order.rb | 6 - .../crm/events/customer_promoted_to_vip.rb | 5 - .../crm/lib/crm/events/customer_registered.rb | 8 - ecommerce/crm/lib/crm/order.rb | 21 - ecommerce/crm/lib/crm/order_service.rb | 22 - .../crm/test/assign_customer_to_order_test.rb | 43 -- .../crm/test/promote_client_to_vip_test.rb | 45 -- ecommerce/crm/test/registration_test.rb | 28 -- ecommerce/crm/test/test_helper.rb | 23 - ecommerce/fulfillment/.mutant.yml | 12 - ecommerce/fulfillment/Gemfile | 4 - ecommerce/fulfillment/Gemfile.lock | 116 ----- ecommerce/fulfillment/Makefile | 10 - ecommerce/fulfillment/lib/fulfillment.rb | 21 - .../lib/fulfillment/commands/cancel_order.rb | 9 - .../lib/fulfillment/commands/confirm_order.rb | 9 - .../fulfillment/commands/register_order.rb | 9 - .../lib/fulfillment/events/order_cancelled.rb | 7 - .../lib/fulfillment/events/order_confirmed.rb | 7 - .../fulfillment/events/order_registered.rb | 7 - .../lib/fulfillment/on_cancel_order.rb | 15 - .../lib/fulfillment/on_confirm_order.rb | 15 - .../lib/fulfillment/on_register_order.rb | 15 - .../fulfillment/lib/fulfillment/order.rb | 40 -- .../fulfillment/test/cancel_order_test.rb | 41 -- .../fulfillment/test/confirm_order_test.rb | 41 -- .../fulfillment/test/register_order_test.rb | 29 -- ecommerce/fulfillment/test/test_helper.rb | 13 - ecommerce/inventory/.mutant.yml | 12 - ecommerce/inventory/Gemfile | 4 - ecommerce/inventory/Gemfile.lock | 119 ------ ecommerce/inventory/Makefile | 10 - ecommerce/inventory/README.md | 9 - ecommerce/inventory/lib/inventory.rb | 36 -- .../lib/inventory/commands/dispatch.rb | 6 - .../lib/inventory/commands/release.rb | 6 - .../lib/inventory/commands/reserve.rb | 6 - .../lib/inventory/commands/supply.rb | 6 - .../inventory/events/availability_changed.rb | 4 - .../inventory/events/stock_level_changed.rb | 4 - .../lib/inventory/events/stock_released.rb | 4 - .../lib/inventory/events/stock_reserved.rb | 4 - .../lib/inventory/inventory_entry.rb | 91 ---- .../lib/inventory/inventory_entry_service.rb | 39 -- ecommerce/inventory/test/dispatch_test.rb | 30 -- ecommerce/inventory/test/release_test.rb | 40 -- ecommerce/inventory/test/reserve_test.rb | 38 -- ecommerce/inventory/test/supply_test.rb | 33 -- ecommerce/inventory/test/test_helper.rb | 39 -- ecommerce/invoicing/.mutant.yml | 14 - ecommerce/invoicing/Gemfile | 4 - ecommerce/invoicing/Gemfile.lock | 119 ------ ecommerce/invoicing/Makefile | 10 - ecommerce/invoicing/README.md | 15 - ecommerce/invoicing/lib/invoicing.rb | 49 --- ecommerce/invoicing/lib/invoicing/commands.rb | 30 -- ecommerce/invoicing/lib/invoicing/events.rb | 33 -- ...ake_concurrent_invoice_number_generator.rb | 19 - ecommerce/invoicing/lib/invoicing/invoice.rb | 110 ----- .../invoicing/invoice_item_title_catalog.rb | 18 - .../lib/invoicing/invoice_number_generator.rb | 18 - ecommerce/invoicing/lib/invoicing/product.rb | 26 -- ecommerce/invoicing/lib/invoicing/services.rb | 55 --- ...oncurrent_invoice_number_generator_test.rb | 15 - ecommerce/invoicing/test/invoice_item_test.rb | 22 - .../test/invoice_number_generator_test.rb | 27 -- .../invoicing/test/invoice_service_test.rb | 177 -------- .../setting_product_displayed_name_test.rb | 23 - ecommerce/invoicing/test/test_helper.rb | 37 -- ecommerce/ordering/.mutant.yml | 13 - ecommerce/ordering/Gemfile | 4 - ecommerce/ordering/Gemfile.lock | 119 ------ ecommerce/ordering/Makefile | 10 - ecommerce/ordering/README.md | 61 --- ecommerce/ordering/lib/ordering.rb | 37 -- .../lib/ordering/commands/accept_order.rb | 7 - .../ordering/commands/add_item_to_basket.rb | 8 - .../lib/ordering/commands/reject_order.rb | 7 - .../commands/remove_item_from_basket.rb | 8 - .../ordering/commands/set_order_as_expired.rb | 7 - .../lib/ordering/commands/submit_order.rb | 7 - .../ordering/events/item_added_to_basket.rb | 6 - .../events/item_removed_from_basket.rb | 6 - .../lib/ordering/events/order_expired.rb | 5 - .../lib/ordering/events/order_placed.rb | 6 - .../lib/ordering/events/order_rejected.rb | 5 - .../lib/ordering/events/order_submitted.rb | 6 - .../lib/ordering/fake_number_generator.rb | 8 - .../ordering/lib/ordering/number_generator.rb | 13 - ecommerce/ordering/lib/ordering/order.rb | 146 ------- ecommerce/ordering/lib/ordering/service.rb | 75 ---- ecommerce/ordering/test/accept_order_test.rb | 54 --- .../ordering/test/add_item_to_basket_test.rb | 49 --- .../ordering/test/number_generator_test.rb | 13 - ecommerce/ordering/test/order_test.rb | 39 -- ecommerce/ordering/test/reject_order_test.rb | 52 --- .../test/remove_item_from_basket_test.rb | 53 --- .../test/set_order_as_expired_test.rb | 46 -- ecommerce/ordering/test/submit_order_test.rb | 75 ---- ecommerce/ordering/test/test_helper.rb | 14 - ecommerce/payments/.mutant.yml | 12 - ecommerce/payments/Gemfile | 4 - ecommerce/payments/Gemfile.lock | 119 ------ ecommerce/payments/Makefile | 10 - ecommerce/payments/README.md | 17 - ecommerce/payments/lib/payments.rb | 27 -- ecommerce/payments/lib/payments/commands.rb | 18 - ecommerce/payments/lib/payments/events.rb | 18 - .../payments/lib/payments/fake_gateway.rb | 19 - .../lib/payments/on_authorize_payment.rb | 15 - .../lib/payments/on_capture_payment.rb | 14 - .../lib/payments/on_release_payment.rb | 14 - .../lib/payments/on_set_payment_amount.rb | 14 - ecommerce/payments/lib/payments/payment.rb | 64 --- ecommerce/payments/test/fake_gateway_test.rb | 15 - .../payments/test/on_capture_payment_test.rb | 24 -- .../payments/test/on_release_payment_test.rb | 21 - ecommerce/payments/test/payment_test.rb | 103 ----- ecommerce/payments/test/test_helper.rb | 16 - ecommerce/pricing/.mutant.yml | 13 - ecommerce/pricing/Gemfile | 8 - ecommerce/pricing/Gemfile.lock | 121 ------ ecommerce/pricing/Makefile | 10 - ecommerce/pricing/README.md | 19 - ecommerce/pricing/lib/pricing.rb | 109 ----- .../calculate_order_sub_amounts_value.rb | 14 - .../pricing/calculate_order_total_value.rb | 14 - ecommerce/pricing/lib/pricing/commands.rb | 83 ---- ecommerce/pricing/lib/pricing/coupon.rb | 31 -- ecommerce/pricing/lib/pricing/discounts.rb | 64 --- ecommerce/pricing/lib/pricing/events.rb | 68 --- ecommerce/pricing/lib/pricing/offer.rb | 251 ----------- ecommerce/pricing/lib/pricing/price_change.rb | 17 - .../pricing/lib/pricing/pricing_catalog.rb | 59 --- .../lib/pricing/promotions_calendar.rb | 40 -- ecommerce/pricing/lib/pricing/services.rb | 183 -------- .../pricing/lib/pricing/time_promotion.rb | 27 -- ecommerce/pricing/test/coupons_test.rb | 40 -- ecommerce/pricing/test/discounts_test.rb | 68 --- ecommerce/pricing/test/free_products_test.rb | 217 ---------- ecommerce/pricing/test/future_prices_test.rb | 125 ------ ecommerce/pricing/test/order_product_test.rb | 47 -- ecommerce/pricing/test/pricing_test.rb | 401 ------------------ ecommerce/pricing/test/product_test.rb | 33 -- ecommerce/pricing/test/simple_offer_test.rb | 36 -- ecommerce/pricing/test/subamounts_test.rb | 41 -- ecommerce/pricing/test/test_helper.rb | 49 --- ecommerce/pricing/test/time_promotion_test.rb | 222 ---------- ecommerce/processes/.mutant.yml | 21 - ecommerce/processes/Gemfile | 4 - ecommerce/processes/Gemfile.lock | 119 ------ ecommerce/processes/Makefile | 10 - ecommerce/processes/lib/processes.rb | 153 ------- .../confirm_order_on_payment_captured.rb | 16 - .../determine_vat_rates_on_order_placed.rb | 20 - .../notify_payments_about_order_value.rb | 17 - .../processes/order_item_invoicing_process.rb | 87 ---- .../lib/processes/registration_process.rb | 4 - .../lib/processes/release_payment_process.rb | 63 --- .../lib/processes/reservation_process.rb | 96 ----- .../lib/processes/shipment_process.rb | 81 ---- .../processes/sync_shipment_from_ordering.rb | 12 - .../lib/processes/three_plus_one_free.rb | 119 ------ .../processes/test/determine_vat_rate_test.rb | 30 -- .../processes/test/money_splitter_test.rb | 18 - .../processes/test/order_confirmation_test.rb | 15 - .../test/order_item_invoicing_process_test.rb | 43 -- .../test/release_payment_process_test.rb | 37 -- .../test/reservation_process_test.rb | 108 ----- ecommerce/processes/test/test_helper.rb | 100 ----- .../test/three_plus_one_free_test.rb | 160 ------- ecommerce/product_catalog/.mutant.yml | 8 - ecommerce/product_catalog/Gemfile | 4 - ecommerce/product_catalog/Gemfile.lock | 119 ------ ecommerce/product_catalog/Makefile | 10 - ecommerce/product_catalog/README.md | 21 - .../product_catalog/lib/product_catalog.rb | 15 - .../lib/product_catalog/commands.rb | 10 - .../lib/product_catalog/events.rb | 11 - .../lib/product_catalog/naming.rb | 27 -- .../lib/product_catalog/registration.rb | 34 -- ecommerce/product_catalog/test/naming_test.rb | 24 -- .../product_catalog/test/registration_test.rb | 52 --- ecommerce/product_catalog/test/test_helper.rb | 14 - ecommerce/shipping/.mutant.yml | 12 - ecommerce/shipping/Gemfile | 4 - ecommerce/shipping/Gemfile.lock | 115 ----- ecommerce/shipping/Makefile | 10 - ecommerce/shipping/README.md | 9 - ecommerce/shipping/lib/shipping.rb | 51 --- .../add_item_to_shipment_picking_list.rb | 8 - .../add_shipping_address_to_shipment.rb | 8 - .../shipping/commands/authorize_shipment.rb | 5 - .../remove_item_from_shipment_picking_list.rb | 8 - .../lib/shipping/commands/submit_shipment.rb | 5 - .../item_added_to_shipment_picking_list.rb | 6 - ...item_removed_from_shipment_picking_list.rb | 6 - .../shipping/events/shipment_authorized.rb | 5 - .../lib/shipping/events/shipment_submitted.rb | 5 - .../shipping_address_added_to_shipment.rb | 6 - .../shipping/lib/shipping/picking_list.rb | 44 -- .../lib/shipping/picking_list_item.rb | 18 - .../on_add_item_to_shipment_picking_list.rb | 16 - .../on_add_shipping_address_to_shipment.rb | 16 - .../services/on_authorize_shipment.rb | 16 - ..._remove_item_from_shipment_picking_list.rb | 16 - .../shipping/services/on_submit_shipment.rb | 16 - ecommerce/shipping/lib/shipping/shipment.rb | 98 ----- ..._add_item_to_shipment_picking_list_test.rb | 23 - ...n_add_shipping_address_to_shipment_test.rb | 30 -- .../test/on_authorize_shipment_test.rb | 56 --- ...ve_item_from_shipment_picking_list_test.rb | 41 -- .../shipping/test/on_submit_shipment_test.rb | 54 --- .../shipping/test/picking_list_item_test.rb | 33 -- ecommerce/shipping/test/picking_list_test.rb | 48 --- ecommerce/shipping/test/shipment_test.rb | 145 ------- ecommerce/shipping/test/test_helper.rb | 25 -- ecommerce/taxes/.mutant.yml | 12 - ecommerce/taxes/Gemfile | 4 - ecommerce/taxes/Gemfile.lock | 119 ------ ecommerce/taxes/Makefile | 10 - ecommerce/taxes/README.md | 10 - ecommerce/taxes/lib/taxes.rb | 24 -- ecommerce/taxes/lib/taxes/commands.rb | 11 - ecommerce/taxes/lib/taxes/events.rb | 12 - ecommerce/taxes/lib/taxes/product.rb | 24 -- ecommerce/taxes/lib/taxes/services.rb | 37 -- ecommerce/taxes/lib/taxes/vat_rate_catalog.rb | 18 - ecommerce/taxes/test/taxes_test.rb | 53 --- ecommerce/taxes/test/test_helper.rb | 21 - hanami_application/README.md | 4 - infra/Gemfile.lock | 23 - infra/infra.gemspec | 2 - infra/lib/infra.rb | 3 - infra/lib/infra/command.rb | 8 +- infra/lib/infra/event.rb | 28 -- infra/lib/infra/types.rb | 41 -- pricing_catalog_rails_app/.dockerignore | 37 -- pricing_catalog_rails_app/.gitignore | 37 -- pricing_catalog_rails_app/Dockerfile | 62 --- pricing_catalog_rails_app/Gemfile | 50 --- pricing_catalog_rails_app/Gemfile.lock | 337 --------------- pricing_catalog_rails_app/README.md | 24 -- pricing_catalog_rails_app/Rakefile | 6 - .../admin_catalog/admin_catalog.rb | 36 -- .../read_models/admin_catalog/index.html.erb | 19 - .../app/admin/register_product.rb | 14 - .../app/assets/config/manifest.js | 4 - .../app/assets/images/.keep | 0 .../app/assets/stylesheets/application.css | 15 - .../app/channels/application_cable/channel.rb | 4 - .../channels/application_cable/connection.rb | 4 - .../controllers/admin/catalog_controller.rb | 16 - .../app/controllers/application_controller.rb | 2 - .../app/controllers/catalog_controller.rb | 7 - .../app/controllers/concerns/.keep | 0 .../app/helpers/application_helper.rb | 2 - .../app/javascript/application.js | 3 - .../app/javascript/controllers/application.js | 9 - .../controllers/hello_controller.js | 7 - .../app/javascript/controllers/index.js | 11 - .../app/jobs/application_job.rb | 7 - .../app/models/application_record.rb | 3 - .../app/models/concerns/.keep | 0 .../read_models/public_catalog/index.html.erb | 7 - .../public_catalog/public_catalog.rb | 36 -- .../app/views/layouts/application.html.erb | 16 - pricing_catalog_rails_app/bin/bundle | 109 ----- .../bin/docker-entrypoint | 8 - pricing_catalog_rails_app/bin/importmap | 4 - pricing_catalog_rails_app/bin/rails | 4 - pricing_catalog_rails_app/bin/rake | 4 - pricing_catalog_rails_app/bin/setup | 33 -- pricing_catalog_rails_app/config.ru | 6 - .../config/application.rb | 39 -- pricing_catalog_rails_app/config/boot.rb | 4 - pricing_catalog_rails_app/config/cable.yml | 11 - .../config/credentials.yml.enc | 1 - pricing_catalog_rails_app/config/database.yml | 25 -- .../config/environment.rb | 5 - .../config/environments/development.rb | 65 --- .../config/environments/production.rb | 88 ---- .../config/environments/test.rb | 54 --- pricing_catalog_rails_app/config/importmap.rb | 7 - .../initializers/content_security_policy.rb | 25 -- .../initializers/filter_parameter_logging.rb | 8 - .../config/initializers/inflections.rb | 16 - .../config/initializers/permissions_policy.rb | 13 - .../config/initializers/rails_event_store.rb | 38 -- .../config/locales/en.yml | 31 -- pricing_catalog_rails_app/config/master.key | 1 - pricing_catalog_rails_app/config/puma.rb | 35 -- pricing_catalog_rails_app/config/routes.rb | 16 - ...0240130110320_create_event_store_events.rb | 26 -- .../20240201132941_enable_pg_crypto.rb | 5 - .../20240201133038_create_products_table.rb | 5 - .../20240201154705_create_admin_products.rb | 5 - pricing_catalog_rails_app/db/schema.rb | 55 --- pricing_catalog_rails_app/db/seeds.rb | 9 - pricing_catalog_rails_app/lib/assets/.keep | 0 pricing_catalog_rails_app/lib/tasks/.keep | 0 pricing_catalog_rails_app/log/.keep | 0 pricing_catalog_rails_app/public/404.html | 67 --- pricing_catalog_rails_app/public/422.html | 67 --- pricing_catalog_rails_app/public/500.html | 66 --- .../public/apple-touch-icon-precomposed.png | 0 .../public/apple-touch-icon.png | 0 pricing_catalog_rails_app/public/favicon.ico | 0 pricing_catalog_rails_app/public/robots.txt | 1 - pricing_catalog_rails_app/storage/.keep | 0 .../test/application_system_test_case.rb | 5 - .../application_cable/connection_test.rb | 13 - .../test/controllers/.keep | 0 .../test/fixtures/files/.keep | 0 pricing_catalog_rails_app/test/helpers/.keep | 0 .../test/integration/.keep | 0 pricing_catalog_rails_app/test/models/.keep | 0 pricing_catalog_rails_app/test/system/.keep | 0 pricing_catalog_rails_app/test/test_helper.rb | 15 - pricing_catalog_rails_app/tmp/.keep | 0 .../tmp/local_secret.txt | 1 - pricing_catalog_rails_app/tmp/pids/.keep | 0 pricing_catalog_rails_app/tmp/storage/.keep | 0 pricing_catalog_rails_app/vendor/.keep | 0 .../vendor/javascript/.keep | 0 rails_application/Gemfile.lock | 25 -- .../billing_addresses_controller.rb | 30 +- .../app/controllers/customers_controller.rb | 31 +- .../controllers/events_catalog_controller.rb | 5 - .../app/controllers/invoices_controller.rb | 20 +- .../app/controllers/orders_controller.rb | 175 +++++--- .../product/future_price_controller.rb | 20 - .../app/controllers/products_controller.rb | 131 ++---- .../app/controllers/shipments_controller.rb | 7 +- .../shipping_addresses_controller.rb | 29 +- .../app/controllers/supplies_controller.rb | 12 +- .../controllers/time_promotions_controller.rb | 34 +- rails_application/app/models/customer.rb | 12 + rails_application/app/models/invoice.rb | 13 + rails_application/app/models/order.rb | 33 ++ rails_application/app/models/order_item.rb | 5 + rails_application/app/models/product.rb | 9 + .../app/models/time_promotion.rb | 7 + .../read_models/availability/configuration.rb | 25 -- .../client_authentication/configuration.rb | 12 - .../client_authentication/create_account.rb | 9 - .../client_authentication/set_password.rb | 13 - .../client_orders/add_item_to_order.rb | 65 --- .../client_orders/assign_customer_to_order.rb | 15 - .../read_models/client_orders/cancel_order.rb | 10 - .../client_orders/change_product_name.rb | 10 - .../client_orders/change_product_price.rb | 7 - .../client_orders/configuration.rb | 52 --- .../client_orders/confirm_order.rb | 10 - .../client_orders/create_customer.rb | 10 - .../read_models/client_orders/expire_order.rb | 10 - .../read_models/client_orders/orders_list.rb | 111 ----- .../app/read_models/client_orders/product.rb | 5 - .../client_orders/register_product.rb | 7 - .../client_orders/remove_item_from_order.rb | 42 -- .../client_orders/reset_discount.rb | 9 - .../read_models/client_orders/show_order.rb | 102 ----- .../read_models/client_orders/submit_order.rb | 11 - .../client_orders/update_discount.rb | 9 - .../client_orders/update_order_total_value.rb | 10 - .../update_paid_orders_summary.rb | 9 - .../app/read_models/coupons/configuration.rb | 11 - .../read_models/coupons/register_coupon.rb | 13 - .../read_models/customers/configuration.rb | 14 - .../read_models/customers/connect_account.rb | 7 - .../read_models/customers/promote_to_vip.rb | 18 - .../customers/register_customer.rb | 7 - .../customers/update_paid_orders_summary.rb | 9 - .../app/read_models/invoices/configuration.rb | 25 -- .../invoices/create_invoice_item.rb | 18 - .../read_models/invoices/mark_as_issued.rb | 12 - .../read_models/invoices/mark_order_placed.rb | 9 - .../invoices/set_billing_address.rb | 15 - .../read_models/invoices/set_payment_date.rb | 11 - .../app/read_models/products/configuration.rb | 55 --- .../refresh_future_prices_calendar.rb | 23 - .../read_models/public_offer/configuration.rb | 76 ---- .../app/read_models/public_offer/product.rb | 9 - .../public_offer/register_lowest_price.rb | 72 ---- .../read_models/shipments/configuration.rb | 25 -- .../shipments/mark_order_placed.rb | 7 - .../shipments/set_shipping_address.rb | 13 - .../read_models/single_table_read_model.rb | 117 ----- .../time_promotions/broadcaster.rb | 10 - .../time_promotions/configuration.rb | 13 - .../time_promotions/create_time_promotion.rb | 16 - .../app/views/billing_addresses/edit.erb | 16 +- .../app/views/customers/index.html.erb | 2 +- .../app/views/customers/new.html.erb | 18 +- .../app/views/customers/show.html.erb | 6 +- .../app/views/invoices/show.html.erb | 30 +- .../app/views/orders/edit.html.erb | 8 +- .../app/views/orders/index.html.erb | 8 +- .../app/views/orders/new.html.erb | 52 ++- .../app/views/orders/show.html.erb | 50 +-- .../app/views/products/_future_price.html.erb | 4 +- .../app/views/products/edit.html.erb | 24 +- .../app/views/products/index.html.erb | 2 +- .../app/views/products/new.html.erb | 10 +- .../app/views/products/show.html.erb | 17 +- .../app/views/shipments/index.html.erb | 10 +- .../views/shipping_addresses/edit.html.erb | 14 +- rails_application/config/routes.rb | 4 +- .../20150429224621_create_order_lines.rb | 10 - .../20150429224628_create_customers.rb | 9 - .../migrate/20150429224746_create_products.rb | 9 - ...0181102132612_create_event_store_events.rb | 42 -- .../20181123154324_index_by_event_type.rb | 5 - .../20181123155503_limit_for_event_id.rb | 6 - ...20181207145051_binary_data_and_metadata.rb | 33 -- .../20210102110315_harmonize_schema.rb | 6 - .../migrate/20210102182818_binary_to_jsonb.rb | 6 - .../20210103114304_created_at_precision.rb | 45 -- .../db/migrate/20210103114309_add_valid_at.rb | 14 - ...20210103114314_no_global_stream_entries.rb | 59 --- ..._attachments_for_blob_id.active_storage.rb | 10 - ...0306222803_create_active_admin_comments.rb | 16 - .../20210318093812_disable_pg_crypto.rb | 9 - .../20210505162028_add_price_to_products.rb | 5 - ...20210505163254_add_price_to_order_lines.rb | 5 - .../20210617230722_add_uid_to_product.rb | 5 - .../20210626171021_add_uid_to_customer.rb | 5 - .../20210626210851_migrate_from_id_to_uuid.rb | 22 - ...otal_value_and_discount_value_to_orders.rb | 7 - ...210830164940_drop_active_admin_comments.rb | 5 - .../20210907115224_string_to_native_uuids.rb | 6 - ...10916191138_customers_add_registered_at.rb | 5 - ...210918000940_products_add_registered_at.rb | 5 - ...20210918003625_products_drop_timestamps.rb | 6 - .../20211003170051_create_shipments.rb | 11 - ...13_create_products_in_orders_read_model.rb | 9 - ...7_create_customers_in_orders_read_model.rb | 8 - ...1124220955_add_vat_rate_code_to_product.rb | 5 - ...0220109162627_create_invoice_read_model.rb | 28 -- ...02_create_orders_in_invoices_read_model.rb | 8 - ...3_create_orders_in_shipments_read_model.rb | 8 - .../20220121131334_add_vip_to_customer.rb | 5 - .../migrate/20220219130650_create_clients.rb | 10 - .../20220219162101_create_client_orders.rb | 12 - .../migrate/20220519094635_create_coupons.rb | 12 - .../20220528213429_create_happy_hours.rb | 14 - ...07201447_add_happy_hour_value_to_orders.rb | 5 - .../20220703122711_drop_happy_hours.rb | 14 - ...703133325_add_active_to_time_promotions.rb | 5 - ...e_constraint_on_code_on_time_promotions.rb | 5 - ...remove_code_column_from_time_promotions.rb | 5 - ...0829155333_create_public_offer_products.rb | 9 - ...03_create_client_order_lines_read_model.rb | 15 - ...create_client_order_products_read_model.rb | 9 - ...221107085656_add_client_column_to_order.rb | 5 - ...ient_order_lines_product_id_column_type.rb | 6 - ...221109150819_add_values_to_client_order.rb | 7 - ...21124200914_add_prices_chart_to_product.rb | 5 - ...21208185429_rename_future_prices_column.rb | 5 - ...2855_add_uniq_uid_index_to_orders_order.rb | 5 - ..._prices_calendar_future_prices_calendar.rb | 5 - ..._total_value_updated_at_to_orders_table.rb | 5 - ...add_discount_updated_at_to_orders_table.rb | 5 - ...t_recent_price_to_client_order_products.rb | 14 - ...0118170447_create_availability_products.rb | 8 - ...50_add_paid_products_summary_to_clients.rb | 5 - ..._add_paid_products_summary_to_customers.rb | 5 - ...95547_remove_price_column_from_products.rb | 5 - ...74907_add_accounting_column_to_customer.rb | 5 - .../20230127125135_create_table_accounts.rb | 8 - ...ove_lowest_recent_price_to_public_offer.rb | 16 - .../20230130172454_rename_accounts_table.rb | 5 - ...230130172623_add_account_id_to_accounts.rb | 5 - ..._recent_price_from_client_order_product.rb | 5 - ..._index_to_event_store_events_in_streams.rb | 9 - ...ent_id_to_event_store_events_in_streams.rb | 7 - ...ent_id_to_event_store_events_in_streams.rb | 7 - .../db/migrate/20240806161206_drop_order.rb | 5 - .../migrate/20240806161443_create_orders.rb | 18 + ...5434_create_old_fashioned_product_table.rb | 15 + .../20240806165554_create_order_items.rb | 11 + .../db/migrate/20240807162106_create_users.rb | 13 + ...101541_add_stock_level_to_product_crud.rb} | 2 +- .../migrate/20240814135823_create_invoices.rb | 15 + ...0240821120809_correlate_order_with_user.rb | 5 + .../20240821121943_rename_user_to_customer.rb | 5 + .../20240821122557_enerich_customer.rb | 5 + ..._user_id_to_customer_id_in_orders_table.rb | 5 + ...821123342_drop_customer_col_from_orders.rb | 5 + ...5153_allow_null_for_orders_customers_fk.rb | 5 + ...ve_shipping_addresses_and_all_that_jazz.rb | 9 + ...2082432_order_must_have_invoice_details.rb | 14 + ...0240822100417_add_invoice_paid_to_order.rb | 5 + ...40822110341_add_future_price_to_product.rb | 6 + ... 20240822170829_create_time_promotions.rb} | 7 +- rails_application/db/schema.rb | 225 +++------- rails_application/db/seeds.rb | 54 --- rails_application/lib/configuration.rb | 61 --- .../test/client_orders/discount_test.rb | 18 +- .../test/orders/discount_test.rb | 18 +- .../orders/update_order_total_value_test.rb | 4 +- 534 files changed, 634 insertions(+), 14148 deletions(-) delete mode 100644 ecommerce/authentication/.mutant.yml delete mode 100644 ecommerce/authentication/Gemfile delete mode 100644 ecommerce/authentication/Gemfile.lock delete mode 100644 ecommerce/authentication/Makefile delete mode 100644 ecommerce/authentication/README.md delete mode 100644 ecommerce/authentication/lib/authentication.rb delete mode 100644 ecommerce/authentication/lib/authentication/account.rb delete mode 100644 ecommerce/authentication/lib/authentication/account_service.rb delete mode 100644 ecommerce/authentication/lib/authentication/commands/connect_account_to_client.rb delete mode 100644 ecommerce/authentication/lib/authentication/commands/register_account.rb delete mode 100644 ecommerce/authentication/lib/authentication/commands/set_login.rb delete mode 100644 ecommerce/authentication/lib/authentication/commands/set_password_hash.rb delete mode 100644 ecommerce/authentication/lib/authentication/events/account_connected_to_client.rb delete mode 100644 ecommerce/authentication/lib/authentication/events/account_registered.rb delete mode 100644 ecommerce/authentication/lib/authentication/events/login_set.rb delete mode 100644 ecommerce/authentication/lib/authentication/events/password_hash_set.rb delete mode 100644 ecommerce/authentication/test/connect_account_to_client_test.rb delete mode 100644 ecommerce/authentication/test/register_account_test.rb delete mode 100644 ecommerce/authentication/test/set_login_test.rb delete mode 100644 ecommerce/authentication/test/set_password_hash_test.rb delete mode 100644 ecommerce/authentication/test/test_helper.rb delete mode 100644 ecommerce/configuration.rb delete mode 100644 ecommerce/crm/.mutant.yml delete mode 100644 ecommerce/crm/Gemfile delete mode 100644 ecommerce/crm/Gemfile.lock delete mode 100644 ecommerce/crm/Makefile delete mode 100644 ecommerce/crm/README.md delete mode 100644 ecommerce/crm/lib/crm.rb delete mode 100644 ecommerce/crm/lib/crm/commands/assign_customer_to_order.rb delete mode 100644 ecommerce/crm/lib/crm/commands/promote_customer_to_vip.rb delete mode 100644 ecommerce/crm/lib/crm/commands/register_customer.rb delete mode 100644 ecommerce/crm/lib/crm/customer.rb delete mode 100644 ecommerce/crm/lib/crm/customer_service.rb delete mode 100644 ecommerce/crm/lib/crm/events/customer_assigned_to_order.rb delete mode 100644 ecommerce/crm/lib/crm/events/customer_promoted_to_vip.rb delete mode 100644 ecommerce/crm/lib/crm/events/customer_registered.rb delete mode 100644 ecommerce/crm/lib/crm/order.rb delete mode 100644 ecommerce/crm/lib/crm/order_service.rb delete mode 100644 ecommerce/crm/test/assign_customer_to_order_test.rb delete mode 100644 ecommerce/crm/test/promote_client_to_vip_test.rb delete mode 100644 ecommerce/crm/test/registration_test.rb delete mode 100644 ecommerce/crm/test/test_helper.rb delete mode 100644 ecommerce/fulfillment/.mutant.yml delete mode 100644 ecommerce/fulfillment/Gemfile delete mode 100644 ecommerce/fulfillment/Gemfile.lock delete mode 100644 ecommerce/fulfillment/Makefile delete mode 100644 ecommerce/fulfillment/lib/fulfillment.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/commands/cancel_order.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/commands/confirm_order.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/commands/register_order.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/events/order_cancelled.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/events/order_confirmed.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/events/order_registered.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/on_cancel_order.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/on_confirm_order.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/on_register_order.rb delete mode 100644 ecommerce/fulfillment/lib/fulfillment/order.rb delete mode 100644 ecommerce/fulfillment/test/cancel_order_test.rb delete mode 100644 ecommerce/fulfillment/test/confirm_order_test.rb delete mode 100644 ecommerce/fulfillment/test/register_order_test.rb delete mode 100644 ecommerce/fulfillment/test/test_helper.rb delete mode 100644 ecommerce/inventory/.mutant.yml delete mode 100644 ecommerce/inventory/Gemfile delete mode 100644 ecommerce/inventory/Gemfile.lock delete mode 100644 ecommerce/inventory/Makefile delete mode 100644 ecommerce/inventory/README.md delete mode 100644 ecommerce/inventory/lib/inventory.rb delete mode 100644 ecommerce/inventory/lib/inventory/commands/dispatch.rb delete mode 100644 ecommerce/inventory/lib/inventory/commands/release.rb delete mode 100644 ecommerce/inventory/lib/inventory/commands/reserve.rb delete mode 100644 ecommerce/inventory/lib/inventory/commands/supply.rb delete mode 100644 ecommerce/inventory/lib/inventory/events/availability_changed.rb delete mode 100644 ecommerce/inventory/lib/inventory/events/stock_level_changed.rb delete mode 100644 ecommerce/inventory/lib/inventory/events/stock_released.rb delete mode 100644 ecommerce/inventory/lib/inventory/events/stock_reserved.rb delete mode 100644 ecommerce/inventory/lib/inventory/inventory_entry.rb delete mode 100644 ecommerce/inventory/lib/inventory/inventory_entry_service.rb delete mode 100644 ecommerce/inventory/test/dispatch_test.rb delete mode 100644 ecommerce/inventory/test/release_test.rb delete mode 100644 ecommerce/inventory/test/reserve_test.rb delete mode 100644 ecommerce/inventory/test/supply_test.rb delete mode 100644 ecommerce/inventory/test/test_helper.rb delete mode 100644 ecommerce/invoicing/.mutant.yml delete mode 100644 ecommerce/invoicing/Gemfile delete mode 100644 ecommerce/invoicing/Gemfile.lock delete mode 100644 ecommerce/invoicing/Makefile delete mode 100644 ecommerce/invoicing/README.md delete mode 100644 ecommerce/invoicing/lib/invoicing.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/commands.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/events.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/fake_concurrent_invoice_number_generator.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/invoice.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/invoice_item_title_catalog.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/invoice_number_generator.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/product.rb delete mode 100644 ecommerce/invoicing/lib/invoicing/services.rb delete mode 100644 ecommerce/invoicing/test/fake_concurrent_invoice_number_generator_test.rb delete mode 100644 ecommerce/invoicing/test/invoice_item_test.rb delete mode 100644 ecommerce/invoicing/test/invoice_number_generator_test.rb delete mode 100644 ecommerce/invoicing/test/invoice_service_test.rb delete mode 100644 ecommerce/invoicing/test/setting_product_displayed_name_test.rb delete mode 100644 ecommerce/invoicing/test/test_helper.rb delete mode 100644 ecommerce/ordering/.mutant.yml delete mode 100644 ecommerce/ordering/Gemfile delete mode 100644 ecommerce/ordering/Gemfile.lock delete mode 100644 ecommerce/ordering/Makefile delete mode 100644 ecommerce/ordering/README.md delete mode 100644 ecommerce/ordering/lib/ordering.rb delete mode 100644 ecommerce/ordering/lib/ordering/commands/accept_order.rb delete mode 100644 ecommerce/ordering/lib/ordering/commands/add_item_to_basket.rb delete mode 100644 ecommerce/ordering/lib/ordering/commands/reject_order.rb delete mode 100644 ecommerce/ordering/lib/ordering/commands/remove_item_from_basket.rb delete mode 100644 ecommerce/ordering/lib/ordering/commands/set_order_as_expired.rb delete mode 100644 ecommerce/ordering/lib/ordering/commands/submit_order.rb delete mode 100644 ecommerce/ordering/lib/ordering/events/item_added_to_basket.rb delete mode 100644 ecommerce/ordering/lib/ordering/events/item_removed_from_basket.rb delete mode 100644 ecommerce/ordering/lib/ordering/events/order_expired.rb delete mode 100644 ecommerce/ordering/lib/ordering/events/order_placed.rb delete mode 100644 ecommerce/ordering/lib/ordering/events/order_rejected.rb delete mode 100644 ecommerce/ordering/lib/ordering/events/order_submitted.rb delete mode 100644 ecommerce/ordering/lib/ordering/fake_number_generator.rb delete mode 100644 ecommerce/ordering/lib/ordering/number_generator.rb delete mode 100644 ecommerce/ordering/lib/ordering/order.rb delete mode 100644 ecommerce/ordering/lib/ordering/service.rb delete mode 100644 ecommerce/ordering/test/accept_order_test.rb delete mode 100644 ecommerce/ordering/test/add_item_to_basket_test.rb delete mode 100644 ecommerce/ordering/test/number_generator_test.rb delete mode 100644 ecommerce/ordering/test/order_test.rb delete mode 100644 ecommerce/ordering/test/reject_order_test.rb delete mode 100644 ecommerce/ordering/test/remove_item_from_basket_test.rb delete mode 100644 ecommerce/ordering/test/set_order_as_expired_test.rb delete mode 100644 ecommerce/ordering/test/submit_order_test.rb delete mode 100644 ecommerce/ordering/test/test_helper.rb delete mode 100644 ecommerce/payments/.mutant.yml delete mode 100644 ecommerce/payments/Gemfile delete mode 100644 ecommerce/payments/Gemfile.lock delete mode 100644 ecommerce/payments/Makefile delete mode 100644 ecommerce/payments/README.md delete mode 100644 ecommerce/payments/lib/payments.rb delete mode 100644 ecommerce/payments/lib/payments/commands.rb delete mode 100644 ecommerce/payments/lib/payments/events.rb delete mode 100644 ecommerce/payments/lib/payments/fake_gateway.rb delete mode 100644 ecommerce/payments/lib/payments/on_authorize_payment.rb delete mode 100644 ecommerce/payments/lib/payments/on_capture_payment.rb delete mode 100644 ecommerce/payments/lib/payments/on_release_payment.rb delete mode 100644 ecommerce/payments/lib/payments/on_set_payment_amount.rb delete mode 100644 ecommerce/payments/lib/payments/payment.rb delete mode 100644 ecommerce/payments/test/fake_gateway_test.rb delete mode 100644 ecommerce/payments/test/on_capture_payment_test.rb delete mode 100644 ecommerce/payments/test/on_release_payment_test.rb delete mode 100644 ecommerce/payments/test/payment_test.rb delete mode 100644 ecommerce/payments/test/test_helper.rb delete mode 100644 ecommerce/pricing/.mutant.yml delete mode 100644 ecommerce/pricing/Gemfile delete mode 100644 ecommerce/pricing/Gemfile.lock delete mode 100644 ecommerce/pricing/Makefile delete mode 100644 ecommerce/pricing/README.md delete mode 100644 ecommerce/pricing/lib/pricing.rb delete mode 100644 ecommerce/pricing/lib/pricing/calculate_order_sub_amounts_value.rb delete mode 100644 ecommerce/pricing/lib/pricing/calculate_order_total_value.rb delete mode 100644 ecommerce/pricing/lib/pricing/commands.rb delete mode 100644 ecommerce/pricing/lib/pricing/coupon.rb delete mode 100644 ecommerce/pricing/lib/pricing/discounts.rb delete mode 100644 ecommerce/pricing/lib/pricing/events.rb delete mode 100644 ecommerce/pricing/lib/pricing/offer.rb delete mode 100644 ecommerce/pricing/lib/pricing/price_change.rb delete mode 100644 ecommerce/pricing/lib/pricing/pricing_catalog.rb delete mode 100644 ecommerce/pricing/lib/pricing/promotions_calendar.rb delete mode 100644 ecommerce/pricing/lib/pricing/services.rb delete mode 100644 ecommerce/pricing/lib/pricing/time_promotion.rb delete mode 100644 ecommerce/pricing/test/coupons_test.rb delete mode 100644 ecommerce/pricing/test/discounts_test.rb delete mode 100644 ecommerce/pricing/test/free_products_test.rb delete mode 100644 ecommerce/pricing/test/future_prices_test.rb delete mode 100644 ecommerce/pricing/test/order_product_test.rb delete mode 100644 ecommerce/pricing/test/pricing_test.rb delete mode 100644 ecommerce/pricing/test/product_test.rb delete mode 100644 ecommerce/pricing/test/simple_offer_test.rb delete mode 100644 ecommerce/pricing/test/subamounts_test.rb delete mode 100644 ecommerce/pricing/test/test_helper.rb delete mode 100644 ecommerce/pricing/test/time_promotion_test.rb delete mode 100644 ecommerce/processes/.mutant.yml delete mode 100644 ecommerce/processes/Gemfile delete mode 100644 ecommerce/processes/Gemfile.lock delete mode 100644 ecommerce/processes/Makefile delete mode 100644 ecommerce/processes/lib/processes.rb delete mode 100644 ecommerce/processes/lib/processes/confirm_order_on_payment_captured.rb delete mode 100644 ecommerce/processes/lib/processes/determine_vat_rates_on_order_placed.rb delete mode 100644 ecommerce/processes/lib/processes/notify_payments_about_order_value.rb delete mode 100644 ecommerce/processes/lib/processes/order_item_invoicing_process.rb delete mode 100644 ecommerce/processes/lib/processes/registration_process.rb delete mode 100644 ecommerce/processes/lib/processes/release_payment_process.rb delete mode 100644 ecommerce/processes/lib/processes/reservation_process.rb delete mode 100644 ecommerce/processes/lib/processes/shipment_process.rb delete mode 100644 ecommerce/processes/lib/processes/sync_shipment_from_ordering.rb delete mode 100644 ecommerce/processes/lib/processes/three_plus_one_free.rb delete mode 100644 ecommerce/processes/test/determine_vat_rate_test.rb delete mode 100644 ecommerce/processes/test/money_splitter_test.rb delete mode 100644 ecommerce/processes/test/order_confirmation_test.rb delete mode 100644 ecommerce/processes/test/order_item_invoicing_process_test.rb delete mode 100644 ecommerce/processes/test/release_payment_process_test.rb delete mode 100644 ecommerce/processes/test/reservation_process_test.rb delete mode 100644 ecommerce/processes/test/test_helper.rb delete mode 100644 ecommerce/processes/test/three_plus_one_free_test.rb delete mode 100644 ecommerce/product_catalog/.mutant.yml delete mode 100644 ecommerce/product_catalog/Gemfile delete mode 100644 ecommerce/product_catalog/Gemfile.lock delete mode 100644 ecommerce/product_catalog/Makefile delete mode 100644 ecommerce/product_catalog/README.md delete mode 100644 ecommerce/product_catalog/lib/product_catalog.rb delete mode 100644 ecommerce/product_catalog/lib/product_catalog/commands.rb delete mode 100644 ecommerce/product_catalog/lib/product_catalog/events.rb delete mode 100644 ecommerce/product_catalog/lib/product_catalog/naming.rb delete mode 100644 ecommerce/product_catalog/lib/product_catalog/registration.rb delete mode 100644 ecommerce/product_catalog/test/naming_test.rb delete mode 100644 ecommerce/product_catalog/test/registration_test.rb delete mode 100644 ecommerce/product_catalog/test/test_helper.rb delete mode 100644 ecommerce/shipping/.mutant.yml delete mode 100644 ecommerce/shipping/Gemfile delete mode 100644 ecommerce/shipping/Gemfile.lock delete mode 100644 ecommerce/shipping/Makefile delete mode 100644 ecommerce/shipping/README.md delete mode 100644 ecommerce/shipping/lib/shipping.rb delete mode 100644 ecommerce/shipping/lib/shipping/commands/add_item_to_shipment_picking_list.rb delete mode 100644 ecommerce/shipping/lib/shipping/commands/add_shipping_address_to_shipment.rb delete mode 100644 ecommerce/shipping/lib/shipping/commands/authorize_shipment.rb delete mode 100644 ecommerce/shipping/lib/shipping/commands/remove_item_from_shipment_picking_list.rb delete mode 100644 ecommerce/shipping/lib/shipping/commands/submit_shipment.rb delete mode 100644 ecommerce/shipping/lib/shipping/events/item_added_to_shipment_picking_list.rb delete mode 100644 ecommerce/shipping/lib/shipping/events/item_removed_from_shipment_picking_list.rb delete mode 100644 ecommerce/shipping/lib/shipping/events/shipment_authorized.rb delete mode 100644 ecommerce/shipping/lib/shipping/events/shipment_submitted.rb delete mode 100644 ecommerce/shipping/lib/shipping/events/shipping_address_added_to_shipment.rb delete mode 100644 ecommerce/shipping/lib/shipping/picking_list.rb delete mode 100644 ecommerce/shipping/lib/shipping/picking_list_item.rb delete mode 100644 ecommerce/shipping/lib/shipping/services/on_add_item_to_shipment_picking_list.rb delete mode 100644 ecommerce/shipping/lib/shipping/services/on_add_shipping_address_to_shipment.rb delete mode 100644 ecommerce/shipping/lib/shipping/services/on_authorize_shipment.rb delete mode 100644 ecommerce/shipping/lib/shipping/services/on_remove_item_from_shipment_picking_list.rb delete mode 100644 ecommerce/shipping/lib/shipping/services/on_submit_shipment.rb delete mode 100644 ecommerce/shipping/lib/shipping/shipment.rb delete mode 100644 ecommerce/shipping/test/on_add_item_to_shipment_picking_list_test.rb delete mode 100644 ecommerce/shipping/test/on_add_shipping_address_to_shipment_test.rb delete mode 100644 ecommerce/shipping/test/on_authorize_shipment_test.rb delete mode 100644 ecommerce/shipping/test/on_remove_item_from_shipment_picking_list_test.rb delete mode 100644 ecommerce/shipping/test/on_submit_shipment_test.rb delete mode 100644 ecommerce/shipping/test/picking_list_item_test.rb delete mode 100644 ecommerce/shipping/test/picking_list_test.rb delete mode 100644 ecommerce/shipping/test/shipment_test.rb delete mode 100644 ecommerce/shipping/test/test_helper.rb delete mode 100644 ecommerce/taxes/.mutant.yml delete mode 100644 ecommerce/taxes/Gemfile delete mode 100644 ecommerce/taxes/Gemfile.lock delete mode 100644 ecommerce/taxes/Makefile delete mode 100644 ecommerce/taxes/README.md delete mode 100644 ecommerce/taxes/lib/taxes.rb delete mode 100644 ecommerce/taxes/lib/taxes/commands.rb delete mode 100644 ecommerce/taxes/lib/taxes/events.rb delete mode 100644 ecommerce/taxes/lib/taxes/product.rb delete mode 100644 ecommerce/taxes/lib/taxes/services.rb delete mode 100644 ecommerce/taxes/lib/taxes/vat_rate_catalog.rb delete mode 100644 ecommerce/taxes/test/taxes_test.rb delete mode 100644 ecommerce/taxes/test/test_helper.rb delete mode 100644 hanami_application/README.md delete mode 100644 infra/lib/infra/types.rb delete mode 100644 pricing_catalog_rails_app/.dockerignore delete mode 100644 pricing_catalog_rails_app/.gitignore delete mode 100644 pricing_catalog_rails_app/Dockerfile delete mode 100644 pricing_catalog_rails_app/Gemfile delete mode 100644 pricing_catalog_rails_app/Gemfile.lock delete mode 100644 pricing_catalog_rails_app/README.md delete mode 100644 pricing_catalog_rails_app/Rakefile delete mode 100644 pricing_catalog_rails_app/app/admin/read_models/admin_catalog/admin_catalog.rb delete mode 100644 pricing_catalog_rails_app/app/admin/read_models/admin_catalog/index.html.erb delete mode 100644 pricing_catalog_rails_app/app/admin/register_product.rb delete mode 100644 pricing_catalog_rails_app/app/assets/config/manifest.js delete mode 100644 pricing_catalog_rails_app/app/assets/images/.keep delete mode 100644 pricing_catalog_rails_app/app/assets/stylesheets/application.css delete mode 100644 pricing_catalog_rails_app/app/channels/application_cable/channel.rb delete mode 100644 pricing_catalog_rails_app/app/channels/application_cable/connection.rb delete mode 100644 pricing_catalog_rails_app/app/controllers/admin/catalog_controller.rb delete mode 100644 pricing_catalog_rails_app/app/controllers/application_controller.rb delete mode 100644 pricing_catalog_rails_app/app/controllers/catalog_controller.rb delete mode 100644 pricing_catalog_rails_app/app/controllers/concerns/.keep delete mode 100644 pricing_catalog_rails_app/app/helpers/application_helper.rb delete mode 100644 pricing_catalog_rails_app/app/javascript/application.js delete mode 100644 pricing_catalog_rails_app/app/javascript/controllers/application.js delete mode 100644 pricing_catalog_rails_app/app/javascript/controllers/hello_controller.js delete mode 100644 pricing_catalog_rails_app/app/javascript/controllers/index.js delete mode 100644 pricing_catalog_rails_app/app/jobs/application_job.rb delete mode 100644 pricing_catalog_rails_app/app/models/application_record.rb delete mode 100644 pricing_catalog_rails_app/app/models/concerns/.keep delete mode 100644 pricing_catalog_rails_app/app/public/read_models/public_catalog/index.html.erb delete mode 100644 pricing_catalog_rails_app/app/public/read_models/public_catalog/public_catalog.rb delete mode 100644 pricing_catalog_rails_app/app/views/layouts/application.html.erb delete mode 100755 pricing_catalog_rails_app/bin/bundle delete mode 100755 pricing_catalog_rails_app/bin/docker-entrypoint delete mode 100755 pricing_catalog_rails_app/bin/importmap delete mode 100755 pricing_catalog_rails_app/bin/rails delete mode 100755 pricing_catalog_rails_app/bin/rake delete mode 100755 pricing_catalog_rails_app/bin/setup delete mode 100644 pricing_catalog_rails_app/config.ru delete mode 100644 pricing_catalog_rails_app/config/application.rb delete mode 100644 pricing_catalog_rails_app/config/boot.rb delete mode 100644 pricing_catalog_rails_app/config/cable.yml delete mode 100644 pricing_catalog_rails_app/config/credentials.yml.enc delete mode 100644 pricing_catalog_rails_app/config/database.yml delete mode 100644 pricing_catalog_rails_app/config/environment.rb delete mode 100644 pricing_catalog_rails_app/config/environments/development.rb delete mode 100644 pricing_catalog_rails_app/config/environments/production.rb delete mode 100644 pricing_catalog_rails_app/config/environments/test.rb delete mode 100644 pricing_catalog_rails_app/config/importmap.rb delete mode 100644 pricing_catalog_rails_app/config/initializers/content_security_policy.rb delete mode 100644 pricing_catalog_rails_app/config/initializers/filter_parameter_logging.rb delete mode 100644 pricing_catalog_rails_app/config/initializers/inflections.rb delete mode 100644 pricing_catalog_rails_app/config/initializers/permissions_policy.rb delete mode 100644 pricing_catalog_rails_app/config/initializers/rails_event_store.rb delete mode 100644 pricing_catalog_rails_app/config/locales/en.yml delete mode 100644 pricing_catalog_rails_app/config/master.key delete mode 100644 pricing_catalog_rails_app/config/puma.rb delete mode 100644 pricing_catalog_rails_app/config/routes.rb delete mode 100644 pricing_catalog_rails_app/db/migrate/20240130110320_create_event_store_events.rb delete mode 100644 pricing_catalog_rails_app/db/migrate/20240201132941_enable_pg_crypto.rb delete mode 100644 pricing_catalog_rails_app/db/migrate/20240201133038_create_products_table.rb delete mode 100644 pricing_catalog_rails_app/db/migrate/20240201154705_create_admin_products.rb delete mode 100644 pricing_catalog_rails_app/db/schema.rb delete mode 100644 pricing_catalog_rails_app/db/seeds.rb delete mode 100644 pricing_catalog_rails_app/lib/assets/.keep delete mode 100644 pricing_catalog_rails_app/lib/tasks/.keep delete mode 100644 pricing_catalog_rails_app/log/.keep delete mode 100644 pricing_catalog_rails_app/public/404.html delete mode 100644 pricing_catalog_rails_app/public/422.html delete mode 100644 pricing_catalog_rails_app/public/500.html delete mode 100644 pricing_catalog_rails_app/public/apple-touch-icon-precomposed.png delete mode 100644 pricing_catalog_rails_app/public/apple-touch-icon.png delete mode 100644 pricing_catalog_rails_app/public/favicon.ico delete mode 100644 pricing_catalog_rails_app/public/robots.txt delete mode 100644 pricing_catalog_rails_app/storage/.keep delete mode 100644 pricing_catalog_rails_app/test/application_system_test_case.rb delete mode 100644 pricing_catalog_rails_app/test/channels/application_cable/connection_test.rb delete mode 100644 pricing_catalog_rails_app/test/controllers/.keep delete mode 100644 pricing_catalog_rails_app/test/fixtures/files/.keep delete mode 100644 pricing_catalog_rails_app/test/helpers/.keep delete mode 100644 pricing_catalog_rails_app/test/integration/.keep delete mode 100644 pricing_catalog_rails_app/test/models/.keep delete mode 100644 pricing_catalog_rails_app/test/system/.keep delete mode 100644 pricing_catalog_rails_app/test/test_helper.rb delete mode 100644 pricing_catalog_rails_app/tmp/.keep delete mode 100644 pricing_catalog_rails_app/tmp/local_secret.txt delete mode 100644 pricing_catalog_rails_app/tmp/pids/.keep delete mode 100644 pricing_catalog_rails_app/tmp/storage/.keep delete mode 100644 pricing_catalog_rails_app/vendor/.keep delete mode 100644 pricing_catalog_rails_app/vendor/javascript/.keep delete mode 100644 rails_application/app/controllers/events_catalog_controller.rb delete mode 100644 rails_application/app/controllers/product/future_price_controller.rb create mode 100644 rails_application/app/models/customer.rb create mode 100644 rails_application/app/models/invoice.rb create mode 100644 rails_application/app/models/order.rb create mode 100644 rails_application/app/models/order_item.rb create mode 100644 rails_application/app/models/product.rb create mode 100644 rails_application/app/models/time_promotion.rb delete mode 100644 rails_application/app/read_models/availability/configuration.rb delete mode 100644 rails_application/app/read_models/client_authentication/configuration.rb delete mode 100644 rails_application/app/read_models/client_authentication/create_account.rb delete mode 100644 rails_application/app/read_models/client_authentication/set_password.rb delete mode 100644 rails_application/app/read_models/client_orders/add_item_to_order.rb delete mode 100644 rails_application/app/read_models/client_orders/assign_customer_to_order.rb delete mode 100644 rails_application/app/read_models/client_orders/cancel_order.rb delete mode 100644 rails_application/app/read_models/client_orders/change_product_name.rb delete mode 100644 rails_application/app/read_models/client_orders/change_product_price.rb delete mode 100644 rails_application/app/read_models/client_orders/configuration.rb delete mode 100644 rails_application/app/read_models/client_orders/confirm_order.rb delete mode 100644 rails_application/app/read_models/client_orders/create_customer.rb delete mode 100644 rails_application/app/read_models/client_orders/expire_order.rb delete mode 100644 rails_application/app/read_models/client_orders/orders_list.rb delete mode 100644 rails_application/app/read_models/client_orders/product.rb delete mode 100644 rails_application/app/read_models/client_orders/register_product.rb delete mode 100644 rails_application/app/read_models/client_orders/remove_item_from_order.rb delete mode 100644 rails_application/app/read_models/client_orders/reset_discount.rb delete mode 100644 rails_application/app/read_models/client_orders/show_order.rb delete mode 100644 rails_application/app/read_models/client_orders/submit_order.rb delete mode 100644 rails_application/app/read_models/client_orders/update_discount.rb delete mode 100644 rails_application/app/read_models/client_orders/update_order_total_value.rb delete mode 100644 rails_application/app/read_models/client_orders/update_paid_orders_summary.rb delete mode 100644 rails_application/app/read_models/coupons/configuration.rb delete mode 100644 rails_application/app/read_models/coupons/register_coupon.rb delete mode 100644 rails_application/app/read_models/customers/configuration.rb delete mode 100644 rails_application/app/read_models/customers/connect_account.rb delete mode 100644 rails_application/app/read_models/customers/promote_to_vip.rb delete mode 100644 rails_application/app/read_models/customers/register_customer.rb delete mode 100644 rails_application/app/read_models/customers/update_paid_orders_summary.rb delete mode 100644 rails_application/app/read_models/invoices/configuration.rb delete mode 100644 rails_application/app/read_models/invoices/create_invoice_item.rb delete mode 100644 rails_application/app/read_models/invoices/mark_as_issued.rb delete mode 100644 rails_application/app/read_models/invoices/mark_order_placed.rb delete mode 100644 rails_application/app/read_models/invoices/set_billing_address.rb delete mode 100644 rails_application/app/read_models/invoices/set_payment_date.rb delete mode 100644 rails_application/app/read_models/products/configuration.rb delete mode 100644 rails_application/app/read_models/products/refresh_future_prices_calendar.rb delete mode 100644 rails_application/app/read_models/public_offer/configuration.rb delete mode 100644 rails_application/app/read_models/public_offer/product.rb delete mode 100644 rails_application/app/read_models/public_offer/register_lowest_price.rb delete mode 100644 rails_application/app/read_models/shipments/configuration.rb delete mode 100644 rails_application/app/read_models/shipments/mark_order_placed.rb delete mode 100644 rails_application/app/read_models/shipments/set_shipping_address.rb delete mode 100644 rails_application/app/read_models/single_table_read_model.rb delete mode 100644 rails_application/app/read_models/time_promotions/broadcaster.rb delete mode 100644 rails_application/app/read_models/time_promotions/configuration.rb delete mode 100644 rails_application/app/read_models/time_promotions/create_time_promotion.rb delete mode 100644 rails_application/db/migrate/20150429224621_create_order_lines.rb delete mode 100644 rails_application/db/migrate/20150429224628_create_customers.rb delete mode 100644 rails_application/db/migrate/20150429224746_create_products.rb delete mode 100644 rails_application/db/migrate/20181102132612_create_event_store_events.rb delete mode 100644 rails_application/db/migrate/20181123154324_index_by_event_type.rb delete mode 100644 rails_application/db/migrate/20181123155503_limit_for_event_id.rb delete mode 100644 rails_application/db/migrate/20181207145051_binary_data_and_metadata.rb delete mode 100644 rails_application/db/migrate/20210102110315_harmonize_schema.rb delete mode 100644 rails_application/db/migrate/20210102182818_binary_to_jsonb.rb delete mode 100644 rails_application/db/migrate/20210103114304_created_at_precision.rb delete mode 100644 rails_application/db/migrate/20210103114309_add_valid_at.rb delete mode 100644 rails_application/db/migrate/20210103114314_no_global_stream_entries.rb delete mode 100644 rails_application/db/migrate/20210103114315_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb delete mode 100644 rails_application/db/migrate/20210306222803_create_active_admin_comments.rb delete mode 100644 rails_application/db/migrate/20210318093812_disable_pg_crypto.rb delete mode 100644 rails_application/db/migrate/20210505162028_add_price_to_products.rb delete mode 100644 rails_application/db/migrate/20210505163254_add_price_to_order_lines.rb delete mode 100644 rails_application/db/migrate/20210617230722_add_uid_to_product.rb delete mode 100644 rails_application/db/migrate/20210626171021_add_uid_to_customer.rb delete mode 100644 rails_application/db/migrate/20210626210851_migrate_from_id_to_uuid.rb delete mode 100644 rails_application/db/migrate/20210719172643_add_discount_and_total_value_and_discount_value_to_orders.rb delete mode 100644 rails_application/db/migrate/20210830164940_drop_active_admin_comments.rb delete mode 100644 rails_application/db/migrate/20210907115224_string_to_native_uuids.rb delete mode 100644 rails_application/db/migrate/20210916191138_customers_add_registered_at.rb delete mode 100644 rails_application/db/migrate/20210918000940_products_add_registered_at.rb delete mode 100644 rails_application/db/migrate/20210918003625_products_drop_timestamps.rb delete mode 100644 rails_application/db/migrate/20211003170051_create_shipments.rb delete mode 100644 rails_application/db/migrate/20211116135113_create_products_in_orders_read_model.rb delete mode 100644 rails_application/db/migrate/20211116154857_create_customers_in_orders_read_model.rb delete mode 100644 rails_application/db/migrate/20211124220955_add_vat_rate_code_to_product.rb delete mode 100644 rails_application/db/migrate/20220109162627_create_invoice_read_model.rb delete mode 100644 rails_application/db/migrate/20220109175702_create_orders_in_invoices_read_model.rb delete mode 100644 rails_application/db/migrate/20220109175753_create_orders_in_shipments_read_model.rb delete mode 100644 rails_application/db/migrate/20220121131334_add_vip_to_customer.rb delete mode 100644 rails_application/db/migrate/20220219130650_create_clients.rb delete mode 100644 rails_application/db/migrate/20220219162101_create_client_orders.rb delete mode 100644 rails_application/db/migrate/20220519094635_create_coupons.rb delete mode 100644 rails_application/db/migrate/20220528213429_create_happy_hours.rb delete mode 100644 rails_application/db/migrate/20220607201447_add_happy_hour_value_to_orders.rb delete mode 100644 rails_application/db/migrate/20220703122711_drop_happy_hours.rb delete mode 100644 rails_application/db/migrate/20220703133325_add_active_to_time_promotions.rb delete mode 100644 rails_application/db/migrate/20220703133431_add_unique_constraint_on_code_on_time_promotions.rb delete mode 100644 rails_application/db/migrate/20220723133454_remove_code_column_from_time_promotions.rb delete mode 100644 rails_application/db/migrate/20220829155333_create_public_offer_products.rb delete mode 100644 rails_application/db/migrate/20221104111403_create_client_order_lines_read_model.rb delete mode 100644 rails_application/db/migrate/20221104152434_create_client_order_products_read_model.rb delete mode 100644 rails_application/db/migrate/20221107085656_add_client_column_to_order.rb delete mode 100644 rails_application/db/migrate/20221109141019_fix_client_order_lines_product_id_column_type.rb delete mode 100644 rails_application/db/migrate/20221109150819_add_values_to_client_order.rb delete mode 100644 rails_application/db/migrate/20221124200914_add_prices_chart_to_product.rb delete mode 100644 rails_application/db/migrate/20221208185429_rename_future_prices_column.rb delete mode 100644 rails_application/db/migrate/20221214202855_add_uniq_uid_index_to_orders_order.rb delete mode 100644 rails_application/db/migrate/20221215214459_rename_future_prices_calendar_future_prices_calendar.rb delete mode 100644 rails_application/db/migrate/20221216113438_add_order_total_value_updated_at_to_orders_table.rb delete mode 100644 rails_application/db/migrate/20221216115301_add_discount_updated_at_to_orders_table.rb delete mode 100644 rails_application/db/migrate/20230110235838_add_lowest_recent_price_to_client_order_products.rb delete mode 100644 rails_application/db/migrate/20230118170447_create_availability_products.rb delete mode 100644 rails_application/db/migrate/20230123202350_add_paid_products_summary_to_clients.rb delete mode 100644 rails_application/db/migrate/20230124134558_add_paid_products_summary_to_customers.rb delete mode 100644 rails_application/db/migrate/20230124195547_remove_price_column_from_products.rb delete mode 100644 rails_application/db/migrate/20230126174907_add_accounting_column_to_customer.rb delete mode 100644 rails_application/db/migrate/20230127125135_create_table_accounts.rb delete mode 100644 rails_application/db/migrate/20230128110104_move_lowest_recent_price_to_public_offer.rb delete mode 100644 rails_application/db/migrate/20230130172454_rename_accounts_table.rb delete mode 100644 rails_application/db/migrate/20230130172623_add_account_id_to_accounts.rb delete mode 100644 rails_application/db/migrate/20230202175228_remove_lowest_recent_price_from_client_order_product.rb delete mode 100644 rails_application/db/migrate/20230906105023_add_event_id_index_to_event_store_events_in_streams.rb delete mode 100644 rails_application/db/migrate/20230906105317_add_foreign_key_on_event_id_to_event_store_events_in_streams.rb delete mode 100644 rails_application/db/migrate/20230906105318_validate_add_foreign_key_on_event_id_to_event_store_events_in_streams.rb delete mode 100644 rails_application/db/migrate/20240806161206_drop_order.rb create mode 100644 rails_application/db/migrate/20240806161443_create_orders.rb create mode 100644 rails_application/db/migrate/20240806165434_create_old_fashioned_product_table.rb create mode 100644 rails_application/db/migrate/20240806165554_create_order_items.rb create mode 100644 rails_application/db/migrate/20240807162106_create_users.rb rename rails_application/db/migrate/{20210824130811_add_stock_level_to_product.rb => 20240808101541_add_stock_level_to_product_crud.rb} (52%) create mode 100644 rails_application/db/migrate/20240814135823_create_invoices.rb create mode 100644 rails_application/db/migrate/20240821120809_correlate_order_with_user.rb create mode 100644 rails_application/db/migrate/20240821121943_rename_user_to_customer.rb create mode 100644 rails_application/db/migrate/20240821122557_enerich_customer.rb create mode 100644 rails_application/db/migrate/20240821123100_rename_user_id_to_customer_id_in_orders_table.rb create mode 100644 rails_application/db/migrate/20240821123342_drop_customer_col_from_orders.rb create mode 100644 rails_application/db/migrate/20240821125153_allow_null_for_orders_customers_fk.rb create mode 100644 rails_application/db/migrate/20240822081509_order_must_have_shipping_addresses_and_all_that_jazz.rb create mode 100644 rails_application/db/migrate/20240822082432_order_must_have_invoice_details.rb create mode 100644 rails_application/db/migrate/20240822100417_add_invoice_paid_to_order.rb create mode 100644 rails_application/db/migrate/20240822110341_add_future_price_to_product.rb rename rails_application/db/migrate/{20220703123059_create_time_promotions.rb => 20240822170829_create_time_promotions.rb} (57%) diff --git a/ecommerce/authentication/.mutant.yml b/ecommerce/authentication/.mutant.yml deleted file mode 100644 index 8c5b2b23f..000000000 --- a/ecommerce/authentication/.mutant.yml +++ /dev/null @@ -1,10 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Authentication* - ignore: - - Authentication::Configuration#call diff --git a/ecommerce/authentication/Gemfile b/ecommerce/authentication/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/authentication/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/authentication/Gemfile.lock b/ecommerce/authentication/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/authentication/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/authentication/Makefile b/ecommerce/authentication/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/authentication/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/authentication/README.md b/ecommerce/authentication/README.md deleted file mode 100644 index c8a17ba12..000000000 --- a/ecommerce/authentication/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Authentication - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/authentication/lib/authentication.rb b/ecommerce/authentication/lib/authentication.rb deleted file mode 100644 index fe28d3c1d..000000000 --- a/ecommerce/authentication/lib/authentication.rb +++ /dev/null @@ -1,25 +0,0 @@ -require "infra" -require_relative "authentication/commands/connect_account_to_client" -require_relative "authentication/commands/set_login" -require_relative "authentication/commands/set_password_hash" -require_relative "authentication/commands/register_account" -require_relative "authentication/events/account_connected_to_client" -require_relative "authentication/events/account_registered" -require_relative "authentication/events/login_set" -require_relative "authentication/events/password_hash_set" -require_relative "authentication/account_service" -require_relative "authentication/account" - -module Authentication - class Configuration - def call(event_store, command_bus) - command_bus.register(RegisterAccount, RegisterAccountHandler.new(event_store)) - command_bus.register(SetLogin, SetLoginHandler.new(event_store)) - command_bus.register(SetPasswordHash, SetPasswordHashHandler.new(event_store)) - command_bus.register( - ConnectAccountToClient, - ConnectAccountToClientHandler.new(event_store) - ) - end - end -end diff --git a/ecommerce/authentication/lib/authentication/account.rb b/ecommerce/authentication/lib/authentication/account.rb deleted file mode 100644 index c790f4f82..000000000 --- a/ecommerce/authentication/lib/authentication/account.rb +++ /dev/null @@ -1,47 +0,0 @@ -module Authentication - class Account - include AggregateRoot - - AlreadyRegistered = Class.new(StandardError) - - def initialize(id) - @id = id - end - - def register - raise AlreadyRegistered if @registered - - apply AccountRegistered.new(data: { account_id: @id }) - end - - def set_login(login) - apply LoginSet.new(data: { account_id: @id, login: login }) - end - - def set_password_hash(password_hash) - apply PasswordHashSet.new(data: { account_id: @id, password_hash: password_hash }) - end - - def connect_client(client_id) - apply AccountConnectedToClient.new(data: { account_id: @id, client_id: client_id }) - end - - private - - on AccountRegistered do |event| - @registered = true - end - - on LoginSet do |event| - @login = event.data[:login] - end - - on PasswordHashSet do |event| - @password_hash = event.data[:password_hash] - end - - on AccountConnectedToClient do |event| - @client_id = event.data[:client_id] - end - end -end diff --git a/ecommerce/authentication/lib/authentication/account_service.rb b/ecommerce/authentication/lib/authentication/account_service.rb deleted file mode 100644 index 1cfabdfd1..000000000 --- a/ecommerce/authentication/lib/authentication/account_service.rb +++ /dev/null @@ -1,49 +0,0 @@ -module Authentication - class RegisterAccountHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Account, command.aggregate_id) do |account| - account.register - end - end - end - - class SetLoginHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Account, command.aggregate_id) do |account| - account.set_login(command.login) - end - end - end - - class SetPasswordHashHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Account, command.aggregate_id) do |account| - account.set_password_hash(command.password_hash) - end - end - end - - class ConnectAccountToClientHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Account, command.aggregate_id) do |account| - account.connect_client(command.client_id) - end - end - end -end diff --git a/ecommerce/authentication/lib/authentication/commands/connect_account_to_client.rb b/ecommerce/authentication/lib/authentication/commands/connect_account_to_client.rb deleted file mode 100644 index 3cea61001..000000000 --- a/ecommerce/authentication/lib/authentication/commands/connect_account_to_client.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Authentication - class ConnectAccountToClient < Infra::Command - attribute :account_id, Infra::Types::UUID - attribute :client_id, Infra::Types::UUID - alias aggregate_id account_id - end -end diff --git a/ecommerce/authentication/lib/authentication/commands/register_account.rb b/ecommerce/authentication/lib/authentication/commands/register_account.rb deleted file mode 100644 index c69492ca4..000000000 --- a/ecommerce/authentication/lib/authentication/commands/register_account.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Authentication - class RegisterAccount < Infra::Command - attribute :account_id, Infra::Types::UUID - alias aggregate_id account_id - end -end diff --git a/ecommerce/authentication/lib/authentication/commands/set_login.rb b/ecommerce/authentication/lib/authentication/commands/set_login.rb deleted file mode 100644 index 1df2f94e2..000000000 --- a/ecommerce/authentication/lib/authentication/commands/set_login.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Authentication - class SetLogin < Infra::Command - attribute :account_id, Infra::Types::UUID - attribute :login, Infra::Types::String - alias aggregate_id account_id - end -end diff --git a/ecommerce/authentication/lib/authentication/commands/set_password_hash.rb b/ecommerce/authentication/lib/authentication/commands/set_password_hash.rb deleted file mode 100644 index 15670dbdb..000000000 --- a/ecommerce/authentication/lib/authentication/commands/set_password_hash.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Authentication - class SetPasswordHash < Infra::Command - attribute :account_id, Infra::Types::UUID - attribute :password_hash, Infra::Types::String - alias aggregate_id account_id - end -end diff --git a/ecommerce/authentication/lib/authentication/events/account_connected_to_client.rb b/ecommerce/authentication/lib/authentication/events/account_connected_to_client.rb deleted file mode 100644 index 2efbffa07..000000000 --- a/ecommerce/authentication/lib/authentication/events/account_connected_to_client.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Authentication - class AccountConnectedToClient < Infra::Event - attribute :account_id, Infra::Types::UUID - attribute :client_id, Infra::Types::UUID - end -end diff --git a/ecommerce/authentication/lib/authentication/events/account_registered.rb b/ecommerce/authentication/lib/authentication/events/account_registered.rb deleted file mode 100644 index f9f6f203f..000000000 --- a/ecommerce/authentication/lib/authentication/events/account_registered.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Authentication - class AccountRegistered < Infra::Event - attribute :account_id, Infra::Types::UUID - end -end diff --git a/ecommerce/authentication/lib/authentication/events/login_set.rb b/ecommerce/authentication/lib/authentication/events/login_set.rb deleted file mode 100644 index 8dfc4187f..000000000 --- a/ecommerce/authentication/lib/authentication/events/login_set.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Authentication - class LoginSet < Infra::Event - attribute :account_id, Infra::Types::UUID - attribute :login, Infra::Types::String - end -end diff --git a/ecommerce/authentication/lib/authentication/events/password_hash_set.rb b/ecommerce/authentication/lib/authentication/events/password_hash_set.rb deleted file mode 100644 index 366133de1..000000000 --- a/ecommerce/authentication/lib/authentication/events/password_hash_set.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Authentication - class PasswordHashSet < Infra::Event - attribute :account_id, Infra::Types::UUID - attribute :password_hash, Infra::Types::String - end -end diff --git a/ecommerce/authentication/test/connect_account_to_client_test.rb b/ecommerce/authentication/test/connect_account_to_client_test.rb deleted file mode 100644 index 0cbd7aeec..000000000 --- a/ecommerce/authentication/test/connect_account_to_client_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require_relative "test_helper" - -module Authentication - class ConnectAccountToClientTest < Test - cover "Authentication*" - - def test_client_id_should_get_set - account_id = SecureRandom.uuid - client_id = SecureRandom.uuid - - act(RegisterAccount.new(account_id: account_id)) - - account_connected_to_client = AccountConnectedToClient.new(data: { account_id: account_id, client_id: client_id }) - - assert_events("Authentication::Account$#{account_id}", account_connected_to_client) do - run_command(ConnectAccountToClient.new(account_id: account_id, client_id: client_id)) - end - end - end -end diff --git a/ecommerce/authentication/test/register_account_test.rb b/ecommerce/authentication/test/register_account_test.rb deleted file mode 100644 index 612985fee..000000000 --- a/ecommerce/authentication/test/register_account_test.rb +++ /dev/null @@ -1,32 +0,0 @@ -require_relative "test_helper" - -module Authentication - class RegisterAccountTest < Test - cover "Authentication*" - - def setup - @uid = SecureRandom.uuid - @data = { account_id: @uid } - end - - def test_account_should_get_registered - account_registered = AccountRegistered.new(data: @data) - assert_events("Authentication::Account$#{@uid}", account_registered) do - register_account(@uid) - end - end - - def test_should_not_allow_for_double_registration - assert_raises(Account::AlreadyRegistered) do - register_account(@uid) - register_account(@uid) - end - end - - private - - def register_account(account_id) - run_command(RegisterAccount.new(account_id: account_id)) - end - end -end diff --git a/ecommerce/authentication/test/set_login_test.rb b/ecommerce/authentication/test/set_login_test.rb deleted file mode 100644 index b47c32d53..000000000 --- a/ecommerce/authentication/test/set_login_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require_relative "test_helper" - -module Authentication - class SetLoginTest < Test - cover "Authentication*" - - def test_login_should_get_set - account_id = SecureRandom.uuid - - act(RegisterAccount.new(account_id: account_id)) - - login_set = LoginSet.new(data: { account_id: account_id, login: fake_login }) - - assert_events("Authentication::Account$#{account_id}", login_set) do - run_command(SetLogin.new(account_id: account_id, login: fake_login)) - end - end - end -end diff --git a/ecommerce/authentication/test/set_password_hash_test.rb b/ecommerce/authentication/test/set_password_hash_test.rb deleted file mode 100644 index 88e8e414e..000000000 --- a/ecommerce/authentication/test/set_password_hash_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require_relative "test_helper" - -module Authentication - class SetPasswordHashTest < Test - cover "Authentication*" - - def test_password_hash_should_get_set - account_id = SecureRandom.uuid - password_hash = SecureRandom.hex(10) - - act(RegisterAccount.new(account_id: account_id)) - - password_hash_set = PasswordHashSet.new(data: { account_id: account_id, password_hash: password_hash }) - - assert_events("Authentication::Account$#{account_id}", password_hash_set) do - run_command(SetPasswordHash.new(account_id: account_id, password_hash: password_hash)) - end - end - end -end diff --git a/ecommerce/authentication/test/test_helper.rb b/ecommerce/authentication/test/test_helper.rb deleted file mode 100644 index bc727dbb5..000000000 --- a/ecommerce/authentication/test/test_helper.rb +++ /dev/null @@ -1,19 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/authentication" - -module Authentication - class Test < Infra::InMemoryTest - def before_setup - super() - Configuration.new.call(event_store, command_bus) - end - - private - - def fake_login - "fake_login" - end - end -end diff --git a/ecommerce/configuration.rb b/ecommerce/configuration.rb deleted file mode 100644 index 2af4d70bf..000000000 --- a/ecommerce/configuration.rb +++ /dev/null @@ -1,50 +0,0 @@ -require_relative "authentication/lib/authentication" -require_relative "ordering/lib/ordering" -require_relative "pricing/lib/pricing" -require_relative "product_catalog/lib/product_catalog" -require_relative "crm/lib/crm" -require_relative "payments/lib/payments" -require_relative "inventory/lib/inventory" -require_relative "shipping/lib/shipping" -require_relative "invoicing/lib/invoicing" -require_relative "taxes/lib/taxes" -require_relative "fulfillment/lib/fulfillment" -require_relative "processes/lib/processes" - -module Ecommerce - class Configuration - def initialize(number_generator: nil, payment_gateway: nil, available_vat_rates: []) - @number_generator = number_generator - @payment_gateway = payment_gateway - @available_vat_rates = available_vat_rates - end - - def call(event_store, command_bus) - configure_bounded_contexts(event_store, command_bus) - configure_processes(event_store, command_bus) - end - - def configure_bounded_contexts(event_store, command_bus) - raise ArgumentError.new( - "Neither number_generator nor payment_gateway can be null" - ) if @number_generator.nil? || @payment_gateway.nil? - [ - Authentication::Configuration.new, - Ordering::Configuration.new(@number_generator), - Crm::Configuration.new, - Inventory::Configuration.new, - Invoicing::Configuration.new, - Payments::Configuration.new(@payment_gateway), - Shipping::Configuration.new, - Pricing::Configuration.new, - Taxes::Configuration.new(@available_vat_rates), - ProductCatalog::Configuration.new, - Fulfillment::Configuration.new - ].each { |c| c.call(event_store, command_bus) } - end - - def configure_processes(event_store, command_bus) - Processes::Configuration.new.call(event_store, command_bus) - end - end -end diff --git a/ecommerce/crm/.mutant.yml b/ecommerce/crm/.mutant.yml deleted file mode 100644 index 952b042b0..000000000 --- a/ecommerce/crm/.mutant.yml +++ /dev/null @@ -1,11 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Crm* - ignore: - - Crm::Configuration#call - diff --git a/ecommerce/crm/Gemfile b/ecommerce/crm/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/crm/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/crm/Gemfile.lock b/ecommerce/crm/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/crm/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/crm/Makefile b/ecommerce/crm/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/crm/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/crm/README.md b/ecommerce/crm/README.md deleted file mode 100644 index 0fe6e4a09..000000000 --- a/ecommerce/crm/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# CRM - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/crm/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/crm.yml) - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/crm/lib/crm.rb b/ecommerce/crm/lib/crm.rb deleted file mode 100644 index 1876d7a00..000000000 --- a/ecommerce/crm/lib/crm.rb +++ /dev/null @@ -1,22 +0,0 @@ -require "infra" -require_relative "crm/commands/promote_customer_to_vip" -require_relative "crm/commands/register_customer" -require_relative "crm/commands/assign_customer_to_order" -require_relative "crm/events/customer_promoted_to_vip" -require_relative "crm/events/customer_registered" -require_relative "crm/events/customer_assigned_to_order.rb" -require_relative "crm/customer_service" -require_relative "crm/customer" -require_relative "crm/order_service" -require_relative "crm/order" - -module Crm - class Configuration - - def call(event_store, command_bus) - command_bus.register(RegisterCustomer, OnRegistration.new(event_store)) - command_bus.register(PromoteCustomerToVip, OnPromoteCustomerToVip.new(event_store)) - command_bus.register(AssignCustomerToOrder, OnSetCustomer.new(event_store)) - end - end -end diff --git a/ecommerce/crm/lib/crm/commands/assign_customer_to_order.rb b/ecommerce/crm/lib/crm/commands/assign_customer_to_order.rb deleted file mode 100644 index 727b9386e..000000000 --- a/ecommerce/crm/lib/crm/commands/assign_customer_to_order.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Crm - class AssignCustomerToOrder < Infra::Command - attribute :customer_id, Infra::Types::UUID - attribute :order_id, Infra::Types::UUID - alias aggregate_id order_id - end -end diff --git a/ecommerce/crm/lib/crm/commands/promote_customer_to_vip.rb b/ecommerce/crm/lib/crm/commands/promote_customer_to_vip.rb deleted file mode 100644 index a2bcae947..000000000 --- a/ecommerce/crm/lib/crm/commands/promote_customer_to_vip.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Crm - class PromoteCustomerToVip < Infra::Command - attribute :customer_id, Infra::Types::UUID - alias aggregate_id customer_id - end -end diff --git a/ecommerce/crm/lib/crm/commands/register_customer.rb b/ecommerce/crm/lib/crm/commands/register_customer.rb deleted file mode 100644 index c5693bd43..000000000 --- a/ecommerce/crm/lib/crm/commands/register_customer.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Crm - class RegisterCustomer < Infra::Command - attribute :customer_id, Infra::Types::UUID - attribute :name, Infra::Types::String - alias aggregate_id customer_id - end -end diff --git a/ecommerce/crm/lib/crm/customer.rb b/ecommerce/crm/lib/crm/customer.rb deleted file mode 100644 index 31c697d6b..000000000 --- a/ecommerce/crm/lib/crm/customer.rb +++ /dev/null @@ -1,40 +0,0 @@ -module Crm - class Customer - include AggregateRoot - - AlreadyVip = Class.new(StandardError) - AlreadyRegistered = Class.new(StandardError) - NotExists = Class.new(StandardError) - - def initialize(id) - @id = id - end - - def register(name) - raise AlreadyRegistered if @registered - apply CustomerRegistered.new( - data: { - customer_id: @id, - name: name - } - ) - end - - def promote_to_vip - raise AlreadyVip if @vip - apply CustomerPromotedToVip.new( - data: { - customer_id: @id - } - ) - end - - on CustomerRegistered do |event| - @registered = true - end - - on CustomerPromotedToVip do |event| - @vip = true - end - end -end diff --git a/ecommerce/crm/lib/crm/customer_service.rb b/ecommerce/crm/lib/crm/customer_service.rb deleted file mode 100644 index a89cbd750..000000000 --- a/ecommerce/crm/lib/crm/customer_service.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Crm - - class OnRegistration - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Customer, command.aggregate_id) do |customer| - customer.register(command.name) - end - end - end - - class OnPromoteCustomerToVip - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Customer, command.aggregate_id) do |customer| - customer.promote_to_vip - end - end - end - -end \ No newline at end of file diff --git a/ecommerce/crm/lib/crm/events/customer_assigned_to_order.rb b/ecommerce/crm/lib/crm/events/customer_assigned_to_order.rb deleted file mode 100644 index dcbc9eda2..000000000 --- a/ecommerce/crm/lib/crm/events/customer_assigned_to_order.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Crm - class CustomerAssignedToOrder < Infra::Event - attribute :customer_id, Infra::Types::UUID - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/crm/lib/crm/events/customer_promoted_to_vip.rb b/ecommerce/crm/lib/crm/events/customer_promoted_to_vip.rb deleted file mode 100644 index b73906d2a..000000000 --- a/ecommerce/crm/lib/crm/events/customer_promoted_to_vip.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Crm - class CustomerPromotedToVip < Infra::Event - attribute :customer_id, Infra::Types::UUID - end -end diff --git a/ecommerce/crm/lib/crm/events/customer_registered.rb b/ecommerce/crm/lib/crm/events/customer_registered.rb deleted file mode 100644 index 8e34598d1..000000000 --- a/ecommerce/crm/lib/crm/events/customer_registered.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Crm - class CustomerRegistered < Infra::Event - attribute :customer_id, Infra::Types::UUID - attribute :name, Infra::Types::String - end -end - - diff --git a/ecommerce/crm/lib/crm/order.rb b/ecommerce/crm/lib/crm/order.rb deleted file mode 100644 index be6bc955d..000000000 --- a/ecommerce/crm/lib/crm/order.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Crm - class Order - include AggregateRoot - CustomerAlreadyAssigned = Class.new(StandardError) - - def initialize(id) - @id = id - end - - def set_customer(customer_id) - raise CustomerAlreadyAssigned if @customer_id - apply CustomerAssignedToOrder.new(data: { order_id: @id, customer_id: customer_id }) - end - - private - - on CustomerAssignedToOrder do |event| - @customer_id = event.data[:customer_id] - end - end -end \ No newline at end of file diff --git a/ecommerce/crm/lib/crm/order_service.rb b/ecommerce/crm/lib/crm/order_service.rb deleted file mode 100644 index edf7d62df..000000000 --- a/ecommerce/crm/lib/crm/order_service.rb +++ /dev/null @@ -1,22 +0,0 @@ -module Crm - class OnSetCustomer - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - @event_store = event_store - end - - def call(command) - raise Customer::NotExists unless customer_exists?(command.customer_id) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.set_customer(command.customer_id) - end - end - - private - - def customer_exists?(customer_id) - customer_stream = @repository.stream_name(Customer, customer_id) - !@event_store.read.stream(customer_stream).count.eql?(0) - end - end -end \ No newline at end of file diff --git a/ecommerce/crm/test/assign_customer_to_order_test.rb b/ecommerce/crm/test/assign_customer_to_order_test.rb deleted file mode 100644 index cbddf33ed..000000000 --- a/ecommerce/crm/test/assign_customer_to_order_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require_relative "test_helper" - -module Crm - class AssignCustomerToOrderTest < Test - cover "Crm*" - - def test_customer_should_get_assigned - customer_id = SecureRandom.uuid - order_id = SecureRandom.uuid - register_customer(customer_id, fake_name) - expected_event = CustomerAssignedToOrder.new(data: {customer_id: customer_id, order_id: order_id}) - assert_events("Crm::Order$#{order_id}", expected_event) do - assign_customer_to_order(order_id, customer_id) - end - end - - def test_customer_should_not_get_assigned_twice - customer_id = SecureRandom.uuid - order_id = SecureRandom.uuid - register_customer(customer_id, fake_name) - assign_customer_to_order(order_id, customer_id) - assert_raises(Order::CustomerAlreadyAssigned) do - assign_customer_to_order(order_id, customer_id) - end - end - - def test_customer_should_not_get_assigned_if_does_not_exist - customer_id = SecureRandom.uuid - another_customer_id = SecureRandom.uuid - order_id = SecureRandom.uuid - register_customer(another_customer_id, fake_name) - assert_raises(Customer::NotExists) do - assign_customer_to_order(order_id, customer_id) - end - end - - private - - def assign_customer_to_order(order_id, customer_id) - run_command(AssignCustomerToOrder.new(order_id: order_id, customer_id: customer_id)) - end - end -end \ No newline at end of file diff --git a/ecommerce/crm/test/promote_client_to_vip_test.rb b/ecommerce/crm/test/promote_client_to_vip_test.rb deleted file mode 100644 index d82209d0b..000000000 --- a/ecommerce/crm/test/promote_client_to_vip_test.rb +++ /dev/null @@ -1,45 +0,0 @@ -require_relative "test_helper" - -module Crm - class PromoteCustomerToVipTest < Test - cover "Crm*" - - def test_should_not_allow_for_marking_vip_as_vip_again - customer_id = SecureRandom.uuid - - arrange( - RegisterCustomer.new( - customer_id: customer_id, - name: fake_name - ) - ) - - assert_raises(Customer::AlreadyVip) do - promote_to_vip(customer_id) - promote_to_vip(customer_id) - end - end - - def test_should_publish_event - customer_id = SecureRandom.uuid - - arrange( - RegisterCustomer.new( - customer_id: customer_id, - name: fake_name - ) - ) - - customer_promoted_to_vip = CustomerPromotedToVip.new(data: {customer_id: customer_id}) - assert_events("Crm::Customer$#{customer_id}", customer_promoted_to_vip) do - promote_to_vip(customer_id) - end - end - - private - - def promote_to_vip(uid) - run_command(PromoteCustomerToVip.new(customer_id: uid)) - end - end -end diff --git a/ecommerce/crm/test/registration_test.rb b/ecommerce/crm/test/registration_test.rb deleted file mode 100644 index db312ab1d..000000000 --- a/ecommerce/crm/test/registration_test.rb +++ /dev/null @@ -1,28 +0,0 @@ -require_relative "test_helper" - -module Crm - class RegistrationTest < Test - cover "Crm*" - - def test_customer_should_get_registered - uid = SecureRandom.uuid - register_customer(uid, fake_name) - end - - def test_should_not_allow_for_double_registration - uid = SecureRandom.uuid - assert_raises(Customer::AlreadyRegistered) do - register_customer(uid, fake_name) - register_customer(uid, fake_name) - end - end - - def test_should_publish_event - uid = SecureRandom.uuid - customer_registered = CustomerRegistered.new(data: {customer_id: uid, name: fake_name}) - assert_events("Crm::Customer$#{uid}", customer_registered) do - register_customer(uid, fake_name) - end - end - end -end diff --git a/ecommerce/crm/test/test_helper.rb b/ecommerce/crm/test/test_helper.rb deleted file mode 100644 index feec8f051..000000000 --- a/ecommerce/crm/test/test_helper.rb +++ /dev/null @@ -1,23 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/crm" - -module Crm - class Test < Infra::InMemoryTest - def before_setup - super() - Configuration.new.call(event_store, command_bus) - end - - private - - def register_customer(uid, name) - run_command(RegisterCustomer.new(customer_id: uid, name: name)) - end - - def fake_name - "Fake name" - end - end -end diff --git a/ecommerce/fulfillment/.mutant.yml b/ecommerce/fulfillment/.mutant.yml deleted file mode 100644 index 6d1df49be..000000000 --- a/ecommerce/fulfillment/.mutant.yml +++ /dev/null @@ -1,12 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Fulfillment* - ignore: - - Fulfillment::Test* - - Fulfillment::Configuration#call - - Fulfillment::Configuration#initialize \ No newline at end of file diff --git a/ecommerce/fulfillment/Gemfile b/ecommerce/fulfillment/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/fulfillment/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/fulfillment/Gemfile.lock b/ecommerce/fulfillment/Gemfile.lock deleted file mode 100644 index 87553b254..000000000 --- a/ecommerce/fulfillment/Gemfile.lock +++ /dev/null @@ -1,116 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.3.2) - 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.14.0) - base64 - ruby_event_store (= 2.14.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.7) - concurrent-ruby (1.2.3) - connection_pool (2.4.1) - diff-lcs (1.5.1) - drb (2.2.1) - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.2) - bigdecimal (~> 3.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.4) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.10) - rake (13.2.1) - redis-client (0.22.1) - connection_pool - regexp_parser (2.8.3) - ruby_event_store (2.14.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.4) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.19.0) - sorbet-runtime (0.5.11368) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.13) - -PLATFORMS - arm64-darwin-23 - ruby - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/fulfillment/Makefile b/ecommerce/fulfillment/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/fulfillment/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/fulfillment/lib/fulfillment.rb b/ecommerce/fulfillment/lib/fulfillment.rb deleted file mode 100644 index 66ea3b558..000000000 --- a/ecommerce/fulfillment/lib/fulfillment.rb +++ /dev/null @@ -1,21 +0,0 @@ -require "infra" -require_relative "fulfillment/events/order_registered" -require_relative "fulfillment/events/order_confirmed" -require_relative "fulfillment/events/order_cancelled" -require_relative "fulfillment/commands/register_order" -require_relative "fulfillment/commands/confirm_order" -require_relative "fulfillment/commands/cancel_order" -require_relative "fulfillment/on_register_order" -require_relative "fulfillment/on_cancel_order" -require_relative "fulfillment/on_confirm_order" -require_relative "fulfillment/order" - -module Fulfillment - class Configuration - def call(event_store, command_bus) - command_bus.register(RegisterOrder, OnRegisterOrder.new(event_store)) - command_bus.register(ConfirmOrder, OnConfirmOrder.new(event_store)) - command_bus.register(CancelOrder, OnCancelOrder.new(event_store)) - end - end -end diff --git a/ecommerce/fulfillment/lib/fulfillment/commands/cancel_order.rb b/ecommerce/fulfillment/lib/fulfillment/commands/cancel_order.rb deleted file mode 100644 index 0d1dd8b70..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/commands/cancel_order.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class CancelOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/fulfillment/lib/fulfillment/commands/confirm_order.rb b/ecommerce/fulfillment/lib/fulfillment/commands/confirm_order.rb deleted file mode 100644 index 729debae4..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/commands/confirm_order.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class ConfirmOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/fulfillment/lib/fulfillment/commands/register_order.rb b/ecommerce/fulfillment/lib/fulfillment/commands/register_order.rb deleted file mode 100644 index 18bb18370..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/commands/register_order.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class RegisterOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end \ No newline at end of file diff --git a/ecommerce/fulfillment/lib/fulfillment/events/order_cancelled.rb b/ecommerce/fulfillment/lib/fulfillment/events/order_cancelled.rb deleted file mode 100644 index 9a937e3f9..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/events/order_cancelled.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class OrderCancelled < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/fulfillment/lib/fulfillment/events/order_confirmed.rb b/ecommerce/fulfillment/lib/fulfillment/events/order_confirmed.rb deleted file mode 100644 index 1342816a5..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/events/order_confirmed.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class OrderConfirmed < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/fulfillment/lib/fulfillment/events/order_registered.rb b/ecommerce/fulfillment/lib/fulfillment/events/order_registered.rb deleted file mode 100644 index 1fce5c007..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/events/order_registered.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class OrderRegistered < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/fulfillment/lib/fulfillment/on_cancel_order.rb b/ecommerce/fulfillment/lib/fulfillment/on_cancel_order.rb deleted file mode 100644 index 91490dcab..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/on_cancel_order.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class OnCancelOrder - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.cancel - end - end - end -end \ No newline at end of file diff --git a/ecommerce/fulfillment/lib/fulfillment/on_confirm_order.rb b/ecommerce/fulfillment/lib/fulfillment/on_confirm_order.rb deleted file mode 100644 index 87b82a377..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/on_confirm_order.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class OnConfirmOrder - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.confirm - end - end - end -end diff --git a/ecommerce/fulfillment/lib/fulfillment/on_register_order.rb b/ecommerce/fulfillment/lib/fulfillment/on_register_order.rb deleted file mode 100644 index b9fa5acb7..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/on_register_order.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class OnRegisterOrder - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.register - end - end - end -end \ No newline at end of file diff --git a/ecommerce/fulfillment/lib/fulfillment/order.rb b/ecommerce/fulfillment/lib/fulfillment/order.rb deleted file mode 100644 index 688ab8f4c..000000000 --- a/ecommerce/fulfillment/lib/fulfillment/order.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module Fulfillment - class Order - include AggregateRoot - - InvalidState = Class.new(StandardError) - - def initialize(id) - @id = id - end - - def register - raise InvalidState if @state - apply OrderRegistered.new(data: { order_id: @id }) - end - - def confirm - raise InvalidState unless @state.equal?(:new) - apply OrderConfirmed.new(data: { order_id: @id }) - end - - def cancel - raise InvalidState unless @state.equal?(:new) - apply OrderCancelled.new(data: { order_id: @id }) - end - - on OrderRegistered do |event| - @state = :new - end - - on OrderConfirmed do |event| - @state = :confirmed - end - - on OrderCancelled do |event| - @state = :cancelled - end - end -end diff --git a/ecommerce/fulfillment/test/cancel_order_test.rb b/ecommerce/fulfillment/test/cancel_order_test.rb deleted file mode 100644 index 55369ac92..000000000 --- a/ecommerce/fulfillment/test/cancel_order_test.rb +++ /dev/null @@ -1,41 +0,0 @@ -require_relative "test_helper" - -module Fulfillment - class CancelOrderTest < Test - cover "Fulfillment::OnCancelOrder*" - - def test_not_registered_order_cant_be_cancelled - aggregate_id = SecureRandom.uuid - - assert_raises(Order::InvalidState) do - act(CancelOrder.new(order_id: aggregate_id)) - end - end - - def test_registered_order_can_be_cancelled - aggregate_id = SecureRandom.uuid - stream = "Fulfillment::Order$#{aggregate_id}" - arrange( - RegisterOrder.new(order_id: aggregate_id) - ) - - assert_events( - stream, - OrderCancelled.new(data: { order_id: aggregate_id }) - ) { act(CancelOrder.new(order_id: aggregate_id)) } - end - - def test_confirmed_order_can_not_be_cancelled - aggregate_id = SecureRandom.uuid - - arrange( - RegisterOrder.new(order_id: aggregate_id), - ConfirmOrder.new(order_id: aggregate_id) - ) - - assert_raises(Order::InvalidState) do - act(CancelOrder.new(order_id: aggregate_id)) - end - end - end -end diff --git a/ecommerce/fulfillment/test/confirm_order_test.rb b/ecommerce/fulfillment/test/confirm_order_test.rb deleted file mode 100644 index ec67b49a6..000000000 --- a/ecommerce/fulfillment/test/confirm_order_test.rb +++ /dev/null @@ -1,41 +0,0 @@ -require_relative "test_helper" - -module Fulfillment - class ConfirmOrderTest < Test - cover "Fulfillment::OnConfirmOrder*" - - def test_not_registered_order_cant_be_confirmed - aggregate_id = SecureRandom.uuid - - assert_raises(Order::InvalidState) do - act(ConfirmOrder.new(order_id: aggregate_id)) - end - end - - def test_registered_order_can_be_confirmed - aggregate_id = SecureRandom.uuid - stream = "Fulfillment::Order$#{aggregate_id}" - arrange( - RegisterOrder.new(order_id: aggregate_id) - ) - - assert_events( - stream, - OrderConfirmed.new(data: { order_id: aggregate_id }) - ) { act(ConfirmOrder.new(order_id: aggregate_id)) } - end - - def test_confirmed_order_can_not_be_confirmed - aggregate_id = SecureRandom.uuid - - arrange( - RegisterOrder.new(order_id: aggregate_id), - CancelOrder.new(order_id: aggregate_id) - ) - - assert_raises(Order::InvalidState) do - act(ConfirmOrder.new(order_id: aggregate_id)) - end - end - end -end diff --git a/ecommerce/fulfillment/test/register_order_test.rb b/ecommerce/fulfillment/test/register_order_test.rb deleted file mode 100644 index c82a1b3f5..000000000 --- a/ecommerce/fulfillment/test/register_order_test.rb +++ /dev/null @@ -1,29 +0,0 @@ -require_relative "test_helper" - -module Fulfillment - class ConfirmOrderTest < Test - cover "Fulfillment::OnRegisterOrder*" - - def test_new_order_can_be_registered - aggregate_id = SecureRandom.uuid - stream = "Fulfillment::Order$#{aggregate_id}" - - assert_events( - stream, - OrderRegistered.new(data: { order_id: aggregate_id }) - ) { act(RegisterOrder.new(order_id: aggregate_id)) } - end - - def test_registered_order_can_not_be_registered_again - aggregate_id = SecureRandom.uuid - - arrange( - RegisterOrder.new(order_id: aggregate_id), - ) - - assert_raises(Order::InvalidState) do - act(RegisterOrder.new(order_id: aggregate_id)) - end - end - end -end \ No newline at end of file diff --git a/ecommerce/fulfillment/test/test_helper.rb b/ecommerce/fulfillment/test/test_helper.rb deleted file mode 100644 index 374827131..000000000 --- a/ecommerce/fulfillment/test/test_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/fulfillment" - -module Fulfillment - class Test < Infra::InMemoryTest - def before_setup - super - Configuration.new.call(event_store, command_bus) - end - end -end diff --git a/ecommerce/inventory/.mutant.yml b/ecommerce/inventory/.mutant.yml deleted file mode 100644 index 075692f1f..000000000 --- a/ecommerce/inventory/.mutant.yml +++ /dev/null @@ -1,12 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Inventory* - ignore: - - Inventory::Test* - - Inventory::Configuration#initialize - - Inventory::Configuration#call \ No newline at end of file diff --git a/ecommerce/inventory/Gemfile b/ecommerce/inventory/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/inventory/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/inventory/Gemfile.lock b/ecommerce/inventory/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/inventory/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/inventory/Makefile b/ecommerce/inventory/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/inventory/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/inventory/README.md b/ecommerce/inventory/README.md deleted file mode 100644 index a05e5cffb..000000000 --- a/ecommerce/inventory/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Inventory - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/inventory/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/inventory.yml) - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/inventory/lib/inventory.rb b/ecommerce/inventory/lib/inventory.rb deleted file mode 100644 index fe432c851..000000000 --- a/ecommerce/inventory/lib/inventory.rb +++ /dev/null @@ -1,36 +0,0 @@ -require "infra" -require_relative "inventory/commands/release" -require_relative "inventory/commands/supply" -require_relative "inventory/commands/reserve" -require_relative "inventory/commands/dispatch" -require_relative "inventory/events/stock_level_changed" -require_relative "inventory/events/stock_released" -require_relative "inventory/events/stock_reserved" -require_relative "inventory/events/availability_changed" -require_relative "inventory/inventory_entry_service" -require_relative "inventory/inventory_entry" - -module Inventory - class Configuration - def call(event_store, command_bus) - inventory = InventoryEntryService.new(event_store) - - command_bus.register( - Reserve, - inventory.method(:reserve) - ) - command_bus.register( - Release, - inventory.method(:release) - ) - command_bus.register( - Supply, - inventory.public_method(:supply) - ) - command_bus.register( - Dispatch, - inventory.public_method(:dispatch) - ) - end - end -end diff --git a/ecommerce/inventory/lib/inventory/commands/dispatch.rb b/ecommerce/inventory/lib/inventory/commands/dispatch.rb deleted file mode 100644 index 1db4643b8..000000000 --- a/ecommerce/inventory/lib/inventory/commands/dispatch.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Inventory - class Dispatch < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :quantity, Infra::Types::Coercible::Integer.constrained(gteq: 1) - end -end diff --git a/ecommerce/inventory/lib/inventory/commands/release.rb b/ecommerce/inventory/lib/inventory/commands/release.rb deleted file mode 100644 index d105f6ad2..000000000 --- a/ecommerce/inventory/lib/inventory/commands/release.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Inventory - class Release < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :quantity, Infra::Types::Coercible::Integer.constrained(gteq: 1) - end -end diff --git a/ecommerce/inventory/lib/inventory/commands/reserve.rb b/ecommerce/inventory/lib/inventory/commands/reserve.rb deleted file mode 100644 index 04f57849d..000000000 --- a/ecommerce/inventory/lib/inventory/commands/reserve.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Inventory - class Reserve < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :quantity, Infra::Types::Coercible::Integer.constrained(gteq: 1) - end -end diff --git a/ecommerce/inventory/lib/inventory/commands/supply.rb b/ecommerce/inventory/lib/inventory/commands/supply.rb deleted file mode 100644 index ecb5c1165..000000000 --- a/ecommerce/inventory/lib/inventory/commands/supply.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Inventory - class Supply < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :quantity, Infra::Types::Coercible::Integer.constrained(gteq: 1) - end -end diff --git a/ecommerce/inventory/lib/inventory/events/availability_changed.rb b/ecommerce/inventory/lib/inventory/events/availability_changed.rb deleted file mode 100644 index 00bc02de7..000000000 --- a/ecommerce/inventory/lib/inventory/events/availability_changed.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Inventory - class AvailabilityChanged < Infra::Event - end -end diff --git a/ecommerce/inventory/lib/inventory/events/stock_level_changed.rb b/ecommerce/inventory/lib/inventory/events/stock_level_changed.rb deleted file mode 100644 index b5623110e..000000000 --- a/ecommerce/inventory/lib/inventory/events/stock_level_changed.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Inventory - class StockLevelChanged < Infra::Event - end -end diff --git a/ecommerce/inventory/lib/inventory/events/stock_released.rb b/ecommerce/inventory/lib/inventory/events/stock_released.rb deleted file mode 100644 index 8d62e01df..000000000 --- a/ecommerce/inventory/lib/inventory/events/stock_released.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Inventory - class StockReleased < Infra::Event - end -end diff --git a/ecommerce/inventory/lib/inventory/events/stock_reserved.rb b/ecommerce/inventory/lib/inventory/events/stock_reserved.rb deleted file mode 100644 index 72ea5bf66..000000000 --- a/ecommerce/inventory/lib/inventory/events/stock_reserved.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Inventory - class StockReserved < Infra::Event - end -end diff --git a/ecommerce/inventory/lib/inventory/inventory_entry.rb b/ecommerce/inventory/lib/inventory/inventory_entry.rb deleted file mode 100644 index d1d11f08d..000000000 --- a/ecommerce/inventory/lib/inventory/inventory_entry.rb +++ /dev/null @@ -1,91 +0,0 @@ -module Inventory - class InventoryEntry - include AggregateRoot - - InventoryNotAvailable = Class.new(StandardError) - InventoryNotEvenReserved = Class.new(StandardError) - - def initialize(product_id) - @product_id = product_id - @reserved = 0 - end - - def supply(quantity) - apply StockLevelChanged.new( - data: { - product_id: @product_id, - quantity: quantity, - stock_level: (@in_stock || 0) + quantity - } - ) - apply_availability_changed - end - - def dispatch(quantity) - apply StockLevelChanged.new( - data: { - product_id: @product_id, - quantity: -quantity, - stock_level: @in_stock - quantity - } - ) if stock_level_defined? - apply_availability_changed - end - - def reserve(quantity) - raise InventoryNotAvailable if stock_level_defined? && quantity > availability - apply StockReserved.new( - data: { - product_id: @product_id, - quantity: quantity - } - ) - apply_availability_changed - end - - def release(quantity) - raise InventoryNotEvenReserved if quantity > @reserved - apply StockReleased.new( - data: { - product_id: @product_id, - quantity: quantity - } - ) - apply_availability_changed - end - - private - - def apply_availability_changed - apply AvailabilityChanged.new( - data: { - product_id: @product_id, - available: availability - } - ) if stock_level_defined? - end - - on StockLevelChanged do |event| - @in_stock = event.data.fetch(:stock_level) - end - - on StockReserved do |event| - @reserved += event.data.fetch(:quantity) - end - - on StockReleased do |event| - @reserved -= event.data.fetch(:quantity) - end - - on AvailabilityChanged do |_| - end - - def availability - @in_stock - @reserved - end - - def stock_level_defined? - !@in_stock.nil? - end - end -end diff --git a/ecommerce/inventory/lib/inventory/inventory_entry_service.rb b/ecommerce/inventory/lib/inventory/inventory_entry_service.rb deleted file mode 100644 index 5d5147601..000000000 --- a/ecommerce/inventory/lib/inventory/inventory_entry_service.rb +++ /dev/null @@ -1,39 +0,0 @@ -module Inventory - class InventoryEntryService - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def supply(command) - with_inventory_entry(command.product_id) do |entry| - entry.supply(command.quantity) - end - end - - def dispatch(command) - with_inventory_entry(command.product_id) do |entry| - entry.dispatch(command.quantity) - end - end - - def reserve(command) - with_inventory_entry(command.product_id) do |entry| - entry.reserve(command.quantity) - end - end - - def release(command) - with_inventory_entry(command.product_id) do |entry| - entry.release(command.quantity) - end - end - - private - - def with_inventory_entry(product_id) - @repository.with_aggregate(InventoryEntry, product_id) do |entry| - yield(entry) - end - end - end -end diff --git a/ecommerce/inventory/test/dispatch_test.rb b/ecommerce/inventory/test/dispatch_test.rb deleted file mode 100644 index 5483d7673..000000000 --- a/ecommerce/inventory/test/dispatch_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -require_relative "test_helper" - -module Inventory - class DispatchTest < Test - def test_nothing_changes_when_stock_level_is_undefined - product_id = SecureRandom.uuid - assert_events(inventory_entry_stream(product_id)) do - act(dispatch(product_id, 1)) - end - end - - def test_stock_level_changes_with_dispatch_command - product_id = SecureRandom.uuid - arrange(supply(product_id, 1)) - assert_events( - inventory_entry_stream(product_id), - StockLevelChanged.new( - data: { - product_id: product_id, - quantity: -1, - stock_level: 0 - } - ), - AvailabilityChanged.new(data: { product_id: product_id, available: 0 }) - ) do - act(dispatch(product_id, 1)) - end - end - end -end diff --git a/ecommerce/inventory/test/release_test.rb b/ecommerce/inventory/test/release_test.rb deleted file mode 100644 index 8d35021cc..000000000 --- a/ecommerce/inventory/test/release_test.rb +++ /dev/null @@ -1,40 +0,0 @@ -require_relative "test_helper" - -module Inventory - class ReleaseTest < Test - def test_stock_gets_released_when_reserved_and_stock_level_undefined - product_id = SecureRandom.uuid - - arrange(reserve(product_id, 1)) - assert_events( - inventory_entry_stream(product_id), - StockReleased.new(data: { product_id: product_id, quantity: 1 }) - ) do - act(Release.new(product_id: product_id, quantity: 1)) - end - end - - def test_stock_gets_released_when_reserved_and_stock_level_defined - product_id = SecureRandom.uuid - - arrange(supply(product_id, 1), reserve(product_id, 1)) - assert_events( - inventory_entry_stream(product_id), - StockReleased.new(data: { product_id: product_id, quantity: 1 }), - AvailabilityChanged.new(data: { product_id: product_id, available: 1 }) - ) do - act(Release.new(product_id: product_id, quantity: 1)) - end - end - - def test_stock_does_not_get_released_when_not_reserved - product_id = SecureRandom.uuid - - assert_raises( - InventoryEntry::InventoryNotEvenReserved - ) do - act(Release.new(product_id: product_id, quantity: 1)) - end - end - end -end diff --git a/ecommerce/inventory/test/reserve_test.rb b/ecommerce/inventory/test/reserve_test.rb deleted file mode 100644 index 89a900c55..000000000 --- a/ecommerce/inventory/test/reserve_test.rb +++ /dev/null @@ -1,38 +0,0 @@ -require_relative "test_helper" - -module Inventory - class ReserveTest < Test - def test_stock_gets_reserved_when_available - product_id = SecureRandom.uuid - arrange(supply(product_id, 1)) - - assert_events( - inventory_entry_stream(product_id), - StockReserved.new(data: { product_id: product_id, quantity: 1 }), - AvailabilityChanged.new(data: { product_id: product_id, available: 0 }) - ) do - act(reserve(product_id, 1)) - end - end - - def test_stock_gets_reserved_when_stock_level_undefined - product_id = SecureRandom.uuid - - assert_events( - inventory_entry_stream(product_id), - StockReserved.new(data: { product_id: product_id, quantity: 1 }) - ) do - act(reserve(product_id, 1)) - end - end - - def test_raises_when_stock_unavailable - product_id = SecureRandom.uuid - arrange(supply(product_id, 1)) - - assert_raises(InventoryEntry::InventoryNotAvailable) do - act(reserve(product_id, 2)) - end - end - end -end diff --git a/ecommerce/inventory/test/supply_test.rb b/ecommerce/inventory/test/supply_test.rb deleted file mode 100644 index 7815e544f..000000000 --- a/ecommerce/inventory/test/supply_test.rb +++ /dev/null @@ -1,33 +0,0 @@ -require_relative "test_helper" - -module Inventory - class SupplyTest < Test - def test_stock_level_changes_with_supply_command - product_id = SecureRandom.uuid - assert_events( - inventory_entry_stream(product_id), - StockLevelChanged.new( - data: { - product_id: product_id, - quantity: 1, - stock_level: 1 - } - ), - AvailabilityChanged.new( - data: { product_id: product_id, available: 1 } - ) - ) { act(supply(product_id, 1)) } - assert_events( - inventory_entry_stream(product_id), - StockLevelChanged.new( - data: { - product_id: product_id, - quantity: 1, - stock_level: 2 - } - ), - AvailabilityChanged.new(data: { product_id: product_id, available: 2 }) - ) { act(supply(product_id, 1)) } - end - end -end diff --git a/ecommerce/inventory/test/test_helper.rb b/ecommerce/inventory/test/test_helper.rb deleted file mode 100644 index 3b3901c49..000000000 --- a/ecommerce/inventory/test/test_helper.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/inventory" - -module Inventory - class Test < Infra::InMemoryTest - cover "Inventory*" - - def before_setup - super - Configuration.new.call(event_store, command_bus) - end - - def inventory_entry_stream(product_id) - "Inventory::InventoryEntry$#{product_id}" - end - - def reserve(product_id, quantity) - Reserve.new(product_id: product_id, quantity: quantity) - end - - def release(product_id, quantity) - Release.new(product_id: product_id, quantity: quantity) - end - - def dispatch(product_id, quantity) - Dispatch.new(product_id: product_id, quantity: quantity) - end - - def supply(product_id, quantity) - Supply.new(product_id: product_id, quantity: quantity) - end - - def cancel_reservation(order_id) - Release.new(order_id: order_id) - end - end -end diff --git a/ecommerce/invoicing/.mutant.yml b/ecommerce/invoicing/.mutant.yml deleted file mode 100644 index 751c1e676..000000000 --- a/ecommerce/invoicing/.mutant.yml +++ /dev/null @@ -1,14 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Invoicing* - ignore: - - Invoicing::Configuration* - - Invoicing::Test* - - Invoicing::InvoiceItemTitleCatalog* - - Invoicing::InvoiceService#initialize - - Invoicing::FakeConcurrentInvoiceNumberGenerator#next_number \ No newline at end of file diff --git a/ecommerce/invoicing/Gemfile b/ecommerce/invoicing/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/invoicing/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/invoicing/Gemfile.lock b/ecommerce/invoicing/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/invoicing/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/invoicing/Makefile b/ecommerce/invoicing/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/invoicing/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/invoicing/README.md b/ecommerce/invoicing/README.md deleted file mode 100644 index ff873a58c..000000000 --- a/ecommerce/invoicing/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Invoicing - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/invoicing/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/invoicing.yml) - - -#### Up and running - -``` -make install test mutate -``` - - -### Domain knowledge - -[Steps for successful invoicing](https://www.xero.com/guides/invoicing/) \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing.rb b/ecommerce/invoicing/lib/invoicing.rb deleted file mode 100644 index dc3c3ce19..000000000 --- a/ecommerce/invoicing/lib/invoicing.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'infra' -require_relative 'invoicing/commands' -require_relative 'invoicing/events' -require_relative 'invoicing/services' -require_relative 'invoicing/invoice' -require_relative 'invoicing/invoice_item_title_catalog' -require_relative 'invoicing/product' -require_relative 'invoicing/invoice_number_generator' - -module Invoicing - class Configuration - def call(event_store, command_bus) - command_bus.register( - SetProductNameDisplayedOnInvoice, - SetProductNameDisplayedOnInvoiceHandler.new(event_store) - ) - command_bus.register( - AddInvoiceItem, - InvoiceService.new(event_store).public_method(:add_item) - ) - command_bus.register( - SetPaymentDate, - InvoiceService.new(event_store).public_method(:set_payment_date) - ) - command_bus.register( - IssueInvoice, - InvoiceService.new(event_store).public_method(:issue) - ) - command_bus.register( - SetBillingAddress, - InvoiceService.new(event_store).public_method(:set_billing_address) - ) - event_store.subscribe( - ->(event) do - stream_name = "InvoiceIssued$#{event.data.fetch(:issue_date).strftime("%Y-%m")}" - ordinal_number = event.data.fetch(:invoice_number).split('/').first.to_i - event_store.link( - event.event_id, - stream_name: stream_name, - expected_version: ordinal_number - 2 - ) - rescue RubyEventStore::WrongExpectedEventVersion - raise Invoice::InvoiceNumberInUse - end, - to: [Invoicing::InvoiceIssued] - ) - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/commands.rb b/ecommerce/invoicing/lib/invoicing/commands.rb deleted file mode 100644 index b49a47a93..000000000 --- a/ecommerce/invoicing/lib/invoicing/commands.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Invoicing - class AddInvoiceItem < Infra::Command - attribute :invoice_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - attribute :quantity, Infra::Types::Quantity - attribute :unit_price, Infra::Types::Price - attribute :vat_rate, Infra::Types::VatRate - end - - class IssueInvoice < Infra::Command - attribute :invoice_id, Infra::Types::UUID - attribute :issue_date, Infra::Types::Date - end - - class SetPaymentDate < Infra::Command - attribute :invoice_id, Infra::Types::UUID - attribute :payment_date, Infra::Types::Date - end - - class SetBillingAddress < Infra::Command - attribute :invoice_id, Infra::Types::UUID - attribute :tax_id_number, Infra::Types::String.optional - attribute :postal_address, Infra::Types::PostalAddress - end - - class SetProductNameDisplayedOnInvoice < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :name_displayed, Infra::Types::String - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/events.rb b/ecommerce/invoicing/lib/invoicing/events.rb deleted file mode 100644 index 30c4bdd67..000000000 --- a/ecommerce/invoicing/lib/invoicing/events.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Invoicing - class InvoiceItemAdded < Infra::Event - attribute :invoice_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - attribute :title, Infra::Types::String - attribute :quantity, Infra::Types::Quantity - attribute :unit_price, Infra::Types::Price - attribute :vat_rate, Infra::Types::VatRate - end - - class InvoicePaymentDateSet < Infra::Event - attribute :invoice_id, Infra::Types::UUID - attribute :payment_date, Infra::Types::Params::Date - end - - class InvoiceIssued < Infra::Event - attribute :invoice_id, Infra::Types::UUID - attribute :issue_date, Infra::Types::Params::Date - attribute :disposal_date, Infra::Types::Params::Date - attribute :invoice_number, Infra::Types::String - end - - class BillingAddressSet < Infra::Event - attribute :invoice_id, Infra::Types::UUID - attribute :tax_id_number, Infra::Types::String.optional - attribute :postal_address, Infra::Types::PostalAddress - end - - class ProductNameDisplayedSet < Infra::Event - attribute :product_id, Infra::Types::UUID - attribute :name_displayed, Infra::Types::String - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/fake_concurrent_invoice_number_generator.rb b/ecommerce/invoicing/lib/invoicing/fake_concurrent_invoice_number_generator.rb deleted file mode 100644 index 7328ece12..000000000 --- a/ecommerce/invoicing/lib/invoicing/fake_concurrent_invoice_number_generator.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Invoicing - class FakeConcurrentInvoiceNumberGenerator - def initialize - @counter = 0 - end - - def call(issue_date) - issue_date.strftime("#{next_number}/%m/%Y") - end - - private - - def next_number - @counter += 1 - return 1 if @counter < 2 - @counter - 1 - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/invoice.rb b/ecommerce/invoicing/lib/invoicing/invoice.rb deleted file mode 100644 index 9d759e807..000000000 --- a/ecommerce/invoicing/lib/invoicing/invoice.rb +++ /dev/null @@ -1,110 +0,0 @@ -module Invoicing - class Invoice - InvoiceAlreadyIssued = Class.new(StandardError) - InvoiceNumberInUse = Class.new(StandardError) - BillingAddressNotSpecified = Class.new(StandardError) - include AggregateRoot - - def initialize(invoice_id) - @invoice_id = invoice_id - @invoice_items = [] - end - - def issue(issue_date, invoice_number) - raise BillingAddressNotSpecified unless @postal_address - raise InvoiceAlreadyIssued unless draft? - disposal_date = [@payment_date, issue_date].compact.min - apply( - InvoiceIssued.new( - data: { - invoice_id: @invoice_id, - issue_date: issue_date, - disposal_date: disposal_date, - invoice_number: invoice_number - } - ) - ) - end - - def set_payment_date(payment_date) - apply( - InvoicePaymentDateSet.new( - data: { - invoice_id: @invoice_id, - payment_date: payment_date - } - ) - ) - end - - def add_item(product_id, title, unit_price, vat_rate, quantity) - raise InvoiceAlreadyIssued unless draft? - apply( - InvoiceItemAdded.new( - data: { - invoice_id: @invoice_id, - product_id: product_id, - title: title, - quantity: quantity, - unit_price: unit_price, - vat_rate: vat_rate - } - ) - ) - end - - def set_billing_address(tax_id_number, postal_address) - raise InvoiceAlreadyIssued unless draft? - apply BillingAddressSet.new( - data: { - invoice_id: @invoice_id, - postal_address: postal_address, - tax_id_number: tax_id_number - } - ) - end - - private - - def draft? - @issue_date.nil? - end - - on InvoiceItemAdded do |event| - @invoice_items << InvoiceItem.new( - event.data[:product_id], - event.data[:title], - event.data[:unit_price], - event.data[:vat_rate], - event.data[:quantity] - ) - end - - on InvoicePaymentDateSet do |event| - @payment_date = event.data[:payment_date] - end - - on InvoiceIssued do |event| - @state = :issued - @issue_date = event.data[:issue_date] - @disposal_date = event.data[:disposal_date] - end - - on BillingAddressSet do |event| - @tax_id_number = event.data.fetch(:tax_id_number) - @postal_address = event.data.fetch(:postal_address) - end - end - - class InvoiceItem - attr_reader :product_id, :quantity, :unit_price, :vat_rate, :title - - def initialize(product_id, title, unit_price, vat_rate, quantity) - @product_id = product_id - @title = title - @unit_price = unit_price - @vat_rate = vat_rate - @quantity = quantity - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/invoice_item_title_catalog.rb b/ecommerce/invoicing/lib/invoicing/invoice_item_title_catalog.rb deleted file mode 100644 index bcabc61d5..000000000 --- a/ecommerce/invoicing/lib/invoicing/invoice_item_title_catalog.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Invoicing - class InvoiceItemTitleCatalog - def initialize(event_store) - @event_store = event_store - end - - def invoice_item_title_for_product(product_id) - @event_store - .read - .of_type(ProductNameDisplayedSet) - .to_a - .filter { |e| e.data.fetch(:product_id).eql?(product_id) } - .last - .data - .fetch(:name_displayed) - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/invoice_number_generator.rb b/ecommerce/invoicing/lib/invoicing/invoice_number_generator.rb deleted file mode 100644 index 0caaa15e1..000000000 --- a/ecommerce/invoicing/lib/invoicing/invoice_number_generator.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Invoicing - class InvoiceNumberGenerator - def initialize(event_store) - @event_store = event_store - end - - def call(issue_date) - issue_date.strftime("#{next_number(issue_date)}/%m/%Y") - end - - private - - def next_number(issue_date) - stream_name = "InvoiceIssued$#{issue_date.strftime("%Y-%m")}" - @event_store.read.stream(stream_name).count + 1 - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/product.rb b/ecommerce/invoicing/lib/invoicing/product.rb deleted file mode 100644 index 01624ff3c..000000000 --- a/ecommerce/invoicing/lib/invoicing/product.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Invoicing - class Product - include AggregateRoot - - def initialize(product_id) - @product_id = product_id - end - - def set_name_displayed(name) - apply( - ProductNameDisplayedSet.new( - data: { - product_id: @product_id, - name_displayed: name - } - ) - ) - end - - private - - on ProductNameDisplayedSet do |event| - @name_displayed = event.data[:name_displayed] - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/lib/invoicing/services.rb b/ecommerce/invoicing/lib/invoicing/services.rb deleted file mode 100644 index b547ae0ab..000000000 --- a/ecommerce/invoicing/lib/invoicing/services.rb +++ /dev/null @@ -1,55 +0,0 @@ -module Invoicing - class InvoiceService - def initialize(event_store, number_generator = InvoiceNumberGenerator.new(event_store)) - @repository = Infra::AggregateRootRepository.new(event_store) - @titles_catalog = InvoiceItemTitleCatalog.new(event_store) - @number_generator = number_generator - end - - def add_item(command) - with_invoice(command.invoice_id) do |invoice| - title = @titles_catalog.invoice_item_title_for_product(command.product_id) - invoice.add_item(command.product_id, title, command.unit_price, command.vat_rate, command.quantity) - end - end - - def set_payment_date(command) - with_invoice(command.invoice_id) do |invoice| - invoice.set_payment_date(command.payment_date) - end - end - - def set_billing_address(command) - with_invoice(command.invoice_id) do |invoice| - invoice.set_billing_address(command.tax_id_number, command.postal_address) - end - end - - def issue(command) - with_invoice(command.invoice_id) do |invoice| - invoice_number = @number_generator.call(command.issue_date) - invoice.issue(command.issue_date, invoice_number) - end - end - - private - - def with_invoice(invoice_id) - @repository.with_aggregate(Invoice, invoice_id) do |invoice| - yield(invoice) - end - end - end - - class SetProductNameDisplayedOnInvoiceHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Product, command.product_id) do |product| - product.set_name_displayed(command.name_displayed) - end - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/test/fake_concurrent_invoice_number_generator_test.rb b/ecommerce/invoicing/test/fake_concurrent_invoice_number_generator_test.rb deleted file mode 100644 index 645b150c6..000000000 --- a/ecommerce/invoicing/test/fake_concurrent_invoice_number_generator_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require_relative "test_helper" - -module Invoicing - class FakeConcurrentInvoiceNumberGeneratorTest < Test - cover "Invoicing::FakeInvoiceNumberGenerator" - - def test_fetching_next_number - issue_date = Date.new(2022, 1, 5) - number_generator = FakeConcurrentInvoiceNumberGenerator.new - assert_equal("1/01/2022", number_generator.call(issue_date)) - assert_equal("1/01/2022", number_generator.call(issue_date)) - assert_equal("2/01/2022", number_generator.call(issue_date)) - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/test/invoice_item_test.rb b/ecommerce/invoicing/test/invoice_item_test.rb deleted file mode 100644 index 3d65d1ec1..000000000 --- a/ecommerce/invoicing/test/invoice_item_test.rb +++ /dev/null @@ -1,22 +0,0 @@ -require_relative "test_helper" - -module Invoicing - class InvoiceItemTest < Test - cover "Invoicing::Invoice" - - def test_initializer - product_id = SecureRandom.uuid - vat_rate = Infra::Types::VatRate.new(rate: 20, code: "20") - unit_price = 100.to_d - quantity = 20 - title = 'test' - item = InvoiceItem.new(product_id, title, unit_price, vat_rate, quantity) - - assert_equal product_id, item.product_id - assert_equal title, item.title - assert_equal vat_rate, item.vat_rate - assert_equal unit_price, item.unit_price - assert_equal quantity, item.quantity - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/test/invoice_number_generator_test.rb b/ecommerce/invoicing/test/invoice_number_generator_test.rb deleted file mode 100644 index b847f7b8b..000000000 --- a/ecommerce/invoicing/test/invoice_number_generator_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -require_relative "test_helper" - -module Invoicing - class InvoiceNumberGeneratorTest < Test - cover "Invoicing::InvoiceNumberGenerator" - - def test_fetching_next_number - issue_date = Date.new(2022, 1, 5) - number_generator = InvoiceNumberGenerator.new(event_store) - assert_equal("1/01/2022", number_generator.call(issue_date)) - issue_random_invoice(issue_date) - assert_equal("2/01/2022", number_generator.call(issue_date)) - next_month_issue_date = Date.new(2022, 2, 5) - assert_equal("1/02/2022", number_generator.call(next_month_issue_date)) - next_year_issue_date = Date.new(2023, 1, 5) - assert_equal("1/01/2023", number_generator.call(next_year_issue_date)) - end - - private - - def issue_random_invoice(issue_date) - invoice_id = SecureRandom.uuid - set_billing_address(invoice_id) - run_command(IssueInvoice.new(invoice_id: invoice_id, issue_date: issue_date)) - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/test/invoice_service_test.rb b/ecommerce/invoicing/test/invoice_service_test.rb deleted file mode 100644 index 11412c942..000000000 --- a/ecommerce/invoicing/test/invoice_service_test.rb +++ /dev/null @@ -1,177 +0,0 @@ -require_relative "test_helper" - -module Invoicing - class InvoiceServiceTest < Test - cover "Invoicing::InvoiceService" - - def test_adding_to_invoice - invoice_id = SecureRandom.uuid - product_id = SecureRandom.uuid - unit_price = 10.0.to_d - vat_rate = Infra::Types::VatRate.new(code: "20", rate: 20) - title = 'test' - - stream = "Invoicing::Invoice$#{invoice_id}" - assert_events( - stream, - InvoiceItemAdded.new( - data: { - invoice_id: invoice_id, - product_id: product_id, - title: title, - vat_rate: vat_rate, - unit_price: unit_price, - quantity: 1, - } - ) - ) { add_item(invoice_id, product_id, vat_rate, unit_price, title) } - end - - def test_setting_billing_address - invoice_id = SecureRandom.uuid - billing_address = fake_address - tax_id_number = "PL1111111111" - stream = "Invoicing::Invoice$#{invoice_id}" - assert_events( - stream, - BillingAddressSet.new( - data: { - invoice_id: invoice_id, - postal_address: fake_address, - tax_id_number: tax_id_number - } - ) - ) { set_billing_address(invoice_id, billing_address, tax_id_number) } - end - - def test_setting_payment_date - invoice_id = SecureRandom.uuid - payment_date = Date.new(2021, 1, 5) - - stream = "Invoicing::Invoice$#{invoice_id}" - assert_events( - stream, - InvoicePaymentDateSet.new( - data: { - invoice_id: invoice_id, - payment_date: payment_date, - } - ) - ) { set_payment_date(invoice_id, payment_date) } - end - - def test_issuing_invoice - invoice_id = SecureRandom.uuid - issue_date = Date.new(2021, 1, 5) - set_billing_address(invoice_id) - - stream = "Invoicing::Invoice$#{invoice_id}" - assert_events( - stream, - InvoiceIssued.new( - data: { - invoice_id: invoice_id, - issue_date: issue_date, - disposal_date: issue_date, - invoice_number: '1/01/2021' - } - ) - ) { issue_invoice(invoice_id, issue_date) } - end - - def test_issuing_invoice_after_setting_payment_date - invoice_id = SecureRandom.uuid - issue_date = Date.new(2021, 1, 5) - payment_date = Date.new(2021, 1, 1) - set_payment_date(invoice_id, payment_date) - set_billing_address(invoice_id) - - stream = "Invoicing::Invoice$#{invoice_id}" - assert_events( - stream, - InvoiceIssued.new( - data: { - invoice_id: invoice_id, - issue_date: issue_date, - disposal_date: payment_date, - invoice_number: '1/01/2021' - } - ) - ) { issue_invoice(invoice_id, issue_date) } - end - - def test_issuing_invoice_with_faked_race_condition - invoice_id = SecureRandom.uuid - another_invoice_id = SecureRandom.uuid - issue_date = Date.new(2021, 1, 5) - set_billing_address(invoice_id) - set_billing_address(another_invoice_id) - - mocked_service = InvoiceService.new( - event_store, - FakeConcurrentInvoiceNumberGenerator.new - ).public_method(:issue) - - stream = "Invoicing::Invoice$#{invoice_id}" - assert_events( - stream, - InvoiceIssued.new( - data: { - invoice_id: invoice_id, - issue_date: issue_date, - disposal_date: issue_date, - invoice_number: '1/01/2021' - } - ) - ) { mocked_service.(issue_invoice_command(invoice_id, issue_date)) } - assert_raises(Invoice::InvoiceNumberInUse) do - mocked_service.(issue_invoice_command(another_invoice_id, issue_date)) - end - end - - def test_issued_invoice_is_a_final_state - invoice_id = SecureRandom.uuid - set_billing_address(invoice_id) - issue_invoice(invoice_id) - assert_raises(Invoice::InvoiceAlreadyIssued) { issue_invoice(invoice_id) } - assert_raises(Invoice::InvoiceAlreadyIssued) { add_item(invoice_id) } - assert_raises(Invoice::InvoiceAlreadyIssued) { set_billing_address(invoice_id) } - end - - def test_invoice_can_not_be_issued_without_billing_address - invoice_id = SecureRandom.uuid - assert_raises(Invoice::BillingAddressNotSpecified) { issue_invoice(invoice_id) } - end - - private - - def add_item ( - invoice_id, - product_id = SecureRandom.uuid, - vat_rate = Infra::Types::VatRate.new(code: "20", rate: 20), - unit_price = 10.0.to_d, - title = 'test' - ) - set_product_name_displayed(product_id, title) - run_command(AddInvoiceItem.new( - invoice_id: invoice_id, - product_id: product_id, - vat_rate: vat_rate, - unit_price: unit_price, - quantity: 1 - )) - end - - def issue_invoice(invoice_id, issue_date = Date.new(2021, 1, 5)) - run_command(issue_invoice_command(invoice_id, issue_date)) - end - - def issue_invoice_command(invoice_id, issue_date) - IssueInvoice.new(invoice_id: invoice_id, issue_date: issue_date) - end - - def set_payment_date(invoice_id, payment_date = Date.new(2021, 1, 5)) - run_command(SetPaymentDate.new(invoice_id: invoice_id, payment_date: payment_date)) - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/test/setting_product_displayed_name_test.rb b/ecommerce/invoicing/test/setting_product_displayed_name_test.rb deleted file mode 100644 index 3c26305c4..000000000 --- a/ecommerce/invoicing/test/setting_product_displayed_name_test.rb +++ /dev/null @@ -1,23 +0,0 @@ -require_relative "test_helper" - -module Invoicing - class SettingProductDisplayedNameTest < Test - cover "Invoicing::SetProductNameDisplayedOnInvoiceHandler" - - def test_adding_to_invoice - product_id = SecureRandom.uuid - name_displayed = 'test' - stream = "Invoicing::Product$#{product_id}" - - assert_events( - stream, - ProductNameDisplayedSet.new( - data: { - product_id: product_id, - name_displayed: name_displayed, - } - ) - ) { set_product_name_displayed(product_id, name_displayed) } - end - end -end \ No newline at end of file diff --git a/ecommerce/invoicing/test/test_helper.rb b/ecommerce/invoicing/test/test_helper.rb deleted file mode 100644 index f44c21892..000000000 --- a/ecommerce/invoicing/test/test_helper.rb +++ /dev/null @@ -1,37 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/invoicing" -require_relative '../lib/invoicing/fake_concurrent_invoice_number_generator' - -module Invoicing - class Test < Infra::InMemoryTest - def before_setup - super - Configuration.new.call(event_store, command_bus) - end - - private - - def set_product_name_displayed(product_id, name_displayed) - run_command(SetProductNameDisplayedOnInvoice.new(product_id: product_id, name_displayed: name_displayed)) - end - - def set_billing_address(invoice_id, postal_address = fake_address, tax_id_number = nil) - run_command(SetBillingAddress.new( - invoice_id: invoice_id, - postal_address: postal_address, - tax_id_number: tax_id_number - )) - end - - def fake_address - Infra::Types::PostalAddress.new( - line_1: "Anna Kowalska", - line_2: "Ul. Bosmanska 1", - line_3: "81-116 GDYNIA", - line_4: "POLAND" - ) - end - end -end diff --git a/ecommerce/ordering/.mutant.yml b/ecommerce/ordering/.mutant.yml deleted file mode 100644 index 6f7998002..000000000 --- a/ecommerce/ordering/.mutant.yml +++ /dev/null @@ -1,13 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Ordering* - ignore: - - Ordering::NumberGenerator* - - Ordering::Test* - - Ordering::Configuration#call - - Ordering::Configuration#initialize \ No newline at end of file diff --git a/ecommerce/ordering/Gemfile b/ecommerce/ordering/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/ordering/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/ordering/Gemfile.lock b/ecommerce/ordering/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/ordering/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/ordering/Makefile b/ecommerce/ordering/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/ordering/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/ordering/README.md b/ecommerce/ordering/README.md deleted file mode 100644 index 26708b6b8..000000000 --- a/ecommerce/ordering/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# Ordering - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/ordering/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/ordering.yml) - -The `Ordering::Order` aggregate manages the state machine of an order: - -- draft -- submitted -- accepted -- expired - -After each successful change an appropriate event is published in the Order stream. -This object is fully event sourced. - -| Order | draft | expired | submitted | accepted | -|-----------|:-----:|:-------:|:---------:|:--------:| -| draft | | ✅ | ✅ | | -| expired | | | | | -| submitted | ✅ | | | ✅ | -| accepted | | | | | - -### Design dilemmas - -#### God Domain - -The state machine mentioned above became a very central place to the whole application. -Almost every other domain either reacts to this domain or triggers Ordering. - -This might be an issue, as we might end up with a God Domain. - -#### Duplication of states - -Some of the states here are actually duplicates of the states of the Order in other domains. - -#### Multiplication and naming of states - -We clearly have a naming issue here. -What is the actual difference between submit/confirm/accept? -Not all the names match between method names and event names. - -#### Order items - -We track order items here, but we actually don't really use it much. -It doesn't have any impact on the state machine. -It's only needed to some read models, which can retrieve it from elsewhere - most notably the `Pricing` -The implementation of `Basket`, because of this, seems duplicated to Pricing or Inventory. - -#### Mapping of events between domains - -UI -> Ordering::SubmitOrder -> Ordering::Submitted -> Reservation(process) -> Ordering::AcceptOrder - -Ordering::AcceptOrder -> Ordering::OrderPlaced -> - --> Shipment::SubmitShipment --> Pricing::CalculateTotalValue - -### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/ordering/lib/ordering.rb b/ecommerce/ordering/lib/ordering.rb deleted file mode 100644 index ca4ad0c1c..000000000 --- a/ecommerce/ordering/lib/ordering.rb +++ /dev/null @@ -1,37 +0,0 @@ -require "infra" -require_relative "ordering/events/item_added_to_basket" -require_relative "ordering/events/item_removed_from_basket" -require_relative "ordering/events/order_placed" -require_relative "ordering/events/order_expired" -require_relative "ordering/events/order_submitted" -require_relative "ordering/events/order_rejected" -require_relative "ordering/commands/add_item_to_basket" -require_relative "ordering/commands/remove_item_from_basket" -require_relative "ordering/commands/submit_order" -require_relative "ordering/commands/set_order_as_expired" -require_relative "ordering/commands/accept_order" -require_relative "ordering/commands/reject_order" -require_relative "ordering/fake_number_generator" -require_relative "ordering/number_generator" -require_relative "ordering/service" -require_relative "ordering/order" - -module Ordering - class Configuration - def initialize(number_generator) - @number_generator = number_generator - end - - def call(event_store, command_bus) - command_bus.register( - SubmitOrder, - OnSubmitOrder.new(event_store, @number_generator.call) - ) - command_bus.register(AddItemToBasket, OnAddItemToBasket.new(event_store)) - command_bus.register(RemoveItemFromBasket, OnRemoveItemFromBasket.new(event_store)) - command_bus.register(SetOrderAsExpired, OnSetOrderAsExpired.new(event_store)) - command_bus.register(AcceptOrder, OnAcceptOrder.new(event_store)) - command_bus.register(RejectOrder, OnRejectOrder.new(event_store)) - end - end -end diff --git a/ecommerce/ordering/lib/ordering/commands/accept_order.rb b/ecommerce/ordering/lib/ordering/commands/accept_order.rb deleted file mode 100644 index 4ca46dee2..000000000 --- a/ecommerce/ordering/lib/ordering/commands/accept_order.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Ordering - class AcceptOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/ordering/lib/ordering/commands/add_item_to_basket.rb b/ecommerce/ordering/lib/ordering/commands/add_item_to_basket.rb deleted file mode 100644 index bad32f450..000000000 --- a/ecommerce/ordering/lib/ordering/commands/add_item_to_basket.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Ordering - class AddItemToBasket < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end \ No newline at end of file diff --git a/ecommerce/ordering/lib/ordering/commands/reject_order.rb b/ecommerce/ordering/lib/ordering/commands/reject_order.rb deleted file mode 100644 index 39a6d522c..000000000 --- a/ecommerce/ordering/lib/ordering/commands/reject_order.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Ordering - class RejectOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/ordering/lib/ordering/commands/remove_item_from_basket.rb b/ecommerce/ordering/lib/ordering/commands/remove_item_from_basket.rb deleted file mode 100644 index dd3e31fe9..000000000 --- a/ecommerce/ordering/lib/ordering/commands/remove_item_from_basket.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Ordering - class RemoveItemFromBasket < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end \ No newline at end of file diff --git a/ecommerce/ordering/lib/ordering/commands/set_order_as_expired.rb b/ecommerce/ordering/lib/ordering/commands/set_order_as_expired.rb deleted file mode 100644 index 938f95fdb..000000000 --- a/ecommerce/ordering/lib/ordering/commands/set_order_as_expired.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Ordering - class SetOrderAsExpired < Infra::Command - attribute :order_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/ordering/lib/ordering/commands/submit_order.rb b/ecommerce/ordering/lib/ordering/commands/submit_order.rb deleted file mode 100644 index 6842fe3b5..000000000 --- a/ecommerce/ordering/lib/ordering/commands/submit_order.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Ordering - class SubmitOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/ordering/lib/ordering/events/item_added_to_basket.rb b/ecommerce/ordering/lib/ordering/events/item_added_to_basket.rb deleted file mode 100644 index d5fe6f697..000000000 --- a/ecommerce/ordering/lib/ordering/events/item_added_to_basket.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Ordering - class ItemAddedToBasket < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end -end \ No newline at end of file diff --git a/ecommerce/ordering/lib/ordering/events/item_removed_from_basket.rb b/ecommerce/ordering/lib/ordering/events/item_removed_from_basket.rb deleted file mode 100644 index f68c68ff2..000000000 --- a/ecommerce/ordering/lib/ordering/events/item_removed_from_basket.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Ordering - class ItemRemovedFromBasket < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end -end \ No newline at end of file diff --git a/ecommerce/ordering/lib/ordering/events/order_expired.rb b/ecommerce/ordering/lib/ordering/events/order_expired.rb deleted file mode 100644 index 178e1b3c0..000000000 --- a/ecommerce/ordering/lib/ordering/events/order_expired.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Ordering - class OrderExpired < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/ordering/lib/ordering/events/order_placed.rb b/ecommerce/ordering/lib/ordering/events/order_placed.rb deleted file mode 100644 index 14a59b4fb..000000000 --- a/ecommerce/ordering/lib/ordering/events/order_placed.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Ordering - class OrderPlaced < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :order_number, Infra::Types::OrderNumber - end -end diff --git a/ecommerce/ordering/lib/ordering/events/order_rejected.rb b/ecommerce/ordering/lib/ordering/events/order_rejected.rb deleted file mode 100644 index 02cd44b60..000000000 --- a/ecommerce/ordering/lib/ordering/events/order_rejected.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Ordering - class OrderRejected < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/ordering/lib/ordering/events/order_submitted.rb b/ecommerce/ordering/lib/ordering/events/order_submitted.rb deleted file mode 100644 index 5ebd08e5c..000000000 --- a/ecommerce/ordering/lib/ordering/events/order_submitted.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Ordering - class OrderSubmitted < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :order_number, Infra::Types::OrderNumber - end -end diff --git a/ecommerce/ordering/lib/ordering/fake_number_generator.rb b/ecommerce/ordering/lib/ordering/fake_number_generator.rb deleted file mode 100644 index a25911d20..000000000 --- a/ecommerce/ordering/lib/ordering/fake_number_generator.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Ordering - class FakeNumberGenerator - FAKE_NUMBER = "2019/01/60".freeze - def call - FAKE_NUMBER - end - end -end diff --git a/ecommerce/ordering/lib/ordering/number_generator.rb b/ecommerce/ordering/lib/ordering/number_generator.rb deleted file mode 100644 index 48fd930c1..000000000 --- a/ecommerce/ordering/lib/ordering/number_generator.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Ordering - class NumberGenerator - def call - Time.now.strftime("%Y/%m/#{random_number}") - end - - private - - def random_number - SecureRandom.random_number(100) - end - end -end diff --git a/ecommerce/ordering/lib/ordering/order.rb b/ecommerce/ordering/lib/ordering/order.rb deleted file mode 100644 index b6ccdd0e9..000000000 --- a/ecommerce/ordering/lib/ordering/order.rb +++ /dev/null @@ -1,146 +0,0 @@ -module Ordering - class Order - include AggregateRoot - - InvalidState = Class.new(StandardError) - AlreadySubmitted = Class.new(InvalidState) - NotPlaced = Class.new(InvalidState) - OrderHasExpired = Class.new(InvalidState) - - def initialize(id) - @id = id - @state = State.draft - @basket = Basket.new - end - - def submit(order_number) - raise OrderHasExpired if @state.expired? - raise AlreadySubmitted unless @state.draft? - apply OrderSubmitted.new( - data: { - order_id: @id, - order_number: order_number, - order_lines: @basket.order_lines - } - ) - end - - def accept - raise InvalidState unless @state.submitted? - apply OrderPlaced.new( - data: { - order_id: @id, - order_number: @order_number, - order_lines: @basket.order_lines - } - ) - end - - def reject - raise InvalidState unless @state.submitted? - apply OrderRejected.new( - data: { - order_id: @id - } - ) - end - - def expire - raise AlreadySubmitted unless @state.draft? - apply OrderExpired.new(data: { order_id: @id }) - end - - def add_item(product_id) - raise AlreadySubmitted unless @state.draft? - apply ItemAddedToBasket.new( - data: { - order_id: @id, - product_id: product_id, - } - ) - end - - def remove_item(product_id) - raise AlreadySubmitted unless @state.draft? - apply ItemRemovedFromBasket.new(data: { order_id: @id, product_id: product_id }) - end - - on OrderPlaced do |_| - @state = State.new(:accepted) - end - - on OrderExpired do |_| - @state = State.expired - end - - on ItemAddedToBasket do |event| - @basket.increase_quantity(event.data[:product_id]) - end - - on ItemRemovedFromBasket do |event| - @basket.decrease_quantity(event.data[:product_id]) - end - - on OrderSubmitted do |event| - @order_number = event.data[:order_number] - @state = State.submitted - end - - on OrderRejected do |_| - @state = State.draft - end - - class Basket - def initialize - @order_lines = Hash.new(0) - end - - def increase_quantity(product_id) - order_lines[product_id] = quantity(product_id) + 1 - end - - def decrease_quantity(product_id) - order_lines[product_id] -= 1 - order_lines.delete(product_id) if order_lines.fetch(product_id).equal?(0) - end - - def order_lines - @order_lines - end - - def quantity(product_id) - order_lines[product_id] - end - end - - class State - def self.draft - new(:draft) - end - - def self.submitted - new(:submitted) - end - - def self.expired - new(:expired) - end - - def initialize(state) - @state = state - end - - def draft? - @state.equal?(:draft) - end - - def submitted? - @state.equal?(:submitted) - end - - def expired? - @state.equal?(:expired) - end - end - end -end diff --git a/ecommerce/ordering/lib/ordering/service.rb b/ecommerce/ordering/lib/ordering/service.rb deleted file mode 100644 index 4ab6dde83..000000000 --- a/ecommerce/ordering/lib/ordering/service.rb +++ /dev/null @@ -1,75 +0,0 @@ -module Ordering - class OnAddItemToBasket - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.add_item(command.product_id) - end - end - end - - class OnRemoveItemFromBasket - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.remove_item(command.product_id) - end - end - end - - class OnSetOrderAsExpired - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.expire - end - end - end - - class OnSubmitOrder - def initialize(event_store, number_generator) - @repository = Infra::AggregateRootRepository.new(event_store) - @number_generator = number_generator - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order_number = @number_generator.call - order.submit(order_number) - end - end - end - - class OnAcceptOrder - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.accept - end - end - end - - class OnRejectOrder - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Order, command.aggregate_id) do |order| - order.reject - end - end - end -end diff --git a/ecommerce/ordering/test/accept_order_test.rb b/ecommerce/ordering/test/accept_order_test.rb deleted file mode 100644 index 331343ee9..000000000 --- a/ecommerce/ordering/test/accept_order_test.rb +++ /dev/null @@ -1,54 +0,0 @@ -require_relative "test_helper" - -module Ordering - class AcceptOrderTest < Test - cover "Ordering::OnAcceptOrder*" - - def test_order_gets_accepted - aggregate_id = SecureRandom.uuid - stream = "Ordering::Order$#{aggregate_id}" - customer_id = SecureRandom.uuid - product_id = SecureRandom.uuid - order_number = FakeNumberGenerator::FAKE_NUMBER - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ), - SubmitOrder.new( - order_id: aggregate_id, - customer_id: customer_id - ) - ) - - assert_events( - stream, - OrderPlaced.new( - data: { - order_id: aggregate_id, - order_number: order_number, - order_lines: { product_id => 1 } - } - ) - ) do - act(AcceptOrder.new(order_id: aggregate_id)) - end - end - - def test_order_must_be_submitted_to_get_accepted - aggregate_id = SecureRandom.uuid - product_id = SecureRandom.uuid - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ) - ) - - assert_raises(Order::InvalidState) do - act(AcceptOrder.new(order_id: aggregate_id)) - end - end - end -end diff --git a/ecommerce/ordering/test/add_item_to_basket_test.rb b/ecommerce/ordering/test/add_item_to_basket_test.rb deleted file mode 100644 index d33ae672c..000000000 --- a/ecommerce/ordering/test/add_item_to_basket_test.rb +++ /dev/null @@ -1,49 +0,0 @@ -require_relative "test_helper" - -module Ordering - class AddItemToBasketTest < Test - cover "Ordering::OnAddItemToBasket*" - - def test_item_is_added_to_draft_order - aggregate_id = SecureRandom.uuid - stream = "Ordering::Order$#{aggregate_id}" - product_id = SecureRandom.uuid - - expected_events = [ - ItemAddedToBasket.new( - data: { - order_id: aggregate_id, - product_id: product_id, - } - ) - ] - assert_events(stream, *expected_events) do - act( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ) - ) - end - end - - def test_no_add_allowed_to_submitted_order - aggregate_id = SecureRandom.uuid - customer_id = SecureRandom.uuid - product_id = SecureRandom.uuid - order_number = FakeNumberGenerator::FAKE_NUMBER - - arrange( - AddItemToBasket.new(order_id: aggregate_id, product_id: product_id), - SubmitOrder.new( - order_id: aggregate_id, - order_number: order_number, - customer_id: customer_id - ) - ) - assert_raises(Order::AlreadySubmitted) do - act(AddItemToBasket.new(order_id: aggregate_id, product_id: product_id)) - end - end - end -end diff --git a/ecommerce/ordering/test/number_generator_test.rb b/ecommerce/ordering/test/number_generator_test.rb deleted file mode 100644 index 3d9c49de8..000000000 --- a/ecommerce/ordering/test/number_generator_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require_relative "test_helper" - -module Ordering - class NumberGeneratorTest < Test - def test_includes_year - assert_includes(NumberGenerator.new.call, "#{Time.now.year}") - end - - def test_includes_month - assert_includes(NumberGenerator.new.call, "#{Time.now.month}") - end - end -end diff --git a/ecommerce/ordering/test/order_test.rb b/ecommerce/ordering/test/order_test.rb deleted file mode 100644 index b398e0ae7..000000000 --- a/ecommerce/ordering/test/order_test.rb +++ /dev/null @@ -1,39 +0,0 @@ -require_relative "test_helper" - -module Ordering - class OrderTest < Test - cover "Ordering::Order" - - def setup - super - @order_id = SecureRandom.uuid - @product_id = SecureRandom.uuid - @customer_id = SecureRandom.uuid - end - - def test_order_lines_are_empty_after_adding_and_removing - order = Order.new(@order_id) - order.add_item(@product_id) - order.remove_item(@product_id) - order.submit(NumberGenerator.new.call) - assert_equal({}, order.unpublished_events.to_a.last.data[:order_lines]) - end - - def test_order_lines_with_the_same_product_twice - order = Order.new(@order_id) - order.add_item(@product_id) - order.add_item(@product_id) - order.submit(NumberGenerator.new.call) - assert_equal({ @product_id => 2 }, order.unpublished_events.to_a.last.data[:order_lines]) - end - - def test_order_lines_after_adding_twice_and_remove_once - order = Order.new(@order_id) - order.add_item(@product_id) - order.add_item(@product_id) - order.remove_item(@product_id) - order.submit(NumberGenerator.new.call) - assert_equal({ @product_id => 1 }, order.unpublished_events.to_a.last.data[:order_lines]) - end - end -end diff --git a/ecommerce/ordering/test/reject_order_test.rb b/ecommerce/ordering/test/reject_order_test.rb deleted file mode 100644 index bc813772d..000000000 --- a/ecommerce/ordering/test/reject_order_test.rb +++ /dev/null @@ -1,52 +0,0 @@ -require_relative "test_helper" - -module Ordering - class RejectOrderTest < Test - cover "Ordering::OnRejectOrder*" - - def test_order_gets_rejected - aggregate_id = SecureRandom.uuid - stream = "Ordering::Order$#{aggregate_id}" - customer_id = SecureRandom.uuid - product_id = SecureRandom.uuid - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ), - SubmitOrder.new( - order_id: aggregate_id, - customer_id: customer_id - ) - ) - - assert_events( - stream, - OrderRejected.new( - data: { - order_id: aggregate_id - } - ) - ) do - act(RejectOrder.new(order_id: aggregate_id)) - end - end - - def test_order_must_be_submitted_to_get_rejected - aggregate_id = SecureRandom.uuid - product_id = SecureRandom.uuid - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ) - ) - - assert_raises(Order::InvalidState) do - act(RejectOrder.new(order_id: aggregate_id)) - end - end - end -end diff --git a/ecommerce/ordering/test/remove_item_from_basket_test.rb b/ecommerce/ordering/test/remove_item_from_basket_test.rb deleted file mode 100644 index 2605eec69..000000000 --- a/ecommerce/ordering/test/remove_item_from_basket_test.rb +++ /dev/null @@ -1,53 +0,0 @@ -require_relative "test_helper" - -module Ordering - class RemoveItemFromBasketTest < Test - cover "Ordering::OnRemoveItemFromBasket*" - - def test_item_is_removed_from_draft_order - aggregate_id = SecureRandom.uuid - stream = "Ordering::Order$#{aggregate_id}" - - product_id = SecureRandom.uuid - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ) - ) - expected_events = [ - ItemRemovedFromBasket.new( - data: { - order_id: aggregate_id, - product_id: product_id - } - ) - ] - assert_events(stream, *expected_events) do - act( - RemoveItemFromBasket.new( - order_id: aggregate_id, - product_id: product_id - ) - ) - end - end - - def test_no_remove_allowed_to_created_order - aggregate_id = SecureRandom.uuid - customer_id = SecureRandom.uuid - product_id = SecureRandom.uuid - order_number = FakeNumberGenerator::FAKE_NUMBER - - arrange( - AddItemToBasket.new(order_id: aggregate_id, product_id: product_id), - SubmitOrder.new(order_id: aggregate_id, order_number: order_number, customer_id: customer_id) - ) - - assert_raises(Order::AlreadySubmitted) do - act(RemoveItemFromBasket.new(order_id: aggregate_id, product_id: product_id)) - end - end - end -end diff --git a/ecommerce/ordering/test/set_order_as_expired_test.rb b/ecommerce/ordering/test/set_order_as_expired_test.rb deleted file mode 100644 index 33d6cb410..000000000 --- a/ecommerce/ordering/test/set_order_as_expired_test.rb +++ /dev/null @@ -1,46 +0,0 @@ -require_relative "test_helper" - -module Ordering - class SetOrderAsExpiredTest < Test - cover "Ordering::OnSetOrderAsExpired*" - - def test_draft_order_will_expire - aggregate_id = SecureRandom.uuid - stream = "Ordering::Order$#{aggregate_id}" - product_id = SecureRandom.uuid - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ) - ) - - assert_events( - stream, - OrderExpired.new(data: { order_id: aggregate_id }) - ) { act(SetOrderAsExpired.new(order_id: aggregate_id)) } - end - - def test_submitted_order_will_not_expire - aggregate_id = SecureRandom.uuid - stream = "Ordering::Order$#{aggregate_id}" - product_id = SecureRandom.uuid - customer_id = SecureRandom.uuid - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ), - SubmitOrder.new( - order_id: aggregate_id, - order_number: "2018/12/1", - customer_id: customer_id - ) - ) - - assert_raises(Order::AlreadySubmitted) { act(SetOrderAsExpired.new(order_id: aggregate_id)) } - end - end -end diff --git a/ecommerce/ordering/test/submit_order_test.rb b/ecommerce/ordering/test/submit_order_test.rb deleted file mode 100644 index a9a579596..000000000 --- a/ecommerce/ordering/test/submit_order_test.rb +++ /dev/null @@ -1,75 +0,0 @@ -require_relative "test_helper" - -module Ordering - class SubmitOrderTest < Test - cover "Ordering::OnSubmitOrder*" - - def test_order_is_submitted - aggregate_id = SecureRandom.uuid - stream = "Ordering::Order$#{aggregate_id}" - product_id = SecureRandom.uuid - order_number = FakeNumberGenerator::FAKE_NUMBER - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ) - ) - - assert_events( - stream, - OrderSubmitted.new( - data: { - order_id: aggregate_id, - order_number: order_number, - order_lines: { product_id => 1 } - } - ) - ) do - act(SubmitOrder.new(order_id: aggregate_id)) - end - end - - def test_already_created_order_could_not_be_created_again - aggregate_id = SecureRandom.uuid - product_id = SecureRandom.uuid - order_number = FakeNumberGenerator::FAKE_NUMBER - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ), - SubmitOrder.new( - order_id: aggregate_id, - order_number: order_number, - ) - ) - - assert_raises(Order::AlreadySubmitted) do - act( - SubmitOrder.new( - order_id: aggregate_id - ) - ) - end - end - - def test_expired_order_could_not_be_created - aggregate_id = SecureRandom.uuid - product_id = SecureRandom.uuid - - arrange( - AddItemToBasket.new( - order_id: aggregate_id, - product_id: product_id - ), - SetOrderAsExpired.new(order_id: aggregate_id) - ) - - assert_raises(Order::OrderHasExpired) do - act(SubmitOrder.new(order_id: aggregate_id)) - end - end - end -end diff --git a/ecommerce/ordering/test/test_helper.rb b/ecommerce/ordering/test/test_helper.rb deleted file mode 100644 index 9097c977d..000000000 --- a/ecommerce/ordering/test/test_helper.rb +++ /dev/null @@ -1,14 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/ordering" - -module Ordering - class Test < Infra::InMemoryTest - def before_setup - super - number_generator = FakeNumberGenerator.new - Configuration.new(-> { number_generator }).call(event_store, command_bus) - end - end -end diff --git a/ecommerce/payments/.mutant.yml b/ecommerce/payments/.mutant.yml deleted file mode 100644 index 68e0d18f9..000000000 --- a/ecommerce/payments/.mutant.yml +++ /dev/null @@ -1,12 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Payments* - ignore: - - Payments::Payment#authorized? - - Payments::Test* - - Payments::Configuration#call diff --git a/ecommerce/payments/Gemfile b/ecommerce/payments/Gemfile deleted file mode 100644 index 00fef6d3c..000000000 --- a/ecommerce/payments/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" diff --git a/ecommerce/payments/Gemfile.lock b/ecommerce/payments/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/payments/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/payments/Makefile b/ecommerce/payments/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/payments/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/payments/README.md b/ecommerce/payments/README.md deleted file mode 100644 index 4dfa6901f..000000000 --- a/ecommerce/payments/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Payments - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/payments/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/payments.yml) - -The `Payments::Payment` aggregate manages the following states: - -- authorized -- captured -- released - -This Payment object is fully event sourced. - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/payments/lib/payments.rb b/ecommerce/payments/lib/payments.rb deleted file mode 100644 index bd6eb54de..000000000 --- a/ecommerce/payments/lib/payments.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "infra" -require_relative "payments/commands" -require_relative "payments/events" -require_relative "payments/on_set_payment_amount" -require_relative "payments/on_authorize_payment" -require_relative "payments/on_capture_payment" -require_relative "payments/on_release_payment" -require_relative "payments/fake_gateway" -require_relative "payments/payment" - -module Payments - class Configuration - def initialize(gateway) - @gateway = gateway - end - - def call(event_store, command_bus) - command_bus.register( - AuthorizePayment, - OnAuthorizePayment.new(event_store, @gateway) - ) - command_bus.register(CapturePayment, OnCapturePayment.new(event_store)) - command_bus.register(ReleasePayment, OnReleasePayment.new(event_store)) - command_bus.register(SetPaymentAmount, OnSetPaymentAmount.new(event_store)) - end - end -end diff --git a/ecommerce/payments/lib/payments/commands.rb b/ecommerce/payments/lib/payments/commands.rb deleted file mode 100644 index e6c1e086d..000000000 --- a/ecommerce/payments/lib/payments/commands.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Payments - class SetPaymentAmount < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :amount, Infra::Types::Nominal::Decimal - end - - class AuthorizePayment < Infra::Command - attribute :order_id, Infra::Types::UUID - end - - class CapturePayment < Infra::Command - attribute :order_id, Infra::Types::UUID - end - - class ReleasePayment < Infra::Command - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/payments/lib/payments/events.rb b/ecommerce/payments/lib/payments/events.rb deleted file mode 100644 index 322474e7d..000000000 --- a/ecommerce/payments/lib/payments/events.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Payments - class PaymentAmountSet < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :amount, Infra::Types::Nominal::Decimal - end - - class PaymentAuthorized < Infra::Event - attribute :order_id, Infra::Types::UUID - end - - class PaymentCaptured < Infra::Event - attribute :order_id, Infra::Types::UUID - end - - class PaymentReleased < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end diff --git a/ecommerce/payments/lib/payments/fake_gateway.rb b/ecommerce/payments/lib/payments/fake_gateway.rb deleted file mode 100644 index ba71d6b7e..000000000 --- a/ecommerce/payments/lib/payments/fake_gateway.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Payments - class FakeGateway - def initialize - @authorized_transactions = [] - end - - def reset - @authorized_transactions = [] - end - - def authorize_transaction(transaction_id, amount) - authorized_transactions << [transaction_id, amount] - end - - def authorized_transactions - @authorized_transactions - end - end -end diff --git a/ecommerce/payments/lib/payments/on_authorize_payment.rb b/ecommerce/payments/lib/payments/on_authorize_payment.rb deleted file mode 100644 index 182112e68..000000000 --- a/ecommerce/payments/lib/payments/on_authorize_payment.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Payments - class OnAuthorizePayment - def initialize(event_store, gateway) - @repository = AggregateRoot::Repository.new(event_store) - @gateway = gateway - end - - def call(command) - @repository.with_aggregate( - Payment.new, - "Payments::Payment$#{command.order_id}" - ) { |payment| payment.authorize(command.order_id, @gateway.call) } - end - end -end diff --git a/ecommerce/payments/lib/payments/on_capture_payment.rb b/ecommerce/payments/lib/payments/on_capture_payment.rb deleted file mode 100644 index 4fbe70cbf..000000000 --- a/ecommerce/payments/lib/payments/on_capture_payment.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Payments - class OnCapturePayment - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Payment.new, - "Payments::Payment$#{command.order_id}" - ) { |payment| payment.capture } - end - end -end diff --git a/ecommerce/payments/lib/payments/on_release_payment.rb b/ecommerce/payments/lib/payments/on_release_payment.rb deleted file mode 100644 index 15a3999c6..000000000 --- a/ecommerce/payments/lib/payments/on_release_payment.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Payments - class OnReleasePayment - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Payment.new, - "Payments::Payment$#{command.order_id}" - ) { |payment| payment.release } - end - end -end diff --git a/ecommerce/payments/lib/payments/on_set_payment_amount.rb b/ecommerce/payments/lib/payments/on_set_payment_amount.rb deleted file mode 100644 index 25f528c59..000000000 --- a/ecommerce/payments/lib/payments/on_set_payment_amount.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Payments - class OnSetPaymentAmount - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Payment.new, - "Payments::Payment$#{command.order_id}" - ) { |payment| payment.set_amount(command.order_id, command.amount) } - end - end -end diff --git a/ecommerce/payments/lib/payments/payment.rb b/ecommerce/payments/lib/payments/payment.rb deleted file mode 100644 index 2c43716ef..000000000 --- a/ecommerce/payments/lib/payments/payment.rb +++ /dev/null @@ -1,64 +0,0 @@ -module Payments - class Payment - include AggregateRoot - - AlreadyAuthorized = Class.new(StandardError) - NotAuthorized = Class.new(StandardError) - AlreadyCaptured = Class.new(StandardError) - AlreadyReleased = Class.new(StandardError) - - def set_amount(order_id, amount) - apply(PaymentAmountSet.new(data: { order_id: order_id, amount: amount })) - end - - def authorize(order_id, gateway) - raise AlreadyAuthorized if authorized? - gateway.authorize_transaction(order_id, @amount) - apply(PaymentAuthorized.new(data: { order_id: order_id })) - end - - def capture - raise AlreadyCaptured if captured? - raise NotAuthorized unless authorized? - apply(PaymentCaptured.new(data: { order_id: @order_id })) - end - - def release - raise AlreadyReleased if released? - raise AlreadyCaptured if captured? - raise NotAuthorized unless authorized? - apply(PaymentReleased.new(data: { order_id: @order_id })) - end - - private - - on PaymentAmountSet do |event| - @amount = event.data.fetch(:amount) - end - - on PaymentAuthorized do |event| - @state = :authorized - @order_id = event.data.fetch(:order_id) - end - - on PaymentCaptured do |event| - @state = :captured - end - - on PaymentReleased do |event| - @state = :released - end - - def authorized? - @state.equal?(:authorized) - end - - def captured? - @state.equal?(:captured) - end - - def released? - @state.equal?(:released) - end - end -end diff --git a/ecommerce/payments/test/fake_gateway_test.rb b/ecommerce/payments/test/fake_gateway_test.rb deleted file mode 100644 index 4010c5bd9..000000000 --- a/ecommerce/payments/test/fake_gateway_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require_relative "test_helper" - -module Payments - class FakeGatewayTest < Test - cover "Payments::FakeGateway*" - - def test_happy_path - gateway = FakeGateway.new - gateway.authorize_transaction("12", 20) - assert_equal([["12", 20]], gateway.authorized_transactions) - gateway.reset - assert_equal([], gateway.authorized_transactions) - end - end -end diff --git a/ecommerce/payments/test/on_capture_payment_test.rb b/ecommerce/payments/test/on_capture_payment_test.rb deleted file mode 100644 index 9ebca5ea0..000000000 --- a/ecommerce/payments/test/on_capture_payment_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -require_relative "test_helper" - -module Payments - class OnCapturePaymentTest < Test - cover "Payments::OnCapturePayment*" - - def test_capture_payment - order_id = SecureRandom.uuid - stream = "Payments::Payment$#{order_id}" - - arrange( - SetPaymentAmount.new(order_id: order_id, amount: 20), - AuthorizePayment.new(order_id: order_id) - ) - - assert_equal(20, payment_gateway.authorized_transactions[0][1]) - - assert_events( - stream, - PaymentCaptured.new(data: { order_id: order_id }) - ) { act(CapturePayment.new(order_id: order_id)) } - end - end -end diff --git a/ecommerce/payments/test/on_release_payment_test.rb b/ecommerce/payments/test/on_release_payment_test.rb deleted file mode 100644 index 5f5bf3f89..000000000 --- a/ecommerce/payments/test/on_release_payment_test.rb +++ /dev/null @@ -1,21 +0,0 @@ -require_relative "test_helper" - -module Payments - class OnReleasePaymentTest < Test - cover "Payments::OnReleasePayment*" - - def test_capture_payment - order_id = SecureRandom.uuid - stream = "Payments::Payment$#{order_id}" - - arrange( - AuthorizePayment.new(order_id: order_id) - ) - - assert_events( - stream, - PaymentReleased.new(data: { order_id: order_id }) - ) { act(ReleasePayment.new(order_id: order_id)) } - end - end -end diff --git a/ecommerce/payments/test/payment_test.rb b/ecommerce/payments/test/payment_test.rb deleted file mode 100644 index 3dfd77f6b..000000000 --- a/ecommerce/payments/test/payment_test.rb +++ /dev/null @@ -1,103 +0,0 @@ -require_relative "test_helper" - -module Payments - class PaymentTest < Test - cover "Payments::Payment*" - - def test_authorize_publishes_event - payment = Payment.new - gateway = FakeGateway.new - payment.set_amount(order_id, 20) - payment.authorize(order_id, gateway) - assert_changes( - payment.unpublished_events, - [ - PaymentAmountSet.new(data: { order_id: order_id, amount: 20 }), - PaymentAuthorized.new(data: { order_id: order_id }) - ] - ) - end - - def test_authorize_contacts_gateway - payment = Payment.new - gateway = FakeGateway.new - payment.set_amount(order_id, 20) - payment.authorize(order_id, gateway) - assert(gateway.authorized_transactions.include?([order_id, 20])) - end - - def test_should_not_allow_for_double_authorization - assert_raises(Payment::AlreadyAuthorized) do - authorized_payment.authorize(order_id, nil) - end - end - - def test_should_capture_authorized_payment - payment = authorized_payment - before = payment.unpublished_events.to_a - - payment.capture - actual = payment.unpublished_events.to_a - before - assert_changes( - actual, - [PaymentCaptured.new(data: { order_id: order_id })] - ) - end - - def test_must_not_capture_not_authorized_payment - assert_raises(Payment::NotAuthorized) { Payment.new.capture } - end - - def test_should_not_allow_for_double_capture - assert_raises(Payment::AlreadyCaptured) { captured_payment.capture } - end - - def test_authorization_could_be_released - payment = authorized_payment - before = payment.unpublished_events.to_a - - payment.release - actual = payment.unpublished_events.to_a - before - assert_changes( - actual, - [PaymentReleased.new(data: { order_id: order_id })] - ) - end - - def test_must_not_release_not_captured_payment - assert_raises(Payment::AlreadyCaptured) { captured_payment.release } - end - - def test_must_not_release_not_authorized_payment - assert_raises(Payment::NotAuthorized) { Payment.new.release } - end - - def test_should_not_allow_for_double_release - assert_raises(Payment::AlreadyReleased) { released_payment.release } - end - - private - - def order_id - @order_id ||= SecureRandom.uuid - end - - def authorized_payment - Payment.new.tap do |payment| - payment.apply(PaymentAuthorized.new(data: { order_id: order_id })) - end - end - - def captured_payment - authorized_payment.tap do |payment| - payment.apply(PaymentCaptured.new(data: { order_id: order_id })) - end - end - - def released_payment - captured_payment.tap do |payment| - payment.apply(PaymentReleased.new(data: { order_id: order_id })) - end - end - end -end diff --git a/ecommerce/payments/test/test_helper.rb b/ecommerce/payments/test/test_helper.rb deleted file mode 100644 index 5e21bf0ce..000000000 --- a/ecommerce/payments/test/test_helper.rb +++ /dev/null @@ -1,16 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/payments" - -module Payments - class Test < Infra::InMemoryTest - attr_reader :payment_gateway - - def before_setup - super - @payment_gateway = FakeGateway.new - Configuration.new(-> { @payment_gateway }).call(event_store, command_bus) - end - end -end diff --git a/ecommerce/pricing/.mutant.yml b/ecommerce/pricing/.mutant.yml deleted file mode 100644 index 26bd2ad34..000000000 --- a/ecommerce/pricing/.mutant.yml +++ /dev/null @@ -1,13 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Pricing* - ignore: - - Pricing::Configuration* - - Pricing::Test* - - Pricing::OnCalculateTotalValue#call - - Pricing::OnCalculateTotalValue#calculate_sub_amounts \ No newline at end of file diff --git a/ecommerce/pricing/Gemfile b/ecommerce/pricing/Gemfile deleted file mode 100644 index acd69f632..000000000 --- a/ecommerce/pricing/Gemfile +++ /dev/null @@ -1,8 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" - -group :test do - gem "timecop" -end diff --git a/ecommerce/pricing/Gemfile.lock b/ecommerce/pricing/Gemfile.lock deleted file mode 100644 index d7e4ebf47..000000000 --- a/ecommerce/pricing/Gemfile.lock +++ /dev/null @@ -1,121 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - timecop (0.9.8) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - timecop - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/pricing/Makefile b/ecommerce/pricing/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/pricing/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/pricing/README.md b/ecommerce/pricing/README.md deleted file mode 100644 index f323e315c..000000000 --- a/ecommerce/pricing/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Pricing - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/pricing/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/pricing.yml) - -The `Pricing::Coupon` aggregate manages the creation and usage of a coupon. This includes as of now: - -- registration - -After each successful action an appropriate event is published in the Coupon stream. - -| Command | Event | Service used to apply | -|:---------------:|:-----:|:----------------------| -| RegisterCoupon | CouponRegistered | OnCouponRegister | - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/pricing/lib/pricing.rb b/ecommerce/pricing/lib/pricing.rb deleted file mode 100644 index 789b5e0f6..000000000 --- a/ecommerce/pricing/lib/pricing.rb +++ /dev/null @@ -1,109 +0,0 @@ -require "infra" -require_relative "pricing/discounts" -require_relative "pricing/coupon" -require_relative "pricing/commands" -require_relative "pricing/events" -require_relative "pricing/services" -require_relative "pricing/offer" -require_relative "pricing/price_change" -require_relative "pricing/pricing_catalog" -require_relative "pricing/time_promotion" -require_relative "pricing/promotions_calendar" -require_relative "pricing/calculate_order_sub_amounts_value" -require_relative "pricing/calculate_order_total_value" - -module Pricing - def self.command_bus=(value) - @command_bus = value - end - - def self.command_bus - @command_bus - end - - def self.event_store=(value) - @event_store = value - end - - def self.event_store - @event_store - end - - class Configuration - def call(event_store, command_bus) - Pricing.event_store = event_store - Pricing.command_bus = command_bus - - command_bus.register( - AddPriceItem, - OnAddItemToBasket.new(event_store) - ) - command_bus.register( - RemovePriceItem, - OnRemoveItemFromBasket.new(event_store) - ) - command_bus.register( - SetPrice, - SetPriceHandler.new(event_store) - ) - command_bus.register( - SetFuturePrice, - SetFuturePriceHandler.new(event_store) - ) - command_bus.register( - CalculateTotalValue, - OnCalculateTotalValue.new(event_store) - ) - command_bus.register( - CalculateSubAmounts, - OnCalculateTotalValue.new(event_store).public_method(:calculate_sub_amounts) - ) - command_bus.register( - SetPercentageDiscount, - SetPercentageDiscountHandler.new(event_store) - ) - command_bus.register( - ResetPercentageDiscount, - ResetPercentageDiscountHandler.new(event_store) - ) - command_bus.register( - ChangePercentageDiscount, - ChangePercentageDiscountHandler.new(event_store) - ) - command_bus.register( - RegisterCoupon, - OnCouponRegister.new(event_store) - ) - command_bus.register( - CreateTimePromotion, - CreateTimePromotionHandler.new(event_store) - ) - command_bus.register( - MakeProductFreeForOrder, - MakeProductFreeForOrderHandler.new(event_store) - ) - command_bus.register( - RemoveFreeProductFromOrder, - RemoveFreeProductFromOrderHandler.new(event_store) - ) - event_store.subscribe(CalculateOrderTotalValue, to: [ - PriceItemAdded, - PriceItemRemoved, - PercentageDiscountSet, - PercentageDiscountReset, - PercentageDiscountChanged, - ProductMadeFreeForOrder, - FreeProductRemovedFromOrder - ]) - event_store.subscribe(CalculateOrderTotalSubAmountsValue, to: [ - PriceItemAdded, - PriceItemRemoved, - PercentageDiscountSet, - PercentageDiscountReset, - PercentageDiscountChanged, - ProductMadeFreeForOrder, - FreeProductRemovedFromOrder - ]) - end - end -end diff --git a/ecommerce/pricing/lib/pricing/calculate_order_sub_amounts_value.rb b/ecommerce/pricing/lib/pricing/calculate_order_sub_amounts_value.rb deleted file mode 100644 index aab491c25..000000000 --- a/ecommerce/pricing/lib/pricing/calculate_order_sub_amounts_value.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Pricing - class CalculateOrderTotalSubAmountsValue - def call(event) - command_bus.(CalculateSubAmounts.new(order_id: event.data.fetch(:order_id))) - end - - private - - def command_bus - Pricing.command_bus - end - end -end - diff --git a/ecommerce/pricing/lib/pricing/calculate_order_total_value.rb b/ecommerce/pricing/lib/pricing/calculate_order_total_value.rb deleted file mode 100644 index e09298c0a..000000000 --- a/ecommerce/pricing/lib/pricing/calculate_order_total_value.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Pricing - class CalculateOrderTotalValue - def call(event) - command_bus.(CalculateTotalValue.new(order_id: event.data.fetch(:order_id))) - end - - private - - def command_bus - Pricing.command_bus - end - end -end - diff --git a/ecommerce/pricing/lib/pricing/commands.rb b/ecommerce/pricing/lib/pricing/commands.rb deleted file mode 100644 index 596077c08..000000000 --- a/ecommerce/pricing/lib/pricing/commands.rb +++ /dev/null @@ -1,83 +0,0 @@ -module Pricing - class AddPriceItem < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end - - class RemovePriceItem < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end - - class CalculateTotalValue < Infra::Command - attribute :order_id, Infra::Types::UUID - alias aggregate_id order_id - end - - class CalculateSubAmounts < Infra::Command - attribute :order_id, Infra::Types::UUID - alias aggregate_id order_id - end - - class SetPrice < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :price, Infra::Types::Price - end - - class SetFuturePrice < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :price, Infra::Types::Price - attribute :valid_since, Infra::Types::Time - end - - class SetPercentageDiscount < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :amount, Infra::Types::PercentageDiscount - alias aggregate_id order_id - end - - class ResetPercentageDiscount < Infra::Command - attribute :order_id, Infra::Types::UUID - alias aggregate_id order_id - end - - class RegisterCoupon < Infra::Command - attribute :coupon_id, Infra::Types::UUID - attribute :name, Infra::Types::String - attribute :code, Infra::Types::String - attribute :discount, Infra::Types::CouponDiscount - alias aggregate_id coupon_id - end - - class CreateTimePromotion < Infra::Command - attribute :time_promotion_id, Infra::Types::UUID.meta(omittable: true) - attribute :discount, Infra::Types::PercentageDiscount - attribute :start_time, Infra::Types::Time - attribute :end_time, Infra::Types::Time - attribute :label, Infra::Types::String - end - - class ChangePercentageDiscount < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :amount, Infra::Types::PercentageDiscount - alias aggregate_id order_id - end - - class MakeProductFreeForOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end - - class RemoveFreeProductFromOrder < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/pricing/lib/pricing/coupon.rb b/ecommerce/pricing/lib/pricing/coupon.rb deleted file mode 100644 index 22c343f0a..000000000 --- a/ecommerce/pricing/lib/pricing/coupon.rb +++ /dev/null @@ -1,31 +0,0 @@ -require_relative 'events' - -module Pricing - class Coupon - include AggregateRoot - - AlreadyRegistered = Class.new(StandardError) - - def initialize(id) - @id = id - end - - def register(name, code, discount) - raise AlreadyRegistered if @registered - - apply CouponRegistered.new( - data: { - coupon_id: @id, - name: name, - code: code, - discount: discount - } - ) - end - - on CouponRegistered do |event| - @registered = true - end - end -end - diff --git a/ecommerce/pricing/lib/pricing/discounts.rb b/ecommerce/pricing/lib/pricing/discounts.rb deleted file mode 100644 index 8134c7edd..000000000 --- a/ecommerce/pricing/lib/pricing/discounts.rb +++ /dev/null @@ -1,64 +0,0 @@ -module Pricing - module Discounts - class UnacceptableDiscountRange < StandardError - end - - class Discount - def self.build(discount) - if discount.zero? - NoPercentageDiscount.new - else - PercentageDiscount.new(discount) - end - end - end - - class PercentageDiscount - attr_reader :value - - def initialize(value) - raise UnacceptableDiscountRange if value <= 0 - raise UnacceptableDiscountRange if value > 100 - - @value = value - end - - def apply(total) - total - discount(total) - end - - def add(other_discount) - new_value = [value + other_discount.value, 100].min - - PercentageDiscount.new(new_value) - end - - def exists? - true - end - - private - - def discount(total) - total * value / 100 - end - end - - class NoPercentageDiscount - def apply(total) - total - end - - def add(other_discount) - other_discount - end - - def value - 0 - end - - def exists? - end - end - end -end diff --git a/ecommerce/pricing/lib/pricing/events.rb b/ecommerce/pricing/lib/pricing/events.rb deleted file mode 100644 index 37e57a76e..000000000 --- a/ecommerce/pricing/lib/pricing/events.rb +++ /dev/null @@ -1,68 +0,0 @@ -module Pricing - class CouponRegistered < Infra::Event - attribute :coupon_id, Infra::Types::UUID - attribute :name, Infra::Types::String - attribute :code, Infra::Types::String - attribute :discount, Infra::Types::CouponDiscount - end - - class PriceSet < Infra::Event - attribute :product_id, Infra::Types::UUID - attribute :price, Infra::Types::Price - end - - class TimePromotionCreated < Infra::Event - attribute :time_promotion_id, Infra::Types::UUID - attribute? :discount, Infra::Types::PercentageDiscount - attribute? :start_time, Infra::Types::Time - attribute? :end_time, Infra::Types::Time - end - - class OrderTotalValueCalculated < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :discounted_amount, Infra::Types::Value - attribute :total_amount, Infra::Types::Value - end - - class PriceItemValueCalculated < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - attribute :quantity, Infra::Types::Quantity - attribute :discounted_amount, Infra::Types::Value - attribute :amount, Infra::Types::Value - end - - class PercentageDiscountSet < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :amount, Infra::Types::Price - end - - class PriceItemAdded < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end - - class PriceItemRemoved < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end - - class PercentageDiscountReset < Infra::Event - attribute :order_id, Infra::Types::UUID - end - - class PercentageDiscountChanged < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :amount, Infra::Types::Price - end - - class ProductMadeFreeForOrder < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end - - class FreeProductRemovedFromOrder < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end -end diff --git a/ecommerce/pricing/lib/pricing/offer.rb b/ecommerce/pricing/lib/pricing/offer.rb deleted file mode 100644 index 38b221441..000000000 --- a/ecommerce/pricing/lib/pricing/offer.rb +++ /dev/null @@ -1,251 +0,0 @@ -module Pricing - class Offer - include AggregateRoot - - def initialize(id) - @id = id - @list = List.new - @discount = Discounts::NoPercentageDiscount.new - end - - def add_item(product_id) - apply PriceItemAdded.new( - data: { - order_id: @id, - product_id: product_id - } - ) - end - - def remove_item(product_id) - apply PriceItemRemoved.new( - data: { - order_id: @id, - product_id: product_id - } - ) - end - - def apply_discount(discount) - raise NotPossibleToAssignDiscountTwice if @discount.exists? - apply PercentageDiscountSet.new( - data: { - order_id: @id, - amount: discount.value - } - ) - end - - def change_discount(discount) - raise NotPossibleToChangeDiscount unless @discount.exists? - apply PercentageDiscountChanged.new( - data: { - order_id: @id, - amount: discount.value - } - ) - end - - def reset_discount - raise NotPossibleToResetWithoutDiscount unless @discount.exists? - apply PercentageDiscountReset.new( - data: { - order_id: @id - } - ) - end - - def make_product_free(order_id, product_id) - raise FreeProductAlreadyMade if @list.contains_free_products? - apply ProductMadeFreeForOrder.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - end - - def remove_free_product(order_id, product_id) - raise FreeProductNotExists unless @list.contains_free_products? - apply FreeProductRemovedFromOrder.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - end - - def calculate_total_value(pricing_catalog, time_promotion_discount) - total_value = @list.base_sum(pricing_catalog) - - discounted_value = @discount.add(time_promotion_discount).apply(total_value) - apply( - OrderTotalValueCalculated.new( - data: { - order_id: @id, - total_amount: total_value, - discounted_amount: discounted_value - } - ) - ) - end - - def calculate_sub_amounts(pricing_catalog, time_promotions_discount) - sub_amounts_total = @list.sub_amounts_total(pricing_catalog) - sub_discounts = calculate_total_sub_discounts(pricing_catalog, time_promotions_discount) - - products = @list.products - quantities = @list.quantities - products.zip(quantities, sub_amounts_total, sub_discounts) do |product, quantity, sub_amount, sub_discount| - apply( - PriceItemValueCalculated.new( - data: { - order_id: @id, - product_id: product.id, - quantity: quantity, - amount: sub_amount, - discounted_amount: sub_amount - sub_discount - } - ) - ) - end - end - - private - - on PriceItemAdded do |event| - @list.add_item(Product.new(event.data.fetch(:product_id))) - end - - on PriceItemRemoved do |event| - @list.remove_item(event.data.fetch(:product_id)) - end - - on PriceItemValueCalculated do |event| - end - - on OrderTotalValueCalculated do |event| - end - - on PercentageDiscountSet do |event| - @discount = Discounts::PercentageDiscount.new(event.data.fetch(:amount)) - end - - on PercentageDiscountChanged do |event| - @discount = Discounts::PercentageDiscount.new(event.data.fetch(:amount)) - end - - on PercentageDiscountReset do |event| - @discount = Discounts::NoPercentageDiscount.new - end - - on ProductMadeFreeForOrder do |event| - @list.replace(Product, FreeProduct, event.data.fetch(:product_id)) - end - - on FreeProductRemovedFromOrder do |event| - @list.replace(FreeProduct, Product, event.data.fetch(:product_id)) - end - - def calculate_total_sub_discounts(pricing_catalog, time_promotions_discount) - @list.sub_discounts(pricing_catalog, time_promotions_discount, @discount) - end - - class List - - def initialize - @products_quantities = Hash.new(0) - end - - def add_item(product) - @products_quantities[product] += 1 - end - - def remove_item(product_id) - @products_quantities[Product.new(product_id)] -= 1 - clear_empty_products - end - - def clear_empty_products - @products_quantities.delete_if { |_, value| value.zero? } - end - - def replace(from, to, product_id) - @products_quantities[from.new(product_id)] -= 1 - @products_quantities[to.new(product_id)] += 1 - clear_empty_products - end - - def products - @products_quantities.keys - end - - def quantities - @products_quantities.values - end - - def contains_free_products? - @products_quantities.keys.any? {|key| key.free? } - end - - def base_sum(pricing_catalog) - @products_quantities.sum { |product, qty| pricing_catalog.price_for(product) * qty } - end - - def sub_amounts_total(pricing_catalog) - @products_quantities.map { |product, quantity| quantity * pricing_catalog.price_for(product) } - end - - def sub_discounts(pricing_catalog, time_promotions_discount, discount) - @products_quantities.map do |product, quantity| - catalog_price_for_single = pricing_catalog.price_for(product) - with_total_discount_single = discount.add(time_promotions_discount).apply(catalog_price_for_single) - quantity * (catalog_price_for_single - with_total_discount_single) - end - end - end - - class Product - attr_reader :id - - def initialize(id) - @id = id - end - - def free? - end - - def eql?(other) - other.instance_of?(Product) && id.eql?(other.id) - end - - alias == eql? - - def hash - Product.hash ^ id.hash - end - end - - class FreeProduct - attr_reader :id - - def initialize(id) - @id = id - end - - def free? - true - end - - def eql?(other) - other.instance_of?(FreeProduct) && id.eql?(other.id) - end - - alias == eql? - - def hash - FreeProduct.hash ^ id.hash - end - end - end -end diff --git a/ecommerce/pricing/lib/pricing/price_change.rb b/ecommerce/pricing/lib/pricing/price_change.rb deleted file mode 100644 index 5bfa92db1..000000000 --- a/ecommerce/pricing/lib/pricing/price_change.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Pricing - class PriceChange - include AggregateRoot - - def initialize(product_id) - @product_id = product_id - end - - def set_price(price) - apply(PriceSet.new(data: { product_id: @product_id, price: price })) - end - - private - - on(PriceSet) { |_| } - end -end diff --git a/ecommerce/pricing/lib/pricing/pricing_catalog.rb b/ecommerce/pricing/lib/pricing/pricing_catalog.rb deleted file mode 100644 index f2b8f53d5..000000000 --- a/ecommerce/pricing/lib/pricing/pricing_catalog.rb +++ /dev/null @@ -1,59 +0,0 @@ -module Pricing - class PricingCatalog - def initialize(event_store) - @event_store = event_store - end - - def price_for(product) - case product - when Offer::FreeProduct - 0 - else - price_by_product_id(product.id) - end - end - - def price_by_product_id(product_id) - current_price(product_id) - .data - .fetch(:price) - end - - def current_prices_catalog_by_product_id(product_id) - ([current_price(product_id)] + future_prices_catalog_by_product_id(product_id)).map(&method(:to_calendar_entry)) - end - - private - - def future_prices_catalog_by_product_id(product_id) - read_prices_set(product_id) - .select(&method(:future_prices)) - end - - def current_price(product_id) - read_prices_set(product_id) - .reject(&method(:future_prices)) - .last - end - - def read_prices_set(product_id) - @event_store - .read - .of_type(PriceSet) - .as_of - .to_a - .filter { |e| e.data.fetch(:product_id).eql?(product_id) } - end - - def future_prices(e) - e.metadata.fetch(:valid_at) > Time.now - end - - def to_calendar_entry(e) - { - price: e.data.fetch(:price), - valid_since: e.metadata.fetch(:valid_at) - } - end - end -end diff --git a/ecommerce/pricing/lib/pricing/promotions_calendar.rb b/ecommerce/pricing/lib/pricing/promotions_calendar.rb deleted file mode 100644 index 8c82a3f21..000000000 --- a/ecommerce/pricing/lib/pricing/promotions_calendar.rb +++ /dev/null @@ -1,40 +0,0 @@ -module Pricing - class PromotionsCalendar - def initialize(event_store) - @event_store = event_store - end - - def current_time_promotions_discount - Discounts::Discount.build( - get_events(TimePromotionCreated) - .filter { |e| current_promotions.include?(e.data.fetch(:time_promotion_id)) } - .map { |e| e.data.fetch(:discount) }.sum - ) - end - - private - - def current_promotions - get_events(TimePromotionCreated) - .filter { |e| is_promotion_running?(e) } - .map { |e| e.data.fetch(:time_promotion_id) } - end - - def is_promotion_running?(event) - timestamp = Time.current - start_time = event.data.fetch(:start_time) - end_time = event.data.fetch(:end_time) - - timestamp >= start_time && end_time > timestamp - end - - def get_events(event_type) - @event_store - .read - .of_type(event_type) - .to_a - .group_by { |e| e.data.fetch(:time_promotion_id) } - .map { |_, events| events.max_by(&:timestamp) } - end - end -end diff --git a/ecommerce/pricing/lib/pricing/services.rb b/ecommerce/pricing/lib/pricing/services.rb deleted file mode 100644 index 1ac73249f..000000000 --- a/ecommerce/pricing/lib/pricing/services.rb +++ /dev/null @@ -1,183 +0,0 @@ -module Pricing - class NotPossibleToAssignDiscountTwice < StandardError - end - - class NotPossibleToResetWithoutDiscount < StandardError - end - - class NotPossibleToChangeDiscount < StandardError - end - - class FreeProductAlreadyMade < StandardError - end - - class FreeProductNotExists < StandardError - end - - class SetPercentageDiscountHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(cmd) - @repository.with_aggregate(Offer, cmd.aggregate_id) do |order| - order.apply_discount(Discounts::PercentageDiscount.new(cmd.amount)) - end - end - end - - class ResetPercentageDiscountHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(cmd) - @repository.with_aggregate(Offer, cmd.aggregate_id) do |order| - order.reset_discount - end - end - end - - class ChangePercentageDiscountHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(cmd) - @repository.with_aggregate(Offer, cmd.aggregate_id) do |order| - order.change_discount(Discounts::PercentageDiscount.new(cmd.amount)) - end - end - end - - class SetPriceHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(cmd) - @repository.with_aggregate(PriceChange, cmd.product_id) do |product| - product.set_price(cmd.price) - end - end - end - - class SetFuturePriceHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - @event_store = event_store - end - - def call(cmd) - @event_store.with_metadata({ valid_at: cmd.valid_since }) do - @repository.with_aggregate(PriceChange, cmd.product_id) do |product| - product.set_price(cmd.price) - end - end - end - end - - class CreateTimePromotionHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(cmd) - @repository.with_aggregate(TimePromotion, cmd.time_promotion_id) do |time_promotion| - time_promotion.create(cmd.discount, cmd.start_time, cmd.end_time, cmd.label) - end - end - end - - class OnAddItemToBasket - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Offer, command.aggregate_id) do |order| - order.add_item(command.product_id) - end - end - end - - class OnRemoveItemFromBasket - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Offer, command.aggregate_id) do |order| - order.remove_item(command.product_id) - end - end - end - - class OnCalculateTotalValue - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - @event_store = event_store - end - - def call(command) - @repository.with_aggregate(Offer, command.aggregate_id) do |order| - order.calculate_total_value(PricingCatalog.new(@event_store), time_promotions_discount) - end - rescue RubyEventStore::WrongExpectedEventVersion - retry - end - - - - def calculate_sub_amounts(command) - @repository.with_aggregate(Offer, command.aggregate_id) do |order| - order.calculate_sub_amounts(PricingCatalog.new(@event_store), time_promotions_discount) - end - rescue RubyEventStore::WrongExpectedEventVersion - retry - end - - private - - def time_promotions_discount - PromotionsCalendar.new(@event_store).current_time_promotions_discount - end - - end - - class OnCouponRegister - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Coupon, command.aggregate_id) do |coupon| - coupon.register(command.name, command.code, command.discount) - end - end - end - - class MakeProductFreeForOrderHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Offer, command.aggregate_id) do |order| - order.make_product_free(command.order_id, command.product_id) - end - end - end - - class RemoveFreeProductFromOrderHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(command) - @repository.with_aggregate(Offer, command.aggregate_id) do |order| - order.remove_free_product(command.order_id, command.product_id) - end - end - end -end diff --git a/ecommerce/pricing/lib/pricing/time_promotion.rb b/ecommerce/pricing/lib/pricing/time_promotion.rb deleted file mode 100644 index 4f1ee9d19..000000000 --- a/ecommerce/pricing/lib/pricing/time_promotion.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Pricing - class TimePromotion - include AggregateRoot - - def initialize(id) - @id = id - end - - def create(discount, start_time, end_time, label) - apply TimePromotionCreated.new( - data: { - time_promotion_id: @id, - discount: discount, - start_time: start_time, - end_time: end_time, - label: label - } - ) - end - - private - - on TimePromotionCreated do |_| - end - - end -end diff --git a/ecommerce/pricing/test/coupons_test.rb b/ecommerce/pricing/test/coupons_test.rb deleted file mode 100644 index b8c7a158e..000000000 --- a/ecommerce/pricing/test/coupons_test.rb +++ /dev/null @@ -1,40 +0,0 @@ -require_relative "test_helper" - -module Pricing - class CouponsTest < Test - cover "Pricing::Coupon*" - - def setup - @uid = SecureRandom.uuid - @code = fake_name.chars.shuffle.join - @discount = 10 - @data = { coupon_id: @uid, name: fake_name, code: @code, discount: @discount } - end - - def test_coupon_should_get_registered - register_coupon(@uid, fake_name, @code, rand(1..20)) - end - - def test_should_not_allow_for_id_based_duplicates - assert_raises(Pricing::Coupon::AlreadyRegistered) do - register_coupon(@uid, fake_name, @code, @discount) - register_coupon(@uid, fake_name, @code, @discount) - end - end - - def test_should_publish_event - coupon_registered = CouponRegistered.new(data: @data) - assert_events("Pricing::Coupon$#{@uid}", coupon_registered) do - register_coupon(@uid, fake_name, @code, @discount) - end - end - - def test_100_is_ok - register_coupon(@uid, fake_name, @code, 100) - end - - def test_0_01_is_ok - register_coupon(@uid, fake_name, @code, 0.01) - end - end -end diff --git a/ecommerce/pricing/test/discounts_test.rb b/ecommerce/pricing/test/discounts_test.rb deleted file mode 100644 index b7387cc70..000000000 --- a/ecommerce/pricing/test/discounts_test.rb +++ /dev/null @@ -1,68 +0,0 @@ -require_relative "test_helper" - -module Pricing - module Discounts - - class PercentageDiscountTest < Test - cover "Pricing::Discounts*" - - def test_is_more_than_zero - assert_raises UnacceptableDiscountRange do - PercentageDiscount.new(0) - end - end - - def test_is_not_lower_than_0 - assert_raises UnacceptableDiscountRange do - PercentageDiscount.new(-0.01) - end - end - - def test_is_not_more_than_100_percent - assert_raises UnacceptableDiscountRange do - PercentageDiscount.new(100.01) - end - end - - def test_100_is_ok - PercentageDiscount.new(100) - end - - def test_0_01_is_ok - PercentageDiscount.new(0.01) - end - - def test_applies_to_value - assert_equal(90, PercentageDiscount.new(10).apply(100)) - end - - def test_calculates_floats_too - assert_equal(90.45, PercentageDiscount.new(10).apply(100.50)) - end - - def test_can_add_another_discount - first_discount = PercentageDiscount.new(20) - second_discount = PercentageDiscount.new(15) - combined = first_discount.add(second_discount) - - assert_equal(65, combined.apply(100)) - end - - def test_cannot_add_to_more_than_100 - first_discount = PercentageDiscount.new(50) - second_discount = PercentageDiscount.new(65) - combined = first_discount.add(second_discount) - - assert_equal(0, combined.apply(100)) - end - end - - class NoPercentageDiscountTest < Test - cover "Pricing::Discounts*" - - def test_doesnt_change_total - assert_equal(100, NoPercentageDiscount.new.apply(100)) - end - end - end -end diff --git a/ecommerce/pricing/test/free_products_test.rb b/ecommerce/pricing/test/free_products_test.rb deleted file mode 100644 index 1982a96d1..000000000 --- a/ecommerce/pricing/test/free_products_test.rb +++ /dev/null @@ -1,217 +0,0 @@ -require_relative "test_helper" - -module Pricing - class FreeProductsTest < Test - cover "Pricing*" - - def test_making_product_free_possible_when_order_is_eligible - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - - assert_events_contain( - stream_name(order_id), - ProductMadeFreeForOrder.new( - data: { - order_id: order_id, - product_id: product_1_id - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 60, - total_amount: 60 - } - ) - ) do - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_1_id) - ) - end - end - - def test_making_only_the_cheapest_product_free - product_1_id = SecureRandom.uuid - cheaper_product = SecureRandom.uuid - set_price(product_1_id, 20) - set_price(cheaper_product, 10) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, cheaper_product) - - assert_events_contain( - stream_name(order_id), - ProductMadeFreeForOrder.new( - data: { - order_id: order_id, - product_id: cheaper_product - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 60, - total_amount: 60 - } - ), - ) do - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: cheaper_product) - ) - end - end - - def test_making_product_free_not_possible_if_is_already_set - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_1_id) - ) - - assert_raises FreeProductAlreadyMade do - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_1_id) - ) - end - end - - def test_making_product_free_possible_after_previous_free_product_was_removed - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_1_id) - ) - - run_command( - Pricing::RemovePriceItem.new(order_id: order_id, product_id: product_1_id) - ) - - run_command( - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_1_id) - ) - - run_command( - Pricing::AddPriceItem.new(order_id: order_id, product_id: product_1_id) - ) - - assert_events_contain( - stream_name(order_id), - ProductMadeFreeForOrder.new( - data: { - order_id: order_id, - product_id: product_1_id - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 60, - total_amount: 60 - } - ) - ) do - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_1_id) - ) - end - end - - def test_removing_free_product_possible_if_it_is_already_set - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_1_id) - ) - - assert_events_contain( - stream_name(order_id), - FreeProductRemovedFromOrder.new( - data: { - order_id: order_id, - product_id: product_1_id - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 80, - total_amount: 80 - } - ) - ) do - run_command( - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_1_id) - ) - end - end - - def test_removing_free_product_not_possible_if_is_not_set - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - - assert_raises FreeProductNotExists do - run_command( - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_1_id) - ) - end - end - - def test_removing_free_product_twice_not_possible - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - add_item(order_id, product_1_id) - - run_command( - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_1_id) - ) - - run_command( - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_1_id) - ) - - assert_raises FreeProductNotExists do - run_command( - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_1_id) - ) - end - end - - private - - def stream_name(id) - "Pricing::Offer$#{id}" - end - - end -end diff --git a/ecommerce/pricing/test/future_prices_test.rb b/ecommerce/pricing/test/future_prices_test.rb deleted file mode 100644 index a1e271b17..000000000 --- a/ecommerce/pricing/test/future_prices_test.rb +++ /dev/null @@ -1,125 +0,0 @@ -require_relative "test_helper" - -module Pricing - class FuturePricesTest < Test - cover "Pricing*" - - def test_future_price_is_not_included_when_calculating_total_value - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - future_date_timestamp = Time.current + days_number(5) - set_future_price(product_1_id, 30, future_date_timestamp) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 20, - total_amount: 20 - } - ) - ) { calculate_total_value(order_id) } - end - - def test_check_future_price - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - future_date_timestamp = Time.current + days_number(5) - set_future_price(product_1_id, 30, future_date_timestamp) - - Timecop.travel(future_date_timestamp + 2137) do - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 30, - total_amount: 30 - } - ) - ) { calculate_total_value(order_id) } - end - end - - def test_future_prices_catalog_by_product_id - product_id = SecureRandom.uuid - set_price(product_id, 20) - future_date_timestamp_1 = with_precision(Time.current + days_number(2)) - future_date_timestamp_2 = with_precision(Time.current + days_number(3)) - future_date_timestamp_3 = with_precision(Time.current + days_number(4)) - - set_future_price(product_id, 30, future_date_timestamp_3) - set_future_price(product_id, 40, future_date_timestamp_1) - set_future_price(product_id, 50, future_date_timestamp_2) - - pricing_catalog = PricingCatalog.new(event_store) - - assert_equal 20, pricing_catalog.price_by_product_id(product_id) - - assert_equal [ - BigDecimal(20), - BigDecimal(40), - BigDecimal(50), - BigDecimal(30) - ], pricing_catalog.current_prices_catalog_by_product_id(product_id).map { |entry| entry[:price] } - - Timecop.travel(future_date_timestamp_1 + 1.second) do - assert_equal [ - BigDecimal(40), - BigDecimal(50), - BigDecimal(30) - ], pricing_catalog.current_prices_catalog_by_product_id(product_id).map { |entry| entry[:price] } - assert_equal [ - future_date_timestamp_1, - future_date_timestamp_2, - future_date_timestamp_3, - ], pricing_catalog.current_prices_catalog_by_product_id(product_id).map { |entry| entry[:valid_since] } - assert_equal BigDecimal(40), pricing_catalog.price_by_product_id(product_id) - end - - Timecop.travel(future_date_timestamp_2 + 1.second) do - assert_equal [ - BigDecimal(50), - BigDecimal(30) - ], pricing_catalog.current_prices_catalog_by_product_id(product_id).map { |entry| entry[:price] } - assert_equal [ - future_date_timestamp_2, - future_date_timestamp_3, - ], pricing_catalog.current_prices_catalog_by_product_id(product_id).map { |entry| entry[:valid_since] } - assert_equal BigDecimal(50), pricing_catalog.price_by_product_id(product_id) - end - - - pricing_catalog = PricingCatalog.new(event_store) - Timecop.travel(future_date_timestamp_3 + 1.second) do - assert_equal [BigDecimal(30)], pricing_catalog.current_prices_catalog_by_product_id(product_id).map { |entry| entry[:price] } - assert_equal [ - future_date_timestamp_3 - ], pricing_catalog.current_prices_catalog_by_product_id(product_id).map { |entry| entry[:valid_since] } - assert_equal BigDecimal(30), pricing_catalog.price_by_product_id(product_id) - end - end - - private - - def stream_name(order_id) - "Pricing::Offer$#{order_id}" - end - - def days_number(n) - 3600 * 24 * n - end - - def with_precision(time) - time.round(6) - end - end -end diff --git a/ecommerce/pricing/test/order_product_test.rb b/ecommerce/pricing/test/order_product_test.rb deleted file mode 100644 index 2d9f34d8d..000000000 --- a/ecommerce/pricing/test/order_product_test.rb +++ /dev/null @@ -1,47 +0,0 @@ -require_relative "test_helper" - -module Pricing - class Offer - class ProductTest < Test - cover "Pricing::Offer::Product" - - def setup - super - @id = SecureRandom.uuid - end - - def test_values_equality - refute(Product.new(@id).eql?(FreeProduct.new(@id))) - refute(Product.new(@id).eql?(Product.new(SecureRandom.uuid))) - refute(Product.new(@id).eql?(@id)) - end - - def test_hash_equality - assert(Product.new(@id).hash.eql?(Product.hash ^ @id.hash)) - refute(Product.new(@id).hash.eql?(Product.hash ^ SecureRandom.uuid.hash)) - refute(Product.new(@id).hash == @id.hash) - end - end - - class FreeProductTest < Test - cover "Pricing::Offer::FreeProduct" - - def setup - super - @id = SecureRandom.uuid - end - - def test_values_equality - refute(FreeProduct.new(@id).eql?(Product.new(@id))) - refute(FreeProduct.new(@id).eql?(FreeProduct.new(SecureRandom.uuid))) - refute(FreeProduct.new(@id).eql?(@id)) - end - - def test_hash_equality - assert(FreeProduct.new(@id).hash.eql?(FreeProduct.hash ^ @id.hash)) - refute(FreeProduct.new(@id).hash.eql?(FreeProduct.hash ^ SecureRandom.uuid.hash)) - refute(FreeProduct.new(@id).hash == @id.hash) - end - end - end -end diff --git a/ecommerce/pricing/test/pricing_test.rb b/ecommerce/pricing/test/pricing_test.rb deleted file mode 100644 index 14f2326e3..000000000 --- a/ecommerce/pricing/test/pricing_test.rb +++ /dev/null @@ -1,401 +0,0 @@ -require_relative "test_helper" - -module Pricing - class PricingTest < Test - cover "Pricing*" - - def test_configuration - Pricing.event_store = Infra::EventStore.in_memory - Pricing.event_store = Infra::CommandBus - - assert Pricing.event_store, Infra::EventStore.in_memory - assert Pricing.command_bus, Infra::CommandBus - end - - def test_calculates_total_value - product_1_id = SecureRandom.uuid - product_2_id = SecureRandom.uuid - set_price(product_1_id, 20) - set_price(product_2_id, 30) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - add_item(order_id, product_2_id) - stream = stream_name(order_id) - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 50, - total_amount: 50 - } - ) - ) { calculate_total_value(order_id) } - end - - def test_calculates_sub_amounts - product_1_id = SecureRandom.uuid - product_2_id = SecureRandom.uuid - set_price(product_1_id, 20) - set_price(product_2_id, 30) - order_id = SecureRandom.uuid - stream = stream_name(order_id) - - assert_events(stream) { calculate_sub_amounts(order_id) } - - add_item(order_id, product_1_id) - add_item(order_id, product_2_id) - add_item(order_id, product_2_id) - assert_events( - stream, - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_1_id, - quantity: 1, - amount: 20, - discounted_amount: 20 - } - ), - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_2_id, - quantity: 2, - amount: 60, - discounted_amount: 60 - } - ) - ) { calculate_sub_amounts(order_id) } - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - assert_events( - stream, - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_1_id, - quantity: 1, - amount: 20, - discounted_amount: 18 - } - ), - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_2_id, - quantity: 2, - amount: 60, - discounted_amount: 54 - } - ) - ) { calculate_sub_amounts(order_id) } - end - - def test_calculates_total_value_with_discount - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 20, - total_amount: 20 - } - ) - ) { run_command(CalculateTotalValue.new(order_id: order_id)) } - assert_events_contain( - stream, - PercentageDiscountSet.new( - data: { - order_id: order_id, - amount: 10 - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 18, - total_amount: 20 - } - ) - ) do - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - end - assert_events_contain( - stream, - PercentageDiscountChanged.new( - data: { - order_id: order_id, - amount: 50 - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 10, - total_amount: 20 - } - ) - ) do - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 50) - ) - end - assert_events_contain( - stream, - PercentageDiscountReset.new( - data: { - order_id: order_id, - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 20, - total_amount: 20 - } - ) - ) do - run_command( - Pricing::ResetPercentageDiscount.new(order_id: order_id) - ) - end - end - - def test_calculates_total_value_with_100_discount - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - assert_events_contain( - stream, - PercentageDiscountSet.new( - data: { - order_id: order_id, - amount: 100 - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 0, - total_amount: 20 - } - ) - ) do - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 100) - ) - end - end - - def test_setting_discounts_twice_not_possible_because_we_want_explicit_discount_change_command - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - assert_raises NotPossibleToAssignDiscountTwice do - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 20) - ) - end - end - - def test_setting_discount_not_possible_when_discount_has_been_set_and_then_changed - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 20) - ) - - assert_raises NotPossibleToAssignDiscountTwice do - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 20) - ) - end - end - - def test_changing_discount_not_possible_when_discount_is_not_set - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - - assert_raises NotPossibleToChangeDiscount do - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 20) - ) - end - end - - def test_changing_discount_not_possible_when_discount_is_reset - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - run_command( - Pricing::ResetPercentageDiscount.new(order_id: order_id) - ) - - assert_raises NotPossibleToChangeDiscount do - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 20) - ) - end - end - - def test_changing_discount_possible_when_discount_is_set - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - - assert_events_contain( - stream, - PercentageDiscountChanged.new( - data: { - order_id: order_id, - amount: 100 - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 0, - total_amount: 20 - } - ) - ) do - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 100) - ) - end - end - - def test_changing_discount_possible_more_than_once - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 20) - ) - - assert_events_contain( - stream, - PercentageDiscountChanged.new( - data: { - order_id: order_id, - amount: 100 - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 0, - total_amount: 20 - } - ) - ) do - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 100) - ) - end - end - - def test_resetting_discount_possible_when_discount_has_been_set_and_then_changed - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - run_command( - Pricing::ChangePercentageDiscount.new(order_id: order_id, amount: 20) - ) - - assert_events_contain( - stream, - PercentageDiscountReset.new( - data: { - order_id: order_id - } - ), - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 20, - total_amount: 20 - } - ) - ) do - run_command( - Pricing::ResetPercentageDiscount.new(order_id: order_id) - ) - end - end - - def test_resetting_with_missing_discount_not_possible - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - assert_raises NotPossibleToResetWithoutDiscount do - run_command( - Pricing::ResetPercentageDiscount.new(order_id: order_id) - ) - end - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - run_command( - Pricing::ResetPercentageDiscount.new(order_id: order_id) - ) - assert_raises NotPossibleToResetWithoutDiscount do - run_command( - Pricing::ResetPercentageDiscount.new(order_id: order_id) - ) - end - end - - private - - def stream_name(order_id) - "Pricing::Offer$#{order_id}" - end - - def calculate_sub_amounts(order_id) - run_command(CalculateSubAmounts.new(order_id: order_id)) - end - end -end diff --git a/ecommerce/pricing/test/product_test.rb b/ecommerce/pricing/test/product_test.rb deleted file mode 100644 index 3217d590b..000000000 --- a/ecommerce/pricing/test/product_test.rb +++ /dev/null @@ -1,33 +0,0 @@ -require_relative "test_helper" - -module Pricing - class ProductTest < Test - cover "Pricing::Product*" - - def test_product_price_is_set - product_id = SecureRandom.uuid - - set_price(product_id, 20) - end - - def test_set_future_price - product_id = SecureRandom.uuid - valid_since = 2.days.from_now - price = 20 - - future_price_set = [ - PriceSet.new(data: { product_id: product_id, price: price }), - ] - - assert_events("Pricing::PriceChange$#{product_id}", *future_price_set) do - set_future_price(product_id, price, valid_since) - end - end - - private - - def set_price(product_id, amount) - run_command(SetPrice.new(product_id: product_id, price: amount)) - end - end -end diff --git a/ecommerce/pricing/test/simple_offer_test.rb b/ecommerce/pricing/test/simple_offer_test.rb deleted file mode 100644 index a8dd80eb2..000000000 --- a/ecommerce/pricing/test/simple_offer_test.rb +++ /dev/null @@ -1,36 +0,0 @@ -require_relative "test_helper" - -module Pricing - class SimpleOfferTest < Test - cover "Pricing*" - - def test_removing - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = "Pricing::Offer$#{order_id}" - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 20, - total_amount: 20 - } - ) - ) { calculate_total_value(order_id) } - remove_item(order_id, product_1_id) - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 0, - total_amount: 0 - } - ) - ) { calculate_total_value(order_id) } - end - end -end diff --git a/ecommerce/pricing/test/subamounts_test.rb b/ecommerce/pricing/test/subamounts_test.rb deleted file mode 100644 index 8328e37df..000000000 --- a/ecommerce/pricing/test/subamounts_test.rb +++ /dev/null @@ -1,41 +0,0 @@ -require_relative "test_helper" - -module Pricing - class SubAmounts < Test - - def test_calculates_sub_amounts - set_price(product_id, 20) - - assert_events_contain(stream, price_item_value_calculated_event(20, 20)) do - add_item(order_id, product_id) - end - end - - private - - def price_item_value_calculated_event(amount, discounted_amount) - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_id, - quantity: 1, - discounted_amount: discounted_amount, - amount: amount - } - ) - end - - def stream - "Pricing::Offer$#{order_id}" - end - - def product_id - @product_id ||= SecureRandom.uuid - end - - def order_id - @order_id ||= SecureRandom.uuid - end - - end -end diff --git a/ecommerce/pricing/test/test_helper.rb b/ecommerce/pricing/test/test_helper.rb deleted file mode 100644 index eb9e385f5..000000000 --- a/ecommerce/pricing/test/test_helper.rb +++ /dev/null @@ -1,49 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" -require "active_support/all" - -require_relative "../lib/pricing" - -module Pricing - class Test < Infra::InMemoryTest - - def before_setup - super - Configuration.new.call(event_store, command_bus) - end - - private - - def set_price(product_id, amount) - run_command(SetPrice.new(product_id: product_id, price: amount)) - end - - def set_future_price(product_id, amount, valid_since) - run_command(SetFuturePrice.new(product_id: product_id, price: amount, valid_since: valid_since)) - end - - def calculate_total_value(order_id) - run_command(CalculateTotalValue.new(order_id: order_id)) - end - - def add_item(order_id, product_id) - run_command( - AddPriceItem.new(order_id: order_id, product_id: product_id) - ) - end - - def remove_item(order_id, product_id) - run_command( - RemovePriceItem.new(order_id: order_id, product_id: product_id) - ) - end - - def register_coupon(uid, name, code, discount) - run_command(RegisterCoupon.new(coupon_id: uid, name: name, code: code, discount: discount)) - end - - def fake_name - "Fake name" - end - end -end diff --git a/ecommerce/pricing/test/time_promotion_test.rb b/ecommerce/pricing/test/time_promotion_test.rb deleted file mode 100644 index e1de88470..000000000 --- a/ecommerce/pricing/test/time_promotion_test.rb +++ /dev/null @@ -1,222 +0,0 @@ -require_relative "test_helper" - -require "timecop" - -module Pricing - class TimePromotionTest < Test - cover "Pricing::TimePromotion*" - - def test_creates_time_promotion - uid = SecureRandom.uuid - start_time = Time.utc(2022, 7, 1, 12, 15, 0) - end_time = Time.utc(2022, 7, 4, 14, 30, 30) - discount = 25 - label = "Summer Sale" - data = { - time_promotion_id: uid, - discount: discount, - start_time: start_time, - end_time: end_time, - label: label - } - - run_command = -> { create_time_promotion(**data) } - - stream = "Pricing::TimePromotion$#{uid}" - event = TimePromotionCreated.new(data: data) - - assert_events(stream, event) do - run_command.call - end - end - - private - - def create_time_promotion(**kwargs) - run_command(CreateTimePromotion.new(kwargs)) - end - end - - class DiscountWithTimePromotionTest < Test - cover "Pricing*" - - def test_calculates_total_value_with_time_promotion - timestamp = Time.utc(2022, 5, 30, 15, 33) - - Timecop.freeze(timestamp) do - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 20, - total_amount: 20 - } - ) - ) { calculate_total_value(order_id) } - - # Current promotions - first_time_promotion_id = SecureRandom.uuid - start_time = timestamp - 1 - end_time = timestamp + 1 - set_time_promotion_range(first_time_promotion_id, start_time, end_time, 49) - - time_promotion_id = SecureRandom.uuid - start_time = timestamp - end_time = timestamp + 1 - set_time_promotion_range(time_promotion_id, start_time, end_time, 1) - - # Not applicable promotions - time_promotion_id = SecureRandom.uuid - start_time = timestamp - 2 - end_time = timestamp - 1 - set_time_promotion_range(time_promotion_id, start_time, end_time, 10) - - time_promotion_id = SecureRandom.uuid - start_time = timestamp + 1 - end_time = timestamp + 2 - set_time_promotion_range(time_promotion_id, start_time, end_time, 15) - - time_promotion_id = SecureRandom.uuid - start_time = timestamp - 1 - end_time = timestamp - set_time_promotion_range(time_promotion_id, start_time, end_time, 15) - - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - total_amount: 20, - discounted_amount: 10, - } - ) - ) { calculate_total_value(order_id) } - end - end - - def test_calculates_sub_amounts_with_combined_discounts - timestamp = Time.utc(2022, 5, 30, 15, 33) - Timecop.freeze(timestamp) do - - product_1_id = SecureRandom.uuid - product_2_id = SecureRandom.uuid - set_price(product_1_id, 20) - set_price(product_2_id, 30) - order_id = SecureRandom.uuid - stream = stream_name(order_id) - - assert_events(stream) { calculate_sub_amounts(order_id) } - - add_item(order_id, product_1_id) - add_item(order_id, product_2_id) - add_item(order_id, product_2_id) - assert_events( - stream, - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_1_id, - quantity: 1, - amount: 20, - discounted_amount: 20 - } - ), - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_2_id, - quantity: 2, - amount: 60, - discounted_amount: 60 - } - ) - ) { calculate_sub_amounts(order_id) } - run_command( - Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10) - ) - - first_time_promotion_id = SecureRandom.uuid - start_time = timestamp - 1 - end_time = timestamp + 1 - set_time_promotion_range(first_time_promotion_id, start_time, end_time, 50) - - assert_events( - stream, - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_1_id, - quantity: 1, - amount: 20, - discounted_amount: 8 - } - ), - PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_2_id, - quantity: 2, - amount: 60, - discounted_amount: 24 - } - ) - ) { calculate_sub_amounts(order_id) } - end - end - - def test_takes_last_values_for_time_promotion - timestamp = Time.new(2022, 5, 30, 15, 33) - time_promotion_id = SecureRandom.uuid - start_time = timestamp - 5 - end_time = timestamp - 2 - set_time_promotion_range(time_promotion_id, start_time, end_time, 30) - - start_time = timestamp - 1 - end_time = timestamp + 1 - set_time_promotion_range(time_promotion_id, start_time, end_time, 50) - set_time_promotion_range(time_promotion_id, start_time, end_time, 40) - - Timecop.freeze(timestamp) do - product_1_id = SecureRandom.uuid - set_price(product_1_id, 20) - order_id = SecureRandom.uuid - add_item(order_id, product_1_id) - stream = stream_name(order_id) - - assert_events( - stream, - OrderTotalValueCalculated.new( - data: { - order_id: order_id, - discounted_amount: 12, - total_amount: 20 - } - ) - ) { calculate_total_value(order_id) } - end - end - - private - - def stream_name(order_id) - "Pricing::Offer$#{order_id}" - end - - def set_time_promotion_range(time_promotion_id, start_time, end_time, discount) - run_command( - CreateTimePromotion.new(time_promotion_id: time_promotion_id, start_time: start_time, end_time: end_time, discount: discount, label: "test") - ) - end - - def calculate_sub_amounts(order_id) - run_command(CalculateSubAmounts.new(order_id: order_id)) - end - end -end diff --git a/ecommerce/processes/.mutant.yml b/ecommerce/processes/.mutant.yml deleted file mode 100644 index e352e65d4..000000000 --- a/ecommerce/processes/.mutant.yml +++ /dev/null @@ -1,21 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Processes* - ignore: - - Processes::Configuration* - - Processes::OrderConfirmation#stream_name - - Processes::Test* - - Processes::ShipmentProcess* - - Processes::ReleasePaymentProcess* - - Processes::OrderItemInvoicingProcess* - - Processes::SyncShipmentFromOrdering* - - Processes::SyncInventoryFromOrdering* - - Processes::NotifyPaymentsAboutOrderValue* - - Processes::ThreePlusOneFree* - - Processes::ReservationProcess#build_state - - Processes::ReservationProcess::ProcessState#call \ No newline at end of file diff --git a/ecommerce/processes/Gemfile b/ecommerce/processes/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/processes/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/processes/Gemfile.lock b/ecommerce/processes/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/processes/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/processes/Makefile b/ecommerce/processes/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/processes/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/processes/lib/processes.rb b/ecommerce/processes/lib/processes.rb deleted file mode 100644 index 153c90df6..000000000 --- a/ecommerce/processes/lib/processes.rb +++ /dev/null @@ -1,153 +0,0 @@ -require_relative "../../ordering/lib/ordering" -require_relative "../../pricing/lib/pricing" -require_relative "../../product_catalog/lib/product_catalog" -require_relative "../../crm/lib/crm" -require_relative "../../payments/lib/payments" -require_relative "../../inventory/lib/inventory" -require_relative "../../shipping/lib/shipping" -require_relative "../../taxes/lib/taxes" -require_relative "../../invoicing/lib/invoicing" -require_relative "../../fulfillment/lib/fulfillment" -require_relative 'processes/confirm_order_on_payment_captured' -require_relative 'processes/release_payment_process' -require_relative 'processes/shipment_process' -require_relative 'processes/determine_vat_rates_on_order_placed' -require_relative 'processes/order_item_invoicing_process' -require_relative 'processes/notify_payments_about_order_value' -require_relative 'processes/sync_shipment_from_ordering' -require_relative 'processes/three_plus_one_free' -require_relative 'processes/reservation_process' - -module Processes - class Configuration - class << self - attr_accessor :event_store, :command_bus - end - - def call(event_store, command_bus) - self.class.event_store = event_store - self.class.command_bus = command_bus - notify_payments_about_order_total_value(event_store, command_bus) - enable_shipment_sync(event_store, command_bus) - determine_vat_rates_on_order_placed(event_store, command_bus) - set_invoice_payment_date_when_order_confirmed(event_store, command_bus) - enable_product_name_sync(event_store, command_bus) - confirm_order_on_payment_captured(event_store, command_bus) - register_order_on_order_placed(event_store, command_bus) - - enable_release_payment_process(event_store, command_bus) - enable_shipment_process(event_store, command_bus) - enable_order_item_invoicing_process(event_store, command_bus) - enable_reservation_process(event_store, command_bus) - build_pricing_offer_from_ordering_items(event_store, command_bus) - end - - private - - def enable_shipment_process(event_store, command_bus) - ShipmentProcess.new(event_store, command_bus) - end - - def build_pricing_offer_from_ordering_items(event_store, command_bus) - Infra::Process.new(event_store, command_bus) - .call(Ordering::ItemAddedToBasket, [:order_id, :product_id], - Pricing::AddPriceItem, [:order_id, :product_id]) - Infra::Process.new(event_store, command_bus) - .call(Ordering::ItemRemovedFromBasket, [:order_id, :product_id], - Pricing::RemovePriceItem, [:order_id, :product_id]) - end - - def enable_shipment_sync(event_store, command_bus) - SyncShipmentFromOrdering.new(event_store, command_bus) - end - - def notify_payments_about_order_total_value(event_store, command_bus) - NotifyPaymentsAboutOrderValue.new(event_store, command_bus) - end - - def confirm_order_on_payment_captured(event_store, command_bus) - event_store.subscribe( - ConfirmOrderOnPaymentCaptured.new(command_bus), - to: [Payments::PaymentCaptured] - ) - end - - def enable_release_payment_process(event_store, command_bus) - event_store.subscribe( - ReleasePaymentProcess.new(event_store, command_bus), - to: [ - Ordering::OrderPlaced, - Ordering::OrderExpired, - Fulfillment::OrderConfirmed, - Payments::PaymentAuthorized, - Payments::PaymentReleased - ] - ) - end - - def enable_order_item_invoicing_process(event_store, command_bus) - event_store.subscribe( - OrderItemInvoicingProcess.new(event_store, command_bus), - to: [ - Pricing::PriceItemValueCalculated, - Taxes::VatRateDetermined - ] - ) - end - - def determine_vat_rates_on_order_placed(event_store, command_bus) - event_store.subscribe( - DetermineVatRatesOnOrderPlaced.new(command_bus), - to: [Ordering::OrderPlaced] - ) - end - - def enable_product_name_sync(event_store, command_bus) - Infra::Process.new(event_store, command_bus) - .call(ProductCatalog::ProductNamed, [:product_id, :name], - Invoicing::SetProductNameDisplayedOnInvoice, [:product_id, :name_displayed]) - end - - def set_invoice_payment_date_when_order_confirmed(event_store, command_bus) - event_store.subscribe( - ->(event) do - command_bus.call( - Invoicing::SetPaymentDate.new( - invoice_id: event.data.fetch(:order_id), - payment_date: Time.zone.at(event.metadata.fetch(:timestamp)).to_date - ) - ) - end, - to: [Fulfillment::OrderConfirmed] - ) - end - - def enable_three_plus_one_free_process(event_store, command_bus) - ThreePlusOneFree.new(event_store, command_bus) - end - - def enable_reservation_process(event_store, command_bus) - event_store.subscribe( - ReservationProcess.new, - to: [ - Ordering::OrderSubmitted, - Fulfillment::OrderCancelled, - Fulfillment::OrderConfirmed - ] - ) - end - - def register_order_on_order_placed(event_store, command_bus) - event_store.subscribe( - ->(event) do - command_bus.call( - Fulfillment::RegisterOrder.new( - order_id: event.data.fetch(:order_id) - ) - ) - end, - to: [Ordering::OrderPlaced] - ) - end - end -end diff --git a/ecommerce/processes/lib/processes/confirm_order_on_payment_captured.rb b/ecommerce/processes/lib/processes/confirm_order_on_payment_captured.rb deleted file mode 100644 index e1d671dac..000000000 --- a/ecommerce/processes/lib/processes/confirm_order_on_payment_captured.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Processes - class ConfirmOrderOnPaymentCaptured - - def initialize(command_bus) - @command_bus = command_bus - end - - def call(event) - order_id = event.data.fetch(:order_id) - command_bus.call(Fulfillment::ConfirmOrder.new(order_id: order_id)) - end - - private - attr_reader :command_bus - end -end diff --git a/ecommerce/processes/lib/processes/determine_vat_rates_on_order_placed.rb b/ecommerce/processes/lib/processes/determine_vat_rates_on_order_placed.rb deleted file mode 100644 index 71b55983f..000000000 --- a/ecommerce/processes/lib/processes/determine_vat_rates_on_order_placed.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Processes - class DetermineVatRatesOnOrderPlaced - def initialize(command_bus) - @command_bus = command_bus - end - - def call(event) - order_id = event.data.fetch(:order_id) - event.data.fetch(:order_lines).each do |product_quantity_hash| - product_id = product_quantity_hash.first - command = Taxes::DetermineVatRate.new(order_id: order_id, product_id: product_id) - command_bus.call(command) - end - end - - private - - attr_reader :command_bus - end -end \ No newline at end of file diff --git a/ecommerce/processes/lib/processes/notify_payments_about_order_value.rb b/ecommerce/processes/lib/processes/notify_payments_about_order_value.rb deleted file mode 100644 index 46fd6c246..000000000 --- a/ecommerce/processes/lib/processes/notify_payments_about_order_value.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Processes - class NotifyPaymentsAboutOrderValue - def initialize(event_store, command_bus) - event_store.subscribe( - ->(event) do - command_bus.call( - Payments::SetPaymentAmount.new( - order_id: event.data.fetch(:order_id), - amount: event.data.fetch(:discounted_amount).to_f - ) - ) - end, - to: [Pricing::OrderTotalValueCalculated] - ) - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/lib/processes/order_item_invoicing_process.rb b/ecommerce/processes/lib/processes/order_item_invoicing_process.rb deleted file mode 100644 index d03b1a0a1..000000000 --- a/ecommerce/processes/lib/processes/order_item_invoicing_process.rb +++ /dev/null @@ -1,87 +0,0 @@ -module Processes - class OrderItemInvoicingProcess - def initialize(event_store, command_bus) - @event_store = event_store - @command_bus = command_bus - end - - def call(event) - state = build_state(event) - return unless state.create_invoice_item? - - unit_prices = MoneySplitter.new(state.discounted_amount, Array.new(state.quantity, 1)).call - unit_prices.tally.each do |unit_price, quantity| - command_bus.call(Invoicing::AddInvoiceItem.new( - invoice_id: state.order_id, - product_id: state.product_id, - vat_rate: state.vat_rate, - quantity: quantity, - unit_price: unit_price - )) - end - end - - private - - attr_reader :event_store, :command_bus - - def build_state(event) - stream_name = "OrderInvoicingProcess$#{event.data.fetch(:order_id)}$#{event.data.fetch(:product_id)}" - past = event_store.read.stream(stream_name).to_a - last_stored = past.size - 1 - event_store.link(event.event_id, stream_name: stream_name, expected_version: last_stored) - ProcessState.new.tap do |state| - past.each { |ev| state.call(ev) } - state.call(event) - end - rescue RubyEventStore::WrongExpectedEventVersion - retry - end - - class ProcessState - attr_reader :order_id, :product_id, :quantity, :vat_rate, :discounted_amount - - def call(event) - @order_id ||= event.data.fetch(:order_id) - @product_id ||= event.data.fetch(:product_id) - case event - when Pricing::PriceItemValueCalculated - @quantity = event.data.fetch(:quantity) - @discounted_amount = event.data.fetch(:discounted_amount) - when Taxes::VatRateDetermined - @vat_rate = event.data.fetch(:vat_rate).symbolize_keys - end - end - - def create_invoice_item? - [order_id, product_id, quantity, vat_rate, discounted_amount].all? - end - end - end - - class MoneySplitter - def initialize(amount, weights) - raise ArgumentError unless weights.instance_of? Array - raise ArgumentError if weights.empty? - @amount = amount - @weights = weights - end - - def call - distributed_amounts = [] - total_weight = @weights.sum.to_d - @weights.each do |weight| - if total_weight.eql?(0) - distributed_amounts << 0 - next - end - p = weight / total_weight - distributed_amount = (p * @amount).round(2) - distributed_amounts << distributed_amount - total_weight -= weight - @amount -= distributed_amount - end - distributed_amounts - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/lib/processes/registration_process.rb b/ecommerce/processes/lib/processes/registration_process.rb deleted file mode 100644 index e69b542b0..000000000 --- a/ecommerce/processes/lib/processes/registration_process.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -class RegistrationProcess -end diff --git a/ecommerce/processes/lib/processes/release_payment_process.rb b/ecommerce/processes/lib/processes/release_payment_process.rb deleted file mode 100644 index e85a338b5..000000000 --- a/ecommerce/processes/lib/processes/release_payment_process.rb +++ /dev/null @@ -1,63 +0,0 @@ -module Processes - class ReleasePaymentProcess - def initialize(event_store, command_bus) - @event_store = event_store - @command_bus = command_bus - end - - def call(event) - state = build_state(event) - release_payment(state) if state.release? - end - - private - - def release_payment(state) - command_bus.call(Payments::ReleasePayment.new(order_id: state.order_id)) - end - - attr_reader :command_bus, :event_store - - def build_state(event) - stream_name = "PaymentProcess$#{event.data.fetch(:order_id)}" - past_events = event_store.read.stream(stream_name).to_a - last_stored = past_events.size - 1 - event_store.link(event.event_id, stream_name: stream_name, expected_version: last_stored) - ProcessState.new.tap do |state| - past_events.each { |ev| state.call(ev) } - state.call(event) - end - rescue RubyEventStore::WrongExpectedEventVersion - retry - end - - class ProcessState - def initialize - @order = :draft - @payment = :none - end - - attr_reader :order_id - - def call(event) - case event - when Payments::PaymentAuthorized - @payment = :authorized - when Payments::PaymentReleased - @payment = :released - when Ordering::OrderPlaced - @order = :placed - @order_id = event.data.fetch(:order_id) - when Ordering::OrderExpired - @order = :expired - when Fulfillment::OrderConfirmed - @order = :confirmed - end - end - - def release? - @payment.eql?(:authorized) && @order.eql?(:expired) - end - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/lib/processes/reservation_process.rb b/ecommerce/processes/lib/processes/reservation_process.rb deleted file mode 100644 index fa920cea2..000000000 --- a/ecommerce/processes/lib/processes/reservation_process.rb +++ /dev/null @@ -1,96 +0,0 @@ -module Processes - class ReservationProcess - def initialize - @event_store = Configuration.event_store - @command_bus = Configuration.command_bus - end - attr_accessor :event_store, :command_bus - - def call(event) - state = build_state(event) - case event.event_type - when 'Ordering::OrderSubmitted' - begin - reserve_stock(state) - rescue Inventory::InventoryEntry::InventoryNotAvailable - release_stock(state) - reject_order(state) - else - accept_order(state) - end - when 'Fulfillment::OrderCancelled' - release_stock(state) - when 'Fulfillment::OrderConfirmed' - dispatch_stock(state) - end - end - - private - - def reserve_stock(state) - state.order_lines.each do |product_id, quantity| - command_bus.(Inventory::Reserve.new(product_id: product_id, quantity: quantity)) - state.product_reserved(product_id) - end - end - - def release_stock(state) - state.order_lines.slice(*state.reserved_product_ids).each do |product_id, quantity| - command_bus.(Inventory::Release.new(product_id: product_id, quantity: quantity)) - end - end - - def dispatch_stock(state) - state.order_lines.each do |product_id, quantity| - command_bus.(Inventory::Dispatch.new(product_id: product_id, quantity: quantity)) - end - end - - def accept_order(state) - command_bus.(Ordering::AcceptOrder.new(order_id: state.order_id)) - end - - def reject_order(state) - command_bus.(Ordering::RejectOrder.new(order_id: state.order_id)) - end - - def build_state(event) - stream_name = "ReservationProcess$#{event.data.fetch(:order_id)}" - begin - past_events = event_store.read.stream(stream_name).to_a - last_stored = past_events.size - 1 - event_store.link(event.event_id, stream_name: stream_name, expected_version: last_stored) - rescue RubyEventStore::WrongExpectedEventVersion - retry - rescue RubyEventStore::EventDuplicatedInStream - return - end - ProcessState.new.tap do |state| - past_events.each { |ev| state.call(ev) } - state.call(event) - end - end - - class ProcessState - def initialize() - @reserved_product_ids = [] - end - - attr_reader :order_id, :order_lines, :reserved_product_ids - - def call(event) - case event - when Ordering::OrderSubmitted - @order_lines = event.data.fetch(:order_lines) - @order_id = event.data.fetch(:order_id) - when Fulfillment::OrderCancelled, Fulfillment::OrderConfirmed - @reserved_product_ids = order_lines.keys - end - end - - def product_reserved(product_id) - reserved_product_ids << product_id - end - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/lib/processes/shipment_process.rb b/ecommerce/processes/lib/processes/shipment_process.rb deleted file mode 100644 index 0a04dae74..000000000 --- a/ecommerce/processes/lib/processes/shipment_process.rb +++ /dev/null @@ -1,81 +0,0 @@ -module Processes - class ShipmentProcess - def initialize(event_store, command_bus) - @event_store = event_store - @command_bus = command_bus - @event_store.subscribe( - self, - to: [ - Shipping::ShippingAddressAddedToShipment, - Shipping::ShipmentSubmitted, - Ordering::OrderPlaced, - Fulfillment::OrderConfirmed - ] - ) - end - - def call(event) - state = build_state(event) - submit_shipment(state) if state.submit? - authorize_shipment(state) if state.authorize? - end - - private - - def submit_shipment(state) - command_bus.call(Shipping::SubmitShipment.new(order_id: state.order_id)) - end - - def authorize_shipment(state) - command_bus.call(Shipping::AuthorizeShipment.new(order_id: state.order_id)) - end - - attr_reader :command_bus, :event_store - - def build_state(event) - stream_name = "ShipmentProcess$#{event.data.fetch(:order_id)}" - past_events = event_store.read.stream(stream_name).to_a - last_stored = past_events.size - 1 - event_store.link(event.event_id, stream_name: stream_name, expected_version: last_stored) - ProcessState.new.tap do |state| - past_events.each { |ev| state.call(ev) } - state.call(event) - end - rescue RubyEventStore::WrongExpectedEventVersion - retry - end - - class ProcessState - def initialize - @order = :draft - @shipment = :draft - end - - attr_reader :order_id - - def call(event) - case event - when Shipping::ShippingAddressAddedToShipment - @shipment = :address_set - when Shipping::ShipmentSubmitted - @shipment = :submitted - when Ordering::OrderPlaced - @order = :placed - @order_id = event.data.fetch(:order_id) - when Fulfillment::OrderConfirmed - @order = :confirmed - end - end - - def submit? - return false if @shipment == :submitted - - @shipment == :address_set && @order != :draft - end - - def authorize? - @shipment == :address_set && @order == :confirmed - end - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/lib/processes/sync_shipment_from_ordering.rb b/ecommerce/processes/lib/processes/sync_shipment_from_ordering.rb deleted file mode 100644 index 4cceacd17..000000000 --- a/ecommerce/processes/lib/processes/sync_shipment_from_ordering.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Processes - class SyncShipmentFromOrdering - def initialize(event_store, command_bus) - Infra::Process.new(event_store, command_bus) - .call(Ordering::ItemAddedToBasket, [:order_id, :product_id], - Shipping::AddItemToShipmentPickingList, [:order_id, :product_id]) - Infra::Process.new(event_store, command_bus) - .call(Ordering::ItemRemovedFromBasket, [:order_id, :product_id], - Shipping::RemoveItemFromShipmentPickingList, [:order_id, :product_id]) - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/lib/processes/three_plus_one_free.rb b/ecommerce/processes/lib/processes/three_plus_one_free.rb deleted file mode 100644 index 5e85a0027..000000000 --- a/ecommerce/processes/lib/processes/three_plus_one_free.rb +++ /dev/null @@ -1,119 +0,0 @@ -module Processes - class ThreePlusOneFree - - def initialize(event_store, command_bus) - @event_store = event_store - @command_bus = command_bus - @event_store.subscribe( - self, - to: [ - Pricing::PriceItemAdded, - Pricing::PriceItemRemoved, - Pricing::ProductMadeFreeForOrder, - Pricing::FreeProductRemovedFromOrder - ] - ) - end - - def call(event) - state = build_state(event) - return if event_only_for_state_building?(event) - - make_or_remove_free_product(state) - end - - private - - def build_state(event) - stream_name = "ThreePlusOneFreeProcess$#{event.data.fetch(:order_id)}" - past_events = @event_store.read.stream(stream_name).to_a - last_stored = past_events.size - 1 - @event_store.link(event.event_id, stream_name: stream_name, expected_version: last_stored) - ProcessState.new(event.data.fetch(:order_id)).tap do |state| - past_events.each { |ev| state.call(ev) } - state.call(event) - end - rescue RubyEventStore::WrongExpectedEventVersion - retry - end - - def make_or_remove_free_product(state) - pricing_catalog = Pricing::PricingCatalog.new(@event_store) - free_product_id = FreeProductResolver.new(state, pricing_catalog).call - - return if current_free_product_not_changed?(free_product_id, state) - - remove_old_free_product(state) - make_new_product_for_free(state, free_product_id) - end - - def event_only_for_state_building?(event) - event.instance_of?(Pricing::FreeProductRemovedFromOrder) || event.instance_of?(Pricing::ProductMadeFreeForOrder) - end - - def current_free_product_not_changed?(free_product_id, state) - free_product_id == state.current_free_product_id - end - - def remove_old_free_product(state) - @command_bus.call(Pricing::RemoveFreeProductFromOrder.new(order_id: state.order_id, product_id: state.current_free_product_id)) if state.current_free_product_id - end - - def make_new_product_for_free(state, free_product_id) - @command_bus.call(Pricing::MakeProductFreeForOrder.new(order_id: state.order_id, product_id: free_product_id)) if free_product_id - end - - class ProcessState - attr_reader :order_id, :order_lines, :current_free_product_id - - def initialize(order_id) - @order_id = order_id - @order_lines = Hash.new(0) - end - - def call(event) - product_id = event.data.fetch(:product_id) - case event - when Pricing::PriceItemAdded - order_lines[product_id] += 1 - when Pricing::PriceItemRemoved - order_lines[product_id] -= 1 - order_lines.delete(product_id) if order_lines.fetch(product_id) <= 0 - when Pricing::ProductMadeFreeForOrder - @current_free_product_id = product_id - when Pricing::FreeProductRemovedFromOrder - @current_free_product_id = nil - end - end - - def total_quantity - order_lines.values.sum - end - end - - class FreeProductResolver - MIN_ORDER_LINES_QUANTITY = 4 - - def initialize(state, pricing_catalog) - @state = state - @pricing_catalog = pricing_catalog - end - - def call - cheapest_product if eligible_for_free_product? - end - - private - - attr_reader :state, :pricing_catalog - - def cheapest_product - state.order_lines.keys.sort_by { |product_id| pricing_catalog.price_by_product_id(product_id) }.first - end - - def eligible_for_free_product? - state.total_quantity >= MIN_ORDER_LINES_QUANTITY - end - end - end -end diff --git a/ecommerce/processes/test/determine_vat_rate_test.rb b/ecommerce/processes/test/determine_vat_rate_test.rb deleted file mode 100644 index edbd3e27e..000000000 --- a/ecommerce/processes/test/determine_vat_rate_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -require_relative "test_helper" - -module Processes - class DetermineVatRateTest < Test - cover "Processes::DetermineVatRatesOnOrderPlaced*" - - def test_inventory_available_error_is_raised - product_id = SecureRandom.uuid - order_id = SecureRandom.uuid - process = DetermineVatRatesOnOrderPlaced.new(command_bus) - given([order_placed(order_id, product_id)]).each do |event| - process.call(event) - end - assert_command(Taxes::DetermineVatRate.new(order_id: order_id, product_id: product_id)) - end - - private - - def order_placed order_id, product_id - Ordering::OrderPlaced.new( - data: { - order_id: order_id, - order_number: order_number, - customer_id: customer_id, - order_lines: { product_id => 1 } - } - ) - end - end -end diff --git a/ecommerce/processes/test/money_splitter_test.rb b/ecommerce/processes/test/money_splitter_test.rb deleted file mode 100644 index 379ba9874..000000000 --- a/ecommerce/processes/test/money_splitter_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -require_relative "test_helper" - -module Processes - class MoneySplitterTest < Minitest::Test - cover "Processes::MoneySplitter" - - def test_splitting_money_without_losing_cents - assert_equal([0.01, 0.01, 0.01], MoneySplitter.new(0.03, [1, 1, 1]).call) - assert_equal([0.01, 0.02], MoneySplitter.new(0.03, [1, 1]).call.sort) - assert_equal([0, 0, 0.01, 0.01, 0.01], MoneySplitter.new(0.03, [1, 1, 1, 1, 1]).call.sort) - assert_equal([0, 0, 0.03], MoneySplitter.new(0.03, [1, 0, 0]).call.sort) - - assert_raises(ArgumentError) { MoneySplitter.new(0.03, nil).call } - assert_raises(ArgumentError) { MoneySplitter.new(0.03, 'not nil nor array').call } - assert_raises(ArgumentError) { MoneySplitter.new(0.03, []).call } - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/test/order_confirmation_test.rb b/ecommerce/processes/test/order_confirmation_test.rb deleted file mode 100644 index 3278e67f7..000000000 --- a/ecommerce/processes/test/order_confirmation_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require_relative "test_helper" - -module Processes - class OrderConfirmationTest < Test - cover "Processes::OrderConfirmation" - - def test_payment_confirms_order - process = ConfirmOrderOnPaymentCaptured.new(command_bus) - given([payment_authorized]).each do |event| - process.call(event) - end - assert_command(Fulfillment::ConfirmOrder.new(order_id: order_id)) - end - end -end diff --git a/ecommerce/processes/test/order_item_invoicing_process_test.rb b/ecommerce/processes/test/order_item_invoicing_process_test.rb deleted file mode 100644 index 97526be44..000000000 --- a/ecommerce/processes/test/order_item_invoicing_process_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require_relative "test_helper" - -module Processes - class OrderItemInvoicingProcessTest < Test - cover "Processes::OrderItemInvoicingProcess*" - - def test_invoice_item_being_created - product_id = SecureRandom.uuid - amount = 100.to_d - discounted_amount = 90.to_d - quantity = 5 - vat_rate = Infra::Types::VatRate.new(rate: 20, code: "20") - - item_value_calculated = Pricing::PriceItemValueCalculated.new( - data: { - order_id: order_id, - product_id: product_id, - quantity: quantity, - amount: amount, - discounted_amount: discounted_amount - } - ) - vat_rate_determined = Taxes::VatRateDetermined.new( - data: { - order_id: order_id, - product_id: product_id, - vat_rate: vat_rate - } - ) - process = OrderItemInvoicingProcess.new(event_store, command_bus) - given([item_value_calculated, vat_rate_determined]).each do |event| - process.call(event) - end - assert_command(Invoicing::AddInvoiceItem.new( - invoice_id: order_id, - product_id: product_id, - quantity: quantity, - vat_rate: vat_rate, - unit_price: 18.to_d - )) - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/test/release_payment_process_test.rb b/ecommerce/processes/test/release_payment_process_test.rb deleted file mode 100644 index 29f0a551d..000000000 --- a/ecommerce/processes/test/release_payment_process_test.rb +++ /dev/null @@ -1,37 +0,0 @@ -require_relative "test_helper" - -module Processes - class ReleasePaymentProcessTest < Test - cover "Processes::ReleasePaymentProcess*" - - def test_happy_path - process = ReleasePaymentProcess.new(event_store, command_bus) - given([order_placed, payment_authorized, order_confirmed]).each do |event| - process.call(event) - end - assert_no_command - end - - def test_order_expired_without_payment - process = ReleasePaymentProcess.new(event_store, command_bus) - given([order_placed, order_expired]).each { |event| process.call(event) } - assert_no_command - end - - def test_order_expired_after_payment_authorization - process = ReleasePaymentProcess.new(event_store, command_bus) - given([order_placed, payment_authorized, order_expired]).each do |event| - process.call(event) - end - assert_command(Payments::ReleasePayment.new(order_id: order_id),) - end - - def test_order_expired_after_payment_released - process = ReleasePaymentProcess.new(event_store, command_bus) - given([order_placed, payment_authorized, payment_released, order_expired]).each do |event| - process.call(event) - end - assert_no_command - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/test/reservation_process_test.rb b/ecommerce/processes/test/reservation_process_test.rb deleted file mode 100644 index a71aa122c..000000000 --- a/ecommerce/processes/test/reservation_process_test.rb +++ /dev/null @@ -1,108 +0,0 @@ -require_relative "test_helper" - -module Processes - class ReservationProcessTest < Test - cover "Processes::ReservationProcess*" - - def test_happy_path - process = ReservationProcess.new - given([order_submitted]).each { |event| process.call(event) } - assert_all_commands( - Inventory::Reserve.new(product_id: product_id, quantity: 1), - Inventory::Reserve.new(product_id: another_product_id, quantity: 2), - Ordering::AcceptOrder.new(order_id: order_id) - ) - end - - class EnhancedFakeCommandBus < SimpleDelegator - def initialize(command_bus, command_error_hash = {}) - super(command_bus) - @command_error_hash = command_error_hash - end - - def call(command) - super(command) - raise @command_error_hash[command] if @command_error_hash[command] - end - end - - def test_reject_order_command_is_dispatched_when_sth_is_unavailable - failing_command = Inventory::Reserve.new(product_id: product_id, quantity: 1) - enhanced_command_bus = EnhancedFakeCommandBus.new(command_bus, failing_command => Inventory::InventoryEntry::InventoryNotAvailable) - process = ReservationProcess.new - process.command_bus = enhanced_command_bus - given([order_submitted]).each { |event| process.call(event) } - assert_all_commands( - failing_command, - Ordering::RejectOrder.new(order_id: order_id) - ) - end - - def test_compensation_when_sth_is_unavailable - failing_command = Inventory::Reserve.new(product_id: another_product_id, quantity: 2) - enhanced_command_bus = EnhancedFakeCommandBus.new(command_bus, failing_command => Inventory::InventoryEntry::InventoryNotAvailable) - process = ReservationProcess.new - process.command_bus = enhanced_command_bus - given([order_submitted]).each { |event| process.call(event) } - assert_all_commands( - Inventory::Reserve.new(product_id: product_id, quantity: 1), - failing_command, - Inventory::Release.new(product_id: product_id, quantity: 1), - Ordering::RejectOrder.new(order_id: order_id) - ) - end - - def test_release_stock_when_order_is_cancelled - process = ReservationProcess.new - given([order_submitted]).each { |event| process.call(event) } - - command_bus.clear_all_received - given([order_cancelled]).each { |event| process.call(event) } - assert_all_commands( - Inventory::Release.new(product_id: product_id, quantity: 1), - Inventory::Release.new(product_id: another_product_id, quantity: 2) - ) - end - - def test_dispatch_stock_when_order_is_confirmed - process = ReservationProcess.new - given([order_submitted]).each { |event| process.call(event) } - - command_bus.clear_all_received - given([order_confirmed]).each { |event| process.call(event) } - assert_all_commands( - Inventory::Dispatch.new(product_id: product_id, quantity: 1), - Inventory::Dispatch.new(product_id: another_product_id, quantity: 2) - ) - end - - private - - def product_id - @product_id ||= SecureRandom.uuid - end - - def another_product_id - @another_product_id ||= SecureRandom.uuid - end - - def order_submitted - Ordering::OrderSubmitted.new( - data: { - order_id: order_id, - order_number: order_number, - customer_id: customer_id, - order_lines: { product_id => 1, another_product_id => 2 } - } - ) - end - - def order_cancelled - Fulfillment::OrderCancelled.new( - data: { - order_id: order_id - } - ) - end - end -end \ No newline at end of file diff --git a/ecommerce/processes/test/test_helper.rb b/ecommerce/processes/test/test_helper.rb deleted file mode 100644 index 2c446bc06..000000000 --- a/ecommerce/processes/test/test_helper.rb +++ /dev/null @@ -1,100 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" -require "infra" -require_relative "../lib/processes" - -module Processes - class Test < Minitest::Test - include Infra::TestPlumbing.with( - event_store: -> { Infra::EventStore.in_memory }, - command_bus: -> { FakeCommandBus.new } - ) - - def before_setup - super - Configuration.new.call(event_store, command_bus) - end - - def assert_command(command) - assert_equal(command, @command_bus.received) - end - - def assert_all_commands(*commands) - assert_equal(commands, @command_bus.all_received) - end - - def assert_no_command - assert_nil(@command_bus.received) - end - - private - - class FakeCommandBus - attr_reader :received, :all_received - - def initialize - @all_received = [] - end - - def call(command) - @received = command - @all_received << command - end - - def clear_all_received - @all_received, @received = [], nil - end - end - - def order_id - @order_id ||= SecureRandom.uuid - end - - def order_number - "2018/12/16" - end - - def customer_id - @customer_id ||= SecureRandom.uuid - end - - def given(events, store: event_store) - events.each { |ev| store.append(ev) } - events - end - - def order_placed - Ordering::OrderPlaced.new( - data: { - order_id: order_id, - order_number: order_number, - customer_id: customer_id - } - ) - end - - def order_expired - Ordering::OrderExpired.new(data: { order_id: order_id }) - end - - def order_confirmed - Fulfillment::OrderConfirmed.new(data: { order_id: order_id }) - end - - def order_cancelled - Fulfillment::OrderCancelled.new(data: { order_id: order_id }) - end - - def payment_authorized - Payments::PaymentAuthorized.new(data: { order_id: order_id }) - end - - def payment_captured - Payments::PaymentCaptured.new(data: { order_id: order_id }) - end - - def payment_released - Payments::PaymentReleased.new(data: { order_id: order_id }) - end - end -end diff --git a/ecommerce/processes/test/three_plus_one_free_test.rb b/ecommerce/processes/test/three_plus_one_free_test.rb deleted file mode 100644 index d14141806..000000000 --- a/ecommerce/processes/test/three_plus_one_free_test.rb +++ /dev/null @@ -1,160 +0,0 @@ -require_relative "test_helper" - -module Processes - class ThreePlusOneFreeTest < Test - cover "Processes::ThreePlusOneFree*" - - def test_one_order_line_is_not_eligible_for_free_product - product_id = SecureRandom.uuid - order_id = SecureRandom.uuid - process = ThreePlusOneFree.new(event_store, command_bus) - given(item_added_event(order_id, product_id, 1)).each do |event| - process.call(event) - end - assert_no_command - end - - def test_four_order_lines_are_eligible_for_free_product - product_id = SecureRandom.uuid - order_id = SecureRandom.uuid - process = ThreePlusOneFree.new(event_store, command_bus) - given([set_price(product_id, 20)]) - given(item_added_event(order_id, product_id, 4)).each do |event| - process.call(event) - end - assert_command(Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_id)) - end - - def test_remove_free_product_when_order_lines_qtn_is_less_than_four - product_id = SecureRandom.uuid - order_id = SecureRandom.uuid - process = ThreePlusOneFree.new(event_store, command_bus) - given([set_price(product_id, 20)]) - given(item_added_event(order_id, product_id, 4) + - product_made_for_free(order_id, product_id) + - item_removed_event(order_id, product_id, 1) + - free_product_removed(order_id, product_id)).each do |event| - process.call(event) - end - - assert_all_commands(Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_id), - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_id)) - end - - def test_change_free_product_if_new_order_line_is_the_cheapest - product_id = SecureRandom.uuid - cheapest_product_id = SecureRandom.uuid - order_id = SecureRandom.uuid - process = ThreePlusOneFree.new(event_store, command_bus) - given([set_price(product_id, 20)]) - given([set_price(cheapest_product_id, 1)]) - - given(item_added_event(order_id, product_id, 4) + - product_made_for_free(order_id, product_id) + - item_added_event(order_id, cheapest_product_id, 1) + - free_product_removed(order_id, product_id) + - product_made_for_free(order_id, cheapest_product_id) - ).each do |event| - process.call(event) - end - - assert_all_commands(Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_id), - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_id), - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: cheapest_product_id)) - end - - def test_do_not_change_free_product_if_new_order_line_is_more_expensive - product_id = SecureRandom.uuid - more_expensive_product_id = SecureRandom.uuid - order_id = SecureRandom.uuid - process = ThreePlusOneFree.new(event_store, command_bus) - given([set_price(product_id, 20)]) - given([set_price(more_expensive_product_id, 50)]) - - given(item_added_event(order_id, product_id, 4) + - product_made_for_free(order_id, product_id) + - item_added_event(order_id, more_expensive_product_id, 1)).each do |event| - process.call(event) - end - - assert_all_commands(Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_id)) - end - - def test_change_free_product_if_the_cheapest_order_line_is_removed - product_id = SecureRandom.uuid - cheapest_product_id = SecureRandom.uuid - order_id = SecureRandom.uuid - process = ThreePlusOneFree.new(event_store, command_bus) - given([set_price(product_id, 20)]) - given([set_price(cheapest_product_id, 1)]) - - given(item_added_event(order_id, product_id, 4) + - product_made_for_free(order_id, product_id) + - item_added_event(order_id, cheapest_product_id, 1) + - free_product_removed(order_id, product_id) + - product_made_for_free(order_id, cheapest_product_id) + - item_removed_event(order_id, cheapest_product_id, 1) + - free_product_removed(order_id, cheapest_product_id) + - product_made_for_free(order_id, product_id)).each do |event| - process.call(event) - end - - assert_all_commands(Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_id), - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: product_id), - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: cheapest_product_id), - Pricing::RemoveFreeProductFromOrder.new(order_id: order_id, product_id: cheapest_product_id), - Pricing::MakeProductFreeForOrder.new(order_id: order_id, product_id: product_id) - ) - end - - private - - def set_price(product_id, amount) - Pricing::PriceSet.new(data: { product_id: product_id, price: amount }) - end - - def item_added_event(order_id, product_id, times) - times.times.collect do - Pricing::PriceItemAdded.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - end - end - - def item_removed_event(order_id, product_id, times) - times.times.collect do - Pricing::PriceItemRemoved.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - end - end - - def product_made_for_free(order_id, product_id) - [ - Pricing::ProductMadeFreeForOrder.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - ] - end - - def free_product_removed(order_id, product_id) - [ - Pricing::FreeProductRemovedFromOrder.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - ] - end - end -end diff --git a/ecommerce/product_catalog/.mutant.yml b/ecommerce/product_catalog/.mutant.yml deleted file mode 100644 index e01cd617f..000000000 --- a/ecommerce/product_catalog/.mutant.yml +++ /dev/null @@ -1,8 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - ProductCatalog* diff --git a/ecommerce/product_catalog/Gemfile b/ecommerce/product_catalog/Gemfile deleted file mode 100644 index 00fef6d3c..000000000 --- a/ecommerce/product_catalog/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" diff --git a/ecommerce/product_catalog/Gemfile.lock b/ecommerce/product_catalog/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/product_catalog/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/product_catalog/Makefile b/ecommerce/product_catalog/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/product_catalog/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/product_catalog/README.md b/ecommerce/product_catalog/README.md deleted file mode 100644 index ffef06baa..000000000 --- a/ecommerce/product_catalog/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Product Catalog - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/product_catalog/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/product_catalog.yml) - -We implement this domain as a CRUD-based bounded context. The goal is to present -how to deal with such CRUD-ish domains and to show how to integrate it with -parts of the system. - -It's just a single ActiveRecord `Product` class. - -We wrap it with a `ProductCatalog` namespace to explicitly set its boundaries. - -This Bounded Context has both - the write part and the read part as the -same model. You can say it's not really CQRS - which is true for many CRUDish -bounded contexts. - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/product_catalog/lib/product_catalog.rb b/ecommerce/product_catalog/lib/product_catalog.rb deleted file mode 100644 index dd2048eab..000000000 --- a/ecommerce/product_catalog/lib/product_catalog.rb +++ /dev/null @@ -1,15 +0,0 @@ -require "infra" -require_relative "product_catalog/commands" -require_relative "product_catalog/events" -require_relative "product_catalog/registration" -require_relative "product_catalog/naming" - -module ProductCatalog - - class Configuration - def call(event_store, command_bus) - command_bus.register(RegisterProduct, Registration.new(event_store)) - command_bus.register(NameProduct, Naming.new(event_store)) - end - end -end diff --git a/ecommerce/product_catalog/lib/product_catalog/commands.rb b/ecommerce/product_catalog/lib/product_catalog/commands.rb deleted file mode 100644 index 98b2ee7fe..000000000 --- a/ecommerce/product_catalog/lib/product_catalog/commands.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ProductCatalog - class RegisterProduct < Infra::Command - attribute :product_id, Infra::Types::UUID - end - - class NameProduct < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :name, Infra::Types::String - end -end diff --git a/ecommerce/product_catalog/lib/product_catalog/events.rb b/ecommerce/product_catalog/lib/product_catalog/events.rb deleted file mode 100644 index 413a7b085..000000000 --- a/ecommerce/product_catalog/lib/product_catalog/events.rb +++ /dev/null @@ -1,11 +0,0 @@ -module ProductCatalog - - class ProductRegistered < Infra::Event - attribute :product_id, Infra::Types::UUID - end - - class ProductNamed < Infra::Event - attribute :product_id, Infra::Types::String - end - -end diff --git a/ecommerce/product_catalog/lib/product_catalog/naming.rb b/ecommerce/product_catalog/lib/product_catalog/naming.rb deleted file mode 100644 index dec9d67cf..000000000 --- a/ecommerce/product_catalog/lib/product_catalog/naming.rb +++ /dev/null @@ -1,27 +0,0 @@ -module ProductCatalog - - class Naming - def initialize(event_store) - @event_store = event_store - end - - def call(cmd) - @event_store.publish(product_named_event(cmd), stream_name: stream_name(cmd)) - end - - private - - def product_named_event(cmd) - ProductNamed.new( - data: { - product_id: cmd.product_id, - name: cmd.name - } - ) - end - - def stream_name(cmd) - "Catalog::ProductName$#{cmd.product_id}" - end - end -end diff --git a/ecommerce/product_catalog/lib/product_catalog/registration.rb b/ecommerce/product_catalog/lib/product_catalog/registration.rb deleted file mode 100644 index 244676896..000000000 --- a/ecommerce/product_catalog/lib/product_catalog/registration.rb +++ /dev/null @@ -1,34 +0,0 @@ -module ProductCatalog - AlreadyRegistered = Class.new(StandardError) - - class Registration - def initialize(event_store) - @event_store = event_store - end - - def call(cmd) - events = all_events_from_stream(stream_name(cmd)) - raise AlreadyRegistered unless events.empty? - - @event_store.publish(product_registered_event(cmd), stream_name: stream_name(cmd)) - end - - private - - def all_events_from_stream(name) - @event_store.read.stream(name).to_a - end - - def product_registered_event(cmd) - ProductRegistered.new( - data: { - product_id: cmd.product_id, - } - ) - end - - def stream_name(cmd) - "Catalog::Product$#{cmd.product_id}" - end - end -end diff --git a/ecommerce/product_catalog/test/naming_test.rb b/ecommerce/product_catalog/test/naming_test.rb deleted file mode 100644 index e5851df06..000000000 --- a/ecommerce/product_catalog/test/naming_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -require_relative 'test_helper' -module ProductCatalog - class NamingTest < Test - cover "ProductCatalog*" - - def test_should_publish_event - uid = SecureRandom.uuid - product_named = ProductCatalog::ProductNamed.new(data: {product_id: uid, name: fake_name}) - assert_events("Catalog::ProductName$#{uid}", product_named) do - name_product(uid, fake_name) - end - end - - private - - def name_product(uid, name) - run_command(NameProduct.new(product_id: uid, name: name)) - end - - def fake_name - "Fake name" - end - end -end diff --git a/ecommerce/product_catalog/test/registration_test.rb b/ecommerce/product_catalog/test/registration_test.rb deleted file mode 100644 index c4140ee61..000000000 --- a/ecommerce/product_catalog/test/registration_test.rb +++ /dev/null @@ -1,52 +0,0 @@ -require_relative 'test_helper' -module ProductCatalog - class RegistrationTest < Test - cover "ProductCatalog*" - - def test_product_should_get_registered - uid = SecureRandom.uuid - assert register_product(uid) - end - - def test_should_not_allow_for_double_registration - uid = SecureRandom.uuid - assert_raises(AlreadyRegistered) do - register_product(uid) - register_product(uid) - end - end - - def test_should_publish_event - uid = SecureRandom.uuid - product_registered = ProductCatalog::ProductRegistered.new(data: { product_id: uid }) - assert_events("Catalog::Product$#{uid}", product_registered) do - register_product(uid) - end - end - - def test_each_product_has_its_own_lifecycle - product_1_id = SecureRandom.uuid - product_1_registered = ProductCatalog::ProductRegistered.new(data: { product_id: product_1_id }) - product_2_id = SecureRandom.uuid - product_2_registered = ProductCatalog::ProductRegistered.new(data: { product_id: product_2_id }) - - assert_events("Catalog::Product$#{product_1_id}", product_1_registered) do - register_product(product_1_id) - end - - assert_events("Catalog::Product$#{product_2_id}", product_2_registered) do - register_product(product_2_id) - end - end - - private - - def register_product(uid) - run_command(RegisterProduct.new(product_id: uid)) - end - - def fake_name - "Fake name" - end - end -end diff --git a/ecommerce/product_catalog/test/test_helper.rb b/ecommerce/product_catalog/test/test_helper.rb deleted file mode 100644 index 5f5820683..000000000 --- a/ecommerce/product_catalog/test/test_helper.rb +++ /dev/null @@ -1,14 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/product_catalog" - -module ProductCatalog - class Test < Infra::InMemoryTest - - def before_setup - super() - Configuration.new.call(event_store, command_bus) - end - end -end diff --git a/ecommerce/shipping/.mutant.yml b/ecommerce/shipping/.mutant.yml deleted file mode 100644 index 074917e2b..000000000 --- a/ecommerce/shipping/.mutant.yml +++ /dev/null @@ -1,12 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Shipping* - ignore: - - Shipping::Test* - - Shipping::Configuration#initialize - - Shipping::Configuration#call diff --git a/ecommerce/shipping/Gemfile b/ecommerce/shipping/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/shipping/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/shipping/Gemfile.lock b/ecommerce/shipping/Gemfile.lock deleted file mode 100644 index 43c29a1da..000000000 --- a/ecommerce/shipping/Gemfile.lock +++ /dev/null @@ -1,115 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - ruby - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/shipping/Makefile b/ecommerce/shipping/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/shipping/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/shipping/README.md b/ecommerce/shipping/README.md deleted file mode 100644 index 54ffc7e08..000000000 --- a/ecommerce/shipping/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Shipping - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/inventory/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/shipping.yml) - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/shipping/lib/shipping.rb b/ecommerce/shipping/lib/shipping.rb deleted file mode 100644 index 78fa022d8..000000000 --- a/ecommerce/shipping/lib/shipping.rb +++ /dev/null @@ -1,51 +0,0 @@ -require "infra" -require_relative "shipping/commands/add_item_to_shipment_picking_list" -require_relative "shipping/events/item_added_to_shipment_picking_list" -require_relative "shipping/services/on_add_item_to_shipment_picking_list" - -require_relative "shipping/commands/remove_item_from_shipment_picking_list" -require_relative "shipping/events/item_removed_from_shipment_picking_list" -require_relative "shipping/services/on_remove_item_from_shipment_picking_list" - -require_relative "shipping/commands/add_shipping_address_to_shipment" -require_relative "shipping/events/shipping_address_added_to_shipment" -require_relative "shipping/services/on_add_shipping_address_to_shipment" - -require_relative "shipping/commands/submit_shipment" -require_relative "shipping/events/shipment_submitted" -require_relative "shipping/services/on_submit_shipment" - -require_relative "shipping/commands/authorize_shipment" -require_relative "shipping/events/shipment_authorized" -require_relative "shipping/services/on_authorize_shipment" - -require_relative "shipping/shipment" -require_relative "shipping/picking_list" -require_relative "shipping/picking_list_item" - -module Shipping - class Configuration - def call(event_store, command_bus) - command_bus.register( - AddItemToShipmentPickingList, - OnAddItemToShipmentPickingList.new(event_store) - ) - command_bus.register( - RemoveItemFromShipmentPickingList, - OnRemoveItemFromShipmentPickingList.new(event_store) - ) - command_bus.register( - AddShippingAddressToShipment, - OnAddShippingAddressToShipment.new(event_store) - ) - command_bus.register( - SubmitShipment, - OnSubmitShipment.new(event_store) - ) - command_bus.register( - AuthorizeShipment, - OnAuthorizeShipment.new(event_store) - ) - end - end -end diff --git a/ecommerce/shipping/lib/shipping/commands/add_item_to_shipment_picking_list.rb b/ecommerce/shipping/lib/shipping/commands/add_item_to_shipment_picking_list.rb deleted file mode 100644 index 500cb32bc..000000000 --- a/ecommerce/shipping/lib/shipping/commands/add_item_to_shipment_picking_list.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Shipping - class AddItemToShipmentPickingList < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/shipping/lib/shipping/commands/add_shipping_address_to_shipment.rb b/ecommerce/shipping/lib/shipping/commands/add_shipping_address_to_shipment.rb deleted file mode 100644 index 19febbd0c..000000000 --- a/ecommerce/shipping/lib/shipping/commands/add_shipping_address_to_shipment.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Shipping - class AddShippingAddressToShipment < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :postal_address, Infra::Types::PostalAddress - - alias aggregate_id order_id - end -end diff --git a/ecommerce/shipping/lib/shipping/commands/authorize_shipment.rb b/ecommerce/shipping/lib/shipping/commands/authorize_shipment.rb deleted file mode 100644 index 7078acc36..000000000 --- a/ecommerce/shipping/lib/shipping/commands/authorize_shipment.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Shipping - class AuthorizeShipment < Infra::Command - attribute :order_id, Infra::Types::UUID - end -end \ No newline at end of file diff --git a/ecommerce/shipping/lib/shipping/commands/remove_item_from_shipment_picking_list.rb b/ecommerce/shipping/lib/shipping/commands/remove_item_from_shipment_picking_list.rb deleted file mode 100644 index 91da4283f..000000000 --- a/ecommerce/shipping/lib/shipping/commands/remove_item_from_shipment_picking_list.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Shipping - class RemoveItemFromShipmentPickingList < Infra::Command - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - - alias aggregate_id order_id - end -end diff --git a/ecommerce/shipping/lib/shipping/commands/submit_shipment.rb b/ecommerce/shipping/lib/shipping/commands/submit_shipment.rb deleted file mode 100644 index 3ccef5452..000000000 --- a/ecommerce/shipping/lib/shipping/commands/submit_shipment.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Shipping - class SubmitShipment < Infra::Command - attribute :order_id, Infra::Types::UUID - end -end \ No newline at end of file diff --git a/ecommerce/shipping/lib/shipping/events/item_added_to_shipment_picking_list.rb b/ecommerce/shipping/lib/shipping/events/item_added_to_shipment_picking_list.rb deleted file mode 100644 index 3b64f1c70..000000000 --- a/ecommerce/shipping/lib/shipping/events/item_added_to_shipment_picking_list.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Shipping - class ItemAddedToShipmentPickingList < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end -end diff --git a/ecommerce/shipping/lib/shipping/events/item_removed_from_shipment_picking_list.rb b/ecommerce/shipping/lib/shipping/events/item_removed_from_shipment_picking_list.rb deleted file mode 100644 index 8898e43b8..000000000 --- a/ecommerce/shipping/lib/shipping/events/item_removed_from_shipment_picking_list.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Shipping - class ItemRemovedFromShipmentPickingList < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - end -end diff --git a/ecommerce/shipping/lib/shipping/events/shipment_authorized.rb b/ecommerce/shipping/lib/shipping/events/shipment_authorized.rb deleted file mode 100644 index 34af937f5..000000000 --- a/ecommerce/shipping/lib/shipping/events/shipment_authorized.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Shipping - class ShipmentAuthorized < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end \ No newline at end of file diff --git a/ecommerce/shipping/lib/shipping/events/shipment_submitted.rb b/ecommerce/shipping/lib/shipping/events/shipment_submitted.rb deleted file mode 100644 index e5a5a63c9..000000000 --- a/ecommerce/shipping/lib/shipping/events/shipment_submitted.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Shipping - class ShipmentSubmitted < Infra::Event - attribute :order_id, Infra::Types::UUID - end -end \ No newline at end of file diff --git a/ecommerce/shipping/lib/shipping/events/shipping_address_added_to_shipment.rb b/ecommerce/shipping/lib/shipping/events/shipping_address_added_to_shipment.rb deleted file mode 100644 index decc5f22a..000000000 --- a/ecommerce/shipping/lib/shipping/events/shipping_address_added_to_shipment.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Shipping - class ShippingAddressAddedToShipment < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :postal_address, Infra::Types::PostalAddress - end -end diff --git a/ecommerce/shipping/lib/shipping/picking_list.rb b/ecommerce/shipping/lib/shipping/picking_list.rb deleted file mode 100644 index 6275eb4ce..000000000 --- a/ecommerce/shipping/lib/shipping/picking_list.rb +++ /dev/null @@ -1,44 +0,0 @@ -module Shipping - class PickingList - attr_reader :items - - def initialize - @items = [] - end - - def increase_item_quantity(product_id) - item = find_or_add_item(product_id) - item.increase - end - - def decrease_item_quantity(product_id) - item = find_item(product_id) - item.decrease - remove_item(item) if item.quantity.zero? - end - - def has_item?(product_id) - find_item(product_id) - end - - def find_or_add_item(product_id) - find_item(product_id) || add_item(product_id) - end - - def find_item(product_id) - items.find {|i| i.product_id === product_id } - end - - private - - def add_item(product_id) - item = PickingListItem.new(product_id) - items << item - item - end - - def remove_item(item) - items.delete(item) - end - end -end \ No newline at end of file diff --git a/ecommerce/shipping/lib/shipping/picking_list_item.rb b/ecommerce/shipping/lib/shipping/picking_list_item.rb deleted file mode 100644 index 67a5a227c..000000000 --- a/ecommerce/shipping/lib/shipping/picking_list_item.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Shipping - class PickingListItem - attr_reader :product_id, :quantity - - def initialize(product_id) - @product_id = product_id - @quantity = 0 - end - - def increase - @quantity += 1 - end - - def decrease - @quantity -= 1 - end - end -end \ No newline at end of file diff --git a/ecommerce/shipping/lib/shipping/services/on_add_item_to_shipment_picking_list.rb b/ecommerce/shipping/lib/shipping/services/on_add_item_to_shipment_picking_list.rb deleted file mode 100644 index 178fa2a77..000000000 --- a/ecommerce/shipping/lib/shipping/services/on_add_item_to_shipment_picking_list.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Shipping - class OnAddItemToShipmentPickingList - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Shipment.new(command.order_id), - "Shipping::Shipment$#{command.order_id}" - ) do |shipment| - shipment.add_item(command.product_id) - end - end - end -end diff --git a/ecommerce/shipping/lib/shipping/services/on_add_shipping_address_to_shipment.rb b/ecommerce/shipping/lib/shipping/services/on_add_shipping_address_to_shipment.rb deleted file mode 100644 index 4df479b36..000000000 --- a/ecommerce/shipping/lib/shipping/services/on_add_shipping_address_to_shipment.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Shipping - class OnAddShippingAddressToShipment - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Shipment.new(command.order_id), - "Shipping::Shipment$#{command.order_id}" - ) do |shipment| - shipment.add_address(command.postal_address) - end - end - end -end diff --git a/ecommerce/shipping/lib/shipping/services/on_authorize_shipment.rb b/ecommerce/shipping/lib/shipping/services/on_authorize_shipment.rb deleted file mode 100644 index 706a6e372..000000000 --- a/ecommerce/shipping/lib/shipping/services/on_authorize_shipment.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Shipping - class OnAuthorizeShipment - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Shipment.new(command.order_id), - "Shipping::Shipment$#{command.order_id}" - ) do |shipment| - shipment.authorize - end - end - end -end diff --git a/ecommerce/shipping/lib/shipping/services/on_remove_item_from_shipment_picking_list.rb b/ecommerce/shipping/lib/shipping/services/on_remove_item_from_shipment_picking_list.rb deleted file mode 100644 index 883bd3c0b..000000000 --- a/ecommerce/shipping/lib/shipping/services/on_remove_item_from_shipment_picking_list.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Shipping - class OnRemoveItemFromShipmentPickingList - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Shipment.new(command.order_id), - "Shipping::Shipment$#{command.order_id}" - ) do |shipment| - shipment.remove_item(command.product_id) - end - end - end -end diff --git a/ecommerce/shipping/lib/shipping/services/on_submit_shipment.rb b/ecommerce/shipping/lib/shipping/services/on_submit_shipment.rb deleted file mode 100644 index f36e3daa3..000000000 --- a/ecommerce/shipping/lib/shipping/services/on_submit_shipment.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Shipping - class OnSubmitShipment - def initialize(event_store) - @repository = AggregateRoot::Repository.new(event_store) - end - - def call(command) - @repository.with_aggregate( - Shipment.new(command.order_id), - "Shipping::Shipment$#{command.order_id}" - ) do |shipment| - shipment.submit - end - end - end -end diff --git a/ecommerce/shipping/lib/shipping/shipment.rb b/ecommerce/shipping/lib/shipping/shipment.rb deleted file mode 100644 index ce272c672..000000000 --- a/ecommerce/shipping/lib/shipping/shipment.rb +++ /dev/null @@ -1,98 +0,0 @@ -module Shipping - class Shipment - include AggregateRoot - attr_reader :state - - ItemNotFound = Class.new(StandardError) - ShippingAddressMissing = Class.new(StandardError) - NotSubmitted = Class.new(StandardError) - AlreadySubmitted = Class.new(StandardError) - AlreadyAuthorized = Class.new(StandardError) - - def initialize(order_id) - @order_id = order_id - @picking_list = PickingList.new - @state = :draft - end - - def add_item(product_id) - apply ItemAddedToShipmentPickingList.new( - data: { - order_id: @order_id, - product_id: product_id - } - ) - end - - def remove_item(product_id) - raise ItemNotFound unless has_item?(product_id) - - apply ItemRemovedFromShipmentPickingList.new( - data: { - order_id: @order_id, - product_id: product_id - } - ) - end - - def add_address(postal_address) - apply ShippingAddressAddedToShipment.new( - data: { - order_id: @order_id, - postal_address: postal_address - } - ) - end - - def submit - raise AlreadySubmitted if state.equal?(:submitted) - raise ShippingAddressMissing unless state.equal?(:address_set) - - apply ShipmentSubmitted.new( - data: { - order_id: @order_id - } - ) - end - - def authorize - raise AlreadyAuthorized if state.equal?(:authorized) - raise NotSubmitted unless state.equal?(:submitted) - - apply ShipmentAuthorized.new( - data: { - order_id: @order_id - } - ) - end - - private - - attr_reader :shipping_address - - on ItemAddedToShipmentPickingList do |event| - @picking_list.increase_item_quantity(event.data.fetch(:product_id)) - end - - on ItemRemovedFromShipmentPickingList do |event| - @picking_list.decrease_item_quantity(event.data.fetch(:product_id)) - end - - on ShippingAddressAddedToShipment do |event| - @shipping_address = event.data.fetch(:postal_address) - @state = :address_set - end - - on ShipmentSubmitted do |event| - @state = :submitted - end - - on ShipmentAuthorized do |event| - @state = :authorized - end - - def has_item?(product_id) - @picking_list.has_item?(product_id) - end - end -end diff --git a/ecommerce/shipping/test/on_add_item_to_shipment_picking_list_test.rb b/ecommerce/shipping/test/on_add_item_to_shipment_picking_list_test.rb deleted file mode 100644 index 11bbfd0fa..000000000 --- a/ecommerce/shipping/test/on_add_item_to_shipment_picking_list_test.rb +++ /dev/null @@ -1,23 +0,0 @@ -require_relative "test_helper" - -module Shipping - class OnAddItemToShipmentPickingListTest < Test - cover "Shipping::OnAddItemToShipmentPickingList*" - - def test_add_item_to_shipment_picking_list - order_id = SecureRandom.uuid - product_id = SecureRandom.uuid - stream = "Shipping::Shipment$#{order_id}" - - assert_events( - stream, - ItemAddedToShipmentPickingList.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - ) { act(AddItemToShipmentPickingList.new(order_id: order_id, product_id: product_id)) } - end - end -end diff --git a/ecommerce/shipping/test/on_add_shipping_address_to_shipment_test.rb b/ecommerce/shipping/test/on_add_shipping_address_to_shipment_test.rb deleted file mode 100644 index def22c50c..000000000 --- a/ecommerce/shipping/test/on_add_shipping_address_to_shipment_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -require_relative "test_helper" - -module Shipping - class OnAddShippingAddressToShipmentTest < Test - cover "Shipping::OnAddShippingAddressToShipment*" - - def test_add_item_to_shipment_picking_list - order_id = SecureRandom.uuid - address = fake_address - stream = "Shipping::Shipment$#{order_id}" - - assert_events( - stream, - ShippingAddressAddedToShipment.new( - data: { - order_id: order_id, - postal_address: address - } - ) - ) do - act( - AddShippingAddressToShipment.new( - order_id: order_id, - postal_address: address - ) - ) - end - end - end -end \ No newline at end of file diff --git a/ecommerce/shipping/test/on_authorize_shipment_test.rb b/ecommerce/shipping/test/on_authorize_shipment_test.rb deleted file mode 100644 index ad0137603..000000000 --- a/ecommerce/shipping/test/on_authorize_shipment_test.rb +++ /dev/null @@ -1,56 +0,0 @@ -require_relative "test_helper" - -module Shipping - class OnAuthorizeShipmentTest < Test - cover "Shipping::OnAuthorizeShipment*" - - def test_authorize_shipment - order_id = SecureRandom.uuid - address = fake_address - stream = "Shipping::Shipment$#{order_id}" - - arrange( - AddShippingAddressToShipment.new( - order_id: order_id, - postal_address: address - ), - SubmitShipment.new(order_id: order_id) - ) - - assert_events( - stream, - ShipmentAuthorized.new( - data: { - order_id: order_id - } - ) - ) { act(AuthorizeShipment.new(order_id: order_id)) } - end - - def test_shipment_cannot_be_authorized_when_not_submitted - order_id = SecureRandom.uuid - - assert_raises(Shipment::NotSubmitted) do - act(AuthorizeShipment.new(order_id: order_id)) - end - end - - def test_shipment_cannot_be_authorized_when_already_authorized - order_id = SecureRandom.uuid - address = fake_address - - arrange( - AddShippingAddressToShipment.new( - order_id: order_id, - postal_address: address - ), - SubmitShipment.new(order_id: order_id), - AuthorizeShipment.new(order_id: order_id) - ) - - assert_raises(Shipment::AlreadyAuthorized) do - act(AuthorizeShipment.new(order_id: order_id)) - end - end - end -end diff --git a/ecommerce/shipping/test/on_remove_item_from_shipment_picking_list_test.rb b/ecommerce/shipping/test/on_remove_item_from_shipment_picking_list_test.rb deleted file mode 100644 index 9b4a903ff..000000000 --- a/ecommerce/shipping/test/on_remove_item_from_shipment_picking_list_test.rb +++ /dev/null @@ -1,41 +0,0 @@ -require_relative "test_helper" - -module Shipping - class OnRemoveItemFromShipmentPickingListTest < Test - cover "Shipping::OnRemoveItemFromShipmentPickingList*" - - def test_remove_item_from_shipment_picking_list - order_id = SecureRandom.uuid - product_id = SecureRandom.uuid - stream = "Shipping::Shipment$#{order_id}" - - run_command(AddItemToShipmentPickingList.new( - order_id: order_id, - product_id: product_id - )) - - assert_events( - stream, - ItemRemovedFromShipmentPickingList.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - ) { act(RemoveItemFromShipmentPickingList.new(order_id: order_id, product_id: product_id)) } - end - - def test_should_not_allow_removing_non_existing_items - order_id = SecureRandom.uuid - product_id = SecureRandom.uuid - stream = "Shipping::Shipment$#{order_id}" - - assert_raises(Shipment::ItemNotFound) do - act(RemoveItemFromShipmentPickingList.new( - order_id: order_id, - product_id: product_id - )) - end - end - end -end diff --git a/ecommerce/shipping/test/on_submit_shipment_test.rb b/ecommerce/shipping/test/on_submit_shipment_test.rb deleted file mode 100644 index df0756b0a..000000000 --- a/ecommerce/shipping/test/on_submit_shipment_test.rb +++ /dev/null @@ -1,54 +0,0 @@ -require_relative "test_helper" - -module Shipping - class OnSubmitShipmentTest < Test - cover "Shipping::OnSubmitShipment*" - - def test_submit_shipment - order_id = SecureRandom.uuid - address = fake_address - stream = "Shipping::Shipment$#{order_id}" - - run_command( - AddShippingAddressToShipment.new( - order_id: order_id, - postal_address: address - ) - ) - - assert_events( - stream, - ShipmentSubmitted.new( - data: { - order_id: order_id - } - ) - ) { act(SubmitShipment.new(order_id: order_id)) } - end - - def test_shipment_cannot_be_submitted_when_shipping_address_is_missing - order_id = SecureRandom.uuid - - assert_raises(Shipment::ShippingAddressMissing) do - act(SubmitShipment.new(order_id: order_id)) - end - end - - def test_shipment_cannot_be_submitted_when_already_submitted - order_id = SecureRandom.uuid - address = fake_address - - arrange( - AddShippingAddressToShipment.new( - order_id: order_id, - postal_address: address - ), - SubmitShipment.new(order_id: order_id) - ) - - assert_raises(Shipment::AlreadySubmitted) do - act(SubmitShipment.new(order_id: order_id)) - end - end - end -end diff --git a/ecommerce/shipping/test/picking_list_item_test.rb b/ecommerce/shipping/test/picking_list_item_test.rb deleted file mode 100644 index cb70bd492..000000000 --- a/ecommerce/shipping/test/picking_list_item_test.rb +++ /dev/null @@ -1,33 +0,0 @@ -require_relative "test_helper" - -module Shipping - class PickingListItemTest < Test - - def test_initialize - product_id = SecureRandom.uuid - list_item = PickingListItem.new(product_id) - - assert_equal product_id, list_item.product_id - assert_equal 0, list_item.quantity - end - - def test_increase - product_id = SecureRandom.uuid - list_item = PickingListItem.new(product_id) - - list_item.increase - - assert_equal 1, list_item.quantity - end - - def test_decrease - product_id = SecureRandom.uuid - list_item = PickingListItem.new(product_id) - - list_item.increase - list_item.decrease - - assert_equal 0, list_item.quantity - end - end -end \ No newline at end of file diff --git a/ecommerce/shipping/test/picking_list_test.rb b/ecommerce/shipping/test/picking_list_test.rb deleted file mode 100644 index b72d85e70..000000000 --- a/ecommerce/shipping/test/picking_list_test.rb +++ /dev/null @@ -1,48 +0,0 @@ -require_relative "test_helper" - -module Shipping - class PickingListTest < Test - - def test_initialize - list = PickingList.new - - assert_equal 0, list.items.size - end - - def test_increase_item_quantity - product_one_id = SecureRandom.uuid - product_two_id = SecureRandom.uuid - list = PickingList.new - - list.increase_item_quantity(product_one_id) - - assert_equal 1, list.items.size - assert_equal 1, list.find_item(product_one_id).quantity - - list.increase_item_quantity(product_two_id) - - assert_equal 2, list.items.size - assert_equal 1, list.find_item(product_two_id).quantity - end - - def test_decrease_item_quantity - product_id = SecureRandom.uuid - list = PickingList.new - - list.increase_item_quantity(product_id) - list.increase_item_quantity(product_id) - - assert_equal 1, list.items.size - assert_equal 2, list.find_item(product_id).quantity - - list.decrease_item_quantity(product_id) - - assert_equal 1, list.items.size - assert_equal 1, list.find_item(product_id).quantity - - list.decrease_item_quantity(product_id) - - assert_equal 0, list.items.size - end - end -end \ No newline at end of file diff --git a/ecommerce/shipping/test/shipment_test.rb b/ecommerce/shipping/test/shipment_test.rb deleted file mode 100644 index 83da43f65..000000000 --- a/ecommerce/shipping/test/shipment_test.rb +++ /dev/null @@ -1,145 +0,0 @@ -require_relative "test_helper" - -module Shipping - class ShipmentTest < Test - cover "Shipping::Shipment*" - - def test_add_item_publishes_event - product_id = SecureRandom.uuid - shipment = Shipment.new(order_id) - - shipment.add_item(product_id) - - assert_changes( - shipment.unpublished_events, - [ - ItemAddedToShipmentPickingList.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - ] - ) - end - - def test_remove_item_publishes_event - product_id = SecureRandom.uuid - shipment = Shipment.new(order_id) - - shipment.add_item(product_id) - shipment.remove_item(product_id) - - assert_changes( - shipment.unpublished_events, - [ - ItemAddedToShipmentPickingList.new( - data: { - order_id: order_id, - product_id: product_id - } - ), - ItemRemovedFromShipmentPickingList.new( - data: { - order_id: order_id, - product_id: product_id - } - ) - ] - ) - end - - def test_should_not_allow_removing_non_existing_items - product_id = SecureRandom.uuid - shipment = Shipment.new(order_id) - - assert_raises(Shipment::ItemNotFound) { shipment.remove_item(product_id) } - end - - def test_add_address_publishes_event - shipment = Shipment.new(order_id) - address = fake_address - - shipment.add_address(address) - - assert_changes( - shipment.unpublished_events, - [ - ShippingAddressAddedToShipment.new( - data: { - order_id: order_id, - postal_address: address - } - ) - ] - ) - end - - def test_submit_shipment_publishes_event - shipment = Shipment.new(order_id) - address = fake_address - - shipment.add_address(address) - shipment.submit - - assert_changes( - shipment.unpublished_events, - [ - ShippingAddressAddedToShipment.new( - data: { - order_id: order_id, - postal_address: address - } - ), - ShipmentSubmitted.new( - data: { - order_id: order_id - } - ) - ] - ) - end - def test_authorize_shipment_publishes_event - shipment = Shipment.new(order_id) - address = fake_address - - shipment.add_address(address) - shipment.submit - shipment.authorize - - assert_changes( - shipment.unpublished_events, - [ - ShippingAddressAddedToShipment.new( - data: { - order_id: order_id, - postal_address: address - } - ), - ShipmentSubmitted.new( - data: { - order_id: order_id - } - ), - ShipmentAuthorized.new( - data: { - order_id: order_id - } - ) - ] - ) - end - - def test_default_state_is_draft - shipment = Shipment.new(order_id) - - assert_equal :draft, shipment.state - end - - private - - def order_id - @order_id ||= SecureRandom.uuid - end - end -end diff --git a/ecommerce/shipping/test/test_helper.rb b/ecommerce/shipping/test/test_helper.rb deleted file mode 100644 index 6064aab04..000000000 --- a/ecommerce/shipping/test/test_helper.rb +++ /dev/null @@ -1,25 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/shipping" - -module Shipping - class Test < Infra::InMemoryTest - - def before_setup - super - Shipping::Configuration.new.call(event_store, command_bus) - end - - private - - def fake_address - Infra::Types::PostalAddress.new( - line_1: "Mme Anna Kowalska", - line_2: "Ul. Bosmanska 1", - line_3: "81-116 GDYNIA", - line_4: "POLAND" - ) - end - end -end diff --git a/ecommerce/taxes/.mutant.yml b/ecommerce/taxes/.mutant.yml deleted file mode 100644 index 327ec3984..000000000 --- a/ecommerce/taxes/.mutant.yml +++ /dev/null @@ -1,12 +0,0 @@ -requires: - - ./test/test_helper -integration: minitest -coverage_criteria: - process_abort: true -matcher: - subjects: - - Taxes* - ignore: - - Taxes::Test* - - Taxes::Configuration* - - Taxes::VatRateCatalog#vat_rate_for \ No newline at end of file diff --git a/ecommerce/taxes/Gemfile b/ecommerce/taxes/Gemfile deleted file mode 100644 index 8fd887144..000000000 --- a/ecommerce/taxes/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -eval_gemfile "../../infra/Gemfile.test" -gem "infra", path: "../../infra" \ No newline at end of file diff --git a/ecommerce/taxes/Gemfile.lock b/ecommerce/taxes/Gemfile.lock deleted file mode 100644 index 4a73abff2..000000000 --- a/ecommerce/taxes/Gemfile.lock +++ /dev/null @@ -1,119 +0,0 @@ -PATH - remote: ../../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://oss:7AXfeZdAfCqL1PvHm2nvDJO6Zd9UW8IK@gem.mutant.dev/ - specs: - mutant-license (0.1.1.2.1627430819213747598431630701693729869473.6) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (7.1.2) - 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.13.0) - ruby_event_store (= 2.13.0) - arkency-command_bus (0.4.1) - concurrent-ruby - ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.4) - concurrent-ruby (1.2.2) - connection_pool (2.4.1) - diff-lcs (1.5.0) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - minitest (5.15.0) - mutant (0.11.26) - diff-lcs (~> 1.3) - parser (~> 3.2.2, >= 3.2.2.4) - regexp_parser (~> 2.8.2) - sorbet-runtime (~> 0.5.0) - unparser (~> 0.6.9) - mutant-minitest (0.11.26) - minitest (~> 5.11) - mutant (= 0.11.26) - mutex_m (0.2.0) - parser (3.2.2.4) - ast (~> 2.4.1) - racc - racc (1.7.3) - rack (3.0.8) - rake (13.1.0) - redis-client (0.19.0) - connection_pool - regexp_parser (2.8.3) - ruby2_keywords (0.0.5) - ruby_event_store (2.13.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - sidekiq (7.2.0) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.14.0) - sorbet-runtime (0.5.11190) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unparser (0.6.12) - diff-lcs (~> 1.3) - parser (>= 3.2.2.4) - zeitwerk (2.6.12) - -PLATFORMS - arm64-darwin-20 - arm64-darwin-21 - ruby - x86_64-darwin-20 - x86_64-linux - -DEPENDENCIES - infra! - minitest (= 5.15.0)! - mutant-license! - mutant-minitest (= 0.11.26)! - -BUNDLED WITH - 2.5.9 diff --git a/ecommerce/taxes/Makefile b/ecommerce/taxes/Makefile deleted file mode 100644 index 23850fab1..000000000 --- a/ecommerce/taxes/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -install: - @bundle install - -test: - @bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb - -mutate: - @RAILS_ENV=test bundle exec mutant run - -.PHONY: install test mutate diff --git a/ecommerce/taxes/README.md b/ecommerce/taxes/README.md deleted file mode 100644 index e4423ba4c..000000000 --- a/ecommerce/taxes/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Taxes - -[![Build Status](https://github.com/RailsEventStore/cqrs-es-sample-with-res/workflows/taxes/badge.svg)](https://github.com/RailsEventStore/cqrs-es-sample-with-res/actions/workflows/taxes.yml) - - -#### Up and running - -``` -make install test mutate -``` diff --git a/ecommerce/taxes/lib/taxes.rb b/ecommerce/taxes/lib/taxes.rb deleted file mode 100644 index f1c9db7a7..000000000 --- a/ecommerce/taxes/lib/taxes.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'infra' -require_relative 'taxes/commands' -require_relative 'taxes/events' -require_relative 'taxes/services' -require_relative 'taxes/product' -require_relative 'taxes/vat_rate_catalog' - -module Taxes - class Configuration - def self.available_vat_rates - @@available_vat_rates - end - - def initialize(available_vat_rates = []) - @available_vat_rates = available_vat_rates - end - - def call(event_store, command_bus) - @@available_vat_rates = @available_vat_rates - command_bus.register(SetVatRate, SetVatRateHandler.new(event_store)) - command_bus.register(DetermineVatRate, DetermineVatRateHandler.new(event_store)) - end - end -end diff --git a/ecommerce/taxes/lib/taxes/commands.rb b/ecommerce/taxes/lib/taxes/commands.rb deleted file mode 100644 index b3bb5153a..000000000 --- a/ecommerce/taxes/lib/taxes/commands.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Taxes - class SetVatRate < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :vat_rate, Infra::Types::VatRate - end - - class DetermineVatRate < Infra::Command - attribute :product_id, Infra::Types::UUID - attribute :order_id, Infra::Types::UUID - end -end \ No newline at end of file diff --git a/ecommerce/taxes/lib/taxes/events.rb b/ecommerce/taxes/lib/taxes/events.rb deleted file mode 100644 index 7f3f308b9..000000000 --- a/ecommerce/taxes/lib/taxes/events.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Taxes - class VatRateSet < Infra::Event - attribute :product_id, Infra::Types::UUID - attribute :vat_rate, Infra::Types::VatRate - end - - class VatRateDetermined < Infra::Event - attribute :order_id, Infra::Types::UUID - attribute :product_id, Infra::Types::UUID - attribute :vat_rate, Infra::Types::VatRate - end -end \ No newline at end of file diff --git a/ecommerce/taxes/lib/taxes/product.rb b/ecommerce/taxes/lib/taxes/product.rb deleted file mode 100644 index 493c1825c..000000000 --- a/ecommerce/taxes/lib/taxes/product.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Taxes - class Product - include AggregateRoot - - VatRateNotApplicable = Class.new(StandardError) - - def initialize(id) - @id = id - end - - def set_vat_rate(vat_rate) - raise VatRateNotApplicable unless vat_rate_applicable?(vat_rate) - apply(VatRateSet.new(data: { product_id: @id, vat_rate: vat_rate })) - end - - private - - def vat_rate_applicable?(vat_rate) - Configuration.available_vat_rates.include?(vat_rate) - end - - on(VatRateSet) { |_| } - end -end diff --git a/ecommerce/taxes/lib/taxes/services.rb b/ecommerce/taxes/lib/taxes/services.rb deleted file mode 100644 index eb639f8bf..000000000 --- a/ecommerce/taxes/lib/taxes/services.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Taxes - class SetVatRateHandler - def initialize(event_store) - @repository = Infra::AggregateRootRepository.new(event_store) - end - - def call(cmd) - @repository.with_aggregate(Product, cmd.product_id) do |product| - product.set_vat_rate(cmd.vat_rate) - end - end - end - - class DetermineVatRateHandler - def initialize(event_store) - @catalog = VatRateCatalog.new(event_store) - @event_store = event_store - end - - def call(cmd) - order_id = cmd.order_id - product_id = cmd.product_id - vat_rate = catalog.vat_rate_for(product_id) - return unless vat_rate - event = VatRateDetermined.new(data: { order_id: order_id, product_id: product_id, vat_rate: vat_rate }) - event_store.publish(event, stream_name: stream_name(order_id)) - end - - private - - attr_reader :catalog, :event_store - - def stream_name(order_id) - "Taxes::Order$#{order_id}" - end - end -end \ No newline at end of file diff --git a/ecommerce/taxes/lib/taxes/vat_rate_catalog.rb b/ecommerce/taxes/lib/taxes/vat_rate_catalog.rb deleted file mode 100644 index d00fd4266..000000000 --- a/ecommerce/taxes/lib/taxes/vat_rate_catalog.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Taxes - class VatRateCatalog - def initialize(event_store) - @event_store = event_store - end - - def vat_rate_for(product_id) - @event_store - .read - .of_type(VatRateSet) - .to_a - .filter { |e| e.data.fetch(:product_id).eql?(product_id) } - .last - &.data - &.fetch(:vat_rate) - end - end -end \ No newline at end of file diff --git a/ecommerce/taxes/test/taxes_test.rb b/ecommerce/taxes/test/taxes_test.rb deleted file mode 100644 index 77e58d57f..000000000 --- a/ecommerce/taxes/test/taxes_test.rb +++ /dev/null @@ -1,53 +0,0 @@ -require_relative "test_helper" - -module Taxes - class TaxesTest < Test - def test_setting_available_vat_rate - product_id = SecureRandom.uuid - vat_rate_set = VatRateSet.new(data: { product_id: product_id, vat_rate: available_vat_rate }) - assert_events("Taxes::Product$#{product_id}", vat_rate_set) do - set_vat_rate(product_id, available_vat_rate) - end - end - - def test_setting_unavailable_vat_rate_should_raise_error - product_id = SecureRandom.uuid - assert_raises(Product::VatRateNotApplicable) do - set_vat_rate(product_id, unavailable_vat_rate) - end - end - - def test_determining_vat_rate - order_id = SecureRandom.uuid - product_id = SecureRandom.uuid - another_product_id = SecureRandom.uuid - - set_vat_rate(product_id, available_vat_rate) - vat_rate_determined = VatRateDetermined.new(data: { order_id: order_id, product_id: product_id, vat_rate: available_vat_rate }) - assert_events("Taxes::Order$#{order_id}", vat_rate_determined) do - determine_vat_rate(order_id, product_id, available_vat_rate) - end - assert_events("Taxes::Order$#{order_id}") do - determine_vat_rate(order_id, another_product_id, available_vat_rate) - end - end - - private - - def set_vat_rate(product_id, vat_rate) - run_command(SetVatRate.new(product_id: product_id, vat_rate: vat_rate)) - end - - def determine_vat_rate(order_id, product_id, vat_rate) - run_command(DetermineVatRate.new(order_id: order_id, product_id: product_id, vat_rate: vat_rate)) - end - - def available_vat_rate - Configuration.available_vat_rates.first - end - - def unavailable_vat_rate - Infra::Types::VatRate.new(code: "50", rate: 50) - end - end -end diff --git a/ecommerce/taxes/test/test_helper.rb b/ecommerce/taxes/test/test_helper.rb deleted file mode 100644 index a23c2d113..000000000 --- a/ecommerce/taxes/test/test_helper.rb +++ /dev/null @@ -1,21 +0,0 @@ -require "minitest/autorun" -require "mutant/minitest/coverage" - -require_relative "../lib/taxes" - -module Taxes - class Test < Infra::InMemoryTest - cover "Taxes*" - - def before_setup - super - Configuration.new([dummy_vat_rate]).call(event_store, command_bus) - end - - private - - def dummy_vat_rate - Infra::Types::VatRate.new(code: "20", rate: 20) - end - end -end diff --git a/hanami_application/README.md b/hanami_application/README.md deleted file mode 100644 index 1c13d671a..000000000 --- a/hanami_application/README.md +++ /dev/null @@ -1,4 +0,0 @@ -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/) - diff --git a/infra/Gemfile.lock b/infra/Gemfile.lock index 6af14d8eb..61ce38f5b 100644 --- a/infra/Gemfile.lock +++ b/infra/Gemfile.lock @@ -4,8 +4,6 @@ PATH infra (1.0.0) aggregate_root (~> 2.13) arkency-command_bus - dry-struct - dry-types rake ruby_event_store (~> 2.13) ruby_event_store-transformations @@ -41,28 +39,8 @@ GEM diff-lcs (1.5.0) drb (2.2.0) ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.1) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) i18n (1.14.1) concurrent-ruby (~> 1.0) - ice_nine (0.11.2) minitest (5.15.0) mutant (0.11.26) diff-lcs (~> 1.3) @@ -100,7 +78,6 @@ GEM unparser (0.6.12) diff-lcs (~> 1.3) parser (>= 3.2.2.4) - zeitwerk (2.6.12) PLATFORMS arm64-darwin-20 diff --git a/infra/infra.gemspec b/infra/infra.gemspec index d11576240..d6600e089 100644 --- a/infra/infra.gemspec +++ b/infra/infra.gemspec @@ -10,8 +10,6 @@ Gem::Specification.new do |spec| spec.summary = "infrastructure for the application" spec.add_dependency "rake" - spec.add_dependency "dry-struct" - spec.add_dependency "dry-types" spec.add_dependency "aggregate_root", "~> 2.13" spec.add_dependency "arkency-command_bus" spec.add_dependency "ruby_event_store", "~> 2.13" diff --git a/infra/lib/infra.rb b/infra/lib/infra.rb index fe6255798..f1d55b580 100644 --- a/infra/lib/infra.rb +++ b/infra/lib/infra.rb @@ -1,8 +1,6 @@ require "ruby_event_store" require "aggregate_root" require "arkency/command_bus" -require "dry-struct" -require "dry-types" require "aggregate_root" require "active_support/notifications" require "minitest" @@ -15,5 +13,4 @@ require_relative "infra/event" require_relative "infra/event_store" require_relative "infra/process" -require_relative "infra/types" require_relative "infra/testing" diff --git a/infra/lib/infra/command.rb b/infra/lib/infra/command.rb index 00c1aa263..37916b6af 100644 --- a/infra/lib/infra/command.rb +++ b/infra/lib/infra/command.rb @@ -1,11 +1,5 @@ module Infra - class Command < Dry::Struct + class Command Invalid = Class.new(StandardError) - - def self.new(*) - super - rescue Dry::Struct::Error => doh - raise Invalid, doh - end end end diff --git a/infra/lib/infra/event.rb b/infra/lib/infra/event.rb index 67a10176f..2548b377c 100644 --- a/infra/lib/infra/event.rb +++ b/infra/lib/infra/event.rb @@ -1,32 +1,4 @@ -require "active_support/core_ext/hash" - module Infra class Event < RubyEventStore::Event - module WithSchema - class Schema < Dry::Struct - transform_keys(&:to_sym) - end - - module ClassMethods - extend Forwardable - def_delegators :schema, :attribute, :attribute? - - def schema - @schema ||= Class.new(Schema) - end - end - - module Constructor - def initialize(event_id: SecureRandom.uuid, metadata: nil, data: {}) - super(event_id: event_id, metadata: metadata, data: data.deep_merge(self.class.schema.new(data.deep_symbolize_keys).to_h)) - end - end - - def self.included(klass) - klass.extend WithSchema::ClassMethods - klass.include WithSchema::Constructor - end - end - include WithSchema end end diff --git a/infra/lib/infra/types.rb b/infra/lib/infra/types.rb deleted file mode 100644 index f4f1d45fb..000000000 --- a/infra/lib/infra/types.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Infra - module Types - include Dry.Types - UUID = - Types::Strict::String.constrained( - format: /\A[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}\z/i - ) - ID = Types::Strict::Integer - Metadata = - Types::Hash.schema( - timestamp: Types::Time.meta(omittable: true) - ) - OrderNumber = - Types::Strict::String.constrained(format: /\A\d{4}\/\d{2}\/\d+\z/i) - Quantity = Types::Strict::Integer.constrained(gt: 0) - Price = Types::Coercible::Decimal.constrained(gt: 0) - Value = Types::Coercible::Decimal - PercentageDiscount = Types::Coercible::Decimal.constrained(gt: 0, lteq: 100) - CouponDiscount = Types::Coercible::Float.constrained(gt: 0, lteq: 100) - UUIDQuantityHash = Types::Hash.map(UUID, Quantity) - - class VatRate < Dry::Struct - include Comparable - attribute :code, Types::String - attribute :rate, Types::Coercible::Decimal.constrained(gteq: 0, lteq: 100) - - def <=>(other) - rate <=> other.rate - end - - alias to_d rate - end - - class PostalAddress < Dry::Struct - attribute :line_1, Types::String - attribute :line_2, Types::String - attribute :line_3, Types::String - attribute :line_4, Types::String - end - end -end diff --git a/pricing_catalog_rails_app/.dockerignore b/pricing_catalog_rails_app/.dockerignore deleted file mode 100644 index 96123753a..000000000 --- a/pricing_catalog_rails_app/.dockerignore +++ /dev/null @@ -1,37 +0,0 @@ -# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. - -# Ignore git directory. -/.git/ - -# Ignore bundler config. -/.bundle - -# Ignore all environment files (except templates). -/.env* -!/.env*.erb - -# Ignore all default key files. -/config/master.key -/config/credentials/*.key - -# Ignore all logfiles and tempfiles. -/log/* -/tmp/* -!/log/.keep -!/tmp/.keep - -# Ignore pidfiles, but keep the directory. -/tmp/pids/* -!/tmp/pids/.keep - -# Ignore storage (uploaded files in development and any SQLite databases). -/storage/* -!/storage/.keep -/tmp/storage/* -!/tmp/storage/.keep - -# Ignore assets. -/node_modules/ -/app/assets/builds/* -!/app/assets/builds/.keep -/public/assets diff --git a/pricing_catalog_rails_app/.gitignore b/pricing_catalog_rails_app/.gitignore deleted file mode 100644 index 802489bb8..000000000 --- a/pricing_catalog_rails_app/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -!/log/.keep -!/storage/.keep -!/tmp/.keep -.byebug_history -.yarn-integrity -/.bundle -/config/master.key -/db/*.sqlite3* -/db/*.sqlite3-journal -/elm-stuff -/log/* -/node_modules -/public/assets -/public/packs -/public/packs-test -/storage/* -/tmp/* -/yarn-error.log -coverage -yarn-debug.log* - -/public/packs -/public/packs-test -/node_modules -/yarn-error.log -yarn-debug.log* -.yarn-integrity -.env*.local - -.idea -.ruby-version -/app/assets/builds/* -!/app/assets/builds/.keep - -# Event to handlers and handler to events mappings generated by big_picture.rb script -/lib/event_to_handlers.rb -/lib/handler_to_events.rb \ No newline at end of file diff --git a/pricing_catalog_rails_app/Dockerfile b/pricing_catalog_rails_app/Dockerfile deleted file mode 100644 index 0ffa0232b..000000000 --- a/pricing_catalog_rails_app/Dockerfile +++ /dev/null @@ -1,62 +0,0 @@ -# syntax = docker/dockerfile:1 - -# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile -ARG RUBY_VERSION=3.2.0 -FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base - -# Rails app lives here -WORKDIR /rails - -# Set production environment -ENV RAILS_ENV="production" \ - BUNDLE_DEPLOYMENT="1" \ - BUNDLE_PATH="/usr/local/bundle" \ - BUNDLE_WITHOUT="development" - - -# Throw-away build stage to reduce size of final image -FROM base as build - -# Install packages needed to build gems -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y build-essential git pkg-config - -# Install application gems -COPY Gemfile Gemfile.lock ./ -RUN bundle install && \ - rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ - bundle exec bootsnap precompile --gemfile - -# Copy application code -COPY . . - -# Precompile bootsnap code for faster boot times -RUN bundle exec bootsnap precompile app/ lib/ - -# Precompiling assets for production without requiring secret RAILS_MASTER_KEY -RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile - - -# Final stage for app image -FROM base - -# Install packages needed for deployment -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y curl libsqlite3-0 && \ - rm -rf /var/lib/apt/lists /var/cache/apt/archives - -# Copy built artifacts: gems, application -COPY --from=build /usr/local/bundle /usr/local/bundle -COPY --from=build /rails /rails - -# Run and own only the runtime files as a non-root user for security -RUN useradd rails --create-home --shell /bin/bash && \ - chown -R rails:rails db log storage tmp -USER rails:rails - -# Entrypoint prepares the database. -ENTRYPOINT ["/rails/bin/docker-entrypoint"] - -# Start the server by default, this can be overwritten at runtime -EXPOSE 3000 -CMD ["./bin/rails", "server"] diff --git a/pricing_catalog_rails_app/Gemfile b/pricing_catalog_rails_app/Gemfile deleted file mode 100644 index 124d5f633..000000000 --- a/pricing_catalog_rails_app/Gemfile +++ /dev/null @@ -1,50 +0,0 @@ -source "https://rubygems.org" - -ruby "3.2.0" -gem "rails", "~> 7.1.3" -gem "sqlite3", "~> 1.4" - -# Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" - -# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] -gem "importmap-rails" - -# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] -gem "turbo-rails" - -# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] -gem "stimulus-rails" - -# Use Redis adapter to run Action Cable in production -gem "redis", ">= 4.0.1" - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] - -# Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false - -group :development, :test do - # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[ mri windows ] -end - -group :development do - # Use console on exceptions pages [https://github.com/rails/web-console] - gem "web-console" - - # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] - # gem "rack-mini-profiler" - - # Speed up commands on slow machines / big apps [https://github.com/rails/spring] - # gem "spring" -end - -group :test do - # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] - gem "capybara" - gem "selenium-webdriver" -end -gem "rails_event_store", "~> 2.14.0" -gem "infra", path: "../infra" \ No newline at end of file diff --git a/pricing_catalog_rails_app/Gemfile.lock b/pricing_catalog_rails_app/Gemfile.lock deleted file mode 100644 index 0ddc0d01e..000000000 --- a/pricing_catalog_rails_app/Gemfile.lock +++ /dev/null @@ -1,337 +0,0 @@ -PATH - remote: ../infra - specs: - infra (1.0.0) - aggregate_root (~> 2.13) - arkency-command_bus - dry-struct - dry-types - rake - ruby_event_store (~> 2.13) - ruby_event_store-transformations - sidekiq - -GEM - remote: https://rubygems.org/ - specs: - actioncable (7.1.3) - actionpack (= 7.1.3) - activesupport (= 7.1.3) - nio4r (~> 2.0) - websocket-driver (>= 0.6.1) - zeitwerk (~> 2.6) - actionmailbox (7.1.3) - actionpack (= 7.1.3) - activejob (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.3) - actionpack (= 7.1.3) - actionview (= 7.1.3) - activejob (= 7.1.3) - activesupport (= 7.1.3) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp - rails-dom-testing (~> 2.2) - actionpack (7.1.3) - actionview (= 7.1.3) - activesupport (= 7.1.3) - nokogiri (>= 1.8.5) - racc - rack (>= 2.2.4) - rack-session (>= 1.0.1) - rack-test (>= 0.6.3) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - actiontext (7.1.3) - actionpack (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) - globalid (>= 0.6.0) - nokogiri (>= 1.8.5) - actionview (7.1.3) - activesupport (= 7.1.3) - builder (~> 3.1) - erubi (~> 1.11) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - activejob (7.1.3) - activesupport (= 7.1.3) - globalid (>= 0.3.6) - activemodel (7.1.3) - activesupport (= 7.1.3) - activerecord (7.1.3) - activemodel (= 7.1.3) - activesupport (= 7.1.3) - timeout (>= 0.4.0) - activestorage (7.1.3) - actionpack (= 7.1.3) - activejob (= 7.1.3) - activerecord (= 7.1.3) - activesupport (= 7.1.3) - marcel (~> 1.0) - activesupport (7.1.3) - 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) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) - aggregate_root (2.14.0) - base64 - ruby_event_store (= 2.14.0) - arkency-command_bus (0.4.1) - concurrent-ruby - base64 (0.2.0) - bigdecimal (3.1.6) - bindex (0.8.1) - bootsnap (1.17.1) - msgpack (~> 1.2) - builder (3.2.4) - capybara (3.40.0) - addressable - matrix - mini_mime (>= 0.1.3) - nokogiri (~> 1.11) - rack (>= 1.6.0) - rack-test (>= 0.6.3) - regexp_parser (>= 1.5, < 3.0) - xpath (~> 3.2) - concurrent-ruby (1.2.3) - connection_pool (2.4.1) - crass (1.0.6) - date (3.3.4) - debug (1.9.1) - irb (~> 1.10) - reline (>= 0.3.8) - drb (2.2.0) - ruby2_keywords - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 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-types (1.7.2) - bigdecimal (~> 3.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - erubi (1.12.0) - globalid (1.2.1) - activesupport (>= 6.1) - i18n (1.14.1) - concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - importmap-rails (2.0.1) - actionpack (>= 6.0.0) - activesupport (>= 6.0.0) - railties (>= 6.0.0) - io-console (0.7.2) - irb (1.11.1) - rdoc - reline (>= 0.4.2) - loofah (2.22.0) - crass (~> 1.0.2) - nokogiri (>= 1.12.0) - mail (2.8.1) - mini_mime (>= 0.1.1) - net-imap - net-pop - net-smtp - marcel (1.0.2) - matrix (0.4.2) - mini_mime (1.1.5) - minitest (5.21.2) - msgpack (1.7.2) - mutex_m (0.2.0) - net-imap (0.4.9.1) - date - net-protocol - net-pop (0.1.2) - net-protocol - net-protocol (0.2.2) - timeout - net-smtp (0.4.0.1) - net-protocol - nio4r (2.7.0) - nokogiri (1.16.0-aarch64-linux) - racc (~> 1.4) - nokogiri (1.16.0-arm-linux) - racc (~> 1.4) - nokogiri (1.16.0-arm64-darwin) - racc (~> 1.4) - nokogiri (1.16.0-x86-linux) - racc (~> 1.4) - nokogiri (1.16.0-x86_64-darwin) - racc (~> 1.4) - nokogiri (1.16.0-x86_64-linux) - racc (~> 1.4) - psych (5.1.2) - stringio - public_suffix (5.0.4) - puma (6.4.2) - nio4r (~> 2.0) - racc (1.7.3) - rack (3.0.8) - rack-session (2.0.0) - rack (>= 3.0.0) - rack-test (2.1.0) - rack (>= 1.3) - rackup (2.1.0) - rack (>= 3) - webrick (~> 1.8) - rails (7.1.3) - actioncable (= 7.1.3) - actionmailbox (= 7.1.3) - actionmailer (= 7.1.3) - actionpack (= 7.1.3) - actiontext (= 7.1.3) - actionview (= 7.1.3) - activejob (= 7.1.3) - activemodel (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) - bundler (>= 1.15.0) - railties (= 7.1.3) - rails-dom-testing (2.2.0) - activesupport (>= 5.0.0) - minitest - nokogiri (>= 1.6) - rails-html-sanitizer (1.6.0) - loofah (~> 2.21) - nokogiri (~> 1.14) - rails_event_store (2.14.0) - activejob (>= 6.0) - activemodel (>= 6.0) - activesupport (>= 6.0) - aggregate_root (= 2.14.0) - arkency-command_bus (>= 0.4) - rails_event_store_active_record (= 2.14.0) - ruby_event_store (= 2.14.0) - ruby_event_store-browser (= 2.14.0) - rails_event_store_active_record (2.14.0) - ruby_event_store-active_record (= 2.14.0) - railties (7.1.3) - actionpack (= 7.1.3) - activesupport (= 7.1.3) - irb - rackup (>= 1.0.0) - rake (>= 12.2) - thor (~> 1.0, >= 1.2.2) - zeitwerk (~> 2.6) - rake (13.1.0) - rdoc (6.6.2) - psych (>= 4.0.0) - redis (5.0.8) - redis-client (>= 0.17.0) - redis-client (0.19.1) - connection_pool - regexp_parser (2.9.0) - reline (0.4.2) - io-console (~> 0.5) - rexml (3.2.6) - ruby2_keywords (0.0.5) - ruby_event_store (2.14.0) - concurrent-ruby (~> 1.0, >= 1.1.6) - ruby_event_store-active_record (2.14.0) - activerecord (>= 6.0) - ruby_event_store (= 2.14.0) - ruby_event_store-browser (2.14.0) - rack - ruby_event_store (= 2.14.0) - ruby_event_store-transformations (0.1.0) - activesupport (>= 5.0) - ruby_event_store (>= 2.0.0, < 3.0.0) - rubyzip (2.3.2) - selenium-webdriver (4.17.0) - base64 (~> 0.2) - rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2, < 3.0) - websocket (~> 1.0) - sidekiq (7.2.1) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.19.0) - sqlite3 (1.7.1-aarch64-linux) - sqlite3 (1.7.1-arm-linux) - sqlite3 (1.7.1-arm64-darwin) - sqlite3 (1.7.1-x86-linux) - sqlite3 (1.7.1-x86_64-darwin) - sqlite3 (1.7.1-x86_64-linux) - stimulus-rails (1.3.3) - railties (>= 6.0.0) - stringio (3.1.0) - thor (1.3.0) - timeout (0.4.1) - turbo-rails (1.5.0) - actionpack (>= 6.0.0) - activejob (>= 6.0.0) - railties (>= 6.0.0) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - web-console (4.2.1) - actionview (>= 6.0.0) - activemodel (>= 6.0.0) - bindex (>= 0.4.0) - railties (>= 6.0.0) - webrick (1.8.1) - websocket (1.2.10) - websocket-driver (0.7.6) - websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.5) - xpath (3.2.0) - nokogiri (~> 1.8) - zeitwerk (2.6.12) - -PLATFORMS - aarch64-linux - arm-linux - arm64-darwin - x86-linux - x86_64-darwin - x86_64-linux - -DEPENDENCIES - bootsnap - capybara - debug - importmap-rails - infra! - puma (>= 5.0) - rails (~> 7.1.3) - rails_event_store (~> 2.14.0) - redis (>= 4.0.1) - selenium-webdriver - sqlite3 (~> 1.4) - stimulus-rails - turbo-rails - tzinfo-data - web-console - -BUNDLED WITH - 2.5.9 diff --git a/pricing_catalog_rails_app/README.md b/pricing_catalog_rails_app/README.md deleted file mode 100644 index 7db80e4ca..000000000 --- a/pricing_catalog_rails_app/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# README - -This README would normally document whatever steps are necessary to get the -application up and running. - -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... diff --git a/pricing_catalog_rails_app/Rakefile b/pricing_catalog_rails_app/Rakefile deleted file mode 100644 index 9a5ea7383..000000000 --- a/pricing_catalog_rails_app/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require_relative "config/application" - -Rails.application.load_tasks diff --git a/pricing_catalog_rails_app/app/admin/read_models/admin_catalog/admin_catalog.rb b/pricing_catalog_rails_app/app/admin/read_models/admin_catalog/admin_catalog.rb deleted file mode 100644 index d7cc7575f..000000000 --- a/pricing_catalog_rails_app/app/admin/read_models/admin_catalog/admin_catalog.rb +++ /dev/null @@ -1,36 +0,0 @@ -module AdminCatalog - - class Migration - def change - ActiveRecord::Base.connection.create_table :admin_catalog_products do |t| - t.string :product_id - t.string :name - t.decimal :price - - t.timestamps - end - end - end - - class Product < ActiveRecord::Base - self.table_name = 'admin_catalog_products' - end - - class Configuration - def call(event_store) - event_store.subscribe( - -> (event) {Product.create(product_id: event.data[:product_id])}, - to: [ProductCatalog::ProductRegistered]) - event_store.subscribe( - -> (event) {Product.find_by(product_id: event.data[:product_id]).update(name: event.data[:name])}, - to: [ProductCatalog::ProductNamed]) - event_store.subscribe( - -> (event) {Product.find_by(product_id: event.data[:product_id]).update(price: event.data[:price])}, - to: [Pricing::PriceSet]) - end - - private - - end - -end \ No newline at end of file diff --git a/pricing_catalog_rails_app/app/admin/read_models/admin_catalog/index.html.erb b/pricing_catalog_rails_app/app/admin/read_models/admin_catalog/index.html.erb deleted file mode 100644 index 67a6aa093..000000000 --- a/pricing_catalog_rails_app/app/admin/read_models/admin_catalog/index.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -Admin Catalog - -<%= form_for new_product, url: {controller: "admin/catalog", action: "create"} do |f| %> -

- <%= f.label :name %> - <%= f.text_field :name %> -

-

- <%= f.label :price %> - <%= f.text_field :price %> -

- <%= f.submit %> -<% end %> - - \ No newline at end of file diff --git a/pricing_catalog_rails_app/app/admin/register_product.rb b/pricing_catalog_rails_app/app/admin/register_product.rb deleted file mode 100644 index 4ca05e618..000000000 --- a/pricing_catalog_rails_app/app/admin/register_product.rb +++ /dev/null @@ -1,14 +0,0 @@ -class RegisterProduct - def call(name, price) - product_id = SecureRandom.uuid - command_bus.(ProductCatalog::RegisterProduct.new(product_id: product_id)) - command_bus.(ProductCatalog::NameProduct.new(product_id: product_id, name: name)) - command_bus.(Pricing::SetPrice.new(product_id: product_id, price: price)) - end - - private - - def command_bus - Rails.configuration.command_bus - end -end \ No newline at end of file diff --git a/pricing_catalog_rails_app/app/assets/config/manifest.js b/pricing_catalog_rails_app/app/assets/config/manifest.js deleted file mode 100644 index ddd546a0b..000000000 --- a/pricing_catalog_rails_app/app/assets/config/manifest.js +++ /dev/null @@ -1,4 +0,0 @@ -//= link_tree ../images -//= link_directory ../stylesheets .css -//= link_tree ../../javascript .js -//= link_tree ../../../vendor/javascript .js diff --git a/pricing_catalog_rails_app/app/assets/images/.keep b/pricing_catalog_rails_app/app/assets/images/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/app/assets/stylesheets/application.css b/pricing_catalog_rails_app/app/assets/stylesheets/application.css deleted file mode 100644 index 288b9ab71..000000000 --- a/pricing_catalog_rails_app/app/assets/stylesheets/application.css +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's - * vendor/assets/stylesheets directory can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any other CSS - * files in this directory. Styles in this file should be added after the last require_* statement. - * It is generally better to create a new file per style scope. - * - *= require_tree . - *= require_self - */ diff --git a/pricing_catalog_rails_app/app/channels/application_cable/channel.rb b/pricing_catalog_rails_app/app/channels/application_cable/channel.rb deleted file mode 100644 index d67269728..000000000 --- a/pricing_catalog_rails_app/app/channels/application_cable/channel.rb +++ /dev/null @@ -1,4 +0,0 @@ -module ApplicationCable - class Channel < ActionCable::Channel::Base - end -end diff --git a/pricing_catalog_rails_app/app/channels/application_cable/connection.rb b/pricing_catalog_rails_app/app/channels/application_cable/connection.rb deleted file mode 100644 index 0ff5442f4..000000000 --- a/pricing_catalog_rails_app/app/channels/application_cable/connection.rb +++ /dev/null @@ -1,4 +0,0 @@ -module ApplicationCable - class Connection < ActionCable::Connection::Base - end -end diff --git a/pricing_catalog_rails_app/app/controllers/admin/catalog_controller.rb b/pricing_catalog_rails_app/app/controllers/admin/catalog_controller.rb deleted file mode 100644 index a7a368379..000000000 --- a/pricing_catalog_rails_app/app/controllers/admin/catalog_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -class Admin::CatalogController < ApplicationController - def index - products = AdminCatalog::Product.all - prepend_view_path Rails.root.join("app", "admin", "read_models") - render template: "admin_catalog/index", - locals: { products: products, new_product: AdminCatalog::Product.new } - end - - def create - RegisterProduct.new.call( - params[:admin_catalog_product][:name], - params[:admin_catalog_product][:price] - ) - redirect_to admin_root_path - end -end \ No newline at end of file diff --git a/pricing_catalog_rails_app/app/controllers/application_controller.rb b/pricing_catalog_rails_app/app/controllers/application_controller.rb deleted file mode 100644 index 09705d12a..000000000 --- a/pricing_catalog_rails_app/app/controllers/application_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class ApplicationController < ActionController::Base -end diff --git a/pricing_catalog_rails_app/app/controllers/catalog_controller.rb b/pricing_catalog_rails_app/app/controllers/catalog_controller.rb deleted file mode 100644 index caa1185f0..000000000 --- a/pricing_catalog_rails_app/app/controllers/catalog_controller.rb +++ /dev/null @@ -1,7 +0,0 @@ -class CatalogController < ApplicationController - def index - products = PublicCatalog::Product.all - prepend_view_path Rails.root.join("app", "public", "read_models") - render template: "public_catalog/index", locals: { products: products } - end -end \ No newline at end of file diff --git a/pricing_catalog_rails_app/app/controllers/concerns/.keep b/pricing_catalog_rails_app/app/controllers/concerns/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/app/helpers/application_helper.rb b/pricing_catalog_rails_app/app/helpers/application_helper.rb deleted file mode 100644 index de6be7945..000000000 --- a/pricing_catalog_rails_app/app/helpers/application_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module ApplicationHelper -end diff --git a/pricing_catalog_rails_app/app/javascript/application.js b/pricing_catalog_rails_app/app/javascript/application.js deleted file mode 100644 index 0d7b49404..000000000 --- a/pricing_catalog_rails_app/app/javascript/application.js +++ /dev/null @@ -1,3 +0,0 @@ -// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails -import "@hotwired/turbo-rails" -import "controllers" diff --git a/pricing_catalog_rails_app/app/javascript/controllers/application.js b/pricing_catalog_rails_app/app/javascript/controllers/application.js deleted file mode 100644 index 1213e85c7..000000000 --- a/pricing_catalog_rails_app/app/javascript/controllers/application.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Application } from "@hotwired/stimulus" - -const application = Application.start() - -// Configure Stimulus development experience -application.debug = false -window.Stimulus = application - -export { application } diff --git a/pricing_catalog_rails_app/app/javascript/controllers/hello_controller.js b/pricing_catalog_rails_app/app/javascript/controllers/hello_controller.js deleted file mode 100644 index 5975c0789..000000000 --- a/pricing_catalog_rails_app/app/javascript/controllers/hello_controller.js +++ /dev/null @@ -1,7 +0,0 @@ -import { Controller } from "@hotwired/stimulus" - -export default class extends Controller { - connect() { - this.element.textContent = "Hello World!" - } -} diff --git a/pricing_catalog_rails_app/app/javascript/controllers/index.js b/pricing_catalog_rails_app/app/javascript/controllers/index.js deleted file mode 100644 index 54ad4cad4..000000000 --- a/pricing_catalog_rails_app/app/javascript/controllers/index.js +++ /dev/null @@ -1,11 +0,0 @@ -// Import and register all your controllers from the importmap under controllers/* - -import { application } from "controllers/application" - -// Eager load all controllers defined in the import map under controllers/**/*_controller -import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" -eagerLoadControllersFrom("controllers", application) - -// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!) -// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading" -// lazyLoadControllersFrom("controllers", application) diff --git a/pricing_catalog_rails_app/app/jobs/application_job.rb b/pricing_catalog_rails_app/app/jobs/application_job.rb deleted file mode 100644 index d394c3d10..000000000 --- a/pricing_catalog_rails_app/app/jobs/application_job.rb +++ /dev/null @@ -1,7 +0,0 @@ -class ApplicationJob < ActiveJob::Base - # Automatically retry jobs that encountered a deadlock - # retry_on ActiveRecord::Deadlocked - - # Most jobs are safe to ignore if the underlying records are no longer available - # discard_on ActiveJob::DeserializationError -end diff --git a/pricing_catalog_rails_app/app/models/application_record.rb b/pricing_catalog_rails_app/app/models/application_record.rb deleted file mode 100644 index b63caeb8a..000000000 --- a/pricing_catalog_rails_app/app/models/application_record.rb +++ /dev/null @@ -1,3 +0,0 @@ -class ApplicationRecord < ActiveRecord::Base - primary_abstract_class -end diff --git a/pricing_catalog_rails_app/app/models/concerns/.keep b/pricing_catalog_rails_app/app/models/concerns/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/app/public/read_models/public_catalog/index.html.erb b/pricing_catalog_rails_app/app/public/read_models/public_catalog/index.html.erb deleted file mode 100644 index a29fdc81c..000000000 --- a/pricing_catalog_rails_app/app/public/read_models/public_catalog/index.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -Catalog - - \ No newline at end of file diff --git a/pricing_catalog_rails_app/app/public/read_models/public_catalog/public_catalog.rb b/pricing_catalog_rails_app/app/public/read_models/public_catalog/public_catalog.rb deleted file mode 100644 index 39276906a..000000000 --- a/pricing_catalog_rails_app/app/public/read_models/public_catalog/public_catalog.rb +++ /dev/null @@ -1,36 +0,0 @@ -module PublicCatalog - - class Migration - def change - ActiveRecord::Base.connection.create_table :public_catalog_products do |t| - t.string :product_id - t.string :name - t.decimal :price - - t.timestamps - end - end - end - - class Product < ActiveRecord::Base - self.table_name = 'public_catalog_products' - end - - class Configuration - def call(event_store) - event_store.subscribe( - -> (event) {Product.create(product_id: event.data[:product_id])}, - to: [ProductCatalog::ProductRegistered]) - event_store.subscribe( - -> (event) {Product.find_by(product_id: event.data[:product_id]).update(name: event.data[:name])}, - to: [ProductCatalog::ProductNamed]) - event_store.subscribe( - -> (event) {Product.find_by(product_id: event.data[:product_id]).update(price: event.data[:price])}, - to: [Pricing::PriceSet]) - end - - private - - end - -end \ No newline at end of file diff --git a/pricing_catalog_rails_app/app/views/layouts/application.html.erb b/pricing_catalog_rails_app/app/views/layouts/application.html.erb deleted file mode 100644 index 453940f01..000000000 --- a/pricing_catalog_rails_app/app/views/layouts/application.html.erb +++ /dev/null @@ -1,16 +0,0 @@ - - - - PricingCatalogRailsApp - - <%= csrf_meta_tags %> - <%= csp_meta_tag %> - - <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> - <%= javascript_importmap_tags %> - - - - <%= yield %> - - diff --git a/pricing_catalog_rails_app/bin/bundle b/pricing_catalog_rails_app/bin/bundle deleted file mode 100755 index 50da5fdf9..000000000 --- a/pricing_catalog_rails_app/bin/bundle +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# -# This file was generated by Bundler. -# -# The application 'bundle' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "rubygems" - -m = Module.new do - module_function - - def invoked_as_script? - File.expand_path($0) == File.expand_path(__FILE__) - end - - def env_var_version - ENV["BUNDLER_VERSION"] - end - - def cli_arg_version - return unless invoked_as_script? # don't want to hijack other binstubs - return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` - bundler_version = nil - update_index = nil - ARGV.each_with_index do |a, i| - if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN) - bundler_version = a - end - next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ - bundler_version = $1 - update_index = i - end - bundler_version - end - - def gemfile - gemfile = ENV["BUNDLE_GEMFILE"] - return gemfile if gemfile && !gemfile.empty? - - File.expand_path("../Gemfile", __dir__) - end - - def lockfile - lockfile = - case File.basename(gemfile) - when "gems.rb" then gemfile.sub(/\.rb$/, ".locked") - else "#{gemfile}.lock" - end - File.expand_path(lockfile) - end - - def lockfile_version - return unless File.file?(lockfile) - lockfile_contents = File.read(lockfile) - return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ - Regexp.last_match(1) - end - - def bundler_requirement - @bundler_requirement ||= - env_var_version || - cli_arg_version || - bundler_requirement_for(lockfile_version) - end - - def bundler_requirement_for(version) - return "#{Gem::Requirement.default}.a" unless version - - bundler_gem_version = Gem::Version.new(version) - - bundler_gem_version.approximate_recommendation - end - - def load_bundler! - ENV["BUNDLE_GEMFILE"] ||= gemfile - - activate_bundler - end - - def activate_bundler - gem_error = activation_error_handling do - gem "bundler", bundler_requirement - end - return if gem_error.nil? - require_error = activation_error_handling do - require "bundler/version" - end - return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) - warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" - exit 42 - end - - def activation_error_handling - yield - nil - rescue StandardError, LoadError => e - e - end -end - -m.load_bundler! - -if m.invoked_as_script? - load Gem.bin_path("bundler", "bundle") -end diff --git a/pricing_catalog_rails_app/bin/docker-entrypoint b/pricing_catalog_rails_app/bin/docker-entrypoint deleted file mode 100755 index 67ef49314..000000000 --- a/pricing_catalog_rails_app/bin/docker-entrypoint +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -e - -# If running the rails server then create or migrate existing database -if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then - ./bin/rails db:prepare -fi - -exec "${@}" diff --git a/pricing_catalog_rails_app/bin/importmap b/pricing_catalog_rails_app/bin/importmap deleted file mode 100755 index 36502ab16..000000000 --- a/pricing_catalog_rails_app/bin/importmap +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby - -require_relative "../config/application" -require "importmap/commands" diff --git a/pricing_catalog_rails_app/bin/rails b/pricing_catalog_rails_app/bin/rails deleted file mode 100755 index efc037749..000000000 --- a/pricing_catalog_rails_app/bin/rails +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby -APP_PATH = File.expand_path("../config/application", __dir__) -require_relative "../config/boot" -require "rails/commands" diff --git a/pricing_catalog_rails_app/bin/rake b/pricing_catalog_rails_app/bin/rake deleted file mode 100755 index 4fbf10b96..000000000 --- a/pricing_catalog_rails_app/bin/rake +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby -require_relative "../config/boot" -require "rake" -Rake.application.run diff --git a/pricing_catalog_rails_app/bin/setup b/pricing_catalog_rails_app/bin/setup deleted file mode 100755 index 3cd5a9d78..000000000 --- a/pricing_catalog_rails_app/bin/setup +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env ruby -require "fileutils" - -# path to your application root. -APP_ROOT = File.expand_path("..", __dir__) - -def system!(*args) - system(*args, exception: true) -end - -FileUtils.chdir APP_ROOT do - # This script is a way to set up or update your development environment automatically. - # This script is idempotent, so that you can run it at any time and get an expectable outcome. - # Add necessary setup steps to this file. - - puts "== Installing dependencies ==" - system! "gem install bundler --conservative" - system("bundle check") || system!("bundle install") - - # puts "\n== Copying sample files ==" - # unless File.exist?("config/database.yml") - # FileUtils.cp "config/database.yml.sample", "config/database.yml" - # end - - puts "\n== Preparing database ==" - system! "bin/rails db:prepare" - - puts "\n== Removing old logs and tempfiles ==" - system! "bin/rails log:clear tmp:clear" - - puts "\n== Restarting application server ==" - system! "bin/rails restart" -end diff --git a/pricing_catalog_rails_app/config.ru b/pricing_catalog_rails_app/config.ru deleted file mode 100644 index 4a3c09a68..000000000 --- a/pricing_catalog_rails_app/config.ru +++ /dev/null @@ -1,6 +0,0 @@ -# This file is used by Rack-based servers to start the application. - -require_relative "config/environment" - -run Rails.application -Rails.application.load_server diff --git a/pricing_catalog_rails_app/config/application.rb b/pricing_catalog_rails_app/config/application.rb deleted file mode 100644 index 780a71cca..000000000 --- a/pricing_catalog_rails_app/config/application.rb +++ /dev/null @@ -1,39 +0,0 @@ -require_relative "boot" - -require "rails" -# Pick the frameworks you want: -require "active_model/railtie" -require "active_job/railtie" -require "active_record/railtie" -# require "active_storage/engine" -require "action_controller/railtie" -# require "action_mailer/railtie" -# require "action_mailbox/engine" -# require "action_text/engine" -require "action_view/railtie" -require "action_cable/engine" -require "rails/test_unit/railtie" - -# Require the gems listed in Gemfile, including any gems -# you've limited to :test, :development, or :production. -Bundler.require(*Rails.groups) - -module PricingCatalogRailsApp - class Application < Rails::Application - # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.1 - - # Please, add to the `ignore` list any other `lib` subdirectories that do - # not contain `.rb` files, or that should not be reloaded or eager loaded. - # Common ones are `templates`, `generators`, or `middleware`, for example. - config.autoload_lib(ignore: %w(assets tasks)) - - # Configuration for the application, engines, and railties goes here. - # - # These settings can be overridden in specific environments using the files - # in config/environments, which are processed later. - # - # config.time_zone = "Central Time (US & Canada)" - # config.eager_load_paths << Rails.root.join("extras") - end -end diff --git a/pricing_catalog_rails_app/config/boot.rb b/pricing_catalog_rails_app/config/boot.rb deleted file mode 100644 index 988a5ddc4..000000000 --- a/pricing_catalog_rails_app/config/boot.rb +++ /dev/null @@ -1,4 +0,0 @@ -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) - -require "bundler/setup" # Set up gems listed in the Gemfile. -require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/pricing_catalog_rails_app/config/cable.yml b/pricing_catalog_rails_app/config/cable.yml deleted file mode 100644 index 2d44db85c..000000000 --- a/pricing_catalog_rails_app/config/cable.yml +++ /dev/null @@ -1,11 +0,0 @@ -development: - adapter: redis - url: redis://localhost:6379/1 - -test: - adapter: test - -production: - adapter: redis - url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> - channel_prefix: pricing_catalog_rails_app_production diff --git a/pricing_catalog_rails_app/config/credentials.yml.enc b/pricing_catalog_rails_app/config/credentials.yml.enc deleted file mode 100644 index 0f0dfd275..000000000 --- a/pricing_catalog_rails_app/config/credentials.yml.enc +++ /dev/null @@ -1 +0,0 @@ -1bVsLr2aTAhLscEGzm9z9M6tAEvNNqGbM+wJgoEaQFkaXELdbldo0WLR2WfGRmKICorkE4reE6N47g30nr0XIHRly9lfRb0/pSXxZY06X37RF+C/amRJJ4G0bqxJTwjcE1GBQ0x3Xv7WZnj0YvIVAfZX1pa3OS4piVDHCgvf/03a5PGcSJxcfF8xbYbHb5NLWIJtJ//mjPpOZiFnJh0W7PKsP0N2KeqjPIvyb97EcOw2l6UKf9pV1ZhkOWUf6RWc3MzfvPVQkvW7qPe6CUVNWp34w5/8eZCFAtNHw9v57A/GF148I3C8p6xuF3/B74xL3yuw/xE//RdwT2Tw0BwtOOFePK+iuxEBZDhZxwDCmB8VuWr0Fai0tI4jx7DUIPC1f2inoDLb+3zrd8Yjc2I8xC0UHDDB--mwsUJW1WffHciEwk--Ih++i+PuMS7pOk1yjdDf9Q== \ No newline at end of file diff --git a/pricing_catalog_rails_app/config/database.yml b/pricing_catalog_rails_app/config/database.yml deleted file mode 100644 index 796466ba2..000000000 --- a/pricing_catalog_rails_app/config/database.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SQLite. Versions 3.8.0 and up are supported. -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem "sqlite3" -# -default: &default - adapter: sqlite3 - pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> - timeout: 5000 - -development: - <<: *default - database: storage/development.sqlite3 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - <<: *default - database: storage/test.sqlite3 - -production: - <<: *default - database: storage/production.sqlite3 diff --git a/pricing_catalog_rails_app/config/environment.rb b/pricing_catalog_rails_app/config/environment.rb deleted file mode 100644 index cac531577..000000000 --- a/pricing_catalog_rails_app/config/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Load the Rails application. -require_relative "application" - -# Initialize the Rails application. -Rails.application.initialize! diff --git a/pricing_catalog_rails_app/config/environments/development.rb b/pricing_catalog_rails_app/config/environments/development.rb deleted file mode 100644 index 94c3ba6ab..000000000 --- a/pricing_catalog_rails_app/config/environments/development.rb +++ /dev/null @@ -1,65 +0,0 @@ -require "active_support/core_ext/integer/time" - -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # In the development environment your application's code is reloaded any time - # it changes. This slows down response time but is perfect for development - # since you don't have to restart the web server when you make code changes. - config.enable_reloading = true - - # Do not eager load code on boot. - config.eager_load = false - - # Show full error reports. - config.consider_all_requests_local = true - - # Enable server timing - config.server_timing = true - - # Enable/disable caching. By default caching is disabled. - # Run rails dev:cache to toggle caching. - if Rails.root.join("tmp/caching-dev.txt").exist? - config.action_controller.perform_caching = true - config.action_controller.enable_fragment_cache_logging = true - - config.cache_store = :memory_store - config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{2.days.to_i}" - } - else - config.action_controller.perform_caching = false - - config.cache_store = :null_store - end - - # Print deprecation notices to the Rails logger. - config.active_support.deprecation = :log - - # Raise exceptions for disallowed deprecations. - config.active_support.disallowed_deprecation = :raise - - # Tell Active Support which deprecation messages to disallow. - config.active_support.disallowed_deprecation_warnings = [] - - # Raise an error on page load if there are pending migrations. - config.active_record.migration_error = :page_load - - # Highlight code that triggered database queries in logs. - config.active_record.verbose_query_logs = true - - # Highlight code that enqueued background job in logs. - config.active_job.verbose_enqueue_logs = true - - # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true - - # Annotate rendered view with file names. - # config.action_view.annotate_rendered_view_with_filenames = true - - # Uncomment if you wish to allow Action Cable access from any origin. - # config.action_cable.disable_request_forgery_protection = true - - # Raise error when a before_action's only/except options reference missing actions - config.action_controller.raise_on_missing_callback_actions = true -end diff --git a/pricing_catalog_rails_app/config/environments/production.rb b/pricing_catalog_rails_app/config/environments/production.rb deleted file mode 100644 index 5f66ca6ab..000000000 --- a/pricing_catalog_rails_app/config/environments/production.rb +++ /dev/null @@ -1,88 +0,0 @@ -require "active_support/core_ext/integer/time" - -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # Code is not reloaded between requests. - config.enable_reloading = false - - # Eager load code on boot. This eager loads most of Rails and - # your application in memory, allowing both threaded web servers - # and those relying on copy on write to perform better. - # Rake tasks automatically ignore this option for performance. - config.eager_load = true - - # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false - config.action_controller.perform_caching = true - - # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment - # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). - # config.require_master_key = true - - # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. - # config.public_file_server.enabled = false - - # Compress CSS using a preprocessor. - # config.assets.css_compressor = :sass - - # Do not fall back to assets pipeline if a precompiled asset is missed. - config.assets.compile = false - - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.asset_host = "http://assets.example.com" - - # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache - # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX - - # Mount Action Cable outside main process or domain. - # config.action_cable.mount_path = nil - # config.action_cable.url = "wss://example.com/cable" - # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] - - # Assume all access to the app is happening through a SSL-terminating reverse proxy. - # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. - # config.assume_ssl = true - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - config.force_ssl = true - - # Log to STDOUT by default - config.logger = ActiveSupport::Logger.new(STDOUT) - .tap { |logger| logger.formatter = ::Logger::Formatter.new } - .then { |logger| ActiveSupport::TaggedLogging.new(logger) } - - # Prepend all log lines with the following tags. - config.log_tags = [ :request_id ] - - # "info" includes generic and useful information about system operation, but avoids logging too much - # information to avoid inadvertent exposure of personally identifiable information (PII). If you - # want to log everything, set the level to "debug". - config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") - - # Use a different cache store in production. - # config.cache_store = :mem_cache_store - - # Use a real queuing backend for Active Job (and separate queues per environment). - # config.active_job.queue_adapter = :resque - # config.active_job.queue_name_prefix = "pricing_catalog_rails_app_production" - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation cannot be found). - config.i18n.fallbacks = true - - # Don't log any deprecations. - config.active_support.report_deprecations = false - - # Do not dump schema after migrations. - config.active_record.dump_schema_after_migration = false - - # Enable DNS rebinding protection and other `Host` header attacks. - # config.hosts = [ - # "example.com", # Allow requests from example.com - # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` - # ] - # Skip DNS rebinding protection for the default health check endpoint. - # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } -end diff --git a/pricing_catalog_rails_app/config/environments/test.rb b/pricing_catalog_rails_app/config/environments/test.rb deleted file mode 100644 index d349c3556..000000000 --- a/pricing_catalog_rails_app/config/environments/test.rb +++ /dev/null @@ -1,54 +0,0 @@ -require "active_support/core_ext/integer/time" - -# The test environment is used exclusively to run your application's -# test suite. You never need to work with it otherwise. Remember that -# your test database is "scratch space" for the test suite and is wiped -# and recreated between test runs. Don't rely on the data there! - -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # While tests run files are not watched, reloading is not necessary. - config.enable_reloading = false - - # Eager loading loads your entire application. When running a single test locally, - # this is usually not necessary, and can slow down your test suite. However, it's - # recommended that you enable it in continuous integration systems to ensure eager - # loading is working properly before deploying your code. - config.eager_load = ENV["CI"].present? - - # Configure public file server for tests with Cache-Control for performance. - config.public_file_server.enabled = true - config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{1.hour.to_i}" - } - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - config.cache_store = :null_store - - # Render exception templates for rescuable exceptions and raise for other exceptions. - config.action_dispatch.show_exceptions = :rescuable - - # Disable request forgery protection in test environment. - config.action_controller.allow_forgery_protection = false - - # Print deprecation notices to the stderr. - config.active_support.deprecation = :stderr - - # Raise exceptions for disallowed deprecations. - config.active_support.disallowed_deprecation = :raise - - # Tell Active Support which deprecation messages to disallow. - config.active_support.disallowed_deprecation_warnings = [] - - # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true - - # Annotate rendered view with file names. - # config.action_view.annotate_rendered_view_with_filenames = true - - # Raise error when a before_action's only/except options reference missing actions - config.action_controller.raise_on_missing_callback_actions = true -end diff --git a/pricing_catalog_rails_app/config/importmap.rb b/pricing_catalog_rails_app/config/importmap.rb deleted file mode 100644 index bc060edb7..000000000 --- a/pricing_catalog_rails_app/config/importmap.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Pin npm packages by running ./bin/importmap - -pin "application" -pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true -pin "@hotwired/stimulus", to: "stimulus.min.js" -pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" -pin_all_from "app/javascript/controllers", under: "controllers" diff --git a/pricing_catalog_rails_app/config/initializers/content_security_policy.rb b/pricing_catalog_rails_app/config/initializers/content_security_policy.rb deleted file mode 100644 index b3076b38f..000000000 --- a/pricing_catalog_rails_app/config/initializers/content_security_policy.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Define an application-wide content security policy. -# See the Securing Rails Applications Guide for more information: -# https://guides.rubyonrails.org/security.html#content-security-policy-header - -# Rails.application.configure do -# config.content_security_policy do |policy| -# policy.default_src :self, :https -# policy.font_src :self, :https, :data -# policy.img_src :self, :https, :data -# policy.object_src :none -# policy.script_src :self, :https -# policy.style_src :self, :https -# # Specify URI for violation reports -# # policy.report_uri "/csp-violation-report-endpoint" -# end -# -# # Generate session nonces for permitted importmap, inline scripts, and inline styles. -# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } -# config.content_security_policy_nonce_directives = %w(script-src style-src) -# -# # Report violations without enforcing the policy. -# # config.content_security_policy_report_only = true -# end diff --git a/pricing_catalog_rails_app/config/initializers/filter_parameter_logging.rb b/pricing_catalog_rails_app/config/initializers/filter_parameter_logging.rb deleted file mode 100644 index c2d89e28a..000000000 --- a/pricing_catalog_rails_app/config/initializers/filter_parameter_logging.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. -# Use this to limit dissemination of sensitive information. -# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. -Rails.application.config.filter_parameters += [ - :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn -] diff --git a/pricing_catalog_rails_app/config/initializers/inflections.rb b/pricing_catalog_rails_app/config/initializers/inflections.rb deleted file mode 100644 index 3860f659e..000000000 --- a/pricing_catalog_rails_app/config/initializers/inflections.rb +++ /dev/null @@ -1,16 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format. Inflections -# are locale specific, and you may define rules for as many different -# locales as you wish. All of these examples are active by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.plural /^(ox)$/i, "\\1en" -# inflect.singular /^(ox)en/i, "\\1" -# inflect.irregular "person", "people" -# inflect.uncountable %w( fish sheep ) -# end - -# These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.acronym "RESTful" -# end diff --git a/pricing_catalog_rails_app/config/initializers/permissions_policy.rb b/pricing_catalog_rails_app/config/initializers/permissions_policy.rb deleted file mode 100644 index 7db3b9577..000000000 --- a/pricing_catalog_rails_app/config/initializers/permissions_policy.rb +++ /dev/null @@ -1,13 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Define an application-wide HTTP permissions policy. For further -# information see: https://developers.google.com/web/updates/2018/06/feature-policy - -# Rails.application.config.permissions_policy do |policy| -# policy.camera :none -# policy.gyroscope :none -# policy.microphone :none -# policy.usb :none -# policy.fullscreen :self -# policy.payment :self, "https://secure.example.com" -# end diff --git a/pricing_catalog_rails_app/config/initializers/rails_event_store.rb b/pricing_catalog_rails_app/config/initializers/rails_event_store.rb deleted file mode 100644 index 78bde65ea..000000000 --- a/pricing_catalog_rails_app/config/initializers/rails_event_store.rb +++ /dev/null @@ -1,38 +0,0 @@ -require_relative "../../../ecommerce/pricing/lib/pricing" -require_relative "../../../ecommerce/product_catalog//lib/product_catalog" -require_relative "../../../infra/lib/infra" -require "rails_event_store" -require "arkency/command_bus" -require_relative "../../app/public/read_models/public_catalog/public_catalog" -require_relative "../../app/admin/read_models/admin_catalog/admin_catalog" - -Rails.configuration.to_prepare do - Rails.configuration.event_store = Infra::EventStore.main - Rails.configuration.command_bus = Arkency::CommandBus.new - Configuration.new.call(Rails.configuration.event_store, Rails.configuration.command_bus) -end - -class Configuration - def call(event_store, command_bus) - enable_res_infra_event_linking(event_store) - [ - Pricing::Configuration.new, - ProductCatalog::Configuration.new, - ].each { |c| c.call(event_store, command_bus) } - PublicCatalog::Configuration.new.call(event_store) - AdminCatalog::Configuration.new.call(event_store) - - end - - private - - def enable_res_infra_event_linking(event_store) - [ - RailsEventStore::LinkByEventType.new, - RailsEventStore::LinkByCorrelationId.new, - RailsEventStore::LinkByCausationId.new - ].each { |h| event_store.subscribe_to_all_events(h) } - end - -end - diff --git a/pricing_catalog_rails_app/config/locales/en.yml b/pricing_catalog_rails_app/config/locales/en.yml deleted file mode 100644 index 6c349ae5e..000000000 --- a/pricing_catalog_rails_app/config/locales/en.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Files in the config/locales directory are used for internationalization and -# are automatically loaded by Rails. If you want to use locales other than -# English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t "hello" -# -# In views, this is aliased to just `t`: -# -# <%= t("hello") %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# To learn more about the API, please read the Rails Internationalization guide -# at https://guides.rubyonrails.org/i18n.html. -# -# Be aware that YAML interprets the following case-insensitive strings as -# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings -# must be quoted to be interpreted as strings. For example: -# -# en: -# "yes": yup -# enabled: "ON" - -en: - hello: "Hello world" diff --git a/pricing_catalog_rails_app/config/master.key b/pricing_catalog_rails_app/config/master.key deleted file mode 100644 index 9bcdf7473..000000000 --- a/pricing_catalog_rails_app/config/master.key +++ /dev/null @@ -1 +0,0 @@ -c2400f761b119d3f092a64d00bad9fdc \ No newline at end of file diff --git a/pricing_catalog_rails_app/config/puma.rb b/pricing_catalog_rails_app/config/puma.rb deleted file mode 100644 index afa809b43..000000000 --- a/pricing_catalog_rails_app/config/puma.rb +++ /dev/null @@ -1,35 +0,0 @@ -# This configuration file will be evaluated by Puma. The top-level methods that -# are invoked here are part of Puma's configuration DSL. For more information -# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. - -# Puma can serve each request in a thread from an internal thread pool. -# The `threads` method setting takes two numbers: a minimum and maximum. -# Any libraries that use thread pools should be configured to match -# the maximum value specified for Puma. Default is set to 5 threads for minimum -# and maximum; this matches the default thread size of Active Record. -max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } -min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } -threads min_threads_count, max_threads_count - -# Specifies that the worker count should equal the number of processors in production. -if ENV["RAILS_ENV"] == "production" - require "concurrent-ruby" - worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count }) - workers worker_count if worker_count > 1 -end - -# Specifies the `worker_timeout` threshold that Puma will use to wait before -# terminating a worker in development environments. -worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" - -# Specifies the `port` that Puma will listen on to receive requests; default is 3000. -port ENV.fetch("PORT") { 3000 } - -# Specifies the `environment` that Puma will run in. -environment ENV.fetch("RAILS_ENV") { "development" } - -# Specifies the `pidfile` that Puma will use. -pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } - -# Allow puma to be restarted by `bin/rails restart` command. -plugin :tmp_restart diff --git a/pricing_catalog_rails_app/config/routes.rb b/pricing_catalog_rails_app/config/routes.rb deleted file mode 100644 index e77d0686b..000000000 --- a/pricing_catalog_rails_app/config/routes.rb +++ /dev/null @@ -1,16 +0,0 @@ -Rails.application.routes.draw do - mount RailsEventStore::Browser => '/res' if Rails.env.development? - # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html - - # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. - # Can be used by load balancers and uptime monitors to verify that the app is live. - get "up" => "rails/health#show", as: :rails_health_check - - # Defines the root path route ("/") - root "catalog#index" - - namespace :admin do - root "catalog#index" - post "catalog", to: "catalog#create" - end -end diff --git a/pricing_catalog_rails_app/db/migrate/20240130110320_create_event_store_events.rb b/pricing_catalog_rails_app/db/migrate/20240130110320_create_event_store_events.rb deleted file mode 100644 index 70389537c..000000000 --- a/pricing_catalog_rails_app/db/migrate/20240130110320_create_event_store_events.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -class CreateEventStoreEvents < ActiveRecord::Migration[7.1] - def change - create_table(:event_store_events_in_streams, force: false) do |t| - t.string :stream, null: false - t.integer :position, null: true - t.references :event, null: false, type: :string, limit: 36, index: false - t.datetime :created_at, null: false, precision: 6, index: true - end - add_index :event_store_events_in_streams, [:stream, :position], unique: true - add_index :event_store_events_in_streams, [:stream, :event_id], unique: true - add_index :event_store_events_in_streams, [:event_id] - - create_table(:event_store_events, force: false) do |t| - t.references :event, null: false, type: :string, limit: 36, index: { unique: true } - t.string :event_type, null: false, index: true - t.binary :metadata - t.binary :data, null: false - t.datetime :created_at, null: false, precision: 6, index: true - t.datetime :valid_at, null: true, precision: 6, index: true - end - - add_foreign_key "event_store_events_in_streams", "event_store_events", column: "event_id", primary_key: "event_id" - end -end diff --git a/pricing_catalog_rails_app/db/migrate/20240201132941_enable_pg_crypto.rb b/pricing_catalog_rails_app/db/migrate/20240201132941_enable_pg_crypto.rb deleted file mode 100644 index aa1d05d93..000000000 --- a/pricing_catalog_rails_app/db/migrate/20240201132941_enable_pg_crypto.rb +++ /dev/null @@ -1,5 +0,0 @@ -class EnablePgCrypto < ActiveRecord::Migration[7.1] - def change - enable_extension "pgcrypto" - end -end diff --git a/pricing_catalog_rails_app/db/migrate/20240201133038_create_products_table.rb b/pricing_catalog_rails_app/db/migrate/20240201133038_create_products_table.rb deleted file mode 100644 index 035f3be94..000000000 --- a/pricing_catalog_rails_app/db/migrate/20240201133038_create_products_table.rb +++ /dev/null @@ -1,5 +0,0 @@ -class CreateProductsTable < ActiveRecord::Migration[7.1] - def change - PublicCatalog::Migration.new.change - end -end diff --git a/pricing_catalog_rails_app/db/migrate/20240201154705_create_admin_products.rb b/pricing_catalog_rails_app/db/migrate/20240201154705_create_admin_products.rb deleted file mode 100644 index dd7f3b56a..000000000 --- a/pricing_catalog_rails_app/db/migrate/20240201154705_create_admin_products.rb +++ /dev/null @@ -1,5 +0,0 @@ -class CreateAdminProducts < ActiveRecord::Migration[7.1] - def change - AdminCatalog::Migration.new.change - end -end diff --git a/pricing_catalog_rails_app/db/schema.rb b/pricing_catalog_rails_app/db/schema.rb deleted file mode 100644 index f73ac726f..000000000 --- a/pricing_catalog_rails_app/db/schema.rb +++ /dev/null @@ -1,55 +0,0 @@ -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# This file is the source Rails uses to define your schema when running `bin/rails -# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to -# be faster and is potentially less error prone than running all of your -# migrations from scratch. Old migrations may fail to apply correctly if those -# migrations use external dependencies or application code. -# -# It's strongly recommended that you check this file into your version control system. - -ActiveRecord::Schema[7.1].define(version: 2024_02_01_154705) do - create_table "admin_catalog_products", force: :cascade do |t| - t.string "product_id" - t.string "name" - t.decimal "price" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "event_store_events", force: :cascade do |t| - t.string "event_id", limit: 36, null: false - t.string "event_type", null: false - t.binary "metadata" - t.binary "data", null: false - t.datetime "created_at", null: false - t.datetime "valid_at" - t.index ["created_at"], name: "index_event_store_events_on_created_at" - t.index ["event_id"], name: "index_event_store_events_on_event_id", unique: true - t.index ["event_type"], name: "index_event_store_events_on_event_type" - t.index ["valid_at"], name: "index_event_store_events_on_valid_at" - end - - create_table "event_store_events_in_streams", force: :cascade do |t| - t.string "stream", null: false - t.integer "position" - t.string "event_id", limit: 36, null: false - t.datetime "created_at", null: false - t.index ["created_at"], name: "index_event_store_events_in_streams_on_created_at" - t.index ["event_id"], name: "index_event_store_events_in_streams_on_event_id" - t.index ["stream", "event_id"], name: "index_event_store_events_in_streams_on_stream_and_event_id", unique: true - t.index ["stream", "position"], name: "index_event_store_events_in_streams_on_stream_and_position", unique: true - end - - create_table "public_catalog_products", force: :cascade do |t| - t.string "product_id" - t.string "name" - t.decimal "price" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - add_foreign_key "event_store_events_in_streams", "event_store_events", column: "event_id", primary_key: "event_id" -end diff --git a/pricing_catalog_rails_app/db/seeds.rb b/pricing_catalog_rails_app/db/seeds.rb deleted file mode 100644 index 4fbd6ed97..000000000 --- a/pricing_catalog_rails_app/db/seeds.rb +++ /dev/null @@ -1,9 +0,0 @@ -# This file should ensure the existence of records required to run the application in every environment (production, -# development, test). The code here should be idempotent so that it can be executed at any point in every environment. -# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). -# -# Example: -# -# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| -# MovieGenre.find_or_create_by!(name: genre_name) -# end diff --git a/pricing_catalog_rails_app/lib/assets/.keep b/pricing_catalog_rails_app/lib/assets/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/lib/tasks/.keep b/pricing_catalog_rails_app/lib/tasks/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/log/.keep b/pricing_catalog_rails_app/log/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/public/404.html b/pricing_catalog_rails_app/public/404.html deleted file mode 100644 index 2be3af26f..000000000 --- a/pricing_catalog_rails_app/public/404.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - - -
-
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/pricing_catalog_rails_app/public/422.html b/pricing_catalog_rails_app/public/422.html deleted file mode 100644 index c08eac0d1..000000000 --- a/pricing_catalog_rails_app/public/422.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - - -
-
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/pricing_catalog_rails_app/public/500.html b/pricing_catalog_rails_app/public/500.html deleted file mode 100644 index 78a030af2..000000000 --- a/pricing_catalog_rails_app/public/500.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - - -
-
-

We're sorry, but something went wrong.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/pricing_catalog_rails_app/public/apple-touch-icon-precomposed.png b/pricing_catalog_rails_app/public/apple-touch-icon-precomposed.png deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/public/apple-touch-icon.png b/pricing_catalog_rails_app/public/apple-touch-icon.png deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/public/favicon.ico b/pricing_catalog_rails_app/public/favicon.ico deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/public/robots.txt b/pricing_catalog_rails_app/public/robots.txt deleted file mode 100644 index c19f78ab6..000000000 --- a/pricing_catalog_rails_app/public/robots.txt +++ /dev/null @@ -1 +0,0 @@ -# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/pricing_catalog_rails_app/storage/.keep b/pricing_catalog_rails_app/storage/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/test/application_system_test_case.rb b/pricing_catalog_rails_app/test/application_system_test_case.rb deleted file mode 100644 index d19212abd..000000000 --- a/pricing_catalog_rails_app/test/application_system_test_case.rb +++ /dev/null @@ -1,5 +0,0 @@ -require "test_helper" - -class ApplicationSystemTestCase < ActionDispatch::SystemTestCase - driven_by :selenium, using: :chrome, screen_size: [1400, 1400] -end diff --git a/pricing_catalog_rails_app/test/channels/application_cable/connection_test.rb b/pricing_catalog_rails_app/test/channels/application_cable/connection_test.rb deleted file mode 100644 index 6340bf9c0..000000000 --- a/pricing_catalog_rails_app/test/channels/application_cable/connection_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "test_helper" - -module ApplicationCable - class ConnectionTest < ActionCable::Connection::TestCase - # test "connects with cookies" do - # cookies.signed[:user_id] = 42 - # - # connect - # - # assert_equal connection.user_id, "42" - # end - end -end diff --git a/pricing_catalog_rails_app/test/controllers/.keep b/pricing_catalog_rails_app/test/controllers/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/test/fixtures/files/.keep b/pricing_catalog_rails_app/test/fixtures/files/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/test/helpers/.keep b/pricing_catalog_rails_app/test/helpers/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/test/integration/.keep b/pricing_catalog_rails_app/test/integration/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/test/models/.keep b/pricing_catalog_rails_app/test/models/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/test/system/.keep b/pricing_catalog_rails_app/test/system/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/test/test_helper.rb b/pricing_catalog_rails_app/test/test_helper.rb deleted file mode 100644 index 0c22470ec..000000000 --- a/pricing_catalog_rails_app/test/test_helper.rb +++ /dev/null @@ -1,15 +0,0 @@ -ENV["RAILS_ENV"] ||= "test" -require_relative "../config/environment" -require "rails/test_help" - -module ActiveSupport - class TestCase - # Run tests in parallel with specified workers - parallelize(workers: :number_of_processors) - - # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. - fixtures :all - - # Add more helper methods to be used by all tests here... - end -end diff --git a/pricing_catalog_rails_app/tmp/.keep b/pricing_catalog_rails_app/tmp/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/tmp/local_secret.txt b/pricing_catalog_rails_app/tmp/local_secret.txt deleted file mode 100644 index 56a4593b2..000000000 --- a/pricing_catalog_rails_app/tmp/local_secret.txt +++ /dev/null @@ -1 +0,0 @@ -4b650a883751aa8985f1c1e9bc291ec5dd22575339d1415cb6ca116e77fc00e6f30ae882aae0a55cc22a7611693563e3e6e3eb07b07726a4628a5665e47b54a3 \ No newline at end of file diff --git a/pricing_catalog_rails_app/tmp/pids/.keep b/pricing_catalog_rails_app/tmp/pids/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/tmp/storage/.keep b/pricing_catalog_rails_app/tmp/storage/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/vendor/.keep b/pricing_catalog_rails_app/vendor/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/pricing_catalog_rails_app/vendor/javascript/.keep b/pricing_catalog_rails_app/vendor/javascript/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/rails_application/Gemfile.lock b/rails_application/Gemfile.lock index e2c06151a..7d4136b4e 100644 --- a/rails_application/Gemfile.lock +++ b/rails_application/Gemfile.lock @@ -4,8 +4,6 @@ PATH infra (1.0.0) aggregate_root (~> 2.13) arkency-command_bus - dry-struct - dry-types rake ruby_event_store (~> 2.13) ruby_event_store-transformations @@ -105,28 +103,6 @@ GEM dotenv-rails (2.7.6) dotenv (= 2.7.6) railties (>= 3.2) - dry-configurable (0.15.0) - concurrent-ruby (~> 1.0) - dry-core (~> 0.6) - dry-container (0.9.0) - concurrent-ruby (~> 1.0) - dry-configurable (~> 0.13, >= 0.13.0) - dry-core (0.7.1) - concurrent-ruby (~> 1.0) - dry-inflector (0.2.1) - dry-logic (1.2.0) - concurrent-ruby (~> 1.0) - dry-core (~> 0.5, >= 0.5) - dry-struct (1.4.0) - dry-core (~> 0.5, >= 0.5) - dry-types (~> 1.5) - ice_nine (~> 0.11) - dry-types (1.5.1) - concurrent-ruby (~> 1.0) - dry-container (~> 0.3) - dry-core (~> 0.5, >= 0.5) - dry-inflector (~> 0.1, >= 0.1.2) - dry-logic (~> 1.0, >= 1.0.2) erubi (1.11.0) ffi (1.15.5) globalid (1.2.1) @@ -134,7 +110,6 @@ GEM honeybadger (4.9.0) i18n (1.14.1) concurrent-ruby (~> 1.0) - ice_nine (0.11.2) importmap-rails (1.1.5) actionpack (>= 6.0.0) railties (>= 6.0.0) diff --git a/rails_application/app/controllers/billing_addresses_controller.rb b/rails_application/app/controllers/billing_addresses_controller.rb index 1240d7544..297054ff7 100644 --- a/rails_application/app/controllers/billing_addresses_controller.rb +++ b/rails_application/app/controllers/billing_addresses_controller.rb @@ -2,23 +2,13 @@ class BillingAddressesController < ApplicationController def edit @invoice = Invoices::Invoice.find_or_initialize_by(order_uid: params[:order_id]) - @order = Shipments::Order.find_or_initialize_by(uid: params[:order_id]) + @order = Order.find(params[:order_id]) end def update - cmd = - Invoicing::SetBillingAddress.new( - invoice_id: params[:order_id], - tax_id_number: address_params[:tax_id_number], - postal_address: { - line_1: address_params[:address_line_1], - line_2: address_params[:address_line_2], - line_3: address_params[:address_line_3], - line_4: address_params[:address_line_4] - } - ) - command_bus.(cmd) - @order = Shipments::Order.find_or_initialize_by(uid: params[:order_id]) + @order = Order.find(params[:order_id]) + @order.update!(address_params) + redirect_to @order.submitted? ? order_path(params[:order_id]) : edit_order_path(params[:order_id]), notice: "Billing Address was successfully updated" end @@ -26,12 +16,12 @@ def update private def address_params - params.require(:invoices_invoice).permit( - :tax_id_number, - :address_line_1, - :address_line_2, - :address_line_3, - :address_line_4 + params.require(:order).permit( + :invoice_tax_id_number, + :invoice_addressed_to, + :invoice_address, + :invoice_city, + :invoice_country ) end end diff --git a/rails_application/app/controllers/customers_controller.rb b/rails_application/app/controllers/customers_controller.rb index 6cf55475f..9fc7b97d2 100644 --- a/rails_application/app/controllers/customers_controller.rb +++ b/rails_application/app/controllers/customers_controller.rb @@ -1,18 +1,14 @@ class CustomersController < ApplicationController def index - @customers = Customers::Customer.all + @customers = Customer.all end def new - @customer_id = SecureRandom.uuid + @customer = Customer.new end def create - create_customer(params[:customer_id], params[:name]) - rescue Crm::Customer::AlreadyRegistered - flash[:notice] = "Customer was already registered" - render "new" - else + Customer.create!(customer_params) redirect_to customers_path, notice: "Customer was successfully created" end @@ -25,27 +21,18 @@ def update end def show - @customer = Customers::Customer.find(params[:id]) - @customer_orders = ClientOrders::Order.where(client_uid: params[:id]) - .order(created_at: :desc) - .page(params[:page]).per(10) + @customer = Customer.find(params[:id]) + @customer_orders = @customer.orders.order(created_at: :desc) + .page(params[:page]).per(10) end private - def create_customer(customer_id, name) - command_bus.(create_customer_cmd(customer_id, name)) + def customer_params + params.require(:customer).permit(:first_name, :last_name, :email) end def promote_to_vip(customer_id) - command_bus.(promote_to_vip_cmd(customer_id)) - end - - def create_customer_cmd(customer_id, name) - Crm::RegisterCustomer.new(customer_id: customer_id, name: name) - end - - def promote_to_vip_cmd(customer_id) - Crm::PromoteCustomerToVip.new(customer_id: customer_id) + Customer.find(customer_id).promote_to_vip end end diff --git a/rails_application/app/controllers/events_catalog_controller.rb b/rails_application/app/controllers/events_catalog_controller.rb deleted file mode 100644 index d90d6e889..000000000 --- a/rails_application/app/controllers/events_catalog_controller.rb +++ /dev/null @@ -1,5 +0,0 @@ -class EventsCatalogController < ApplicationController - def index - render file: ENV["EVENTS_CATALOG_PATH"] || "../events_catalog/out/index.html" - end -end diff --git a/rails_application/app/controllers/invoices_controller.rb b/rails_application/app/controllers/invoices_controller.rb index bae493b21..6e1dbe079 100644 --- a/rails_application/app/controllers/invoices_controller.rb +++ b/rails_application/app/controllers/invoices_controller.rb @@ -1,20 +1,22 @@ class InvoicesController < ApplicationController def show - @invoice = Invoices::Invoice.find_by_order_uid(params[:id]) + @invoice = Order.find(params[:id]) end def create - begin - ActiveRecord::Base.transaction do - command_bus.(Invoicing::IssueInvoice.new(invoice_id: params[:order_id], issue_date: Time.zone.now.to_date)) - end - rescue Invoicing::Invoice::BillingAddressNotSpecified + @order = Order.find(params[:order_id]) + + if !@order.billing_address_specified? flash[:alert] = "Billing address is missing" - rescue Invoicing::Invoice::InvoiceAlreadyIssued + elsif @order.invoice_issued? flash[:alert] = "Invoice was already issued" - rescue Invoicing::Invoice::InvoiceNumberInUse - retry + else + @order.invoice_issued = true + @order.invoice_issue_date = Time.current + @order.invoice_total_value = @order.total - ((@order.total * @order.discount) / 100) + @order.save! end + redirect_to(invoice_path(params[:order_id])) end end \ No newline at end of file diff --git a/rails_application/app/controllers/orders_controller.rb b/rails_application/app/controllers/orders_controller.rb index 005355a63..633c084df 100644 --- a/rails_application/app/controllers/orders_controller.rb +++ b/rails_application/app/controllers/orders_controller.rb @@ -1,35 +1,48 @@ class OrdersController < ApplicationController def index - @orders = Orders::Order.order("id DESC").page(params[:page]).per(10) + @orders = Order.order("id DESC").page(params[:page]).per(10) end def show - @order = Orders::Order.find_by_uid(params[:id]) + @order = Order.find(params[:id]) return not_found unless @order - @order_lines = Orders::OrderLine.where(order_uid: @order.uid) - @shipment = Shipments::Shipment.find_by(order_uid: @order.uid) - @invoice = Invoices::Invoice.find_or_initialize_by(order_uid: @order.uid) + @total = @order.total - ((@order.total * @order.discount) / 100) + @order_lines = @order.order_items end def new - redirect_to edit_order_path(SecureRandom.uuid) + @order = Order.new + @order.status = "Draft" + @order.total = 0 + @order.discount = 0 + @order.save! + @order_id = @order.id + @products = Product.all + @customers = Customer.all + @time_promotions = TimePromotion.current end def edit @order_id = params[:id] - @order = Orders::Order.find_by_uid(params[:id]) - @order_lines = Orders::OrderLine.where(order_uid: params[:id]) - @products = Products::Product.all - @customers = Customers::Customer.all - @time_promotions = TimePromotions::TimePromotion.current + @order = Order.find(params[:id]) + @products = Product.all + @customers = Customer.all + @time_promotions = TimePromotion.current + discounted_value = @order.total - ((@order.total * @order.discount) / 100) + + if @time_promotions.any? + @time_promotions.sum(&:discount).tap do |discount| + discounted_value -= (discounted_value * discount) / 100 + end + end render :edit, locals: { - discounted_value: @order&.discounted_value || 0, - total_value: @order&.total_value || 0, - percentage_discount: @order&.percentage_discount + discounted_value:, + total_value: @order.total, + percentage_discount: @order.discount } end @@ -38,98 +51,124 @@ def edit_discount end def update_discount - @order_id = params[:id] - order = Orders::Order.find_or_create_by!(uid: params[:id]) - if order.percentage_discount - command_bus.(Pricing::ChangePercentageDiscount.new(order_id: @order_id, amount: params[:amount])) - else - command_bus.(Pricing::SetPercentageDiscount.new(order_id: @order_id, amount: params[:amount])) - end + order = Order.find(params[:id]) + order.discount = params[:amount] + order.discount_updated_at = Time.current + order.save! - redirect_to edit_order_path(@order_id) + redirect_to edit_order_path(order) end def reset_discount - @order_id = params[:id] - command_bus.(Pricing::ResetPercentageDiscount.new(order_id: @order_id)) + order = Order.find(params[:id]) + order.discount = 0 + order.discount_updated_at = Time.current + order.save! - redirect_to edit_order_path(@order_id) + redirect_to edit_order_path(order) end def add_item - read_model = Orders::OrderLine.where(order_uid: params[:id], product_id: params[:product_id]).first - unless Availability.approximately_available?(params[:product_id], (read_model&.quantity || 0) + 1) + product = Product.find(params[:product_id]) + if product.stock_level < 1 redirect_to edit_order_path(params[:id]), alert: "Product not available in requested quantity!" and return end - ActiveRecord::Base.transaction do - command_bus.(Ordering::AddItemToBasket.new(order_id: params[:id], product_id: params[:product_id])) + + @order = Order.find(params[:id]) + if @order.order_items.any? { |order_item| order_item.product_id == params[:product_id].to_i } + @order.order_items.find_by(product_id: params[:product_id]).increment!(:quantity) + @order.total = @order.total + product.price + else + @order.order_items.create!(product_id: params[:product_id], quantity: 1) + @order.total = @order.total + product.price end - head :ok + product.decrement!(:stock_level) + @order.save! + + redirect_to edit_order_path(params[:id]) end def remove_item - command_bus.(Ordering::RemoveItemFromBasket.new(order_id: params[:id], product_id: params[:product_id])) - head :ok + product = Product.find(params[:product_id]) + @order = Order.find(params[:id]) + order_item = @order.order_items.find_by(product_id: params[:product_id]) + if order_item && order_item.quantity > 0 + @order.order_items.find_by(product_id: params[:product_id]).decrement!(:quantity) + product.increment!(:stock_level) + @order.total = @order.total - product.price + @order.save! + end + + redirect_to edit_order_path(params[:id]) end def create - ApplicationRecord.transaction { submit_order(params[:order_id], params[:customer_id]) } + order = Order.find(params[:order_id]) + if order.order_items.empty? + redirect_to order_path(order.id), alert: "Order cannot be submitted because it is empty" + return + end + customer = Customer.find_by(id: params[:customer_id]) + unless customer + redirect_to order_path(order.id), alert: "Order can not be submitted! Customer does not exist." + return + end + ApplicationRecord.transaction { submit_order(order, params[:customer_id]) } redirect_to order_path(params[:order_id]), notice: "Your order is being submitted" - rescue Crm::Customer::NotExists - redirect_to order_path(params[:order_id]), alert: "Order can not be submitted! Customer does not exist." end def expire - Orders::Order - .where(state: "Draft") - .find_each { |order| command_bus.(Ordering::SetOrderAsExpired.new(order_id: order.uid)) } + Order + .where(status: "Draft") + .find_each { |order| order.status = "Expired"; order.save! } redirect_to root_path end def pay - ActiveRecord::Base.transaction do - authorize_payment(params[:id]) - capture_payment(params[:id]) - flash[:notice] = "Order paid successfully" - rescue Payments::Payment::AlreadyAuthorized + order = Order.find(params[:id]) + + if order.invoice_payment_status == "Authorized" flash[:alert] = "Payment was already authorized" - rescue Payments::Payment::AlreadyCaptured + elsif order.invoice_payment_status == "Captured" flash[:alert] = "Payment was already captured" - rescue Payments::Payment::NotAuthorized - flash[:alert] = "Payment wasn't yet authorized" - rescue Ordering::Order::NotPlaced - flash[:alert] = "You can't pay for an order which is not submitted" + + else + ActiveRecord::Base.transaction do + order.invoice_payment_status = "Authorized" + order.save! + + order.invoice_payment_status = "Captured" + order.invoice_payment_date = Time.current + order.status = "Paid" + customer = order.customer + customer.paid_orders_summary += order.total + order.save! + customer.save! + + flash[:notice] = "Order paid successfully" + end end + redirect_to orders_path end def cancel - command_bus.(Fulfillment::CancelOrder.new(order_id: params[:id])) + order = Order.find(params[:id]) + order.status = "Cancelled" + order.save! redirect_to root_path, notice: "Order cancelled" 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 - - def authorize_payment(order_id) - command_bus.call(authorize_payment_cmd(order_id)) - end - - def capture_payment(order_id) - command_bus.call(capture_payment_cmd(order_id)) - end - - def authorize_payment_cmd(order_id) - Payments::AuthorizePayment.new(order_id: order_id) - end - - def capture_payment_cmd(order_id) - Payments::CapturePayment.new(order_id: order_id) + def submit_order(order, customer_id) + if order.status == "Draft" + order.status = "Submitted" + order.number = Time.now.strftime("%Y/%m/#{SecureRandom.random_number(100)}") + order.customer_id = customer_id.to_i + order.save! + end end def not_found diff --git a/rails_application/app/controllers/product/future_price_controller.rb b/rails_application/app/controllers/product/future_price_controller.rb deleted file mode 100644 index 6e4b5e8ab..000000000 --- a/rails_application/app/controllers/product/future_price_controller.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Product - class FuturePriceController < ApplicationController - def add_future_price - respond_to do |format| - format.turbo_stream do - render turbo_stream: - turbo_stream.append( - "future_prices", - partial: "/products/future_price", - locals: { - disabled: false, - valid_since: nil, - price: nil - } - ) - end - end - end - end -end diff --git a/rails_application/app/controllers/products_controller.rb b/rails_application/app/controllers/products_controller.rb index 87b0e14ca..e9ba45faf 100644 --- a/rails_application/app/controllers/products_controller.rb +++ b/rails_application/app/controllers/products_controller.rb @@ -1,130 +1,57 @@ class ProductsController < ApplicationController - class ProductForm - include ActiveModel::Model - include ActiveModel::Attributes - include ActiveModel::Validations - - attribute :name, :string - attribute :price, :decimal - attribute :vat_rate, :string - attribute :product_id, :string - - validates :name, presence: true - validates :price, presence: true, numericality: { greater_than: 0 } - validates :vat_rate, presence: true, numericality: { greater_than: 0 } - validates :product_id, presence: true - end - def index - @products = Products::Product.all + @products = Product.all end def show - @product = Products::Product.find(params[:id]) + @product = Product.find(params[:id]) end def new - @product_id = SecureRandom.uuid + @product = Product.new end def edit - @product = Products::Product.find(params[:id]) + @product = Product.find(params[:id]) end def create - product_form = ProductForm.new(**product_params) + Product.create!(product_params) + redirect_to products_path, notice: "Product was successfully created" + end - unless product_form.valid? - return render "new", locals: { errors: product_form.errors }, status: :unprocessable_entity - end + def update + @product = Product.find(params[:id]) - ActiveRecord::Base.transaction do - create_product(product_form.product_id, product_form.name) - if product_form.price.present? - set_product_price(product_form.product_id, product_form.price) - end - if product_form.vat_rate.present? - set_product_vat_rate(product_form.product_id, product_form.vat_rate) - end - rescue ProductCatalog::AlreadyRegistered - flash[:notice] = "Product was already registered" - render "new" - rescue Taxes::Product::VatRateNotApplicable - flash[:notice] = "Selected VAT rate not applicable" - render "new" - else - redirect_to products_path, notice: "Product was successfully created" + if params["future_price"].present? + @product.future_price = params["future_price"]["price"] + @product.future_price_start_time = params["future_price"]["start_time"] + @product.save! end + @product.update!(product_params) + redirect_to products_path, notice: "Product was successfully updated" end - def update - if params[:name].present? - set_product_name(params[:product_id], params[:name]) - end - if params[:price].present? - set_product_price(params[:product_id], params[:price]) - end - if params[:future_prices].present? - params[:future_prices].each do |future_price| - set_future_product_price( - params[:product_id], - future_price["price"], - Time.zone.parse(future_price["start_time"]).utc - ) + def add_future_price + respond_to do |format| + format.turbo_stream do + render turbo_stream: + turbo_stream.update( + "future_prices", + partial: "/products/future_price", + locals: { + disabled: false, + valid_since: nil, + price: nil + } + ) end end - redirect_to products_path, notice: "Product was successfully updated" end private - def create_product(product_id, name) - command_bus.(create_product_cmd(product_id)) - command_bus.(name_product_cmd(product_id, name)) - end - - def set_product_price(product_id, price) - command_bus.(set_product_price_cmd(product_id, price)) - end - - def set_future_product_price(product_id, price, valid_since) - command_bus.(set_product_future_price_cmd(product_id, price, valid_since)) - end - - def set_product_vat_rate(product_id, vat_rate_code) - vat_rate = Taxes::Configuration.available_vat_rates.find{|rate| rate.code == vat_rate_code} - command_bus.(set_product_vat_rate_cmd(product_id, vat_rate)) - end - - def set_product_name(product_id, name) - command_bus.(name_product_cmd(product_id, name)) - end - - def create_product_cmd(product_id) - ProductCatalog::RegisterProduct.new(product_id: product_id) - end - - def name_product_cmd(product_id, name) - ProductCatalog::NameProduct.new(product_id: product_id, name: name) - end - - def set_product_price_cmd(product_id, price) - Pricing::SetPrice.new(product_id: product_id, price: price) - end - - def set_product_vat_rate_cmd(product_id, vat_rate) - Taxes::SetVatRate.new(product_id: product_id, vat_rate: vat_rate) - end - - def set_product_future_price_cmd(product_id, price, valid_since) - Pricing::SetFuturePrice.new( - product_id: product_id, - price: price, - valid_since: valid_since - ) - end - def product_params - params.permit(:name, :price, :vat_rate, :product_id).to_h.symbolize_keys.slice(:price, :vat_rate, :product_id, :name) + params.require(:product).permit(:name, :price, :vat_rate).to_h.symbolize_keys.slice(:price, :vat_rate, :name) end end diff --git a/rails_application/app/controllers/shipments_controller.rb b/rails_application/app/controllers/shipments_controller.rb index 297a55cba..e7abb91a8 100644 --- a/rails_application/app/controllers/shipments_controller.rb +++ b/rails_application/app/controllers/shipments_controller.rb @@ -1,10 +1,5 @@ class ShipmentsController < ApplicationController def index - @shipments = - Shipments::Shipment - .includes(:order) - .order("id DESC") - .page(params[:page]) - .per(10) + @orders = Order.order("id DESC").page(params[:page]).per(10) end end diff --git a/rails_application/app/controllers/shipping_addresses_controller.rb b/rails_application/app/controllers/shipping_addresses_controller.rb index c166844b1..42dbd2607 100644 --- a/rails_application/app/controllers/shipping_addresses_controller.rb +++ b/rails_application/app/controllers/shipping_addresses_controller.rb @@ -1,23 +1,14 @@ class ShippingAddressesController < ApplicationController def edit - @shipment = Shipments::Shipment.find_or_initialize_by(order_uid: params[:order_id]) - @order = Shipments::Order.find_or_initialize_by(uid: params[:order_id]) + @order = Order.find(params[:order_id]) end def update - cmd = - Shipping::AddShippingAddressToShipment.new( - order_id: params[:order_id], - postal_address: { - line_1: address_params[:address_line_1], - line_2: address_params[:address_line_2], - line_3: address_params[:address_line_3], - line_4: address_params[:address_line_4] - } - ) - command_bus.(cmd) - @order = Shipments::Order.find_or_initialize_by(uid: params[:order_id]) + @order = Order.find(params[:order_id]) + + @order.update!(address_params) + redirect_to @order.submitted? ? order_path(params[:order_id]) : edit_order_path(params[:order_id]), notice: "Shippping Address was successfully updated" end @@ -25,11 +16,11 @@ def update private def address_params - params.require(:shipments_shipment).permit( - :address_line_1, - :address_line_2, - :address_line_3, - :address_line_4 + params.require(:order).permit( + :addressed_to, + :address, + :city, + :country ) end end diff --git a/rails_application/app/controllers/supplies_controller.rb b/rails_application/app/controllers/supplies_controller.rb index 471ce29a4..38ad8cc4a 100644 --- a/rails_application/app/controllers/supplies_controller.rb +++ b/rails_application/app/controllers/supplies_controller.rb @@ -4,15 +4,9 @@ def new end def create - supply(params[:product_id], params[:quantity]) + product = Product.find(params[:product_id]) + product.stock_level == nil ? product.stock_level = params[:quantity].to_i : product.stock_level += params[:quantity].to_i + product.save! redirect_to products_path, notice: "Stock level changed" end - - private - - def supply(product_id, quantity) - command_bus.( - Inventory::Supply.new(product_id: product_id, quantity: quantity) - ) - end end diff --git a/rails_application/app/controllers/time_promotions_controller.rb b/rails_application/app/controllers/time_promotions_controller.rb index 097250142..f8ca1c0a0 100644 --- a/rails_application/app/controllers/time_promotions_controller.rb +++ b/rails_application/app/controllers/time_promotions_controller.rb @@ -1,37 +1,17 @@ class TimePromotionsController < ApplicationController def index - @time_promotions = TimePromotions::TimePromotion.all + @time_promotions = TimePromotion.all end def new; end def create - id = SecureRandom.uuid - - TimePromotions::TimePromotion.transaction do - create_time_promotion(id) - end - rescue ActiveRecord::RecordNotUnique => error - flash.now[:alert] = error - render "new" - else - respond_to do |format| - format.html { redirect_to time_promotions_path, notice: "Time promotion was successfully created" } - format.turbo_stream { head :ok } - end - end - - private - - def create_time_promotion(id) - command_bus.( - Pricing::CreateTimePromotion.new( - time_promotion_id: id, - discount: params[:discount], - start_time: Time.zone.parse(params[:start_time]), - end_time: Time.zone.parse(params[:end_time]), - label: params[:label] - ) + TimePromotion.create!( + start_time: Time.parse(params[:start_time]), + end_time: Time.parse(params[:end_time]), + label: params[:label], + discount: params[:discount] ) + redirect_to time_promotions_path, notice: "Time promotion was successfully created" end end diff --git a/rails_application/app/models/customer.rb b/rails_application/app/models/customer.rb new file mode 100644 index 000000000..818048015 --- /dev/null +++ b/rails_application/app/models/customer.rb @@ -0,0 +1,12 @@ +class Customer < ApplicationRecord + has_many :orders + + def full_name + "#{first_name} #{last_name}" + end + + def promote_to_vip + raise AlreadyVip if vip + update!(vip: true) + end +end diff --git a/rails_application/app/models/invoice.rb b/rails_application/app/models/invoice.rb new file mode 100644 index 000000000..51e318981 --- /dev/null +++ b/rails_application/app/models/invoice.rb @@ -0,0 +1,13 @@ +class Invoice < ApplicationRecord + self.table_name = "invoices_tbl" + + belongs_to :order, class_name: "Order", foreign_key: "order_id" + + def issued? + issued_at.present? + end + + def address_present? + address.present? + end +end diff --git a/rails_application/app/models/order.rb b/rails_application/app/models/order.rb new file mode 100644 index 000000000..b0e03a602 --- /dev/null +++ b/rails_application/app/models/order.rb @@ -0,0 +1,33 @@ +class Order < ApplicationRecord + has_many :order_items + has_one :invoice + + def state + self.status + end + + def customer + Customer.find(customer_id) if customer_id + end + + def submitted? + status == "Submitted" + end + + def invoice_issued? + invoice_issued + end + + def shipment_full_address + "#{address}, #{city}, #{country} #{addressed_to}" + end + + def billing_address_specified? + invoice_tax_id_number.present? && + invoice_country.present? && + invoice_address.present? && + invoice_city.present? && + invoice_addressed_to.present? && + invoice_address.present? + end +end diff --git a/rails_application/app/models/order_item.rb b/rails_application/app/models/order_item.rb new file mode 100644 index 000000000..1376198f2 --- /dev/null +++ b/rails_application/app/models/order_item.rb @@ -0,0 +1,5 @@ +class OrderItem < ApplicationRecord + def product + Product.find(product_id) + end +end diff --git a/rails_application/app/models/product.rb b/rails_application/app/models/product.rb new file mode 100644 index 000000000..ee38eb4aa --- /dev/null +++ b/rails_application/app/models/product.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Product < ApplicationRecord + before_create :set_stock_level + + def set_stock_level + self.stock_level = 0 + end +end diff --git a/rails_application/app/models/time_promotion.rb b/rails_application/app/models/time_promotion.rb new file mode 100644 index 000000000..d59804ba4 --- /dev/null +++ b/rails_application/app/models/time_promotion.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class TimePromotion < ApplicationRecord + def self.current + where("start_time < ? AND end_time > ?", Time.current, Time.current) + end +end diff --git a/rails_application/app/read_models/availability/configuration.rb b/rails_application/app/read_models/availability/configuration.rb deleted file mode 100644 index b67ef280c..000000000 --- a/rails_application/app/read_models/availability/configuration.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Availability - class Product < ApplicationRecord - self.table_name = "availability_products" - end - - private_constant :Product - - def self.approximately_available?(product_id, desired_quantity) - !Product.exists?(["uid = ? and available < ?", product_id, desired_quantity]) - end - - class UpdateAvailability - def call(event) - order = Product.find_or_create_by!(uid: event.data.fetch(:product_id)) - order.available = event.data.fetch(:available) - order.save! - end - end - - class Configuration - def call(event_store) - event_store.subscribe(UpdateAvailability, to: [Inventory::AvailabilityChanged]) - end - end -end \ No newline at end of file diff --git a/rails_application/app/read_models/client_authentication/configuration.rb b/rails_application/app/read_models/client_authentication/configuration.rb deleted file mode 100644 index 91242a124..000000000 --- a/rails_application/app/read_models/client_authentication/configuration.rb +++ /dev/null @@ -1,12 +0,0 @@ -module ClientAuthentication - class Account < ApplicationRecord - self.table_name = "accounts" - end - - class Configuration - def call(event_store) - event_store.subscribe(CreateAccount, to: [Authentication::AccountConnectedToClient]) - event_store.subscribe(SetPassword, to: [Authentication::PasswordHashSet]) - end - end -end diff --git a/rails_application/app/read_models/client_authentication/create_account.rb b/rails_application/app/read_models/client_authentication/create_account.rb deleted file mode 100644 index bc688bc20..000000000 --- a/rails_application/app/read_models/client_authentication/create_account.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ClientAuthentication - class CreateAccount - def call(event) - client_id = event.data.fetch(:client_id) - account_id = event.data.fetch(:account_id) - Account.find_or_create_by(account_id: account_id).update(client_id: client_id) - end - end -end diff --git a/rails_application/app/read_models/client_authentication/set_password.rb b/rails_application/app/read_models/client_authentication/set_password.rb deleted file mode 100644 index a58658bd0..000000000 --- a/rails_application/app/read_models/client_authentication/set_password.rb +++ /dev/null @@ -1,13 +0,0 @@ -module ClientAuthentication - class SetPassword - def call(event) - find(event.data.fetch(:account_id)).update(password: event.data.fetch(:password_hash)) - end - - private - - def find(account_id) - Account.find_or_create_by(account_id: account_id) - end - end -end diff --git a/rails_application/app/read_models/client_orders/add_item_to_order.rb b/rails_application/app/read_models/client_orders/add_item_to_order.rb deleted file mode 100644 index 93c97e361..000000000 --- a/rails_application/app/read_models/client_orders/add_item_to_order.rb +++ /dev/null @@ -1,65 +0,0 @@ -module ClientOrders - class AddItemToOrder - include Rails.application.routes.url_helpers - include ActionView::Helpers::UrlHelper - include ActionView::Helpers::FormTagHelper - - def call(event) - order_id = event.data.fetch(:order_id) - product_id = event.data.fetch(:product_id) - create_draft_order(order_id) - item = - find(order_id, product_id) || - create(order_id, product_id) - item.product_quantity += 1 - item.save! - - broadcast_update(order_id, product_id, "product_quantity", item.product_quantity) - broadcast_update(order_id, product_id, "value", ActiveSupport::NumberHelper.number_to_currency(item.value)) - show_remove_item_button(order_id, product_id) - end - - private - - def show_remove_item_button(order_id, product_id) - broadcast_update(order_id, product_id, "remove_item_button", remove_button_html(order_id, product_id)) - end - - def remove_button_html(order_id, product_id) - button_to("Remove", remove_item_client_order_path(id: order_id, product_id: product_id), class: "hover:underline text-blue-500") - end - - def broadcast_update(order_id, product_id, target, content) - Turbo::StreamsChannel.broadcast_update_to( - "client_orders_#{order_id}", - target: "client_orders_#{product_id}_#{target}", - html: content) - end - - def create_draft_order(uid) - return if Order.where(order_uid: uid).exists? - Order.create!(order_uid: uid, state: "Draft") - end - - def find(order_uid, product_id) - Order - .find_by(order_uid: order_uid) - .order_lines - .where(product_id: product_id) - .first - end - - def create(order_uid, product_id) - product = Product.find_by_uid(product_id) - Order - .find_by(order_uid: order_uid) - .order_lines - .create( - product_id: product_id, - product_name: product.name, - product_price: product.price, - product_quantity: 0 - ) - end - end -end diff --git a/rails_application/app/read_models/client_orders/assign_customer_to_order.rb b/rails_application/app/read_models/client_orders/assign_customer_to_order.rb deleted file mode 100644 index 76fcd6547..000000000 --- a/rails_application/app/read_models/client_orders/assign_customer_to_order.rb +++ /dev/null @@ -1,15 +0,0 @@ -module ClientOrders - class AssignCustomerToOrder - def call(event) - order_uid = event.data.fetch(:order_id) - order = Order.find_by(order_uid: order_uid) - - if order.nil? - order = Order.create!(order_uid: order_uid, state: "Draft") - end - - order.client_uid = event.data.fetch(:customer_id) - order.save! - end - end -end diff --git a/rails_application/app/read_models/client_orders/cancel_order.rb b/rails_application/app/read_models/client_orders/cancel_order.rb deleted file mode 100644 index 48b21b3b5..000000000 --- a/rails_application/app/read_models/client_orders/cancel_order.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ClientOrders - class CancelOrder - def call(event) - order = Order.find_by(order_uid: event.data.fetch(:order_id)) - order.state = "Cancelled" - order.save! - end - end -end - diff --git a/rails_application/app/read_models/client_orders/change_product_name.rb b/rails_application/app/read_models/client_orders/change_product_name.rb deleted file mode 100644 index 139f76bac..000000000 --- a/rails_application/app/read_models/client_orders/change_product_name.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ClientOrders - class ChangeProductName - def call(event) - Product.find_or_create_by(uid: event.data.fetch(:product_id)).update( - name: event.data.fetch(:name) - ) - end - end -end - diff --git a/rails_application/app/read_models/client_orders/change_product_price.rb b/rails_application/app/read_models/client_orders/change_product_price.rb deleted file mode 100644 index b3a6a016c..000000000 --- a/rails_application/app/read_models/client_orders/change_product_price.rb +++ /dev/null @@ -1,7 +0,0 @@ -module ClientOrders - class ChangeProductPrice - def call(event) - Product.find_or_create_by(uid: event.data.fetch(:product_id)).update(price: event.data.fetch(:price)) - end - end -end diff --git a/rails_application/app/read_models/client_orders/configuration.rb b/rails_application/app/read_models/client_orders/configuration.rb deleted file mode 100644 index f2b162783..000000000 --- a/rails_application/app/read_models/client_orders/configuration.rb +++ /dev/null @@ -1,52 +0,0 @@ -module ClientOrders - - class Client < ApplicationRecord - self.table_name = "clients" - - has_many :client_orders, - -> { client(id: :asc) }, - class_name: "ClientOrders::Order", - foreign_key: :client_uid, - primary_key: :uid - end - - class Order < ApplicationRecord - self.table_name = "client_orders" - - has_many :order_lines, - -> { order(id: :asc) }, - class_name: "ClientOrders::OrderLine", - foreign_key: :order_uid, - primary_key: :order_uid - end - - class OrderLine < ApplicationRecord - self.table_name = "client_order_lines" - - def value - product_price * product_quantity - end - end - - class Configuration - def call(event_store) - event_store.subscribe(ExpireOrder, to: [Ordering::OrderExpired]) - event_store.subscribe(CancelOrder, to: [Fulfillment::OrderCancelled]) - event_store.subscribe(SubmitOrder, to: [Ordering::OrderPlaced]) - event_store.subscribe(ConfirmOrder, to: [Fulfillment::OrderConfirmed]) - event_store.subscribe(AddItemToOrder, to: [Ordering::ItemAddedToBasket]) - event_store.subscribe(RemoveItemFromOrder, to: [Ordering::ItemRemovedFromBasket]) - - event_store.subscribe(CreateCustomer.new, to: [Crm::CustomerRegistered]) - event_store.subscribe(AssignCustomerToOrder, to: [Crm::CustomerAssignedToOrder]) - - event_store.subscribe(ChangeProductName, to: [ProductCatalog::ProductNamed]) - event_store.subscribe(ChangeProductPrice, to: [Pricing::PriceSet]) - event_store.subscribe(RegisterProduct, to: [ProductCatalog::ProductRegistered]) - event_store.subscribe(UpdateDiscount, to: [Pricing::PercentageDiscountSet, Pricing::PercentageDiscountChanged]) - event_store.subscribe(ResetDiscount, to: [Pricing::PercentageDiscountReset]) - event_store.subscribe(UpdateOrderTotalValue, to: [Pricing::OrderTotalValueCalculated]) - event_store.subscribe(UpdatePaidOrdersSummary, to: [Fulfillment::OrderConfirmed]) - end - end -end diff --git a/rails_application/app/read_models/client_orders/confirm_order.rb b/rails_application/app/read_models/client_orders/confirm_order.rb deleted file mode 100644 index 14f47521f..000000000 --- a/rails_application/app/read_models/client_orders/confirm_order.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ClientOrders - class ConfirmOrder - def call(event) - order = Order.find_by(order_uid: event.data.fetch(:order_id)) - order.state = "Paid" - order.save! - end - end -end - diff --git a/rails_application/app/read_models/client_orders/create_customer.rb b/rails_application/app/read_models/client_orders/create_customer.rb deleted file mode 100644 index 2f6b2349e..000000000 --- a/rails_application/app/read_models/client_orders/create_customer.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ClientOrders - class CreateCustomer - def call(event) - Client.create( - uid: event.data.fetch(:customer_id), - name: event.data.fetch(:name) - ) - end - end -end diff --git a/rails_application/app/read_models/client_orders/expire_order.rb b/rails_application/app/read_models/client_orders/expire_order.rb deleted file mode 100644 index b3663460e..000000000 --- a/rails_application/app/read_models/client_orders/expire_order.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ClientOrders - class ExpireOrder - def call(event) - order = Order.find_by(order_uid: event.data.fetch(:order_id)) - order.state = "Expired" - order.save! - end - end -end - diff --git a/rails_application/app/read_models/client_orders/orders_list.rb b/rails_application/app/read_models/client_orders/orders_list.rb deleted file mode 100644 index c73cd0fa9..000000000 --- a/rails_application/app/read_models/client_orders/orders_list.rb +++ /dev/null @@ -1,111 +0,0 @@ -module ClientOrders - class OrdersList < Arbre::Component - include Rails.application.routes.url_helpers - - def self.build(view_context, client_id) - new(Arbre::Context.new(nil, view_context)).build( - Client.find_by(uid: client_id), - Order.where(client_uid: client_id) - ) - end - - def build(client, client_orders, attributes = {}) - super(attributes) - - div class: "max-w-6xl mx-auto py-6 sm:px-6 lg:px-8" do - client_name_header(client) - orders_table(client, client_orders) - new_order_button - end - - end - - private - - def client_name_header(client) - h1 class: "text-3xl font-bold text-gray-900" do - client.name - end - end - - def orders_table(client, client_orders) - return no_orders_message if client_orders.empty? - orders_table_content(client, client_orders) - end - - def orders_table_content(client, client_orders) - table class: "w-full", id: "orders" do - headers_row - tbody do - orders_rows(client_orders) - summary_row(client) - end - end - end - - def no_orders_message - para class: "py-6" do - "No orders to display." - end - end - - def summary_row(client) - tr class: "border-t font-bold" do - td colspan: 2, class: "py-2" do - para "Total paid orders" - end - td class: "py-2 text-right border-t" do - number_to_currency(client.paid_orders_summary) - end - end - end - - def orders_rows(client_orders) - client_orders.each do |client_order| - tr class: "border-t" do - td class: "py-2" do - para(order_link_with_order_number(client_order) || 'Not submitted') - end - td class: "py-2 text-left" do - client_order.state - end - td class: "py-2 text-right" do - number_to_currency(client_order.discounted_value) - end - end - end - end - - def headers_row - thead do - tr class: "border-t" do - th class: "text-left py-2" do - "Number" - end - th class: "text-left py-2" do - "State" - end - th class: "text-right py-2" do - "Price" - end - end - end - end - - def new_order_button - para( - link_to( - "New order", - new_client_order_path, - class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded")) - end - - def order_link_with_order_number(order) - link_to( - order.number, - client_order_path(order.order_uid), - class: "text-blue-500 hover:text-blue-700" - ) - end - end -end \ No newline at end of file diff --git a/rails_application/app/read_models/client_orders/product.rb b/rails_application/app/read_models/client_orders/product.rb deleted file mode 100644 index 238d7f831..000000000 --- a/rails_application/app/read_models/client_orders/product.rb +++ /dev/null @@ -1,5 +0,0 @@ -module ClientOrders - class Product < ApplicationRecord - self.table_name = "client_order_products" - end -end diff --git a/rails_application/app/read_models/client_orders/register_product.rb b/rails_application/app/read_models/client_orders/register_product.rb deleted file mode 100644 index 12b8c813a..000000000 --- a/rails_application/app/read_models/client_orders/register_product.rb +++ /dev/null @@ -1,7 +0,0 @@ -module ClientOrders - class RegisterProduct - def call(event) - Product.find_or_create_by(uid: event.data.fetch(:product_id)) - end - end -end diff --git a/rails_application/app/read_models/client_orders/remove_item_from_order.rb b/rails_application/app/read_models/client_orders/remove_item_from_order.rb deleted file mode 100644 index cabc86109..000000000 --- a/rails_application/app/read_models/client_orders/remove_item_from_order.rb +++ /dev/null @@ -1,42 +0,0 @@ -module ClientOrders - class RemoveItemFromOrder - def call(event) - product_id = event.data.fetch(:product_id) - order_id = event.data.fetch(:order_id) - item = find(order_id , product_id) - item.product_quantity -= 1 - item.product_quantity > 0 ? item.save! : item.destroy! - - broadcast_update(order_id, product_id, "product_quantity", item.product_quantity) - broadcast_update(order_id, product_id, "value", ActiveSupport::NumberHelper.number_to_currency(item.value)) - broadcast_update(order_id, product_id, "remove_item_button", "") if zero_quantity?(item) - - event_store.link_event_to_stream(event, "ClientOrders$all") - end - - private - - def event_store - Rails.configuration.event_store - end - - def zero_quantity?(item) - item.nil? || item.product_quantity.zero? - end - - def broadcast_update(order_id, product_id, target, content) - Turbo::StreamsChannel.broadcast_update_to( - "client_orders_#{order_id}", - target: "client_orders_#{product_id}_#{target}", - html: content) - end - - def find(order_uid, product_id) - Order - .find_by(order_uid: order_uid) - .order_lines - .where(product_id: product_id) - .first - end - end -end diff --git a/rails_application/app/read_models/client_orders/reset_discount.rb b/rails_application/app/read_models/client_orders/reset_discount.rb deleted file mode 100644 index 8af8d72d7..000000000 --- a/rails_application/app/read_models/client_orders/reset_discount.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ClientOrders - class ResetDiscount - def call(event) - order = Order.find_by(order_uid: event.data.fetch(:order_id)) - order.percentage_discount = nil - order.save! - end - end -end diff --git a/rails_application/app/read_models/client_orders/show_order.rb b/rails_application/app/read_models/client_orders/show_order.rb deleted file mode 100644 index c764b43d7..000000000 --- a/rails_application/app/read_models/client_orders/show_order.rb +++ /dev/null @@ -1,102 +0,0 @@ -module ClientOrders - class ShowOrder < Arbre::Component - include Rails.application.routes.url_helpers - - def self.build(view_context, order, order_lines) - new(Arbre::Context.new(nil, view_context)).build(order, order_lines) - end - - def build(order, order_lines, attributes = {}) - super(attributes) - div do - div do - para(secondary_action_button { link_to 'Back', client_orders_path }) - end - div class: "max-w-6xl mx-auto py-6 sm:px-6 lg:px-8" do - header_content(order) - - div class: "mb-8" do - state_section(order) - end - - order_table(order_lines, order) - end - end - end - - private - - def header_content(order) - h2 do - "Order #{order.number}" - end - end - - def state_section(order) - dl do - dt(class: "font-bold") { "State" } - dd(class: "mb-2") { order.state } - end - end - - def order_table(order_lines, order) - table class: "w-full" do - headers_row - tbody do - order_lines.each do |item| - item_row(item) - end - end - footer_rows(order) - end - end - - def headers_row - thead do - tr do - %w[Product Quantity Price Value].each do |header| - th(class: "text-left py-2") { header } - end - end - end - end - - def item_row(item) - tr class: "border-t" do - td(class: "py-2") { item.product_name } - td(class: "py-2") { item.product_quantity } - td(class: "py-2") { number_to_currency(item.product_price) } - td(class: "py-2 text-right") { number_to_currency(item.value) } - end - end - - def footer_rows(order) - tfoot class: "border-t-4" do - before_discounts_row(order) if order.discounted_value != order.total_value - general_discount_row(order) if order.percentage_discount - total_row(order) - end - end - - def before_discounts_row(order) - tr class: "border-t" do - td(class: "py-2", colspan: 3) { "Before discounts" } - td(class: "py-2 text-right", id: "before-discounts-value") { number_to_currency(order.total_value) } - end - end - - def general_discount_row(order) - tr class: "border-t" do - td(class: "py-2", colspan: 3) { "General discount" } - td(class: "py-2 text-right") { "#{order.percentage_discount}%" } - end - end - - def total_row(order) - tr class: "border-t" do - td(class: "py-2", colspan: 3) { "Total" } - td(class: "py-2 text-right font-bold") { number_to_currency(order.discounted_value) } - end - end - end -end diff --git a/rails_application/app/read_models/client_orders/submit_order.rb b/rails_application/app/read_models/client_orders/submit_order.rb deleted file mode 100644 index 0cc1ecb89..000000000 --- a/rails_application/app/read_models/client_orders/submit_order.rb +++ /dev/null @@ -1,11 +0,0 @@ -module ClientOrders - class SubmitOrder - def call(event) - order = Order.find_or_create_by(order_uid: event.data.fetch(:order_id)) - order.number = event.data.fetch(:order_number) - order.state = "Submitted" - order.save! - end - end -end - diff --git a/rails_application/app/read_models/client_orders/update_discount.rb b/rails_application/app/read_models/client_orders/update_discount.rb deleted file mode 100644 index ca393197c..000000000 --- a/rails_application/app/read_models/client_orders/update_discount.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ClientOrders - class UpdateDiscount - def call(event) - order = Order.find_or_create_by!(order_uid: event.data.fetch(:order_id)) - order.percentage_discount = event.data.fetch(:amount) - order.save! - end - end -end diff --git a/rails_application/app/read_models/client_orders/update_order_total_value.rb b/rails_application/app/read_models/client_orders/update_order_total_value.rb deleted file mode 100644 index 87a879b48..000000000 --- a/rails_application/app/read_models/client_orders/update_order_total_value.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ClientOrders - class UpdateOrderTotalValue - def call(event) - order = Order.find_or_create_by!(order_uid: event.data.fetch(:order_id)) { |order| order.state = "Draft" } - order.discounted_value = event.data.fetch(:discounted_amount) - order.total_value = event.data.fetch(:total_amount) - order.save! - end - end -end diff --git a/rails_application/app/read_models/client_orders/update_paid_orders_summary.rb b/rails_application/app/read_models/client_orders/update_paid_orders_summary.rb deleted file mode 100644 index 20f73be80..000000000 --- a/rails_application/app/read_models/client_orders/update_paid_orders_summary.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ClientOrders - class UpdatePaidOrdersSummary - def call(event) - order = Order.find_by(order_uid: event.data.fetch(:order_id)) - client = Client.where(uid: order.client_uid).first - client.update(paid_orders_summary: client.paid_orders_summary + order.discounted_value) - end - end -end diff --git a/rails_application/app/read_models/coupons/configuration.rb b/rails_application/app/read_models/coupons/configuration.rb deleted file mode 100644 index e5222e3d4..000000000 --- a/rails_application/app/read_models/coupons/configuration.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Coupons - class Coupon < ApplicationRecord - self.table_name = "coupons" - end - - class Configuration - def call(event_store) - event_store.subscribe(RegisterCoupon.new, to: [Pricing::CouponRegistered]) - end - end -end diff --git a/rails_application/app/read_models/coupons/register_coupon.rb b/rails_application/app/read_models/coupons/register_coupon.rb deleted file mode 100644 index 45cbd2d71..000000000 --- a/rails_application/app/read_models/coupons/register_coupon.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Coupons - class RegisterCoupon - def call(event) - event_data = event.data - Coupon.create( - uid: event_data.fetch(:coupon_id), - name: event_data.fetch(:name), - code: event_data.fetch(:code), - discount: event_data.fetch(:discount) - ) - end - end -end diff --git a/rails_application/app/read_models/customers/configuration.rb b/rails_application/app/read_models/customers/configuration.rb deleted file mode 100644 index b3465237f..000000000 --- a/rails_application/app/read_models/customers/configuration.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Customers - class Customer < ApplicationRecord - self.table_name = "customers" - end - - class Configuration - def call(event_store) - event_store.subscribe(RegisterCustomer.new, to: [Crm::CustomerRegistered]) - event_store.subscribe(PromoteToVip.new, to: [Crm::CustomerPromotedToVip]) - event_store.subscribe(UpdatePaidOrdersSummary.new, to: [Fulfillment::OrderConfirmed]) - event_store.subscribe(ConnectAccount.new, to: [Authentication::AccountConnectedToClient]) - end - end -end diff --git a/rails_application/app/read_models/customers/connect_account.rb b/rails_application/app/read_models/customers/connect_account.rb deleted file mode 100644 index 18503d9b9..000000000 --- a/rails_application/app/read_models/customers/connect_account.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Customers - class ConnectAccount - def call(event) - Customer.find_or_create_by(id: event.data.fetch(:client_id)).update(account_id: event.data.fetch(:account_id)) - end - end -end diff --git a/rails_application/app/read_models/customers/promote_to_vip.rb b/rails_application/app/read_models/customers/promote_to_vip.rb deleted file mode 100644 index 0669cf8e0..000000000 --- a/rails_application/app/read_models/customers/promote_to_vip.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Customers - class PromoteToVip - def call(event) - promote_to_vip(event) - end - - private - - def promote_to_vip(event) - find(event.data.fetch(:customer_id)).update(vip: true) - end - - def find(customer_id) - Customer.where(id: customer_id).first - end - - end -end diff --git a/rails_application/app/read_models/customers/register_customer.rb b/rails_application/app/read_models/customers/register_customer.rb deleted file mode 100644 index 7fc69a478..000000000 --- a/rails_application/app/read_models/customers/register_customer.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Customers - class RegisterCustomer - def call(event) - Customer.find_or_create_by(id: event.data.fetch(:customer_id)).update(name: event.data.fetch(:name)) - end - end -end diff --git a/rails_application/app/read_models/customers/update_paid_orders_summary.rb b/rails_application/app/read_models/customers/update_paid_orders_summary.rb deleted file mode 100644 index 9c9d29659..000000000 --- a/rails_application/app/read_models/customers/update_paid_orders_summary.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Customers - class UpdatePaidOrdersSummary - def call(event) - order = ClientOrders::Order.find_by(order_uid: event.data.fetch(:order_id)) - customer = Customer.find(order.client_uid) - customer.update(paid_orders_summary: customer.paid_orders_summary + order.discounted_value) - end - end -end diff --git a/rails_application/app/read_models/invoices/configuration.rb b/rails_application/app/read_models/invoices/configuration.rb deleted file mode 100644 index 1edf7411d..000000000 --- a/rails_application/app/read_models/invoices/configuration.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Invoices - class Invoice < ApplicationRecord - self.table_name = "invoices" - has_many :invoice_items - end - - class InvoiceItem < ApplicationRecord - self.table_name = "invoice_items" - belongs_to :invoice - end - - class Order < ApplicationRecord - self.table_name = "invoices_orders" - end - - class Configuration - def call(event_store) - event_store.subscribe(CreateInvoiceItem.new, to: [Invoicing::InvoiceItemAdded]) - event_store.subscribe(SetBillingAddress.new, to: [Invoicing::BillingAddressSet]) - event_store.subscribe(SetPaymentDate.new, to: [Invoicing::InvoicePaymentDateSet]) - event_store.subscribe(MarkAsIssued.new, to: [Invoicing::InvoiceIssued]) - event_store.subscribe(MarkOrderPlaced.new, to: [Ordering::OrderPlaced]) - end - end -end diff --git a/rails_application/app/read_models/invoices/create_invoice_item.rb b/rails_application/app/read_models/invoices/create_invoice_item.rb deleted file mode 100644 index c94aa288a..000000000 --- a/rails_application/app/read_models/invoices/create_invoice_item.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Invoices - class CreateInvoiceItem - def call(event) - invoice = Invoice.find_or_initialize_by(order_uid: event.data.fetch(:invoice_id)) - - item = InvoiceItem.create( - invoice: invoice, - name: event.data.fetch(:title), - vat_rate: event.data.fetch(:vat_rate).fetch(:rate), - unit_price: event.data.fetch(:unit_price), - quantity: event.data.fetch(:quantity), - value: event.data.fetch(:unit_price) * event.data.fetch(:quantity) - ) - invoice.total_value = (invoice.total_value || 0) + item.value - invoice.save! - end - end -end diff --git a/rails_application/app/read_models/invoices/mark_as_issued.rb b/rails_application/app/read_models/invoices/mark_as_issued.rb deleted file mode 100644 index 8fa56e41e..000000000 --- a/rails_application/app/read_models/invoices/mark_as_issued.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Invoices - class MarkAsIssued - def call(event) - invoice = Invoice.find_or_initialize_by(order_uid: event.data.fetch(:invoice_id)) - invoice.issued = true - invoice.issue_date = event.data.fetch(:issue_date) - invoice.disposal_date = event.data.fetch(:disposal_date) - invoice.number = event.data.fetch(:invoice_number) - invoice.save! - end - end -end diff --git a/rails_application/app/read_models/invoices/mark_order_placed.rb b/rails_application/app/read_models/invoices/mark_order_placed.rb deleted file mode 100644 index 1ccd2b3c0..000000000 --- a/rails_application/app/read_models/invoices/mark_order_placed.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Invoices - class MarkOrderPlaced - def call(event) - invoice = Invoice.find_or_initialize_by(order_uid: event.data.fetch(:order_id)) - Order.find_or_initialize_by(uid: event.data.fetch(:order_id)).update!(submitted: true) - invoice.save! - end - end -end diff --git a/rails_application/app/read_models/invoices/set_billing_address.rb b/rails_application/app/read_models/invoices/set_billing_address.rb deleted file mode 100644 index cbdd75518..000000000 --- a/rails_application/app/read_models/invoices/set_billing_address.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Invoices - class SetBillingAddress - def call(event) - invoice = Invoice.find_or_initialize_by(order_uid: event.data.fetch(:invoice_id)) - invoice.address_present = true - invoice.tax_id_number = event.data.fetch(:tax_id_number) - postal_address = event.data.fetch(:postal_address) - invoice.address_line_1 = postal_address.fetch(:line_1) - invoice.address_line_2 = postal_address.fetch(:line_2) - invoice.address_line_3 = postal_address.fetch(:line_3) - invoice.address_line_4 = postal_address.fetch(:line_4) - invoice.save! - end - end -end diff --git a/rails_application/app/read_models/invoices/set_payment_date.rb b/rails_application/app/read_models/invoices/set_payment_date.rb deleted file mode 100644 index 4ee6a43c9..000000000 --- a/rails_application/app/read_models/invoices/set_payment_date.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Invoices - class SetPaymentDate - def call(event) - invoice = - Invoice.find_or_initialize_by(order_uid: event.data.fetch(:invoice_id)) - invoice.payment_date = event.data.fetch(:payment_date) - invoice.save! - end - end -end - diff --git a/rails_application/app/read_models/products/configuration.rb b/rails_application/app/read_models/products/configuration.rb deleted file mode 100644 index e8174f0af..000000000 --- a/rails_application/app/read_models/products/configuration.rb +++ /dev/null @@ -1,55 +0,0 @@ -module Products - class Product < ApplicationRecord - self.table_name = "products" - serialize :current_prices_calendar, Array - - def current_prices_calendar - return [] unless super - super.map(&method(:parse_calendar_entry)) - end - - def price(time = Time.current) - last_price_before(time) - end - - def future_prices_calendar - current_prices_calendar.select { |entry| entry[:valid_since] > Time.current } - end - - private - - def last_price_before(time) - (prices_before(time).last || {})[:price] - end - - def prices_before(time) - current_prices_calendar.partition { |entry| entry[:valid_since] < time }.first - end - - def parse_calendar_entry(entry) - { - valid_since: Time.zone.parse(time_of(entry)).in_time_zone(Time.current.zone), - price: BigDecimal(entry[:price]) - } - end - - def time_of(entry) - entry[:valid_since] - end - end - - class Configuration - def initialize(event_store) - @read_model = SingleTableReadModel.new(event_store, Product, :product_id) - @event_store = event_store - end - - def call - @read_model.subscribe_create(ProductCatalog::ProductRegistered) - @read_model.subscribe_copy(ProductCatalog::ProductNamed, :name) - @read_model.subscribe_copy(Inventory::StockLevelChanged, :stock_level) - @read_model.subscribe_copy(Taxes::VatRateSet, [:vat_rate, :code]) - @event_store.subscribe(RefreshFuturePricesCalendar, to: [Pricing::PriceSet]) - end - end -end diff --git a/rails_application/app/read_models/products/refresh_future_prices_calendar.rb b/rails_application/app/read_models/products/refresh_future_prices_calendar.rb deleted file mode 100644 index 276a8982f..000000000 --- a/rails_application/app/read_models/products/refresh_future_prices_calendar.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Products - class RefreshFuturePricesCalendar - def call(event) - product_id = event.data.fetch(:product_id) - product = Product.find_or_create_by(id: product_id) - product.update!(current_prices_calendar: updated_prices_calendar(event, product)) - end - - private - - def updated_prices_calendar(event, product) - (product.read_attribute(:current_prices_calendar) << new_entry_from_event(event)) - .sort_by { |entry| Time.parse(entry[:valid_since]) } - end - - def new_entry_from_event(event) - { - price: event.data.fetch(:price).to_s, - valid_since: event.metadata.fetch(:valid_at).to_s - } - end - end -end diff --git a/rails_application/app/read_models/public_offer/configuration.rb b/rails_application/app/read_models/public_offer/configuration.rb deleted file mode 100644 index 301d9354c..000000000 --- a/rails_application/app/read_models/public_offer/configuration.rb +++ /dev/null @@ -1,76 +0,0 @@ -module PublicOffer - class ProductsList < Arbre::Component - - def self.build(view_context) - new(Arbre::Context.new(nil, view_context)).build(Product.all) - end - - def build(products, attributes = {}) - super(attributes) - - div class: "max-w-6xl mx-auto py-6 sm:px-6 lg:px-8" do - products_table(products) - end - - end - - private - - def products_table(products) - if products.count > 0 - table class: "w-full" do - thead do - tr class: "border-t" do - th class: "text-left py-2" do - "Name" - end - th class: "text-right py-2" do - "Price" - end - end - end - tbody do - products.each do |product| - tr class: "border-t" do - - td class: "py-2 text-left" do - product.name - end - td class: "py-2 text-right" do - if product.lowest_recent_price_lower_from_current? - span title: "Lowest recent price: #{number_to_currency(product.lowest_recent_price)}", - id: "lowest-price-info-#{product.id}" do - "ℹ️" - end - end - - span do - number_to_currency(product.price) - end - end - end - end - end - end - else - para do - "No products to display." - end - end - end - end - - class Configuration - def initialize(event_store) - @read_model = SingleTableReadModel.new(event_store, Product, :product_id) - @event_store = event_store - end - - def call - @read_model.subscribe_create(ProductCatalog::ProductRegistered) - @read_model.subscribe_copy(ProductCatalog::ProductNamed, :name) - @read_model.subscribe_copy(Pricing::PriceSet, :price) - @event_store.subscribe(RegisterLowestPrice, to: [Pricing::PriceSet]) - end - end -end diff --git a/rails_application/app/read_models/public_offer/product.rb b/rails_application/app/read_models/public_offer/product.rb deleted file mode 100644 index 5a69caa15..000000000 --- a/rails_application/app/read_models/public_offer/product.rb +++ /dev/null @@ -1,9 +0,0 @@ -module PublicOffer - class Product < ApplicationRecord - self.table_name = "public_offer_products" - - def lowest_recent_price_lower_from_current? - lowest_recent_price && lowest_recent_price < price - end - end -end diff --git a/rails_application/app/read_models/public_offer/register_lowest_price.rb b/rails_application/app/read_models/public_offer/register_lowest_price.rb deleted file mode 100644 index 7d47d6c8b..000000000 --- a/rails_application/app/read_models/public_offer/register_lowest_price.rb +++ /dev/null @@ -1,72 +0,0 @@ -module PublicOffer - class RegisterLowestPrice - RECENT_PERIOD = 30.days - - def call(event) - product_id = event.data.fetch(:product_id) - - link_to_stream(event, product_id) - - lowest_recent_price = lowest_recent_price_for(product_id) - - product = Product.find(product_id) - product.update!(lowest_recent_price: lowest_recent_price) - end - - private - - def lowest_recent_price_for(product_id) - price_changes = project_price_changes(product_id) - border_event = find_border_event(price_changes) - - events_to_compare = price_changes.select do |price_change| - recent_event?(price_change) && !future_event?(price_change) - end - - events_to_compare.push(border_event) if border_event.present? - - events_to_compare.min_by { |price_change| price_change.fetch(:price) }&.fetch(:price) - end - - def project_price_changes(product_id) - RailsEventStore::Projection - .from_stream(stream_name(product_id)) - .init(-> { [] }) - .when( - Pricing::PriceSet, - ->(state, event) { state.push({ valid_at: event.valid_at, price: event.data.fetch(:price) }) } - ) - .run(event_store) - .sort_by { |price_change| price_change.fetch(:valid_at) } - end - - def find_border_event(price_changes) - price_changes.reverse.find { |price_change| !recent_event?(price_change) } - end - - def recent_event?(price_change) - price_change.fetch(:valid_at) > RECENT_PERIOD.ago.beginning_of_day - end - - def future_event?(price_change) - price_change.fetch(:valid_at) > Time.now - end - - def link_to_stream(event, product_id) - event_store.link( - event.event_id, - stream_name: stream_name(product_id) - ) - rescue RubyEventStore::EventDuplicatedInStream => error - Rails.logger.info("Duplicated event registered for PricesHistoryReport: #{error}") - end - - def event_store - Rails.configuration.event_store - end - - def stream_name(product_id) - "PricesHistoryReport$#{product_id}" - end - end -end diff --git a/rails_application/app/read_models/shipments/configuration.rb b/rails_application/app/read_models/shipments/configuration.rb deleted file mode 100644 index d6f082712..000000000 --- a/rails_application/app/read_models/shipments/configuration.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Shipments - class Shipment < ApplicationRecord - self.table_name = "shipments" - - has_one :order, - class_name: "Orders::Order", - foreign_key: :uid, - primary_key: :order_uid - - def full_address - [self.address_line_1, self.address_line_2, self.address_line_3, self.address_line_4].join(" ") - end - end - - class Order < ApplicationRecord - self.table_name = "shipments_orders" - end - - class Configuration - def call(event_store) - event_store.subscribe(SetShippingAddress, to: [Shipping::ShippingAddressAddedToShipment]) - event_store.subscribe(MarkOrderPlaced, to: [Ordering::OrderPlaced]) - end - end -end diff --git a/rails_application/app/read_models/shipments/mark_order_placed.rb b/rails_application/app/read_models/shipments/mark_order_placed.rb deleted file mode 100644 index ed0868a75..000000000 --- a/rails_application/app/read_models/shipments/mark_order_placed.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Shipments - class MarkOrderPlaced - def call(event) - Order.find_or_initialize_by(uid: event.data.fetch(:order_id)).update!(submitted: true) - end - end -end diff --git a/rails_application/app/read_models/shipments/set_shipping_address.rb b/rails_application/app/read_models/shipments/set_shipping_address.rb deleted file mode 100644 index f5e2ceec6..000000000 --- a/rails_application/app/read_models/shipments/set_shipping_address.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Shipments - class SetShippingAddress - def call(event) - shipment = Shipment.find_or_create_by(order_uid: event.data.fetch(:order_id)) - postal_address = event.data.fetch(:postal_address) - shipment.address_line_1 = postal_address.fetch(:line_1) - shipment.address_line_2 = postal_address.fetch(:line_2) - shipment.address_line_3 = postal_address.fetch(:line_3) - shipment.address_line_4 = postal_address.fetch(:line_4) - shipment.save! - end - end -end diff --git a/rails_application/app/read_models/single_table_read_model.rb b/rails_application/app/read_models/single_table_read_model.rb deleted file mode 100644 index dafe81310..000000000 --- a/rails_application/app/read_models/single_table_read_model.rb +++ /dev/null @@ -1,117 +0,0 @@ -class SingleTableReadModel - def initialize(event_store, active_record_name, id_column) - @event_store = event_store - @active_record_name = active_record_name - @id_column = id_column - end - - def subscribe_create(creation_event) - @event_store.subscribe(create_handler(creation_event), to: [creation_event]) - end - - def subscribe_copy(event, sequence_of_keys, column = Array(sequence_of_keys).join('_')) - @event_store.subscribe(copy_handler(event, sequence_of_keys, column), to: [event]) - end - - private - - def create_handler(event) - handler_class_name = "Create#{@active_record_name.name.gsub('::', '')}On#{event.name.gsub('::', '')}" - Object.send(:remove_const, handler_class_name) if self.class.const_defined?(handler_class_name) - _active_record_name_, _id_column_, _event_store_ = @active_record_name, @id_column, @event_store - Object.const_set( - handler_class_name, - Class.new(CreateRecord) do - define_method(:event_store) { _event_store_ } - define_method(:active_record_name) { _active_record_name_ } - define_method(:id_column) { _id_column_ } - end - ) - end - - def copy_handler(event, sequence_of_keys, column) - handler_class_name = "Set#{@active_record_name.name.gsub('::', '')}#{column.to_s.camelcase}On#{event.name.gsub('::', '')}" - Object.send(:remove_const, handler_class_name) if self.class.const_defined?(handler_class_name) - _active_record_name_, _id_column_, _event_store_ = @active_record_name, @id_column, @event_store - Object.const_set( - handler_class_name, - Class.new(CopyEventAttribute) do - define_method(:event_store) { _event_store_ } - define_method(:active_record_name) { _active_record_name_ } - define_method(:id_column) { _id_column_ } - define_method(:sequence_of_keys) { sequence_of_keys } - define_method(:column) { column } - end - ) - end -end - -class ReadModelHandler - def initialize(*args) - if args.present? - @event_store = args[0] - @active_record_name = args[1] - @id_column = args[2] - end - super() - end - - private - - attr_reader :active_record_name, :id_column, :event_store - - def concurrent_safely(event) - stream_name = "#{active_record_name}$#{record_id(event)}$#{event.event_type}" - read_scope = event_store.read.as_at.stream(stream_name) - begin - last_event = read_scope.last - return if last_event && last_event.timestamp > event.timestamp - ApplicationRecord.with_advisory_lock(active_record_name, record_id(event)) do - yield - event_store.link( - event.event_id, - stream_name: stream_name, - expected_version: last_event ? read_scope.to(last_event.event_id).count : -1 - ) - end - rescue RubyEventStore::WrongExpectedEventVersion - retry - rescue RubyEventStore::EventDuplicatedInStream - end - end - - def find_or_initialize_record(event) - active_record_name.find_or_initialize_by(id: record_id(event)) - end - - def record_id(event) - event.data.fetch(id_column) - end -end - -class CreateRecord < ReadModelHandler - def call(event) - concurrent_safely(event) do - find_or_initialize_record(event).save - end - end -end - -class CopyEventAttribute < ReadModelHandler - def initialize(*args) - if args.present? - @sequence_of_keys = args[3] - @column = args[4] - end - super - end - - def call(event) - concurrent_safely(event) do - find_or_initialize_record(event).update_attribute(column, event.data.dig(*sequence_of_keys)) - end - end - - private - attr_reader :sequence_of_keys, :column -end \ No newline at end of file diff --git a/rails_application/app/read_models/time_promotions/broadcaster.rb b/rails_application/app/read_models/time_promotions/broadcaster.rb deleted file mode 100644 index a62bd7813..000000000 --- a/rails_application/app/read_models/time_promotions/broadcaster.rb +++ /dev/null @@ -1,10 +0,0 @@ -module TimePromotions - class Broadcaster - def call(content) - Turbo::StreamsChannel.broadcast_append_to( - "time_promotions", - target: "time_promotions_table", - html: content) - end - end -end \ No newline at end of file diff --git a/rails_application/app/read_models/time_promotions/configuration.rb b/rails_application/app/read_models/time_promotions/configuration.rb deleted file mode 100644 index 6dedc84b6..000000000 --- a/rails_application/app/read_models/time_promotions/configuration.rb +++ /dev/null @@ -1,13 +0,0 @@ -module TimePromotions - class TimePromotion < ApplicationRecord - self.table_name = "time_promotions" - - scope :current, -> { where("start_time < ? AND end_time > ?", Time.current, Time.current) } - end - - class Configuration - def call(event_store) - event_store.subscribe(CreateTimePromotion, to: [Pricing::TimePromotionCreated]) - end - end -end diff --git a/rails_application/app/read_models/time_promotions/create_time_promotion.rb b/rails_application/app/read_models/time_promotions/create_time_promotion.rb deleted file mode 100644 index f68ba572b..000000000 --- a/rails_application/app/read_models/time_promotions/create_time_promotion.rb +++ /dev/null @@ -1,16 +0,0 @@ -module TimePromotions - class CreateTimePromotion - def call(event) - time_promotion = TimePromotion.create!(event.data.slice(:code, :discount, :start_time, :end_time, :label).merge(id: event.data[:time_promotion_id])) - Broadcaster.new.call(<<~HTML - - #{time_promotion.label} - #{time_promotion.discount} - #{time_promotion.start_time} - #{time_promotion.end_time} - - HTML -) - end - end -end diff --git a/rails_application/app/views/billing_addresses/edit.erb b/rails_application/app/views/billing_addresses/edit.erb index 5d61da338..7db7db63a 100644 --- a/rails_application/app/views/billing_addresses/edit.erb +++ b/rails_application/app/views/billing_addresses/edit.erb @@ -5,9 +5,9 @@ <% content_for(:actions) do %> <%= secondary_action_button do %> <% if @order.submitted? %> - <%= link_to 'Back', order_path(@order.uid) %> + <%= link_to 'Back', order_path(@order.id) %> <% else %> - <%= link_to 'Back', edit_order_path(@order.uid) %> + <%= link_to 'Back', edit_order_path(@order.id) %> <% end %> <% end %> @@ -16,35 +16,35 @@ <% end %> <% end %> -<%= form_with(model: @invoice, url: order_billing_address_path(@invoice.order_uid), method: "patch", id: "form") do |form| %> +<%= form_with(model: @order, url: order_billing_address_path(@order.id), method: "patch", id: "form") do |form| %>
- <%= form.text_field :tax_id_number, required: false, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %> + <%= form.text_field :invoice_tax_id_number, required: false, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %>
- <%= form.text_field :address_line_1, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %> + <%= form.text_field :invoice_addressed_to, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %>
- <%= form.text_field :address_line_2, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %> + <%= form.text_field :invoice_address, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %>
- <%= form.text_field :address_line_3, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %> + <%= form.text_field :invoice_city, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md" %>
- <%= form.text_field :address_line_4, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %> + <%= form.text_field :invoice_country, required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
<% end %> diff --git a/rails_application/app/views/customers/index.html.erb b/rails_application/app/views/customers/index.html.erb index 2200db920..ae69bb94a 100644 --- a/rails_application/app/views/customers/index.html.erb +++ b/rails_application/app/views/customers/index.html.erb @@ -20,7 +20,7 @@ <% @customers.each do |customer| %> - <%= link_to customer.name, customer_path(customer), class: "text-blue-500 hover:underline" %> + <%= link_to customer.email, customer_path(customer), class: "text-blue-500 hover:underline" %> <%- if customer.vip %> Already a VIP diff --git a/rails_application/app/views/customers/new.html.erb b/rails_application/app/views/customers/new.html.erb index 97733f124..a3d4cd400 100644 --- a/rails_application/app/views/customers/new.html.erb +++ b/rails_application/app/views/customers/new.html.erb @@ -12,11 +12,17 @@ <% end %> <% end %> -<%= form_tag({controller: "customers", action: "create"}, method: "post", id: "form") do %> - <%= hidden_field_tag(:customer_id, @customer_id) %> - -