opcotech/elemo

View on GitHub
docs/ADRs/0001.software-architecture.md

Summary

Maintainability
Test Coverage
# Software Architecture

| author       | created at | updated at | status   |
|:-------------|:-----------|------------|:---------|
| @gabor-boros | 2023-03-16 | 2024-04-17 | accepted |

## Abstract

This document describes the architecture the project will follow unless major
changes are required.

## Decision

To have flexibility while keeping the concerns separated, the project partially
follows the hexagonal approach with domain-driven development practices. The
goal of the architecture is separating the business logic from technical details
as much as reasonably possible.

As we don't want to blindly follow general architectural patterns, we are trying
to keep the architecture as simple as possible, decoupled, easy to understand
and maintain.

The application structure is split into multiple packages, highlighting the
ones below:

* `config` -- The configuration that the application parses. Packages that need
  to extract configuration details are dependent on `config`.
* `email` -- As it is neither a simple reusable package nor a service, template
  parsing and email sending is handled by this package.
* `license` -- The application is designed in a way to require a license to
  operate. A license tells the application who is the licensee, what are the
  resource (organizations, roles, users, etc.) thresholds that need to be
  respected, and more.
* `model` -- The `model` package contains the entities that the application
  operates on and passed around as Data Transfer Objects (DTOs). Although the
  models do not have business logic, validation and parsing are defined within
  the package.
* `pkg` -- Contains utility packages that the application is highly dependent
  on, such as `tracing`, `logging`, and more
* `queue` -- The package contains the tasks, task scheduler and client for
  implementing async communication using a queue. The tasks are processed using
  workers, defined in the `transport` package.
* `repository` -- The `repository` package contains the interfaces and use-case
  specific implementation for the databases. As the cache layer is treated as a
  database too, caching logic is also defined in this package.
* `service` -- The `service` package contains the interfaces and implementation
  for the services. The services are used to perform the business logic,
  utilizing the repositories, models, packages, queue, and in some cases, other
  services.
* `transport` -- The `transport` package defines the methods the application is
  using to communicate. As the queue is treated as an external party, the worker
  for the tasks are defined in the transport package.

## Consequences

The architecture is easy to understand and maintain. The business logic is
separated from the technical details. The system is easy to extend. However,
this pattern requires some additional work to do in the beginning.

## References

* [Hexagonal architecture](https://en.wikipedia.org/wiki/Hexagonal_architecture_(software))
* [Domain-driven design](https://en.wikipedia.org/wiki/Domain-driven_design)
* [Reference implementation of DDD in Go](https://github.com/percybolmer/ddd-go)