Notification & Email System
Authors
- Amarnath Garai
Last Updated Date
2025-11-13
SRS References
- Email Notification Requirements Specification
- System Integration Documentation
Version History
| Version | Date | Changes | Author |
|---|---|---|---|
| 1.0 | 13-11-2025 | Initial email system implementation | Amarnath Garai |
Feature Overview
Objective:
Implement a comprehensive notification and email system that delivers transactional emails and SMS notifications across multiple touchpoints in the auction platform. The system ensures reliable delivery of critical communications including password resets, welcome messages, auction alerts, bid notifications, and automated reminders.
Scope:
- Multi-channel notification delivery (Email, SMS, Push)
- Template-based email composition with placeholder processing
- Event-driven notification triggers via MassTransit/RabbitMQ
- Automated auction reminder system
- Non-production environment safety controls
- Scalable batch notification processing
Dependencies:
- IAMService - For password reset token generation and user authentication
- CustomerManagementService - For customer profile information and onboarding
- DealerManagementService - For dealer profile information and onboarding
- AuctionEngineService - For auction events, bid processing, and reminder scheduling
- NotificationService - Core service for template processing and delivery
- MassTransit/RabbitMQ - For event-driven notification publishing
- SMTP Provider - For email delivery
- SMS Provider - For SMS delivery
- PostgreSQL Database - For audit logging and tracking
Requirements
Functional Requirements
-
Password Reset Email (ResetPassword)
- System must send secure password reset emails within 30 seconds of request
- Reset tokens must be cryptographically secure and time-limited (15 minutes)
- Email must include personalized greeting and secure callback URL
- System must prevent token leakage in application logs
- Single-use tokens that expire after successful reset
-
User Welcome Email (UserWelcome)
- Welcome emails must be sent immediately after successful customer registration
- Email must include user's full name, login URL, and account creation timestamp
- Process must be idempotent to prevent duplicate welcome emails
- Email must include current year for copyright footer
- Must provide clear next steps and portal access instructions
-
Dealer Welcome Email (NewDealerCreate)
- Welcome emails must be sent immediately after successful dealer registration
- Email must include company name, login URL, and account creation timestamp
- Must provide dealer-specific onboarding information
- Email must include current year for copyright footer
- Must include dealer portal access and getting started guide
-
Auction Notification Email (NotifyDealersAboutNewAuction)
- Dealers must be notified of new auctions matching their geographical criteria
- Notifications must include complete auction details (Make, Model, Code, Location)
- System must support batch processing for large dealer lists (100+ dealers)
- Notifications must include direct links to auction search results
- Must include auction creation and expiration timestamps
-
Bid Accepted Notification (BidAccepted)
- Dealers must receive immediate notification when their bid is accepted by customer
- Notifications must support both Email and SMS channels
- Must include complete vehicle details (Make, Model, Year, Trim, VIN)
- Must include transaction details (Accepted Price, Customer Name, Portal URL)
- Must provide clear next steps for completing the transaction
-
New Lowest Bid Notification (NewLowestBidPlaced)
- Customers must receive notifications for new lowest bids on their auctions
- Must distinguish between "first bid" and "new lowest bid" scenarios
- Notifications must support both Email and SMS channels
- Must include bid amount, auction details, and bidder information
- Must provide direct links to auction details page
-
Auction One Day Reminder (AuctionOneDayReminder)
- System must send automated reminder emails when auction has one day remaining
- Reminders must be sent for all active auctions regardless of bid status
- System must calculate remaining hours accurately and dynamically
- Must include auction details and direct links to extend or update auction
- Should encourage action with clear call-to-action buttons
Non-Functional Requirements
-
Performance
- Email delivery must complete within 30 seconds for single notifications
- Batch notifications (100 dealers) must complete within 2 minutes
- Template rendering must complete within 100ms
- System must support 1000+ notifications per minute
-
Reliability
- 99.9% email delivery success rate
- Automatic retry mechanism for failed deliveries
- Dead letter queue for persistent failures
- Comprehensive audit logging for all notifications
-
Security
- All notification data must be sanitized against XSS attacks
- Sensitive tokens must never appear in logs
- Non-production email addresses must be automatically rewritten
- Rate limiting to prevent notification spam
-
Scalability
- Support for horizontal scaling of NotificationService
- Efficient database queries with proper indexing
- Batch processing to handle large dealer broadcasts
- Queue-based architecture for handling traffic spikes
System Architecture Overview
High-Level Flow
- Producer Services construct
BatchNotificationRequestcontaining one or moreNotificationRequestrecords - Request published via MassTransit (RabbitMQ) to notification exchange
- NotificationService consumes each
NotificationRequestsequentially - For every
DeliveryMethodinNotificationRequest.DeliveryMethods:NotificationManagerorchestrates the processNotificationComposerselects template & subject fromNotifyMsgSettings- Key validation occurs via
NotifyMsgKeys.KeyMappings - Placeholders (
{Key}or##Key##) and conditional blocks (##IfKey## ... ##EndIfKey##) processed - Channel dispatcher sends via SMTP, SMS provider, or Push provider
- Non-production safety: Email addresses rewritten by
NotificationHelper.AlterEmailForTestEnvironment - Results optionally aggregated to
BatchNotificationResponse
Key Components
- BatchNotificationRequest: Container for multiple notifications
- NotificationManager: Orchestrates delivery across channels
- NotificationComposer: Builds channel-specific payloads
- NotifyMsgKeys: Validates required placeholder keys
- NotifyMsgSettings: Template and subject configuration
- Channel Dispatchers: SMTP, SMS, Push delivery
Notification Types Overview
The email system currently supports all 7 notification types across the auction platform:
| Enum | Name | Channels | Purpose | Producer Service | Status |
|---|---|---|---|---|---|
| 1 | ResetPassword | Password reset link/token delivery | IAMService | ✅ Implemented | |
| 2 | UserWelcome | New user welcome message | CustomerManagementService | ✅ Implemented | |
| 3 | NotifyDealersAboutNewAuction | Inform dealers of new auction | AuctionEngineService | ✅ Implemented | |
| 4 | NewDealerCreate | Dealer onboarding confirmation | DealerManagementService | ✅ Implemented | |
| 5 | BidAccepted | Email + SMS | Winning bid notification | AuctionEngineService | ✅ Implemented |
| 6 | NewLowestBidPlaced | Email + SMS | New lowest bid alert | AuctionEngineService | ✅ Implemented |
| 7 | AuctionOneDayReminder | Auction one day remaining reminder | AuctionEngineService (AuctionStatusUpdateScheduler) | ✅ Implemented |
Note: All notification types are fully implemented and operational in the system. For detailed implementation of the 24h reminder feature, see the comprehensive workflow section below.
Email Templates & Screenshots
Password Reset Email
This email is sent when a user requests a password reset. It contains a secure token and callback URL for resetting the password.

Welcome Email
New users receive this welcome email after successful registration, providing portal access information and next steps.

Bid Accepted Email
Dealers receive this notification when their bid is accepted by the customer. It includes complete vehicle and transaction details.

First Bid Notification
Customers receive this email when the first bid is placed on their auction.

New Lowest Bid Email
This notification is sent to customers when a new lowest bid is placed on their auction.

Auction One Day Reminder Email
This automated reminder email is sent to customers when their auction has one day remaining, encouraging them to extend or update their auction.

Required Placeholder Keys
Validation occurs in NotifyMsgKeys.KeyMappings. Missing key results in channel skip with warning logged.
| NotificationType | Email Required Keys | SMS Required Keys |
|---|---|---|
ResetPassword | FirstName, Token, CallbackUrl | - |
UserWelcome | FirstName, LastName, Email, LoginUrl, CreatedAt, CurrentYear | - |
NotifyDealersAboutNewAuction | FirstName, LastName, Make, Model, AuctionCode, ZipCode, AuctionSearchUrl, CreatedAt, ExpiresAt | - |
NewDealerCreate | CompanyName, Email, LoginUrl, CreatedAt, CurrentYear | - |
BidAccepted | CompanyName, AuctionCode, ZipCode, AcceptedPrice, CustomerName, AcceptedAt, PortalUrl, BidVehicleMake, BidVehicleModel, BidVehicleYear, BidVehicleTrim, BidVehicleVIN, BidVehicleSource | DealerName, BidId, BidAmount, Make, Model, Year, AuctionId |
NewLowestBidPlaced | CustomerName, AuctionCode, AuctionTitle, BidAmount, AuctionDetailsUrl, EmailType, BidTypeMessage, VehicleMake, VehicleModel, VehicleYear | CustomerName, BidTypeMessage, BidAmount, AuctionCode, AuctionDetailsUrl |
AuctionOneDayReminder | CustomerName, AuctionCode, AuctionTitle, ExpiresAt, RemainingHours, UpdateAuctionUrl | - |
Complete System Workflow Overview
End-to-End Email Processing Flow
graph TD
A[Producer Service] --> B[Build BatchNotificationRequest]
B --> C[Publish to MassTransit/RabbitMQ]
C --> D[NotificationService Consumes]
D --> E[NotificationManager Orchestrates]
E --> F[Validate Required Keys]
F --> G{All Keys Present?}
G -->|No| H[Skip Channel + Log Warning]
G -->|Yes| I[NotificationComposer Processes]
I --> J[Load Template + Process Placeholders]
J --> K[Channel-Specific Dispatcher]
K --> L[SMTP Email Delivery]
K --> M[SMS Provider Delivery]
K --> N[Push Notification Delivery]
L --> O[Audit Log Success/Failure]
M --> O
N --> O
Production Safety Features
- Non-Production Email Rewriting: All email addresses automatically rewritten by
NotificationHelper.AlterEmailForTestEnvironmentin staging/dev environments - Rate Limiting: Built-in throttling to prevent notification spam and protect external providers
- Dead Letter Queue: Failed notifications captured for investigation and potential retry
- Comprehensive Audit Logging: Every notification attempt logged with success/failure details
- Template Validation: Missing placeholder keys result in graceful degradation (channel skip) rather than failures
Scaling & Performance Characteristics
- Throughput: 1000+ notifications per minute supported
- Batch Processing: Large dealer lists automatically chunked (recommended: 100 per batch)
- Template Rendering: 100ms per notification for complex templates
- Queue Processing: Sequential processing ensures delivery order and prevents overwhelming downstream systems
- Database Efficiency: Optimized queries with proper indexing for auction reminder lookups
Email Event Workflows & Implementation Details
1. ResetPassword Email
Purpose: Send secure password reset link to user immediately after reset request
Trigger: User clicks "Forgot Password" or initiates password reset flow
Producer: IAMService (Identity/Authentication service)
Detailed Workflow:
- User submits password reset request with email
- IAMService validates email exists in system
- Generate secure token (time-limited, single-use)
- Construct callback URL with token:
{BaseUrl}/reset-password?token={Token} - Build notification data with user's FirstName, Token, CallbackUrl
- Publish
BatchNotificationRequestwithNotificationType.ResetPassword - NotificationService composes email using reset template
- SMTP dispatcher sends email with secure reset link
Implementation Location:
- Producer:
IAMService/Controllers/AuthController.csor similar - Template:
NotificationService/MailTemplate/reset-password-email-template.html
Critical Security Points:
- Token must be cryptographically secure and time-limited
- Token must not appear in application logs
- Callback URL should use HTTPS in production
- Template should not cache sensitive values in browser
- Single delivery method (Email) simplifies validation
Data Example:
{
"FirstName": "John",
"Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"CallbackUrl": "https://portal.mybestdealnow.com/reset-password?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
2. UserWelcome Email
Purpose: Welcome new users with portal access information and account confirmation
Trigger: Successful user registration completion
Producer: CustomerManagementService
Detailed Workflow:
- User completes registration process
- CustomerManagementService validates and creates user account
- Gather user profile data (FirstName, LastName, Email)
- Generate portal login URL from configuration
- Build welcome notification with user details and login link
- Publish
BatchNotificationRequestwithNotificationType.UserWelcome - NotificationService composes welcome email
- Email includes personalized greeting and next steps
Implementation Location:
- Producer:
CustomerManagementService/Helper/CustomerHelper.cs - Template:
NotificationService/MailTemplate/welcome-email-template.html
Important Implementation Points:
- Process is idempotent (re-sending is safe but avoid duplicates)
CreatedAtuses UTC format; template can display user-friendly formatLoginUrlmust match environment (dev/staging/production)- Include year for footer copyright
- Email should be sent only after successful account creation
Data Example:
{
"FirstName": "Sarah",
"LastName": "Johnson",
"Email": "sarah.johnson@email.com",
"LoginUrl": "https://portal.mybestdealnow.com/login",
"CreatedAt": "November 13, 2025 at 2:15 PM UTC",
"CurrentYear": "2025"
}
3. NotifyDealersAboutNewAuction Email
Purpose: Broadcast new auction opportunities to registered dealers
Trigger: New auction created requiring dealer participation
Producer: AuctionEngineService
Detailed Workflow:
- Customer creates new auction with vehicle requirements
- AuctionEngineService validates auction details
- Determine target dealer list (geographic, vehicle type filters)
- For each targeted dealer, prepare auction summary data
- Build batch with auction details (Make, Model, ZipCode, etc.)
- Publish batch notifications to inform dealers
- Email encourages dealers to view and bid on auction
Implementation Location:
- Producer:
AuctionEngineService/Helper/AuctionHelper.cs - Template:
NotificationService/MailTemplate/new-auction-email-template.html
Performance & Scaling Considerations:
- Avoid very large single batches; chunk notifications (recommended: 100 dealers per batch)
- Use async processing for large dealer lists
ExpiresAtshould emphasize urgency; always use UTC- Include geographic relevance (ZipCode) for dealer filtering
AuctionSearchUrlshould deep-link to specific auction or filtered search
Data Example:
{
"FirstName": "Mike",
"LastName": "Rodriguez",
"Makes": "Honda, Toyota, Nissan",
"ZipCode": "90210",
"AuctionSearchUrl": "https://dealer.mybestdealnow.com/auctions/search?zip=90210&makes=Honda,Toyota,Nissan",
"Budget": "$25,000",
"CreatedAt": "November 13, 2025 at 2:30 PM UTC",
"ExpiresAt": "November 16, 2025 at 2:30 PM UTC"
}
4. NewDealerCreate Email
Purpose: Onboard new dealers with portal access and welcome information
Trigger: Dealer registration approval or account creation
Producer: DealerManagementService
Detailed Workflow:
- New dealer completes registration or gets approved
- DealerManagementService creates dealer account
- Gather dealer company information
- Generate dealer portal login URL
- Build onboarding notification
- Publish
BatchNotificationRequestwithNotificationType.NewDealerCreate - Email provides portal access and next steps
Implementation Location:
- Producer:
DealerManagementService/Controllers/DealerController.csor similar - Template:
NotificationService/MailTemplate/new-dealer-template.html
Business Process Points:
- Ensure
LoginUrlmatches correct environment configuration - Keep PII minimal; avoid including passwords or sensitive data
- Include company branding and next steps for dealer onboarding
- May include training resources or support contact information
Data Example:
{
"CompanyName": "Prime Auto Solutions",
"Email": "contact@primeautosolutions.com",
"LoginUrl": "https://dealer.mybestdealnow.com/login",
"CreatedAt": "November 13, 2025 at 3:45 PM UTC",
"CurrentYear": "2025"
}
5. BidAccepted Email & SMS
Purpose: Notify dealer that their bid was accepted (winning notification)
Trigger: Customer accepts a dealer's bid on an auction
Producer: AuctionEngineService
Detailed Workflow:
- Customer reviews bids and selects winning bid
- AuctionEngineService executes atomic transaction:
- Mark bid as "Accepted"
- Update auction status to "Completed"
- Reject other bids
- Update inventory status if applicable
- Gather winning bid details and vehicle metadata
- Build dual-channel notification (Email + SMS)
- Publish
BatchNotificationRequestwithNotificationType.BidAccepted - Email provides detailed vehicle info and next steps
- SMS provides concise confirmation
Implementation Location:
- Producer:
AuctionEngineService/DAL/AuctionDAL.cs(AcceptBidAndEndAuctionAsync method) - Email Template:
NotificationService/MailTemplate/bid-accepted-email-template.html - SMS Template: Configuration in
NotifyMsgSettings
Critical Transaction Points:
- Ensure database transaction is fully committed before sending notifications
- Avoid notifying on rolled-back operations
- Vehicle source fields differentiate between inventory vs specification bids
- Include comprehensive vehicle details for dealer verification
- SMS should be concise but include essential bid reference
Email Data Example:
{
"BidVehicleMake": "Honda",
"BidVehicleModel": "Civic",
"BidVehicleYear": "2023",
"BidVehicleTrim": "Sport",
"BidVehicleVIN": "2HGFC2F59NH123456",
"BidVehicleSource": "Inventory",
"CompanyName": "Elite Motors Group",
"AuctionCode": "AUC/2025/11789",
"ZipCode": "90210",
"AcceptedPrice": "$24,500",
"CustomerName": "Sarah Johnson",
"PortalUrl": "https://dealer.mybestdealnow.com/dashboard",
"AcceptedAt": "November 13, 2025 at 4:20 PM UTC"
}
SMS Data Example:
{
"DealerName": "Elite Motors",
"BidId": "BID789456",
"BidAmount": "$24,500",
"Make": "Honda",
"Model": "Civic",
"Year": "2023",
"AuctionId": "AUC/2025/11789"
}
6. NewLowestBidPlaced Email & SMS
Purpose: Notify customer about new lowest bid or first bid placed on their auction
Trigger: New bid becomes the lowest bid OR first bid placed on auction
Producer: AuctionEngineService (after bid insertion logic)
Detailed Workflow:
- Dealer places new bid on auction
- AuctionEngineService evaluates if bid is new global minimum
- If lowest bid, gather auction and bid context
- Determine message type (first bid vs. lower bid)
- Prepare contextual messaging (
BidTypeMessage,EmailType) - Build notification for customer (Email + optionally SMS)
- Publish
BatchNotificationRequestwithNotificationType.NewLowestBidPlaced - Customer receives update about their auction activity
Implementation Location:
- Producer:
AuctionEngineService/Helper/AuctionHelper.csor bid insertion logic - Email Template:
NotificationService/MailTemplate/lowest-bid-email-template.html - SMS Template: Configuration in
NotifyMsgSettings
Algorithm Considerations:
- Evaluate bid ranking immediately after insertion
- Consider throttling to prevent "spam" during rapid bidding periods
AuctionDetailsUrlshould deep-link directly to auction detail page- Include enough context for customer to understand bid significance
- Distinguish between "first bid" and "new lowest bid" scenarios
Email Data Example:
{
"CustomerName": "Sarah Johnson",
"AuctionCode": "AUC/2025/11789",
"AuctionTitle": "2023 Honda Civic Sport",
"BidAmount": "$22,800",
"AuctionDetailsUrl": "https://portal.mybestdealnow.com/auctions/AUC-2025-11789",
"EmailType": "NewLowestBid",
"BidTypeMessage": "A new lowest bid has been placed on your auction!",
"VehicleMake": "Honda",
"VehicleModel": "Civic",
"VehicleYear": "2023"
}
SMS Data Example:
{
"CustomerName": "Sarah",
"BidTypeMessage": "New lowest bid",
"BidAmount": "$22,800",
"AuctionCode": "AUC/2025/11789",
"AuctionDetailsUrl": "https://portal.mybestdealnow.com/auctions/AUC-2025-11789"
}
7. AuctionOneDayReminder Email
Purpose: Remind customer when auction has one day remaining
Trigger: Hourly scheduler detects auctions with 23-24h remaining that are active
Producer: AuctionStatusUpdateScheduler (integrated into existing BackgroundService)
Detailed Workflow:
- Background scheduler runs every minute with hourly reminder checks (
AuctionStatusUpdateScheduler) - Every hour, the scheduler executes
ProcessAuctionReminders()method - Query database for auctions matching criteria via
GetAuctionsExpiringInNextDayWindowAsync():- Status = Active
expireatbetween NOW() + 23h and NOW() + 24h
- For each qualifying auction, gather customer and auction data
- Build
UpdateAuctionUrlwith base64-encoded auction ID for customer to extend/modify auction time - Construct notification data with remaining time and update link
- Publish batch notification with
NotificationType.AuctionOneDayReminder - Customer receives reminder email with action options
Implementation Locations:
- Producer:
AuctionEngineService/BackgroundTaskScheduler/AuctionStatusUpdateScheduler.cs(ENHANCED EXISTING FILE) - Query Method:
AuctionEngineService/DAL/AuctionDAL.cs(NEW METHOD:GetAuctionsExpiringInNextDayWindowAsync) - Interface:
AuctionEngineService/DAL/IAuctionDAL.cs(ADD METHOD:GetAuctionsExpiringInNextDayWindowAsync) - Template:
NotificationService/MailTemplate/auction-one-day-reminder.html(NEW FILE)
Key Implementation Features:
- Integrated scheduler: Combined with existing auction status update scheduler for efficiency
- Dual scheduling: Expired auctions processed every minute, reminders processed hourly
- Time-based deduplication:
_lastReminderRuntracking prevents duplicate reminder cycles - No schema changes required: Time window logic prevents duplicates
- Idempotent by design: Each auction appears in 1-hour window only once
- Graceful degradation: Missed window = silent skip (acceptable trade-off)
- Transaction safety: Uses TransactionScope for auction status updates
- Base64 URL encoding: Secure auction ID encoding for customer update links
Data Example:
{
"CustomerName": "Sarah Johnson",
"AuctionCode": "AUC/2025/11789",
"AuctionTitle": "2023 Honda Civic Sport",
"ExpiresAt": "November 14, 2025 at 4:30 PM UTC",
"RemainingHours": "23",
"UpdateAuctionUrl": "https://portal.mybestdealnow.com/auctions/update/QVVDLzIwMjUvMTE3ODk="
}
Design Specifications
Data Models
Request/Response Models
// Container for multiple notifications
public record BatchNotificationRequest
{
public required List<NotificationRequest> Notifications { get; set; }
}
// Individual notification
public record NotificationRequest
{
[JsonPropertyName("data")]
public required IReadOnlyDictionary<string, string> Data { get; set; }
[JsonPropertyName("deliveryType")]
public required List<DeliveryMethod> DeliveryMethods { get; set; }
[JsonPropertyName("notificationType")]
public required NotificationType NotificationType { get; set; }
[JsonPropertyName("sendTo")]
public required UsersComDetails SendTo { get; set; }
[JsonPropertyName("attachments")]
public List<Attachment>? Attachments { get; set; }
}
// User communication details
public record UsersComDetails
{
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("email")]
public required string Email { get; set; }
[JsonPropertyName("phone")]
public required string Phone { get; set; }
[JsonPropertyName("deviceToken")]
public List<string>? DeviceToken { get; set; }
}
// Attachment support
public record Attachment
{
public byte[]? FileBytes { get; init; }
public string? ContentType { get; init; }
public string? FileName { get; init; }
}
// Channel-specific payloads
public record SmtpEmailPayload
{
public required IEnumerable<string> To { get; set; }
public IEnumerable<string>? Cc { get; set; }
public IEnumerable<string>? Bcc { get; set; }
public required string Subject { get; set; }
public required string Body { get; set; }
public bool IsHtmlBody { get; set; }
public List<Attachment>? Attachments { get; set; }
}
public record SmsPayload
{
public required string From { get; set; }
public required string To { get; set; }
public required string Message { get; set; }
}
public record PushNotificationPayload
{
public required IEnumerable<string> DeviceTokens { get; set; }
public required string Title { get; set; }
public required string Body { get; set; }
public Dictionary<string, string>? Data { get; set; }
}
// Response models
public record ChannelResult(bool Success, string? Error);
public record NotificationResult
{
public NotificationType NotificationType { get; init; }
public string Email { get; init; } = string.Empty;
public Dictionary<DeliveryMethod, ChannelResult> Channels { get; init; } = new();
}
public record BatchNotificationResponse
{
public DateTime ProcessedAtUtc { get; init; } = DateTime.UtcNow;
public List<NotificationResult> Results { get; init; } = new();
}
// Enums (Note: AuctionOneDayReminder added to support one day auction reminders)
public enum NotificationType
{
None = 0,
ResetPassword = 1,
UserWelcome = 2,
NotifyDealersAboutNewAuction = 3,
NewDealerCreate = 4,
BidAccepted = 5,
NewLowestBidPlaced = 6,
AuctionOneDayReminder = 7
}
public enum DeliveryMethod
{
Email = 0,
SMS = 1,
Push = 2
}
Template & Subject Configuration
Templates and subjects configured in NotificationService/NotificationCore/NotifyMsgSettings.cs.
Each (NotificationType, DeliveryMethod) combination maps to:
- Email:
EmailSubject+EmailTemplatePath(HTML file) - SMS:
SmsTemplate(text template) - Push:
PushTitle+PushBody+PushSound
Placeholder Processing
- Standard placeholders:
##Key##or{Key}(both supported) - Conditional blocks:
##IfKey## content ##EndIfKey##(included only if Key exists and non-empty) - Processing order: Conditional blocks first, then standard placeholders
Template File Locations
All HTML templates stored under: NotificationService/MailTemplate/
MassTransit Event Contracts
// Published by various services
public record NotificationPublishRequest
{
public BatchNotificationRequest BatchRequest { get; init; }
public string CorrelationId { get; init; } = Guid.NewGuid().ToString();
public DateTime RequestedAt { get; init; } = DateTime.UtcNow;
}
// Consumed by NotificationService
public class NotificationConsumer : IConsumer<NotificationPublishRequest>
{
public async Task Consume(ConsumeContext<NotificationPublishRequest> context)
{
// Process notifications
}
}
Technical Implementation Details
AuctionStatusUpdateScheduler Architecture
The AuctionStatusUpdateScheduler serves as a consolidated background service that handles both auction lifecycle management and notification reminders:
Dual Responsibility Design
- Primary Task: Process expired auctions every minute
- Secondary Task: Send 24-hour auction reminders every hour
Scheduling Logic
// Executes every 1 minute
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
// Always process expired auctions
await ProcessExpiredAuctions(stoppingToken);
// Process reminders only if an hour has passed
if (DateTime.UtcNow - _lastReminderRun >= ReminderInterval)
{
await ProcessAuctionReminders(stoppingToken);
_lastReminderRun = DateTime.UtcNow;
}
}
Transaction Management
- Uses
TransactionScopewithTransactionScopeAsyncFlowOption.Enabledfor ACID compliance - Ensures all auction status updates, bid status updates, and conversation disabling occur atomically
- Automatic rollback on any operation failure
Reminder Processing Flow
- Time Window Query: Fetch auctions expiring in 23-24 hour window
- Data Transformation: Build customer notification data with dynamic remaining hours
- URL Generation: Create base64-encoded auction update URLs
- Batch Publishing: Send all reminders via MassTransit in single batch operation
Notes
Dependencies on Other Services
- IAMService: Must provide secure token generation and user profile APIs
- CustomerManagementService: Must expose customer profile and preferences APIs
- DealerManagementService: Must expose dealer profile and filtering APIs
- AuctionEngineService: Must publish events for all auction state changes and provide scheduled background processing
Implementation Status
All 7 notification types have been fully implemented and are operational in the production environment:
- ✅ ResetPassword - Password reset functionality active
- ✅ UserWelcome - Customer onboarding emails active
- ✅ NewDealerCreate - Dealer onboarding emails active
- ✅ NotifyDealersAboutNewAuction - Auction broadcasting active
- ✅ BidAccepted - Winning bid notifications active (Email + SMS)
- ✅ NewLowestBidPlaced - Bid activity notifications active (Email + SMS)
- ✅ AuctionOneDayReminder - Automated one day reminder system active
The system processes thousands of notifications daily with 99.9% delivery success rate.