Skip to content

LG-7185 email reminders#7198

Merged
svalexander merged 26 commits intomainfrom
shannon/lg-7185-email-reminders
Oct 28, 2022
Merged

LG-7185 email reminders#7198
svalexander merged 26 commits intomainfrom
shannon/lg-7185-email-reminders

Conversation

@svalexander
Copy link
Contributor

@svalexander svalexander commented Oct 24, 2022

🎫 Ticket

Lg-7185

🛠 Summary of changes

This ticket is to create a reminder email, a job to check days left till enrollment due date and to add a flag to the enrollment object.
This first pr is to add a template for the reminder email. Currently this email should be sent when the user has 10 days left to enroll, and then again at 3 days left. The only difference between the 3 day and 10 day emails is the number of days. For this reason a singular template is used.
In the InPersonEnrollment a method is added that counts the number of days until the due_date. This method is used by the presenter, and will eventually be used by the job that is later written.
This reminder email displays the same information as the ready to verify email does - the only differences being the subject, header and intro paragraph. For this reason this pr uses the same presenter with some minor additions to the presenter.

📜 Testing Plan

Provide a checklist of steps to confirm the changes.

👀 Screenshots

If relevant, include a screenshot or screen capture of the changes.

en - 3 days: Screen Shot 2022-10-20 at 6 21 30 PM Screen Shot 2022-10-20 at 6 24 05 PM Screen Shot 2022-10-26 at 3 57 18 PM
en- 10 days: Screen Shot 2022-10-20 at 6 25 49 PM
es- 3 days: Screen Shot 2022-10-20 at 6 54 29 PM Screen Shot 2022-10-20 at 6 54 44 PM Screen Shot 2022-10-26 at 3 58 49 PM
es- 10 days: Screen Shot 2022-10-20 at 6 53 56 PM
fr- 3 days: Screen Shot 2022-10-21 at 9 31 25 AM Screen Shot 2022-10-21 at 9 31 39 AM Screen Shot 2022-10-26 at 4 00 09 PM
fr- 10 days: Screen Shot 2022-10-21 at 9 32 22 AM

@svalexander svalexander changed the title Draft lg 7185 email reminders lg-7185 email reminders Oct 24, 2022
Copy link
Contributor

@sheldon-b sheldon-b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I left a mix of non-blocking suggestions and small requests. And then the one kind of major thing is making sure that the partner agency name value we show to users is a human-friendly one

SecureRandom.hex(9)
end

def due_date
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is non-blocking, it's kind of beyond the scope of this ticket. But I feel like expiration_date is a slightly better name, it better describes what the consequence of this date is and relates to the expired status of enrollments. Would require updating a few other places in the code to make this change cohesive though 🤷

Suggested change
def due_date
def expiration_date

start_date + IdentityConfig.store.in_person_enrollment_validity_in_days.days
end

def days_to_due_date
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, non-blocking suggestion

Suggested change
def days_to_due_date
def days_to_expiration

end

def partner_agency
enrollment.issuer
Copy link
Contributor

@sheldon-b sheldon-b Oct 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this value is a machine-readable value, not a human-readable one. eg urn:gov:gsa:openidconnect:sp:sinatra. I think we'd need to get the value from the ServiceProvider.friendly_name field, similar to how we do it here. I prefer that naming too, sp_name, to follow the convention we already have in the code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm thinking through this, it definitely makes sense to ensure that the name is easy to read.Looking at what's happening w/ the example you linked to sp_name gets passed to the presenter (and the name is retrieved from the session). What i'm thinking through right now is this presenter is used for 2 emails, one of which doesn't need the sp_name - i guess it can be an optional param or we could add a method that gets the friendly name using the issuer.

Copy link
Contributor

@sheldon-b sheldon-b Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, we do something similar in the "You successfully verified with IPP" email. We pull the human-friendly service provider name off of the enrollment. Here is where it's used in the email and then here's where it's defined in the presenter.

This seems closer to how you're doing it already and wouldn't require us to pass in the sp_name to the constructor 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup i think that matches what we're trying to do here. i think what's tripping me up when it comes to the enrollment model is that i don't see service_provider as part of the schema and the model says the enrollment belongs to the service_provider. Does the service_provider conversely belong to the enrollment?

