docs: add initial email-worker implementation specification

Add comprehensive specification document for email-worker service detailing:
  - Email verification request workflow
  - Rent due notification workflow
  - Utility bills due notification workflow
  - Email budget/throttling strategy (default: 10 emails per run)
  - Priority system (verification requests first)
  - Complete email templates with dynamic content
  - MongoDB integration requirements
This commit is contained in:
Knee Cola
2025-12-30 11:29:05 +01:00
parent e9012ed231
commit f8291f9f7b

View File

@@ -0,0 +1,129 @@
# Context
E-mail worker in workspace `email-server` has the following task:
- send e-mail verficiation requests
- send rent due notifications
- send utility bills due notifications
The worker runs every 60 seconds (can be modified via env variable).
During each run it checks which e-mails it needs to send, composes approrpate e-mail text and sends them.
## Standoff strategy & Priority
For each run there's budget which limits on total number of e-mails which can be sent in one go. This provides a stand-off so that the remote mail server is not overwhelmed. Default budget is 10, which can be configured via env variable.
E-mail verficiation request have priority and are sent first.
## Web App
This worker is a companion to the web app in workspace `web-app`. It connects to the same DB and uses same data structures.
In this document we use typescript types which can be found in /home/kneecola/projects/evidencija-rezija/web-app/app/lib/db-types.ts
## Sending e-mail verficiation requests
The process of sending e-mail verification requests is as follows:
- connect to MongoDB (see how web app in `web-app` workspace connects to the DB)
- fetch all `BillingLocations` from `lokacije` collection (see `locationActions.ts` in `web-app` workspace) - filter only records which satisfy the following:
- `yearMonth.year` and `yearMonth.month` equal to current year and month
- `tenantEmailStatus` is equal to `EmailStatus.Unverified`
- for each record found
- check the e-mail budget counter
-> if the value is 0 then exit
- compile an e-mail containing the content listed below
- send the e-mail
- set `tenantEmailStatus` to `EmailStatus.VerificationPending`
- decrement the e-mail budget counter
### Verficiation requests E-mail content
```html
<p>Hello ${tenantName}!</p>
<p>You have received this e-mail because your landloard <strong>${userSettings.ownerName}</strong> wants to send you rent and utility bills invoices via rezije.app</p>
<p><strong>rezije.app</strong> is an online app which helps proprty owners to manage expenses related to properties they lease.</p>
<p>Before the app can start sending you rent due and utility bills emails we need your verification.</p>
<p>To verify that you want to receive these notifications please click on the following link: <a href="https://rezije.app/email/verify/${shareId}">Verify</a></p>
<p>You can ignore this email if you don't want to receive notifications. You can also unsubscribe at any time using the link included in every notification email you receive.</p>
<p>Thank you!</p>
<a href="https://rezije.app" target="_blank">rezije.app</a>
```
The `shareId` is generated using algorithm found in `/home/kneecola/projects/evidencija-rezija/web-app/app/lib/shareChecksum.ts`.
# Sending rent due notifications
The process of sending rent-due e-mail notifications is as follows:
- check the e-mail budget counter
-> if the value is 0 then exit
- connect to MongoDB (see how web app in `web-app` workspace connects to the DB)
- fetch all `BillingLocations` from `lokacije` collection (see `locationActions.ts` in `web-app` workspace) - filter only records which satisfy the following:
- `yearMonth.year` and `yearMonth.month` equal to current year and month
- `rentDueNotificationEnabled === true`
- `rentDueDay` = current day (1-31)
- `rentDueNotificationStatus` === undefined OR `rentDueNotificationStatus` === null
- for each record found
- check the e-mail budget counter
-> if the value is 0 then exit
- compile an e-mail containing the content listed below
- send the e-mail
- set `rentDueNotificationStatus` to `sent`
- decrement the e-mail budget counter
### Rent due notifications E-mail content
```html
<p>Hello ${location.tenantName}!</p>
<p>Your rent for the apartment ${location.name} is due today.</p>
<p>For details and payment options please click the following link: <a href="https://rezije.app/share/location/rent/${shareId}">Rent details</a></p>
<p>Thank you!</p>
<p><a href="https://rezije.app" target="_blank">rezije.app</a></p>
<p style="font-size:.7em">If you do no longer want to receive these notifications please click the following link: <a href="https://rezije.app/email/unsubscribe/${shareId}">Rent details</a></p>
```
# Sending utility bills due notifications
The process of sending rent-due e-mail notifications is as follows:
- check the e-mail budget counter
-> if the value is 0 then exit
- connect to MongoDB (see how web app in `web-app` workspace connects to the DB)
- fetch all `BillingLocations` from `lokacije` collection (see `locationActions.ts` in `web-app` workspace) - filter only records which satisfy the following:
- `yearMonth.year` and `yearMonth.month` equal to current year and month
- `billFwdEnabled === true`
- `billFwdStatus === 'pending'`
- for each record found
- check the e-mail budget counter
-> if the value is 0 then exit
- compile an e-mail containing the content listed below
- send the e-mail
- set `billFwdStatus` to `sent`
- decrement the e-mail budget counter
### Verficiation requests E-mail content
```html
<p>Hello ${location.tenantName}!</p>
<p>Your utitlity bills for the apartment ${location.name} are due today.</p>
<p>For details and payment options please click the following link: <a href="https://rezije.app/share/location/bills/${shareId}">Utility Bills</a></p>
<p>Thank you!</p>
<p><a href="https://rezije.app" target="_blank">rezije.app</a></p>
<p style="font-size:.7em">If you do no longer want to receive these notifications please click the following link: <a href="https://rezije.app/email/unsubscribe/${shareId}">Rent details</a></p>
```