-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Problem
Developers currently rely on SendGrid for email template verification, which requires sending real emails and a valid API key. This makes local development and testing workflows cumbersome. This effort aligns with the overall direction we are heading for disconnected development, which allows local development to progress without reliance on any external integrations.
Public Interface Direction
The key consideration is that @sthrift/transactional-email-service should be just a package with a single interface in it. It has to be generic enough to support multiple 3rd party vendors. The publicly exposed interface for the facade should be minimal, hiding all proprietary details and specific datatypes that are part of the SendGrid library, exposing only the absolute simplest interface necessary to get the job done. The code within the facade should translate this simple public interface into the proprietary calls to the email provider's API. This ensures we can swap implementations of mail sending services without having to change the public interface or upstream logic—enabling a true plug-and-play approach (e.g., swapping in Azure Communication Services). We should take this approach for all of our 3rd party integrations going forward.
We should start by defining the public interface first—such as:
@sthrift/transactional-email-service(only defines the facade interface; the rest of the system refers only to this interface)
Then, the specific implementations are fully interchangeable and can be swapped without impacting upstream code:
@sthrift/transactional-email-service-sendgrid-v3(facade-implementation)@sthrift/transactional-email-service-sendgrid-v4(facade-implementation)@sthrift/transactional-email-service-azure-communication(facade-implementation, example only)@sthrift/transactional-email-service-mock(facade-implementation)
For this task, only concrete implementations for transactional email service sendgrid and transactional email service mock are required. Azure Communication Services is provided as an example of how this architecture enables easily swappable integrations and may be explored in the future.
Configuration Approach
The @sthrift/api package will be responsible for determining which facade implementation is actually registered at application startup. This should be determined by environment variable values.
Proposal
Refactor the existing @sthrift/service-sendgrid package so it becomes the facade for ServiceSendGrid. This facade should:
- Expose the same interface for sending emails as the current implementation.
- The implementation should determine which email service to use based on the value of the
SENDGRID_API_KEYenvironment variable. If the environment variable is set for local development, the mock implementation should be used; if set for production/remote, the actual SendGrid service should be used.
Mock Implementation
- Instead of sending emails, the mock should save the HTML email template (including all styling) to a local folder (suggested:
tmp/inside the service-sendgrid package). - Ensure the folder is included in
.gitignoreso downloaded templates are not committed. - This enables developers to verify email content and styling locally without using SendGrid.
- You can explore existing mock implementations such as:
- sendGrid-mock for inspiration or reuse.
- @yudppp/simple-sendgrid-mock-server/files/server.js for additional mock server logic or reference implementation.
Acceptance Criteria
@sthrift/transactional-email-servicepackage provides a minimal, generic interface for sending transactional emails, hiding all proprietary details.- Only two concrete implementations are required for this task:
@sthrift/transactional-email-service-sendgrid-v3(or v4) as the SendGrid implementation@sthrift/transactional-email-service-mockas the mock implementation
- The mock implementation saves HTML emails to
tmp/and never sends to SendGrid. - The mock's output folder is ignored by git.
- The
@sthrift/apipackage determines which implementation is registered at app startup via environment variables. - The system remains fully compatible with existing logic and can easily swap new providers in the future (e.g., Azure Communication Services).
- The implementation does not need to replicate SendGrid exactly, only provide local verification for email templates.
- API and integration are unchanged for consumers of the package.
Related Code & References
sendgrid.ts- Main SendGrid classget-email-template.ts- Reads and parses email templatesindex.ts- Package entry point
With the help of below repo:-
https://github.com/CellixJs/cellixjs/tree/main
Take the reference of below files:-
packages/ocom/domain/src/domain/events/types/community-created.ts
packages/ocom/domain/src/domain/services/community/community-provisioning.service.ts
packages/ocom/domain/src/domain/contexts/community/community/community.ts
packages/ocom/event-handler/src/handlers/integration/community-created--provision-member-and-default-role.ts
apps/api/src/index.ts
Create an event for ReservationRequestCreation, should behave in a similar way to how community creation is handled in cellix, but the actual service being called by the event handler will have its functionality changed. It should instead fetch relevant infomration bout the user needed for the transactional-email-service function being called, then also taking a dependency and receiving a parameter of that service, in a similar way to how domaindatasource is passed down in the cellix service, call the transactional-email-servic and send an email to the sharer of the listing that the reservation request is connected to. So in simpler terms notifiying the listing owner that their listing was reserved.
Sub-issues
Metadata
Metadata
Assignees
Labels
Type
Projects
Status