opcotech/elemo

View on GitHub
docs/ADRs/0006.sending-notifications-and-emails.md

Summary

Maintainability
Test Coverage
# Sending Notifications and Emails

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

## Abstract

Sending in-app notifications and emails is crucial for the user experience of
the application. In-app notifications serves as one-shot communication to the
user, while emails are used for more long-term communication, such as
notifications about changes in context of followed issues, projects, etc.

From a technical perspective, the in-app notifications is a bit trickier to
implement as it is not well suited for graph databases. This ADR describes the
architecture of the notification system.

## Decision

For email sending we will use Go's built-in `net/smpt` package. The package is
using the SMTP protocol to send emails, so any SMTP server can be used to send
emails. However, the SMTP server will not be part of the application. Setting
up and operating an SMTP server will be the responsibility of the system
administrator who is deploying the application.

For our self-hosted solution, we will use a self-hosted SMTP server, we are
going to use [Postfix] due to its simplicity and reliability.

The in-app notifications are trickier to implement, because they are not well
suited for graph databases. We have three options:

1. We can use a relational database (Postgres) to store the notifications. This
   is the simplest solution, and probably the most maintainable.
2. We can use a graph database (Neo4j) to store the notifications. This is not
   suitable nor maintainable.
3. We can use a cache database (Redis) to store the notifications, though it
   could happen that messages get lost.

Considering the above, the second option is not viable, and the third option is
not a good fit either, because of persistence. Therefore, we are going to use
the first option.

The relational database of choice is [PostgreSQL], because it has a great
community, maintainability, and operational costs are relatively low. Also, the
relational database could be used for other purposes in the future, such as
storing the audit log, vertex and edge history, etc.

[Postfix]: http://www.postfix.org/
[PostgreSQL]: https://www.postgresql.org/

## Consequences

We are going to introduce an extra dependency that requires additional
maintenance, but the benefits of using a complementary relational database
outweigh the maintenance costs.

For the in-app notifications, we are going to use PostgreSQL, which is a good
fit for other purposes too, such as storing the audit log, vertex and edge,
history, etc.

For the emails, we are going to use Postfix, which is a simple and reliable
SMTP server, combined with Go's built-in `net/smtp` package.

## References

None.