feat: send email confirmation - #36
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request implements a comprehensive email confirmation flow for new user registrations. The implementation follows Domain-Driven Design principles with clear separation between domain, application, and infrastructure layers. The feature introduces a token-based email verification system that triggers asynchronously via event-driven architecture and queue-based processing.
Key Changes:
- Introduced
Tokenentity with validation, expiration, and invalidation logic for managing email confirmation tokens - Implemented queue-based email processing using BullMQ with dedicated consumer for sending confirmation emails
- Added database migrations for tokens table with proper indexing and foreign key relationships
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 20 comments.
Show a summary per file
| File | Description |
|---|---|
| src/domain/users/entities/token.entity.ts | New Token entity with EMAIL_CONFIRMATION type, expiration logic, and validation methods |
| src/domain/users/entities/user.entity.ts | Added tokens relationship and createToken method for managing user tokens |
| src/infrastructure/mailer/mailer.service.ts | Nodemailer-based email service with Handlebars template support |
| src/infrastructure/mailer/mailer.module.ts | Module configuration for mailer service (contains typo in class name) |
| src/infrastructure/mailer/templates/email-confirmation.hbs | Handlebars email template for confirmation emails |
| src/infrastructure/queues/queues.service.ts | Service for managing queue operations across different queue types |
| src/infrastructure/queues/queues.model.ts | BullMQ module configuration with Redis connection (incorrect file extension) |
| src/infrastructure/queues/queues.enum.ts | Queue type enumeration for EMAIL_CONFIRMATION |
| src/infrastructure/queues/consumers/email-confirmation.consumer.ts | Consumer that processes email confirmation jobs (missing null checks) |
| src/infrastructure/repositories/postgres/users.repository.ts | Updated to persist and retrieve tokens with users (missing deleted_at in INSERT) |
| src/infrastructure/repositories/mappers/user.mapper.ts | Updated to map tokens between domain and persistence models |
| src/infrastructure/repositories/mappers/token.mapper.ts | New mapper for Token entity persistence (inconsistent null handling) |
| src/infrastructure/repositories/providers.enum.ts | Removed in favor of named constants pattern |
| src/infrastructure/event-handlers/send-email-confirmation.handler.ts | Event handler that queues email confirmation jobs on user creation |
| src/infrastructure/migrations/1734736313692_create-updated-at-function-trigger.js | Extracted trigger function for reusability across tables |
| src/infrastructure/migrations/1734736313693_create-users-table.js | Refactored to use shared trigger function |
| src/infrastructure/migrations/1764436999962_create-tokens-table.js | Creates tokens table with foreign key to users |
| src/api/users/users.module.ts | Updated to register event handlers and use new provider pattern |
| src/application/users/use-cases/create-user.service.ts | Updated to use new repository provider constant |
| src/app.module.ts | Added QueuesModule to application imports |
| src/shared/domain/Aggregate.ts | New base class for aggregate roots |
| tests/unit/domain/users/entities/token.entity.test.ts | Comprehensive tests for Token entity functionality |
| tests/unit/domain/users/entities/user.entity.test.ts | Updated to include tokens in user entity tests |
| tests/unit/application/users/use-cases/create-user.service.test.ts | Updated to include tokens in expected user structure |
| tests/unit/infrastructure/queues/consumers/email-confirmation.consumer.test.ts | Tests for email confirmation consumer (needs more error scenario coverage) |
| tests/integration/test.setup.ts | Updated to mock queue module for integration tests |
| tests/integration/api/users/controllers/create-user.controller.test.ts | Added verification that email confirmation queue is triggered |
| tests/mocks/factories/user.factory.ts | Updated to support tokens in factory |
| tests/mocks/factories/token.factory.ts | New factory for creating test tokens |
| tests/mocks/models/queue.module.ts | Mock queue module for testing |
| jest.config.ts | Excluded mailer infrastructure from coverage |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated 15 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| SendEmailConfirmationHandler, | ||
| { | ||
| provide: SEND_EMAIL_CONFIRMATION_HANDLER_PROVIDER, | ||
| useFactory: (handler: SendEmailConfirmationHandler) => { | ||
| DomainEvent.register(handler, UserCreatedEvent.name); | ||
| return handler; | ||
| }, | ||
| inject: [SendEmailConfirmationHandler], | ||
| }, |
There was a problem hiding this comment.
The SendEmailConfirmationHandler is registered twice in the providers array (lines 40 and 41-48). This creates two instances of the handler, which is redundant. The handler should only be registered once using the factory provider that also handles the domain event registration. Remove line 40.
This pull request introduces a comprehensive email confirmation flow for new users, including domain, infrastructure, and migration changes. The main additions are a token system for email confirmation, a mailer service, queue-based email processing, and the necessary event handlers and consumers to automate sending confirmation emails upon user creation. Database migrations and repository updates support these features.
Email Confirmation Flow Implementation
Domain Layer: Token Entity
Tokenentity andTokenTypeenum to handle email confirmation tokens, including creation, validation, and expiration logic withintoken.entity.ts. TheUserentity now manages tokens and can generate/invalidate them as needed. [1] [2] [3] [4] [5] [6]Infrastructure Layer: Email, Queues, and Event Handling
MailerServiceusing Nodemailer and Handlebars templates for sending emails (mailer.service.ts,mailer.module.ts,email-confirmation.hbs). [1] [2] [3]QueuesModule,QueuesService, andEmailConfirmationConsumerhandle async email confirmation jobs. [1] [2] [3] [4]SendEmailConfirmationHandler) that listens for user creation events and triggers the email confirmation flow. [1] [2]Database Layer: Migrations and Repository Mapping
tokenstable, including triggers for timestamp updates and indexing for user lookups. [1] [2] [3] [4]Module and Configuration Updates
users.module.ts,app.module.ts, and related configuration files. [1] [2] [3] [4] [5] [6]