Implement email receipt delivery via SendGrid#146
Conversation
kilodesodiq-arch
left a comment
There was a problem hiding this comment.
Thanks @noevidence1017 — SendGrid wiring plus the new delivery metrics are well done and the provider+processor+service specs are thorough. One follow-up (not blocking): make sure the service falls back gracefully when SENDGRID_API_KEY is unset rather than throwing on init. We can tighten that in a separate PR. Merging for now.
|
Heads up @noevidence1017 — #139 (Twilio SMS) merged first and touched The approval still stands conceptually — please rebase onto current |
d29deb6 to
0b1c762
Compare
|
Rebased onto current
Verified locally: |
|
Thanks @noevidence1017 — clean SendGrid integration with metrics and error handling in place. Backend CI is green and #94 is fully resolved. Merging now. |
I implemented real email delivery for claim receipts, resolving issue #94, on branch fix/email-receipt-delivery.
What changed:
app/backend/src/notifications/email/email.service.ts (new) — wraps the SendGrid SDK, reads SENDGRID_API_KEY/EMAIL_FROM_ADDRESS/EMAIL_FROM_NAME from env, throws on failure (no swallowing) so the BullMQ processor's existing retry/backoff/DLQ logic kicks in, and records Prometheus metrics for every attempt.
app/backend/src/notifications/email/email.service.spec.ts (new) — unit tests for configured/unconfigured/success/failure paths.
app/backend/src/notifications/notifications.processor.ts — replaced the mock email branch with a real call to EmailService.sendEmail; SMS remains mocked (out of scope for #94).
app/backend/src/notifications/notifications.module.ts — registers EmailService.
app/backend/src/observability/metrics/metrics.providers.ts + metrics.service.ts — added email_delivery_total counter and email_delivery_duration_seconds histogram, plus a recordEmailDelivery helper that also feeds the existing error-rate counter.
app/backend/src/claims/claims.service.ts — sendReceiptViaEmail now calls NotificationsService.sendEmail (existing BullMQ-backed outbox path) per recipient instead of just logging a stub; logs only counts/claim IDs, never addresses or receipt text.
app/backend/src/claims/claims.module.ts — imports NotificationsModule so ClaimsService can inject NotificationsService.
app/backend/package.json — added @sendgrid/mail dependency.
app/backend/.env.example — added SENDGRID_API_KEY, EMAIL_FROM_ADDRESS, EMAIL_FROM_NAME.
Updated claims.service.spec.ts and notifications.processor.spec.ts to provide/mock the new dependencies so existing DI wiring keeps compiling.
Note: I could not run npm install/jest in this sandbox — the project requires Node ≥18.18 for Prisma and the environment has Node 18.16.1, plus an unrelated npm cache permission issue. This is a pre-existing environment limitation, not something introduced by this change. I'd recommend running the test suite in CI/your local environment before merging.
Git commands:
git add app/backend/package.json app/backend/.env.example app/backend/src/claims/claims.module.ts app/backend/src/claims/claims.service.ts app/backend/src/claims/claims.service.spec.ts app/backend/src/notifications/notifications.module.ts app/backend/src/notifications/notifications.processor.ts app/backend/src/notifications/notifications.processor.spec.ts app/backend/src/notifications/email/ app/backend/src/observability/metrics/metrics.providers.ts app/backend/src/observability/metrics/metrics.service.ts
git commit -m "feat(backend): implement email receipt delivery via SendGrid"
Suggested PR description:
Title: Implement email receipt delivery via SendGrid
Summary
sendReceiptViaEmail in claims.service.ts was a logging-only stub — claim receipts requested via email were never actually delivered. This wires the existing BullMQ notifications infrastructure to a real SendGrid-backed EmailService.
Added EmailService (notifications/email/email.service.ts) wrapping the SendGrid SDK, configured via SENDGRID_API_KEY, EMAIL_FROM_ADDRESS, EMAIL_FROM_NAME env vars.
NotificationProcessor now calls EmailService.sendEmail for queued email jobs instead of mocking the send; failures propagate so the existing BullMQ attempts: 3 exponential backoff and DLQ handling apply unchanged.
ClaimsService.sendReceiptViaEmail now enqueues through NotificationsService.sendEmail (existing outbox-backed queue) rather than logging a stub message.
Added email_delivery_total counter and email_delivery_duration_seconds histogram to the metrics module, feeding the existing error-rate counter on failure.
Logging only includes claim IDs and recipient counts — never email addresses or receipt content.
Closes #94
Test plan
npm test in app/backend (added email.service.spec.ts, updated notifications.processor.spec.ts and claims.service.spec.ts for the new DI wiring)
Set SENDGRID_API_KEY in a dev environment and confirm a real receipt email is delivered end-to-end
Confirm /metrics exposes email_delivery_total and email_delivery_duration_seconds
Confirm a forced SendGrid failure retries per the existing backoff and lands in the DLQ/outbox failed status after exhausting attempts