From a51476d82bc1b22bbc968d6fb75f6f88ac2036cf Mon Sep 17 00:00:00 2001 From: Knee Cola Date: Mon, 29 Dec 2025 18:01:10 +0100 Subject: [PATCH] docs: clarify email verification implementation details MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added DB integration details for external email system - Clarified share-id validation (404 on invalid) - Enhanced subsequent matching to include tenantEmail - Specified exact UI placement for email status indicators - Fixed typo: EmailStatus.Verifies → EmailStatus.Verified 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- sprints/sprint--confirm-unsubscribe.md | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/sprints/sprint--confirm-unsubscribe.md b/sprints/sprint--confirm-unsubscribe.md index 99beaf5..10a8b14 100644 --- a/sprints/sprint--confirm-unsubscribe.md +++ b/sprints/sprint--confirm-unsubscribe.md @@ -8,16 +8,18 @@ To prevent missuse and ensure that the e-mail is correct, before an e-mail addre This verification is done via a link sent to the tenant in a verification-request e-mail, which is sent to the tenant automatically when the landloard (app user) assigns this e-mail address to a BillingLocation. -Sending of this verification-request e-mail is handled by a system separate from NextJS app in `web-app` workspace. +Sending of this verification-request e-mail is handled by a system separate from NextJS app in `web-app` workspace. It detects newly assigned addresses from their status bein equal `EmailStatus.Unverified`. The two systems don't talk to each other at all - what's holding them together is the DB. ### Implementation details Verification link points to the NextJS app in `web-app` workspace at path `/email/verify/[share-id]` (share-id is calculated using `generateShareId` from `/home/kneecola/projects/evidencija-rezija/web-app/app/lib/shareChecksum.ts`). +The web page served at this path cerifies if the [share-id] is correct and if not it shows 404 page. + The web page served at this path contains an text explanation and "Verify e-mail" button. The text includes the following information: * what the web app is about - very short into -* why the e-mail was sent = because the landloard of the property X configured the rent (`BillingLocation.rentDueNotification`) and/or utility bills (`BillingLocation.billFwdStrategy`) to be delivered to that e-mail address +* why the e-mail was sent = because the landloard of the property `BillingLocation.name` configured the rent (`BillingLocation.rentDueNotification`) and/or utility bills (`BillingLocation.billFwdStrategy`) to be delivered to that e-mail address * what will hapen if he/she clicks on the "Verify e-mail" button = they will be receiving rent due (`BillingLocation.rentDueNotification`) or utility bills due (`BillingLocation.billFwdStrategy`) notification or both - 2x a month - depending on the config set by the landloard * opt-out infomation (they can ignore this e-mail, but can also opt-out at any moment) @@ -25,36 +27,42 @@ If the user clicks the button "Verify e-mail" this triggers update of `BillingLo Here's the expected stats flow: -* landloard/app user assigns an an new address top `BillingLocation` -> `BillingLocation.tenantEmailStatus` is set to `EmailStatus.Unverified` -* a verification si sent to the entered e-mail address -> `BillingLocation.tenantEmailStatus` is set to `EmailStatus.VerificationPending` +* landloard/app user assigns an an new address to `BillingLocation` -> `BillingLocation.tenantEmailStatus` is set to `EmailStatus.Unverified` +* an automated system detects that a new address was set (as indicated by `EmailStatus.Unverified` status), it then sets verification-email -> `BillingLocation.tenantEmailStatus` is set to `EmailStatus.VerificationPending` * tenant click the link from the verification-requets e-mail -> `BillingLocation.tenantEmailStatus` is set to `EmailStatus.Verified` -**Note:** status is updated for the `BillingLocation` inidcated by locationID (decoded from `[share-id]` param), and all subsequent matching `BillingLocation` records (matched by comparing `BillingLocation.name` and `BillingLocation.userId`). Similar pattern is already implemented in `updateOrAddLocation` fn in `locationAction.ts` (`updateScope === "subsequent"`). +**Note:** status is updated for the `BillingLocation` inidcated by locationID (decoded from `[share-id]` param), and all subsequent (later in time) matching `BillingLocation` records (matched by comparing `BillingLocation.name`, `BillingLocation.userId` and `BillingLocation.tenantEmail`). Similar pattern is already implemented in `updateOrAddLocation` fn in `locationAction.ts` (`updateScope === "subsequent"`). ## E-mail unsubscribe Tenant can out-out from receiving e-mail notifications at any time via an `unsubscribe` link included at the end of every mail sent to the tenant. ### Implementation details -Verification link points to the NextJS app in `web-app` workspace at path `/email/unsubscribe/[share-id]` (share-id is calculated using `generateShareId` from `/home/kneecola/projects/evidencija-rezija/web-app/app/lib/shareChecksum.ts`). +Verification link points to the NextJS app in `web-app` workspace at path `/email/unsubscribe/[share-id]` (share-id is calculated using `generateShareId` from `/home/kneecola/projects/evidencija-rezija/web-app/app/lib/shareChecksum.ts` ... search of examples of how this function is used). The web page served at this path contains an text explanation and "Confirm unsubscribe" button. The text includes the following information: * what the web app is about - very short into -* why are they receiveing e-mails from this page = because their landlord for property X has configured the app to deliver rent due or utility bills due notification or both to that address +* why are they receiveing e-mails from this page = because their landlord for property `BillingLocation.name` has configured the app to deliver rent due or utility bills due notification or both to that address * what will hapen if they click on "Confirm unsubscribe" = they will no longer receive rent due / utility bull due reminders E-mail address's verification status is tracked via `BillingLocation.tenantEmailStatus`, which is set to `EmailStatus.Unsubscribed`. -**Note:** status is updated for the `BillingLocation` inidcated by locationID (decoded from `[share-id]` param), and all subsequent matching `BillingLocation` records (matched by comparing `BillingLocation.name` and `BillingLocation.userId`). Similar pattern is already implemented in `updateOrAddLocation` fn in `locationAction.ts` (`updateScope === "subsequent"`). +**Note:** status is updated for the `BillingLocation` inidcated by locationID (decoded from `[share-id]` param), and all subsequent (later in time) matching `BillingLocation` records (matched by comparing `BillingLocation.name`, `BillingLocation.userId` and `BillingLocation.tenantEmail`). Similar pattern is already implemented in `updateOrAddLocation` fn in `locationAction.ts` (`updateScope === "subsequent"`). ## E-mail status in `LocationCard.tsx` -If the e-mail is not in `EmailStatus.Verifies` state for a given location, then this will be indicated in `LocationCard.tsx` as a sibling of `total-payed-label` block (`
`) +If the e-mail is not in `EmailStatus.Verified` state for a given location, then this will be indicated in `LocationCard.tsx` as a sibling of `total-payed-label` block (`
`) ## E-mail status in `LocationEditForm.tsx` -Current e-mail status will be indicated as a sibling of `
`. +Current e-mail status will be indicated as a sibling of: +``` + {/* Email status indicator should go here */} +
+ ... +``` + Use appropriate utf-8 icon for each status. # Logical Units of work