Subscription Workflow and Email Notifications
Relevant source files - config/upstash.js - controllers/subscription.controller.js - controllers/workflow.controller.js - utils/email-template.js
The Subscription Tracker utilizes an asynchronous workflow engine to manage the lifecycle of user subscriptions. When a subscription is created, a background process is initiated to monitor the renewal date and dispatch automated email reminders at specific intervals. This system ensures that users are notified before their payment methods are charged, providing a seamless and transparent experience.
System Overview
The lifecycle is managed through a combination of Upstash QStash for workflow orchestration and Nodemailer (via Brevo) for email delivery. The process follows a "set-and-forget" pattern: the API triggers the workflow once, and the workflow engine handles the scheduling, state persistence, and execution of reminder logic over several days or months.
High-Level Workflow Sequence
The following diagram illustrates the interaction between the API, the Workflow Engine, and the Email System:
Subscription Lifecycle Flow
sequenceDiagram
participant User
participant API as "Subscription Controller"
participant QStash as "Upstash Workflow Engine"
participant Mail as "Email System (Brevo)"
User->>API: POST /api/v1/subscriptions
API->>API: Create Subscription in MongoDB
API->>QStash: workflowClient.trigger()
QStash->>API: 201 Created (workflowRunId)
API-->>User: Return subscription + workflowRunId
QStash->>QStash: context.sleepUntil(reminderDate)
QStash->>API: POST /api/v1/workflows/subscription/reminder
API->>Mail: sendReminderEmail()
Mail-->>User: Send HTML Email
Sources:
- controllers/subscription.controller.js22-31
- controllers/workflow.controller.js8-10
- controllers/workflow.controller.js24-32
Upstash Workflow Engine
The core logic for scheduling and execution resides in the Upstash Workflow integration. This system allows the application to pause execution for long periods (days or weeks) without consuming server resources.
- Triggering: The
createSubscriptioncontroller usesworkflowClient.trigger()to initiate the process controllers/subscription.controller.js22-31 - State Management: The workflow is defined in
sendReminders, which usescontext.runto perform side effects like fetching the latest subscription data from the database controllers/workflow.controller.js10-13 - Scheduling: It utilizes a
REMINDERSarray[7, 5, 2, 1]to calculate dates relative to therenewalDatecontrollers/workflow.controller.js8 - Efficiency: The engine uses
context.sleepUntil()to put the workflow into a dormant state until the next reminder is due controllers/workflow.controller.js41-45
For details on the implementation of the workflow client and the sendReminders handler, see Upstash Workflow Engine.
Workflow Logic Mapping
[Flowchart Diagram]
Sources:
- config/upstash.js4-7
- controllers/subscription.controller.js22-31
- controllers/workflow.controller.js10-11
- controllers/workflow.controller.js35-39
Email Notification System
The email system is responsible for generating and sending professional HTML notifications to users. It is decoupled from the workflow logic, acting as a service invoked by the workflow engine.
- SMTP Configuration: Uses Nodemailer configured with Brevo's SMTP settings for reliable delivery.
- Dynamic Templates: The
generateEmailTemplatefunction creates responsive HTML emails including details such as plan name, price, and renewal date utils/email-template.js1-11 - Reminder Intervals: Four distinct templates are provided for 7, 5, 2, and 1-day reminders, each with specific subject lines and urgency utils/email-template.js69-94
- Data Injection: The system populates templates with user-specific data fetched during the workflow's execution controllers/workflow.controller.js51-55
For details on SMTP configuration, template structures, and the email utility, see Email Notification System.
Email Pipeline Components
| Component | Responsibility | Code Reference |
|---|---|---|
| Workflow Trigger | Invokes the email utility with subscription data | controllers/workflow.controller.js51-55 |
| Template Generator | Produces HTML string with injected variables | utils/email-template.js1-11 |
| Email Utility | sendReminderEmail handles the logic of sending |
controllers/workflow.controller.js6 |
| Templates | Array of subject/body configurations for each interval | utils/email-template.js69-94 |
Sources: