sequenceDiagram actor User participant API as API Controller participant Mediator as MediatR pipeline
(ValidationBehavior) box Handler Layer participant ResendHandler as ResendConfirmationEmailHandler participant UserMgr as UserManager(ApplicationUser) participant TokenSvc as TokenService end box Infrastructure Layer participant SMTP as Email Provider participant Template as Template Provider end box Repository / Cross-slice participant UserStore as DapperUserStore
(IUserStore/IUserPasswordStore/IUserEmailStore) participant EmailDispatcher as EmailDispatcher
(Features.Emails) end participant DB as SQL Server User->>API: POST /api/auth/confirm/resend?userId={id} (requires Bearer access token) activate API API->>Mediator: Send(ResendConfirmationEmailCommand(userId)) activate Mediator Mediator->>ResendHandler: Handle(command) activate ResendHandler ResendHandler->>UserMgr: FindByIdAsync(userId) activate UserMgr UserMgr->>UserStore: FindByIdAsync(userId) activate UserStore UserStore->>DB: SELECT ... FROM UserAccount WHERE UserAccountID = @Id activate DB DB-->>UserStore: row or null deactivate DB UserStore-->>UserMgr: ApplicationUser or null deactivate UserStore UserMgr-->>ResendHandler: ApplicationUser or null deactivate UserMgr alt User not found ResendHandler->>ResendHandler: return silently (prevents user enumeration) else User found ResendHandler->>UserMgr: IsEmailConfirmedAsync(user) UserMgr-->>ResendHandler: bool alt Already confirmed ResendHandler->>ResendHandler: return silently (no-op) else Not yet confirmed ResendHandler->>TokenSvc: GenerateConfirmationToken(user) activate TokenSvc TokenSvc-->>ResendHandler: confirmation token deactivate TokenSvc ResendHandler->>Mediator: Send(SendResendConfirmationEmailCommand) activate Mediator Mediator->>EmailDispatcher: SendResendConfirmationEmailAsync(firstName, email, confirmationToken) activate EmailDispatcher EmailDispatcher->>Template: Render email (same Razor pipeline as registration) EmailDispatcher->>SMTP: SendAsync(email, subject, body) deactivate EmailDispatcher deactivate Mediator end end ResendHandler-->>Mediator: (void) deactivate ResendHandler Mediator-->>API: (void) deactivate Mediator API->>User: 200 OK {message: "confirmation email has been resent"} Note right of API: Always 200 OK regardless of outcome above — same user-enumeration precaution as a not-found user or an already-confirmed account deactivate API