Domain Driven Design diagram for Umbrella app

I’m trying out the following structure

umbrella
├── core (Elixir)
├── web (Phoenix)
└── api (GraphQL)
├── config
│   ├── config.exs
│   ├── dev.exs
│   ├── prod.exs
│   └── test.exs
├── lib
│   ├── core
│   │   ├── checkout
│   │   │   ├── (...)
│   │   ├── account
│   │   │   ├── authorizers
│   │   │   │   ├── organization_authorizer.ex
│   │   │   │   ├── sales_channel_authorizer.ex
│   │   │   │   ├── shop_authorizer.ex
│   │   │   │   └── user_authorizer.ex
│   │   │   ├── models
│   │   │   │   ├── domain.ex
│   │   │   │   ├── organization.ex
│   │   │   │   ├── sales_channel.ex
│   │   │   │   ├── shop.ex
│   │   │   │   ├── tax_setting.ex
│   │   │   │   ├── theme.ex
│   │   │   │   └── user.ex
│   │   │   ├── repositories
│   │   │   │   ├── organization_repository.ex
│   │   │   │   ├── sales_channel_repository.ex
│   │   │   │   ├── shop_repository.ex
│   │   │   │   ├── theme_repository.ex
│   │   │   │   └── user_repository.ex
│   │   │   ├── organization_service.ex
│   │   │   ├── sales_channel_service.ex
│   │   │   ├── shop_service.ex
│   │   │   ├── theme_service.ex
│   │   │   └── user_service.ex
│   │   ├── inventory
│   │   │   ├── authorizers
│   │   │   │   ├── collection_authorizer.ex
│   │   │   │   ├── permalink_authorizer.ex
│   │   │   │   ├── variant_authorizer.ex
│   │   │   │   └── product_authorizer.ex
│   │   │   ├── models
│   │   │   │   ├── collection.ex
│   │   │   │   ├── image.ex
│   │   │   │   ├── permalink.ex
│   │   │   │   ├── price.ex
│   │   │   │   ├── product.ex
│   │   │   │   ├── stock.ex
│   │   │   │   └── variant.ex
│   │   │   ├── repositories
│   │   │   │   ├── collection_repository.ex
│   │   │   │   ├── permalink_repository.ex
│   │   │   │   ├── variant_repository.ex
│   │   │   │   └── product_repository.ex
│   │   │   ├── uploaders
│   │   │   │   └── image_uploader.ex
│   │   │   ├── collection_service.ex
│   │   │   │── permalink_service.ex
│   │   │   │── variant_service.ex
│   │   │   └── product_service.ex
│   │   ├── relation
│   │   │   └── models
│   │   │       ├── collection_permalink.ex
│   │   │       ├── product_collection.ex
│   │   │       ├── product_image.ex
│   │   │       ├── product_permalink.ex
│   │   │       ├── product_price.ex
│   │   │       ├── product_shop.ex
│   │   │       ├── product_stock.ex
│   │   │       ├── shop_organization.ex
│   │   │       ├── user_organization.ex
│   │   │       ├── variant_image.ex
│   │   │       ├── variant_permalink.ex
│   │   │       ├── variant_price.ex
│   │   │       └── variant_stock.ex
│   │   ├── application.ex
│   │   ├── authorizer.ex
│   │   ├── definitions.ex
│   │   └── repo.ex
│   └── core.ex
├── priv
│   └── repo
│       ├── migrations
│       │   ├── (...)
│       └── seeds.exs
├── test
│   └── (...)
├── README.md
└── mix.exs

In web and api I use the core package like:

{:ok, shop} = MyApp.Core.Account.ShopService.get(1)
{:ok, shop} = MyApp.Core.Account.ShopService.update(shop, params)

defmodule MyApp.Core.Account.ShopService do
  alias MyApp.Core.Account.{ShopAuthorizer,ShopRepository,Shop}

  def update(%Shop{} = shop, params) when is_map(params) do
    with :ok <- ShopAuthorizer.authorize(:update, shop),
      do: ShopRepository.update(shop, params)
  end
end
12 Likes