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