All Projects → herbsjs → buchu

herbsjs / buchu

Licence: other
Use Cases - Uniform, auditable and secure use case library

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to buchu

MonolithicArchitecture
This repository presents an approach on how to build an application using Monolithic architecture, ASP.NET Core, EntityFrameworkCore, Identity Server, CQRS, DDD
Stars: ✭ 18 (-21.74%)
Mutual labels:  ddd, domain-driven-design, clean-architecture, cleanarchitecture
Plastic
This project provides encapsulation of things like Domain, Application Rules, Business Rules or Business Logic in Application.
Stars: ✭ 30 (+30.43%)
Mutual labels:  ddd, domain-driven-design, clean-architecture, usecase
Clean-Architecture-Template
Configurable Clean Architecture template containing the DDD + CQRS approach for .NET Core applications.
Stars: ✭ 14 (-39.13%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Event Sourcing Castanha
An Event Sourcing service template with DDD, TDD and SOLID. It has High Cohesion and Loose Coupling, it's a good start for your next Microservice application.
Stars: ✭ 68 (+195.65%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Run Aspnetcore
A starter kit for your next ASP.NET Core web application. Boilerplate for ASP.NET Core reference application, demonstrating a layered application architecture with applying Clean Architecture and DDD best practices. Download 100+ page eBook PDF from here ->
Stars: ✭ 227 (+886.96%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
clean-ddd-php-poc-contacts
A simple contact manager API to demonstrate the concepts of Clean Architecture and DDD with PHP 7.4+.
Stars: ✭ 31 (+34.78%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Modular Monolith With Ddd
Full Modular Monolith application with Domain-Driven Design approach.
Stars: ✭ 6,210 (+26900%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Architecture
.NET 6, ASP.NET Core 6, Entity Framework Core 6, C# 10, Angular 13, Clean Code, SOLID, DDD.
Stars: ✭ 2,285 (+9834.78%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Sample Dotnet Core Cqrs Api
Sample .NET Core REST API CQRS implementation with raw SQL and DDD using Clean Architecture.
Stars: ✭ 1,273 (+5434.78%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
repository
[PHP 7] Implementation and definition of a base Repository in Domain land.
Stars: ✭ 26 (+13.04%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
clean-architecture
Package for isolate your domain code from framework dependency using DDD concepts.
Stars: ✭ 93 (+304.35%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
EcommerceDDD
Experimental full-stack application using Domain-Driven Design, CQRS, and Event Sourcing.
Stars: ✭ 178 (+673.91%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Jivejdon
Jivejdon is a Domain Driven Design appication with CQRS/ES/Clean/Hexagonal architecture
Stars: ✭ 287 (+1147.83%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Clean Architecture Manga
🌀 Clean Architecture with .NET6, C#10 and React+Redux. Use cases as central organizing structure, completely testable, decoupled from frameworks
Stars: ✭ 3,104 (+13395.65%)
Mutual labels:  domain-driven-design, clean-architecture, cleanarchitecture
Cp Ddd Framework
A lightweight flexible development framework for complex business architecture with full ecosystem!轻量级业务中台开发框架,中台架构的顶层设计和完整解决方案!
Stars: ✭ 566 (+2360.87%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
Dotnet New Caju
Learn Clean Architecture with .NET Core 3.0 🔥
Stars: ✭ 228 (+891.3%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
educational-platform
Modular Monolith Java application with DDD
Stars: ✭ 124 (+439.13%)
Mutual labels:  ddd, domain-driven-design, clean-architecture
go-hexagonal http api-course
Ejemplos del curso de API HTTP en Go aplicando Arquitectura Hexagonal
Stars: ✭ 78 (+239.13%)
Mutual labels:  ddd, domain-driven-design
delta
DDD-centric event-sourcing library for the JVM
Stars: ✭ 15 (-34.78%)
Mutual labels:  ddd, domain-driven-design
typescript-ddd-example
🔷🎯 TypeScript DDD Example: Complete project applying Hexagonal Architecture and Domain-Driven Design patterns
Stars: ✭ 607 (+2539.13%)
Mutual labels:  ddd, domain-driven-design

CI build codecov

buchu

Uniform, auditable and secure use case javascript library. Influenced by Clean Architecture and Trailblazer

index

Installing

$ npm install @herbsjs/buchu

Using

Check the complete examples here or for a complete solution using herbsJS here.

usecases/addOrUpdateItem.js:

const { entity, field } = require('@herbsjs/gotu')
const Item = entity('Item', {
  id: field(Number),
  description: field(String),
  isDone: field(Boolean),
  position: field(Number)
})

const { Ok, Err, usecase, step, ifElse } = require('@herbsjs/buchu')
const dependency = {
    ItemRepository: require('../repositories/ItemRepository').ItemRepository,
    ...
}

const addOrUpdateItem = (injection) =>

    usecase('Add or Update an Item on a to-do List', {

        // Input/Request type validation
        request: { listId: Number, item: Item },

        // Output/Response type
        response: { item: Item },

        // Authorization Audit
        authorize: async (user) => user.isAdmin ? Ok() : Err(),

        // Dependency Injection control
        setup: (ctx) => ctx.di = Object.assign({}, dependency, injection),

        // Step audit and description
        'Check if the Item is valid': step((ctx) => {
            ...
            return item.validate() // Ok or Error
        }),

        'Check if the List exists': step(async (ctx) => {
            ...
            return Ok()
        }),

        // Conditional step
        'Add or Update the Item': ifElse({

            'If the Item exists': step(async (ctx) => {
                ...
                return Ok(newItem)
            }),

            'Then: Add a new Item to the List': step(async (ctx) => {
                ...
                return ctx.ret = await itemRepo.save(item) // Ok or Error
            }),

            'Else: Update Item on the List': step(async (ctx) => {
                ...
                return ctx.ret = await itemRepo.save(item) // Ok or Error
            })
        })
    })

to another resources like, ctx.stop() used to stop a use case next steps execution, look here

controler/addOrUpdateItem.js:

app.put('/items/:item', function (req, res) {
    const request = req.params
    const user = { name: 'John', id: '923b8b9a', isAdmin: true } // from session

    const uc = addOrUpdateItem()
    await uc.authorize(user)
    const ret = await uc.run(request)
    res.send(ret)
})

uc.doc():

{
  type: 'use case',
  description: 'Add or Update an Item on a to-do List',
  request: { listId: Number, item: Item },
  response: String,
  steps: [
    { type: 'step', description: 'Check if the Item is valid', steps: null },
    { type: 'step', description: 'Check if the List exists', steps: null },
    {
        type: 'if else',
        if: { type: 'step', description: 'If the Item exists', steps: null },
        then: { type: 'step', description: 'Then: Add a new Item to the List', steps: null },
        else: { type: 'step', description: 'Else: Update Item on the List', steps: null }
    }
  ]
}

Motivations

Maintainability

"Programs must be written for people to read, and only incidentally for machines to execute" - Harold Abelson, Structure and Interpretation of Computer Programs

Understanding what a software is doing from a business perspective is a must in order to be able to change it quickly and in a sustainable way.

Metadata for system intent

It should be easy to retrieve a system's metadata for all its use cases and steps. This info could be used to leverage innovative interfaces (ex: dynamic admin pages, use case documentations, etc), helping narrow the gap between developers, testers and product managers.

Auditable and Secure

It should be easy to have enterprise grade features even for simple applications. Authorization and auditing, for instance, should be available out of the box. Not using should be opt-in.

Audit

It is possible to retrieve the audit trail of an use case after its execution

uc.auditTrail:

{
    type: 'use case',
    description: 'Add or Update an Item on a to-do List',
    transactionId: '9985fb70-f56d-466a-b466-e200d1d4848c',
    elapsedTime: 1981800n, // in nanosecods
    user: { name: 'John', id: '923b8b9a', isAdmin: true },
    authorized: true,
    return: {
        Ok: { item: { id: 100, name: 'Do not forget this', position: 9 } }
    },
    steps: [
        { type: 'step', description: 'Check if the Item is valid', elapsedTime: 208201n , return: {} },
        { type: 'step', description: 'Check if the List exists', elapsedTime: 114300n , return: {}  },
        {
            type: 'if else',
            description: 'Add or Update the Item',
            returnIf: { Ok: true },
            returnThen: {}
        }
    ]
}

TIP: If you need to audit the exceptions thrown by the use case use process.env.HERBS_EXCEPTION = "audit". This will swallow the exceptions and return a Err on the step. Recommended for production environments.

Request Validation

A request can be validated against the field's type.

const addOrUpdateItem = (injection) =>

    usecase('Add or Update an Item on a to-do List', {

        // Input/Request type validation
        request: { listId: Number, item: Object },

    ...

Request types

A field in a request can be basic types from Javascript or entities created from gotu herbs lib:

Number: double-precision 64-bit binary format IEEE 754 value

String: a UTF‐16 character sequence

Boolean: true or false

Date: represents a single moment in time in a platform-independent format.

Object: the Object class represents one of JavaScript's data types.

Array: the Array class is a object that is used in the construction of arrays.

Entity: entity object represents an gotu base entity.

Use Case

What is it?

A Use Case reflects a single action exposed by the Domain to the end user. Ex: Reopen Ticket, Reply Message, Add User

Internaly a Use Case control the interaction between Entities, Repositories (infrastructure) and other Domain components.

It should:

  • Be modeled around business
  • Be reusable
  • Be testable / Have clear acceptance criteria
  • Help identify right architecture
  • Ubiquitous language

"Use cases orchestrate the flow of data to and from the entities, and direct those entities to use their Critical Business Rules to achieve the goals of the use case." - Clean Architecture book

Best pratices

  • Keep it simple by telling stories
  • Understand the big picture
  • Focus on value
  • Build the use case in steps

Architecture:

  • Implement business flows using Use Cases.

    Ex: Reply Message use case interacts with Message, Ticket, User and others entities in order to reply a message for a user

  • Split the flows in smaller steps

  • Avoid implement validations using Use Cases. Prefer Entities for validations

  • Access Use Cases from outside the Domain

    Use cases are the "entry points" for the Domain layer, so it is the only accessible layer from outside the Domain.

  • Don't access any other sublayer which belongs to Domain layer (Entities, etc) apart Use Case from outside Domain

  • Name the Use Case folder, file and its steps as an action (verb).

    Ex: OpenTicket.js, ReplyMessage.js, AddUser.js

    Use Cases are implemented as command patterns.

References:

  • Clean Architecture book link
  • Use Case 2.0 link
  • Use Case diagram link
  • Service Layer link

Errors

As you noted into example session you can return an Err object, this class can be an generic Err as can be a structured Err too

const options = { message: 'message', payload: { entity: 'user' }, cause: Err("my message") || new Error() }
Err.notFound(options),
Err.alreadyExists(options),
Err.invalidEntity(options),
Err.invalidArguments({ ...options, args: { name: 'cant be empty' }}),
Err.permissionDenied(options),
Err.unknown(options),
Err.buildCustomErr(options),

or you can create your own structured Err

Err._buildCustomErr('ERROR_CODE', message, payload, cause)

To Do

  • Base - Run a use case
  • Use Case Error - Ok or Error results for a use case (Rust inspired)
  • Steps - Enable multiple steps for a use case
  • Nested Steps - Enable multiple steps for a parent step
  • Nested Steps - multiple files - Enable multiple steps in diferent files for a parent step
  • Use usecase as a step
  • Doc Step - Get description and structure from use case and its steps
  • Request - Be able to describe and validate the use case request object
  • Response - Be able to describe and validate the use case response object
  • Dependency Injection (removed)
  • ctx var - Share context between Steps
  • Conditional Steps - Enable a If/Else constructor for steps
  • Authorization - Be able to authorize the execution of a use case and its steps
  • Audit - Be able to track use case runtime information
  • Audit - Timing - Be able to track use case and its steps execution time
  • Async / MQ - Multiple Rounds - Be able to partially execute a use case and continue (when a MQ is necessary, for instance)
  • transaction ID - A ID to track execution between steps
  • session ID - A ID to track execution between use cases
  • Deal with exceptions
  • Deal with no default results (Ok/Err)
  • Deal with async / await steps
  • Use case examples

Contribute

Come with us to make an awesome Buchu.

Now, if you do not have technical knowledge and also have intend to help us, do not feel shy, click here to open an issue and collaborate their ideas, the contribution may be a criticism or a compliment (why not?)

If you would like to help contribute to this repository, please see CONTRIBUTING

The Herb

Buchu is most often used as a stimulating tonic and a diuretic. It is now commonly used to treat urinary tract infections. In the past, this herb has also been used to treat arthritis, kidney stones and gout. It can also be used externally for bruises and sprains.

https://www.herbslist.net/

https://en.wikipedia.org/wiki/Agathosma_betulina

License

Buchu is released under the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].