Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature (mix task): Add generator to scaffold the code by Domain, Resources and Actions for the core business logic #4

Open
Exadra37 opened this issue Jul 17, 2024 · 0 comments
Assignees
Milestone

Comments

@Exadra37
Copy link
Collaborator

Exadra37 commented Jul 17, 2024

Mix Task to generate a folder structure organized by Domain, Resource and Actions

Github Sponsor: https://github.com/sponsors/Exadra37

Why?

To enable developers to write Clean Code in a Clean Software Architecture that respects the Single Responsibility Principle.

The traditional approach in software development tends to group all actions for a resource under the same module, which violates the Single Responsibility Principle because the module has more than one reason to change, as many as the number of actions on the resource.

What?

What to expect from this task is that when the developer executes the mix scribe.gen.domain ... command in the terminal, the result is a folder structure where a module is created for each action of a resource in a domain. This respects the Single Responsibility Principle because each module only has one reason to change: the business logic for the single action it is responsible for.

When?

The developer should use this generator whenever they need to create a new feature scoped to the core business logic. For features that also require interaction with the external world, the developer needs to use one of the other generators that will invoke this one. For example: mix scribe.gen.html, mix scribe.gen.live, mix scribe.gen.api, and others.

Acceptance Criteria

Let's base the acceptance criteria's on a developer tasked with building an Online Shop.

1. Creating a Domain Resource with the Default Actions (CRUD)

Feature: Adding the Sales Catalog

Scenario: Adding the Category resource to the Sales Catalog with the default actions (Create, Read, Update, Delete)
Given that the developer is on a terminal
When it executes the command mix scribe.gen.domain Sales.Catalog Category categories name:string desc:string
Then it generates a folder structure with a module per each CRUD action (create, read, update and delete) for the Category resource of the Sales Catalog domain.

$ mix scribe.gen.domain Sales.Catalog Category categories name:string desc:string
...
$ tree --dirsfirst -L 6 lib/my_app
lib/my_app
├── domain
│   └── sales
│       └── catalog
│           ├── category
│           │   ├── create
│           │   │   └── create_category.ex
│           │   ├── delete
│           │   │   └── delete_category.ex
│           │   ├── edit
│           │   │   └── edit_category.ex
│           │   ├── list
│           │   │   └── list_categories.ex
│           │   ├── new
│           │   │   └── new_category.ex
│           │   ├── read
│           │   │   └── read_category.ex
│           │   ├── update
│           │   │   └── update_category.ex
│           │   └── category_schema.ex
│           └── category_api.ex
├── application.ex
├── mailer.ex
└── repo.ex

2. Creating a Domain Resource with the Default Actions (CRUD) and Extra Actions

Feature: Adding the Sales Catalog

Scenario: Adding the Product resource to the Sales Catalog with the default actions (Create, Read, Update, Delete) and Extra Actions (import, export)
Given that the developer is on a terminal
When it executes the command mix scribe.gen.domain Sales.Catalog Product products sku:string name:string desc:string --actions import,export
Then it generates a folder structure with a module per each action (create, read, update, delete, import and export) for the Product resource of the Sales Catalog domain.

$ mix scribe.gen.domain Sales.Catalog Product products sku:string name:string desc:string --actions import,export
...
$  tree --dirsfirst -L 6 lib/my_app
lib/my_app
├── domain
│   └── sales
│       └── catalog
│           ├── product
│           │   ├── create
│           │   │   └── create_product.ex
│           │   ├── delete
│           │   │   └── delete_product.ex
│           │   ├── edit
│           │   │   └── edit_product.ex
│           │   ├── export
│           │   │   └── export_product.ex
│           │   ├── import
│           │   │   └── import_product.ex
│           │   ├── list
│           │   │   └── list_products.ex
│           │   ├── new
│           │   │   └── new_product.ex
│           │   ├── read
│           │   │   └── read_product.ex
│           │   ├── update
│           │   │   └── update_product.ex
│           │   └── product_schema.ex
│           └── product_api.ex
├── application.ex
├── mailer.ex
└── repo.ex


3. Creating a Domain Resource only with Extra Actions

Feature: Adding the Warehouse Fulfillment

Scenario: Adding the Fulfillment Order resource to the Warehouse Fulfillment Domain only with the list action
Given that the developer is on a terminal
When it executes the command mix scribe.gen.domain Warehouse.Fulfillment FulfillmentOrder fulfillment_orders uuid:string label:string total_quantity:integer location:string products_sku:array:string --no-default-actions --actions list
Then it generates a folder structure with only one module for the extra action list.

$ mix scribe.gen.domain Warehouse.Fulfillment FulfillmentOrder fulfillment_orders uuid:string label:string total_quantity:integer location:string products_sku:array:string --no-default-actions --actions list
...
$ tree --dirsfirst -L 6 lib/my_app
lib/my_app
├── domain
│   └── warehouse
│       └── fulfillment
│           ├── fulfillment_order
│           │   ├── list
│           │   │   └── list_fulfillment_orders.ex
│           │   └── fulfillment_order_schema.ex
│           └── fulfillment_order_api.ex
├── application.ex
├── mailer.ex
└── repo.ex

Folder Structure for all Acceptance Criteria's

$ tree --dirsfirst -L 6 lib/my_app
lib/my_app
├── domain
│   ├── sales
│   │   └── catalog
│   │       ├── category
│   │       │   ├── create
│   │       │   │   └── create_category.ex
│   │       │   ├── delete
│   │       │   │   └── delete_category.ex
│   │       │   ├── edit
│   │       │   │   └── edit_category.ex
│   │       │   ├── list
│   │       │   │   └── list_categories.ex
│   │       │   ├── new
│   │       │   │   └── new_category.ex
│   │       │   ├── read
│   │       │   │   └── read_category.ex
│   │       │   ├── update
│   │       │   │   └── update_category.ex
│   │       │   └── category_schema.ex
│   │       ├── product
│   │       │   ├── create
│   │       │   │   └── create_product.ex
│   │       │   ├── delete
│   │       │   │   └── delete_product.ex
│   │       │   ├── edit
│   │       │   │   └── edit_product.ex
│   │       │   ├── export
│   │       │   │   └── export_product.ex
│   │       │   ├── import
│   │       │   │   └── import_product.ex
│   │       │   ├── list
│   │       │   │   └── list_products.ex
│   │       │   ├── new
│   │       │   │   └── new_product.ex
│   │       │   ├── read
│   │       │   │   └── read_product.ex
│   │       │   ├── update
│   │       │   │   └── update_product.ex
│   │       │   └── product_schema.ex
│   │       ├── category_api.ex
│   │       └── product_api.ex
│   └── warehouse
│       └── fulfillment
│           ├── fulfillment_order
│           │   ├── list
│           │   │   └── list_fulfillment_orders.ex
│           │   └── fulfillment_order_schema.ex
│           └── fulfillment_order_api.ex
├── application.ex
├── mailer.ex
└── repo.ex

Tip

→ To only see dirs in the tree add the option -d: tree -d --dirsfirst -L 7 lib/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

1 participant