[CORE-342] Submit Success Email#189
Conversation
There was a problem hiding this comment.
Problem
After a successful submit, the handler looked up the user's email addresses and sent thank-you messages synchronously before writing the HTTP response. Slow or hung SMTP relays could delay or block 201 even though the submission had already been persisted. Client retries in that window could also trigger duplicate emails.
Proposed change
- Return the HTTP response first — write 201 Created as soon as Submit succeeds.
- Dispatch email in the background — start a detached goroutine after the response is sent:
go email.SendSubmissionEmails(context.WithoutCancel(traceCtx), currentUser.ID, newResponse)
| for _, email := range emails { | ||
| err := h.mailer.SendSubmissionMail(traceCtx, email, newResponse) | ||
| if err != nil { | ||
| logger.Error( | ||
| "send submission email failed", | ||
| zap.Error(err), | ||
| zap.String("email", email), | ||
| zap.String("user_id", currentUser.ID.String()), | ||
| zap.String("response_id", responseID.String()), | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| submitResponse := Response{ |
There was a problem hiding this comment.
Consider making thank-you email delivery asynchronous by running it in a detached goroutine after the response is sent. By doing so, the HTTP 201 responses are not blocked by SMTP
go email.SendSubmissionEmails(context.WithoutCancel(traceCtx), currentUser.ID, newResponse)
| } | ||
| } | ||
|
|
||
| func (s *SMTPSender) Send( |
There was a problem hiding this comment.
Consider adding a timeout to Email submission, so that it can be shut down if it cannot be sent successfully.
| s.host, | ||
| ) | ||
|
|
||
| message := []byte( |
There was a problem hiding this comment.
Consider adding a sanitiser in the message to prevent injection in the email.
There was a problem hiding this comment.
Currently, the subject is controlled by our application, so it is not user input. However, I'll add validation to prevent potential header injection issues in the future.
| ID: newResponse.ID.String(), | ||
| FormID: newResponse.FormID.String(), | ||
| CreatedAt: newResponse.CreatedAt.Time, | ||
| UpdatedAt: newResponse.UpdatedAt.Time, |
There was a problem hiding this comment.
Consider using the submission time instead of the mail-sent time so it matches the user's actual form submission time.
There was a problem hiding this comment.
change in internal/email/service.go
Type of changes
Purpose
Additional Information