-
Notifications
You must be signed in to change notification settings - Fork 17
Feat/welcome-email-after-signup #472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ions - Added new webhook endpoints for processing Google Forms submissions and Slack interactions. - Enhanced the NotificationConfiguration struct to include VerificationLink and SlackBotToken. - Implemented email services for sending KYB approval and rejection notifications. - Integrated Slack notifications for new KYB submissions and action feedback. - Updated routes to include new webhook functionalities.
- Implemented mechanisms to track and prevent duplicate processing of approve and reject actions in Slack interactions. - Introduced a mutex for safe concurrent access to the processed actions map. - Enhanced the SlackInteractionHandler to respond appropriately when actions are already processed.
…unctionality - Implemented KYBFormSubmission schema with fields for email, company name, business addresses, and policy URLs. - Added BeneficialOwner schema with relevant fields including ownership percentage and identification URLs. - Created update builders for KYBFormSubmission to handle updates to its fields and relationships. - Established edges between KYBFormSubmission and BeneficialOwner, allowing for cascading deletes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- write migration to check if user's scope contains "provider", and move its existing kyb info to the new kyb schema for the user
- remove KYB fields from providerprofile schema
return []ent.Field{ | ||
field.UUID("id", uuid.UUID{}). | ||
Default(uuid.New), | ||
field.String("email"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not necessary... fetch email from user schema
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace it with mobile number
field.String("proof_of_residential_address_url"), | ||
field.String("aml_policy_url"). | ||
Optional(). | ||
Nillable(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove nillable
BeneficialOwner should be in a separate schema file
KYBFormSubmission
should be KYBProfile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also add a boolean field isApproved
edge.To("user", User.Type). | ||
Unique(). | ||
Annotations(entsql.OnDelete(entsql.Cascade)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be from... and shouldn't be cascading deletion
@@ -40,7 +40,7 @@ func (User) Fields() []ent.Field { | |||
field.Bool("is_email_verified"). | |||
Default(false), | |||
field.Bool("has_early_access"). // has_early_access is "false" by default | |||
Default(false), | |||
Default(false), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove unnecessary indentation
v1.POST("slack-interaction", ctrl.SlackInteractionHandler) | ||
|
||
// KYB route | ||
v1.POST("kyb-submission", ctrl.SubmitKYBForm) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
controller name should be HandleKYBSubmission
logger.Errorf("Failed to send KYB rejection email to %s: %v, response: %+v", email, err, resp) | ||
return resp, fmt.Errorf("failed to send rejection email: %v", err) | ||
} | ||
logger.Infof("KYB rejection email sent to %s, message ID: %s, response: %+v", email, resp.Id, resp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove log
resp, err := SendTemplateEmail(payload, "d-b425f024e6554c5ba2b4d03ab0a8b25d") | ||
if err != nil { | ||
logger.Errorf("Failed to send welcome email to %s: %v", email, err) | ||
} else { | ||
logger.Infof("Welcome email sent successfully.") | ||
} | ||
return resp, err | ||
} | ||
|
||
// SendKYBApprovalEmail sends a KYB approval email. | ||
func (m *EmailService) SendKYBApprovalEmail(email, firstName string) (types.SendEmailResponse, error) { | ||
payload := types.SendEmailPayload{ | ||
FromAddress: _DefaultFromAddress, | ||
ToAddress: email, | ||
DynamicData: map[string]interface{}{ | ||
"first_name": firstName, | ||
}, | ||
} | ||
resp, err := SendTemplateEmail(payload, "d-5ebb862274214ba79eae226c09300aa7") | ||
if err != nil { | ||
logger.Errorf("Failed to send KYB approval email to %s: %v", email, err) | ||
} else { | ||
logger.Infof("KYB approval email sent to %s, message ID: %s", email, resp.Id) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
improve error logs with logger.WithFields
refer other parts of codebase
v1.POST("slack-interaction", ctrl.SlackInteractionHandler) | ||
|
||
// KYB route | ||
v1.POST("kyb-submission", ctrl.SubmitKYBForm) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this endpoint should be authenticated just like profile/register endpoints
|
||
// KYBFormSubmissionInput represents the input structure for KYB form submission | ||
type KYBFormSubmissionInput struct { | ||
Email string `json:"email" binding:"required,email"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this field... already in user object
func (BeneficialOwner) Fields() []ent.Field { | ||
return []ent.Field{ | ||
field.UUID("id", uuid.UUID{}). | ||
Default(uuid.New), | ||
field.String("full_name"). | ||
MaxLen(160), | ||
field.String("residential_address"), | ||
field.String("proof_of_residential_address_url"), | ||
field.String("government_issued_id_url"), | ||
field.String("date_of_birth"), | ||
field.Float("ownership_percentage"), | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
include id document type
field.Enum("government_issued_id_type").
Values("passport", "drivers_license", "national_id").
Optional(),
Description
This pull request implements the welcome email feature for the Paycrest aggregator, enabling a welcome email to be sent to users immediately after signup, before the verification email (in production environments). The feature enhances user onboarding by providing immediate confirmation of account creation with account-type-specific content based on the user’s selected scopes (sender, provider, or both).
References
Closes #471
Testing
Unit and Integration Tests
Checklist
main
By submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.