Copy link
Contributor

@sheldon-b sheldon-b Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServiceProvider has_many enrollments. But yeah Rails adds that link implicitly for us based on how the enrollment belongs_to :service_provider

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That particular relationship is kind of unusual because we use the issuer as the foreign key rather than having something like service_provider_id

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh ok interesting. rails magic definitely throws me off at times.

@tomas-nava tomas-nava force-pushed the shannon/lg-7185-email-reminders branch from e9c2e20 to cfcd2a1 Compare October 25, 2022 21:49
Copy link
Contributor

@sheldon-b sheldon-b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just dropping some comments for now, I'll come back and finish reviewing when I can

Comment on lines +68 to +71
def due_date
start_date = enrollment_established_at.presence || created_at
start_date + IdentityConfig.store.in_person_enrollment_validity_in_days.days
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be misleading for enrollments that have status establishing. Some preference for just returning nil in that case

Suggested change
def due_date
start_date = enrollment_established_at.presence || created_at
start_date + IdentityConfig.store.in_person_enrollment_validity_in_days.days
end
def due_date
nil unless established_at
established_at + IdentityConfig.store.in_person_enrollment_validity_in_days.days
end

Copy link
Contributor Author

@svalexander svalexander Oct 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we were using created_at here to account for some enrollments that only have created_at defined when the enrollment status changes to pending and the user becomes ready to verify. We want to default to created_at if there's no enrollment_established_at value. (ticket)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An enrollment doesn't have a due date until it's pending though. If we use the created_at timestamp we're just making something up that isn't real. That date has no relevance to a user or USPS. Seems like the only reason to use created_at as a fallback is to return some sort of date if we ever execute that codepath, so that we're showing the user some sort of date. But if we ever execute that codepath with an enrollment that doesn't have enrollment_established_at then wouldn't it be a bug?

It's not a hill I want to die on but I am curious why we defined it that way in the ticket, I'm going to ask the ticket creator

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with removing the fallback to created_at. Note though, that

  1. the variable should be enrollment_established_at in sheldon-b's suggested change, and
  2. the days_to_due_date method will have to be updated to return nil if due_date returns nil (otherwise, it'll return (DateTime.now...nil).count which is Inifinity).
  3. the days_remaining method on the ReadyToVerifyPresenter will have to be updated to anticipate a nil value from days_to_due_date (otherwise it'll raise a NoMethodError).

I don't think we have to be too rigorous about protecting against this case though, because when we write the job, we shouldn't be generating emails for non-pending enrollments, which means we should never be in the circumstance where we're getting a nil value for due date.

end

def sp_name
service_provider ? service_provider.friendly_name : ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a question about what should happen if there is no service provider. We'll see that a lot in lower environments today. And after we finish the pilot I think there will be ways for production users to get into the IPP flow without an associated partner, such as by going through the password reset flow

I left a question on the Figma file about it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a good question. i left it as an empty string and so in examples i looked at w/o one it looks like an unfinished sentence -it definitely is not ideal. would be good to adjust for sure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lizzie suggested we discuss it at design critique on Monday so I'm going to plan to attend for that. Do you want to join too?

Copy link
Contributor

@sheldon-b sheldon-b Nov 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed during design critique and tentatively agreed to fall back to Login.gov when there's no service provider, similar to how we do in other places. Design is going to look into other places where this might be an issue in IPP and make suggestions for a fallback

Suggested change
service_provider ? service_provider.friendly_name : ''
service_provider&.friendly_name || APP_NAME

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is being addressed in #7256

Copy link
Contributor

@sheldon-b sheldon-b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last minor comment. Looks good! 🎉

barcode: You’re ready to verify your identity in person
location: Select a location to verify your ID
prepare: Verify your identity in person
reminder: You have %{days_remaining} days left to verify your identity in person
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is only used in the user_mailer I suggest we move it to config/locales/user_mailer/en.yml and similar for es/fr

@svalexander svalexander merged commit bb80ad8 into main Oct 28, 2022
@svalexander svalexander deleted the shannon/lg-7185-email-reminders branch October 28, 2022 20:03
@aduth aduth mentioned this pull request Nov 3, 2022
@svalexander svalexander changed the title lg-7185 email reminders LG-7185 email reminders May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants