feat: Email ingestion notifications and error emails (#149) #159

Closed
opened 2026-02-13 03:52:31 +00:00 by egullickson · 1 comment
Owner

Relates to #149

Scope

Implement all notification paths for the email ingestion flow.

Email Templates (content)

Define template content for the 3 templates created in migration sub-issue:

  • receipt_processed: Variables: userName, vehicleName, recordType, merchantName, totalAmount, date
  • receipt_failed: Variables: userName, errorReason, guidance
  • receipt_pending_vehicle: Variables: userName, recordType, merchantName

In-App Notifications

  • Success: Create user_notification with type='email_ingestion', title='Receipt Processed', message with details, referenceType='fuel_log' or 'maintenance_record', referenceId=created record ID, vehicleId
  • Pending vehicle: Create notification with type='email_ingestion', title='Vehicle Selection Required', referenceType='pending_vehicle_association', referenceId=pending association ID
  • Error: Create notification with type='email_ingestion', title='Receipt Processing Failed', message with error details

Error Reply Emails

  • Unregistered sender: Send error email explaining the email must come from registered address
  • No vehicle: Send error email explaining user must add a vehicle first
  • OCR failure (after 3 retries): Send error email with details
  • Unsupported attachment: Send error email listing supported formats
  • File too large: Send error email with size limits

Notification Logging

  • All emails logged to notification_logs with reference_type='email_ingestion'

Files

  • backend/src/features/email-ingestion/domain/notification-handler.ts
  • Template content in migration SQL

Acceptance Criteria

  • Success email sent and in-app notification created
  • Pending vehicle notification created for multi-vehicle users
  • Error emails sent for each failure scenario
  • All emails logged to notification_logs
Relates to #149 ## Scope Implement all notification paths for the email ingestion flow. ### Email Templates (content) Define template content for the 3 templates created in migration sub-issue: - **receipt_processed**: Variables: userName, vehicleName, recordType, merchantName, totalAmount, date - **receipt_failed**: Variables: userName, errorReason, guidance - **receipt_pending_vehicle**: Variables: userName, recordType, merchantName ### In-App Notifications - **Success**: Create `user_notification` with type='email_ingestion', title='Receipt Processed', message with details, referenceType='fuel_log' or 'maintenance_record', referenceId=created record ID, vehicleId - **Pending vehicle**: Create notification with type='email_ingestion', title='Vehicle Selection Required', referenceType='pending_vehicle_association', referenceId=pending association ID - **Error**: Create notification with type='email_ingestion', title='Receipt Processing Failed', message with error details ### Error Reply Emails - Unregistered sender: Send error email explaining the email must come from registered address - No vehicle: Send error email explaining user must add a vehicle first - OCR failure (after 3 retries): Send error email with details - Unsupported attachment: Send error email listing supported formats - File too large: Send error email with size limits ### Notification Logging - All emails logged to `notification_logs` with reference_type='email_ingestion' ### Files - `backend/src/features/email-ingestion/domain/notification-handler.ts` - Template content in migration SQL ## Acceptance Criteria - [ ] Success email sent and in-app notification created - [ ] Pending vehicle notification created for multi-vehicle users - [ ] Error emails sent for each failure scenario - [ ] All emails logged to notification_logs
egullickson added the
status
backlog
type
feature
labels 2026-02-13 03:52:50 +00:00
egullickson added this to the Sprint 2026-02-02 milestone 2026-02-13 03:53:00 +00:00
egullickson added
status
in-progress
and removed
status
backlog
labels 2026-02-13 15:18:58 +00:00
Author
Owner

Milestone: Implementation Complete

Phase: Execution | Agent: Developer | Status: PASS

Changes Made

New file: notification-handler.ts

  • EmailIngestionNotificationHandler class encapsulating all notification logic
  • Methods: notifyReceiptProcessed, notifyPendingVehicleSelection, notifyUnregisteredSender, notifyNoVehicles, notifyNoValidAttachments, notifyOcrFailure, notifyProcessingFailure
  • Every email sent is logged to notification_logs via insertNotificationLog (both success and failure)
  • In-app user_notification created for all scenarios (success, pending vehicle, all error types)
  • Error scenarios without userId (unregistered sender) gracefully skip in-app notification and logging

Updated: email-ingestion.service.ts

  • Replaced 6 inline notification methods (~130 lines) with delegation to EmailIngestionNotificationHandler
  • Error handlers now pass userId/userName to notification handler for in-app notifications
  • Vehicle name built from nickname || year make model (no name field on Vehicle type)
  • Removed sendConfirmationEmail, sendFailureEmail, sendNoVehiclesEmail, sendPendingVehicleEmail

Updated: 002_create_email_templates.sql

  • receipt_processed: Added merchantName, renamed receiptDate->date, amount->totalAmount
  • receipt_failed: Replaced emailSubject with guidance variable, updated HTML to show guidance section
  • receipt_pending_vehicle: Added merchantName, totalAmount, date variables

Updated: notifications.service.ts

  • Added sample variables for receipt_processed, receipt_failed, receipt_pending_vehicle in test email flow

Acceptance Criteria

  • Success email sent and in-app notification created
  • Pending vehicle notification created for multi-vehicle users
  • Error emails sent for each failure scenario (unregistered sender, no vehicles, no attachments, OCR failure, processing failure)
  • All emails logged to notification_logs

Validation

  • TypeScript: 0 errors
  • Lint: 0 errors (656 pre-existing warnings)

Verdict: PASS | Next: Quality review

## Milestone: Implementation Complete **Phase**: Execution | **Agent**: Developer | **Status**: PASS ### Changes Made **New file: `notification-handler.ts`** - `EmailIngestionNotificationHandler` class encapsulating all notification logic - Methods: `notifyReceiptProcessed`, `notifyPendingVehicleSelection`, `notifyUnregisteredSender`, `notifyNoVehicles`, `notifyNoValidAttachments`, `notifyOcrFailure`, `notifyProcessingFailure` - Every email sent is logged to `notification_logs` via `insertNotificationLog` (both success and failure) - In-app `user_notification` created for all scenarios (success, pending vehicle, all error types) - Error scenarios without userId (unregistered sender) gracefully skip in-app notification and logging **Updated: `email-ingestion.service.ts`** - Replaced 6 inline notification methods (~130 lines) with delegation to `EmailIngestionNotificationHandler` - Error handlers now pass `userId`/`userName` to notification handler for in-app notifications - Vehicle name built from `nickname || year make model` (no `name` field on Vehicle type) - Removed `sendConfirmationEmail`, `sendFailureEmail`, `sendNoVehiclesEmail`, `sendPendingVehicleEmail` **Updated: `002_create_email_templates.sql`** - `receipt_processed`: Added `merchantName`, renamed `receiptDate`->`date`, `amount`->`totalAmount` - `receipt_failed`: Replaced `emailSubject` with `guidance` variable, updated HTML to show guidance section - `receipt_pending_vehicle`: Added `merchantName`, `totalAmount`, `date` variables **Updated: `notifications.service.ts`** - Added sample variables for `receipt_processed`, `receipt_failed`, `receipt_pending_vehicle` in test email flow ### Acceptance Criteria - [x] Success email sent and in-app notification created - [x] Pending vehicle notification created for multi-vehicle users - [x] Error emails sent for each failure scenario (unregistered sender, no vehicles, no attachments, OCR failure, processing failure) - [x] All emails logged to notification_logs ### Validation - TypeScript: 0 errors - Lint: 0 errors (656 pre-existing warnings) *Verdict*: PASS | *Next*: Quality review
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: egullickson/motovaultpro#159