docs/ADRs/0001.software-architecture.md
# 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)