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 HTML generator to scaffold the code by Domain, Resources and Actions for the Web layer #5

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

Comments

@Exadra37
Copy link
Collaborator

Exadra37 commented Jul 18, 2024

Mix Task to generate the Web 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.html ... command in the terminal, the result is a folder structure where a module is created for each action of a resource in a domain at lib/my_app_web/. This respects the Single Responsibility Principle because each module only has one reason to change: the web logic for the single action it is responsible for.

This generator will also invoke mix scribe.gen.domain (issue #4) to generate the Domain, Resource and Actions for the core business logic.

When?

The developer should use this generator whenever they need to create a new feature consumed by a web app via HTML endpoints.

Acceptance Criteria's

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) for the HTML and Core layers

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.html 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 at lib/my_app_web and lib/my_app.

$ mix scribe.gen.html Sales.Catalog Category categories name:string desc:string
...
$ tree --dirsfirst -L 6 lib/my_app_web/domain
lib/my_app_web/domain
└── sales
    └── catalog
        └── category
            ├── create
            │   └── create_category_controller.ex
            ├── delete
            │   └── delete_category_controller.ex
            ├── edit
            │   ├── edit_category.html.heex
            │   └── edit_category_controller.ex
            ├── list
            │   ├── list_categories.html.heex
            │   └── list_categories_controller.ex
            ├── new
            │   ├── new_category.html.heex
            │   └── new_category_controller.ex
            ├── read
            │   ├── read_category.html.heex
            │   └── read_category_controller.ex
            ├── update
            │   └── update_category_controller.ex
            ├── category_form.html.heex
            └── category_html.ex

2. Creating a Domain Resource with the Default Actions (CRUD) and Extra Actions for the HTML and Core layers

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.html 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 at lib/my_app_web and lib/my_app.

$ mix scribe.gen.html Sales.Catalog Product products sku:string name:string desc:string --actions import,export
...
$  tree --dirsfirst -L 6 lib/my_app_web/domain
lib/my_app_web/domain
└── sales
    └── catalog
        └── product
            ├── create
            │   └── create_product_controller.ex
            ├── delete
            │   └── delete_product_controller.ex
            ├── edit
            │   ├── edit_product.html.heex
            │   └── edit_product_controller.ex
            ├── export
            │   └── default_product_controller.ex
            ├── import
            │   └── default_product_controller.ex
            ├── list
            │   ├── list_products.html.heex
            │   └── list_products_controller.ex
            ├── new
            │   ├── new_product.html.heex
            │   └── new_product_controller.ex
            ├── read
            │   ├── read_product.html.heex
            │   └── read_product_controller.ex
            ├── update
            │   └── update_product_controller.ex
            ├── product_form.html.heex
            └── product_html.ex

3. Creating a Domain Resource only with Extra Actions for the HTML and COre layers

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.html 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 at lib/my_app_web and lib/my_app.

$ mix scribe.gen.html Warehouse.Fulfillment FulfillmentOrder fulfillment_orders uuid:string label:string total_quantity:integer location:string products_sku:array:string --no-default-actions --actions list
...
$  lib/my_app_web/domain
└── warehouse
    └── fulfillment
        └── fulfillment_order
            ├── list
            │   ├── list_fulfillment_orders.html.heex
            │   └── list_fulfillment_orders_controller.ex
            ├── fulfillment_order_form.html.heex
            └── fulfillment_order_html.ex

Folder Structure for all Acceptance Criteria's

$  tree --dirsfirst -L 7 lib/
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
├── my_app_web
│   ├── components
│   │   ├── layouts
│   │   │   ├── app.html.heex
│   │   │   └── root.html.heex
│   │   ├── core_components.ex
│   │   └── layouts.ex
│   ├── controllers
│   │   ├── page_html
│   │   │   └── home.html.heex
│   │   ├── error_html.ex
│   │   ├── error_json.ex
│   │   ├── page_controller.ex
│   │   └── page_html.ex
│   ├── domain
│   │   ├── sales
│   │   │   └── catalog
│   │   │       ├── category
│   │   │       │   ├── create
│   │   │       │   │   └── create_category_controller.ex
│   │   │       │   ├── delete
│   │   │       │   │   └── delete_category_controller.ex
│   │   │       │   ├── edit
│   │   │       │   │   ├── edit_category.html.heex
│   │   │       │   │   └── edit_category_controller.ex
│   │   │       │   ├── list
│   │   │       │   │   ├── list_categories.html.heex
│   │   │       │   │   └── list_categories_controller.ex
│   │   │       │   ├── new
│   │   │       │   │   ├── new_category.html.heex
│   │   │       │   │   └── new_category_controller.ex
│   │   │       │   ├── read
│   │   │       │   │   ├── read_category.html.heex
│   │   │       │   │   └── read_category_controller.ex
│   │   │       │   ├── update
│   │   │       │   │   └── update_category_controller.ex
│   │   │       │   ├── category_form.html.heex
│   │   │       │   └── category_html.ex
│   │   │       └── product
│   │   │           ├── create
│   │   │           │   └── create_product_controller.ex
│   │   │           ├── delete
│   │   │           │   └── delete_product_controller.ex
│   │   │           ├── edit
│   │   │           │   ├── edit_product.html.heex
│   │   │           │   └── edit_product_controller.ex
│   │   │           ├── export
│   │   │           │   └── default_product_controller.ex
│   │   │           ├── import
│   │   │           │   └── default_product_controller.ex
│   │   │           ├── list
│   │   │           │   ├── list_products.html.heex
│   │   │           │   └── list_products_controller.ex
│   │   │           ├── new
│   │   │           │   ├── new_product.html.heex
│   │   │           │   └── new_product_controller.ex
│   │   │           ├── read
│   │   │           │   ├── read_product.html.heex
│   │   │           │   └── read_product_controller.ex
│   │   │           ├── update
│   │   │           │   └── update_product_controller.ex
│   │   │           ├── product_form.html.heex
│   │   │           └── product_html.ex
│   │   └── warehouse
│   │       └── fulfillment
│   │           └── fulfillment_order
│   │               ├── list
│   │               │   ├── list_fulfillment_orders.html.heex
│   │               │   └── list_fulfillment_orders_controller.ex
│   │               ├── fulfillment_order_form.html.heex
│   │               └── fulfillment_order_html.ex
│   ├── endpoint.ex
│   ├── gettext.ex
│   ├── router.ex
│   └── telemetry.ex
├── my_app.ex
└── my_app_web.ex

Tip

→ To only see the Core layer run: tree --dirsfirst -L 6 lib/my_app
→ To see both the Web and Core layer together run: tree --dirsfirst -L 7 lib
→ To only see dirs in the tree add the option -d: tree -d --dirsfirst -L 7 lib/

@Exadra37 Exadra37 self-assigned this Jul 18, 2024
@Exadra37 Exadra37 added this to the Release 0.3.0 milestone Jul 18, 2024
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

No branches or pull requests

1 participant