usecases

package
v0.3.85 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 23, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package usecases contains the usecases layer for the application.

Usecases combine the business logic and models in the domain layer to provide a set of business processes for the application. They operate exclusively on the domain representation and are therefore agnostic to the input and output formats used by the application.

The usecases layer codifies how the application performs the functions for which is has been designed and built. As a result, it can be used as a reference to understand what the application does. Furthermore, as each usecase is a separate file, a summary of application behaviour can be obtained by simply listing the files.

Stateless

Each usecase is either stateless or contains state configured at runtime and not modified during the lifetime of the process. This allows a single instance of each usecase to be created at startup and injected into the rest of the application as needed.

Any state that could change is provided when the usecase is executed. This includes request-scoped values such as database transactions. As a result, usecases are thread-safe and can be used concurrently without risk of race conditions.

Deviations from this stateless approach can be made as long as the core assumption still fits. For example, a usecase field could internally manage its own runtime state as long as that state management is fully encapculated and thread-safe.

Error Boundary

The usecases layer is a natural error boundary for the application. This means that errors that occur during the usecase execution are not bubbled up to caller of the usecase. Instead, a separate, clean error is returned that does not wrap any other error.

This approach simplifies error handling in the caller as other packages do not need to be reviewed to identify the full range of error values. It also helps reinforce the idea that usecases are the entry and exit point of the business logic in the application. Finally, it means wrapped error types do not need to be considered when using errors.Is and errors.As.

Consumer-Defined Interfaces

In idiomatic Go, interfaces should be defined by the consumer and implicit interface implementation should be leveraged. The usecases here embrace that philosophy. This means that usecases avoid making any assumptions about how usecases are organised and invoked. It also allows for greater decoupling of the layers within the application.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CreateResource

type CreateResource struct {
	// contains filtered or unexported fields
}

CreateResource provides the business logic for creating a resource.

func NewCreateResource

func NewCreateResource(
	clock repositories.Clock,
	uuidgen repositories.UUIDGenerator,
) *CreateResource

NewCreateResource creates a new CreateResource.

func (*CreateResource) Execute

func (u *CreateResource) Execute(
	ctx context.Context,
	logger *slog.Logger,
	store repositories.Resource,
	resource *entities.Resource,
) (*entities.Resource, error)

Execute creates a resource.

If the resource name is already in use, ErrAlreadyExists is returned. Any other failure will cause ErrInternal to be returned.

type DeleteResource

type DeleteResource struct{}

DeleteResource provides the business logic for deleting a resource.

func NewDeleteResource

func NewDeleteResource() *DeleteResource

NewDeleteResource creates a new DeleteResource.

func (*DeleteResource) Execute

func (u *DeleteResource) Execute(
	ctx context.Context,
	logger *slog.Logger,
	store repositories.Resource,
	id uuid.UUID,
) error

Execute deletes a resource.

If the resource ID does not exist, ErrNotFound is returned. Any other failure will cause ErrInternal to be returned.

type GetResource

type GetResource struct{}

GetResource provides the business logic for getting a single resource.

func NewGetResource

func NewGetResource() *GetResource

NewGetResource creates a new GetResource.

func (*GetResource) Execute

func (u *GetResource) Execute(
	ctx context.Context,
	logger *slog.Logger,
	store repositories.Resource,
	id uuid.UUID,
) (*entities.Resource, error)

Execute gets a single resource.

If the resource ID does not exist, ErrNotFound is returned. Any other failure will cause ErrInternal to be returned.

type ListAuditEvents

type ListAuditEvents struct{}

ListResources provides the business logic for listing multiple audit events.

func NewListAuditEvents

func NewListAuditEvents() *ListAuditEvents

NewListResources creates a new ListResources.

func (*ListAuditEvents) Execute

func (u *ListAuditEvents) Execute(
	ctx context.Context,
	logger *slog.Logger,
	store repositories.AuditEvent,
) ([]*entities.AuditEvent, error)

Execute lists multiple audit events.

Any failure will cause ErrInternal to be returned.

type ListResources

type ListResources struct{}

ListResources provides the business logic for listing multiple resources.

func NewListResources

func NewListResources() *ListResources

NewListResources creates a new ListResources.

func (*ListResources) Execute

Execute lists multiple resources.

Any failure will cause ErrInternal to be returned.

type UpdateResource

type UpdateResource struct {
	// contains filtered or unexported fields
}

UpdateResource provides the business logic for updating a resource.

func NewUpdateResource

func NewUpdateResource(
	clock repositories.Clock,
) *UpdateResource

NewUpdateResource creates a new UpdateResource.

func (*UpdateResource) Execute

func (u *UpdateResource) Execute(
	ctx context.Context,
	logger *slog.Logger,
	store repositories.Resource,
	changes *entities.Resource,
) (*entities.Resource, error)

Execute gets a single resource.

If the resource ID does not exist, ErrNotFound is returned. If the resource name is already in use, ErrAlreadyExists is returned. Any other failure will cause ErrInternal to be returned.

type WatchAuditEvents

type WatchAuditEvents struct{}

...

func NewWatchAuditEvents

func NewWatchAuditEvents() *WatchAuditEvents

...

func (*WatchAuditEvents) Execute

func (u *WatchAuditEvents) Execute(
	ctx context.Context,
	logger *slog.Logger,
	store repositories.AuditEvent,
) <-chan *entities.AuditEvent

...

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL