-
Notifications
You must be signed in to change notification settings - Fork 19
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
docs: add ADR on supporting learner credit with EMET #686
base: master
Are you sure you want to change the base?
Conversation
b99f95c
to
44786fc
Compare
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #686 +/- ##
==========================================
- Coverage 81.73% 81.30% -0.44%
==========================================
Files 284 288 +4
Lines 5618 5649 +31
Branches 1355 1365 +10
==========================================
+ Hits 4592 4593 +1
- Misses 1001 1032 +31
+ Partials 25 24 -1
... and 21 files with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
* Poll against `enterprise-subsidy` API for the status of the returned transaction UUID until the transaction is in a non-pending state (e.g., "committed"). | ||
* If in a "committed" state, redirect learner to courseware URL for OCM courses to begin learning. | ||
* If in an "error" state, we will ensure appropriate messaging is displayed and an option to retry. |
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.
Currently the create transaction endpoint (POST /api/v1/transactions/) is synchronous.
Returns 201 (and state will be "committed"), or some other state (in which case the transaction may not get created, or it ended up in "failed"). Either way, after the response is sent, the transaction is in a terminal state if it exists.
Should we be changing this enterprise-subsidy endpoint to be async, or change this ADR to assume that it is synchronous?
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.
I guess what makes the API call synchronous or asynchronous is really just whether the returned transaction is "committed"/"failed" or "pending", which doesn't really change the fundamental shape of the endpoint. Request args and status codes would not change when switching from synchronous to asynchronous mode. In other words, the frontend logic could be:
- Make a
POST
request to theredeem
endpoint for the redeemable access policy returned bycan_redeem
. This returns the transaction payload fromenterprise-subsidy
. - If the transaction has state "committed":
- redirect learner to courseware URL for OCM courses to begin learning.
- If the transaction has state "failed":
- ensure appropriate messaging is displayed and an option to retry.
- If the transaction has state "pending":
- Poll against
enterprise-subsidy
API for the status of the returned transaction UUID until the transaction is in a non-pending state (e.g., "committed"). - If in a "committed" state, redirect learner to courseware URL for OCM courses to begin learning.
- If in an "failed" state, we will ensure appropriate messaging is displayed and an option to retry.
- Poll against
This frontend flexibility will allow us to defer architecture changes to this create endpoint until a later milestone.
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.
What you're describing is exactly the intent of this ADR and this PR.
While the first EMET release is synchronous as you called out (will always return state: committed
), we're opting to future-proof the frontend to account for when the transaction state may not be synchronous such that when state: 'pending'
or state: 'failed'
is returned, the frontend should handle it appropriately already.
|
||
In order to support existing enrollments that were redeemed outside of the EMET system (e.g., subscription license), the new `CourseRunCard` component (via `CourseRunCards`) will continue to rely on parsing the learner's existing `EnterpriseCourseEnrollments`, data available and used by the course page today, to understand whether the learner has an existing enterprise enrollment that was subsidized outside of the EMET system. | ||
|
||
## Consequences |
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.
One other consequence related to the point made in the rejected alternatives:
- This results in enterprise business logic embedded in frontend code for as long as it takes for us to migrate or age-off old subsidies.
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.
Good callout, will add!
|
||
The metadata pertinent to learner credit that gets exposed by `UserSubsidyContext` is fetched via the [`useEnterpriseOffers`](https://github.com/openedx/frontend-app-learner-portal-enterprise/blob/5034f5ab170589a923c223cfe238112eff48f5c4/src/components/enterprise-user-subsidy/enterprise-offers/data/hooks.js#L11) React hook. | ||
|
||
It currently relies on the system-wide feature flag `FEATURE_ENROLL_WITH_ENTERPRISE_OFFERS` and the enterprise customer configuration flag `enableLearnerPortalOffers` to both be truthy. To support the new learner credit system, we will not be relying `enableLearnerPortalOffers`. This boolean flag on the customer configuration is currently used to detemrine whether we should attempt to make API calls to retrieve any learner credit data (such that we can avoid making API calls if a customer doesn't rely on learner credit). The recommendation for the new learner credit system is to no longer rely on `enableLearnerPortalOffers` and always make the API calls even if the customer doesn't utilize learner credit. The performance impacts should largely be mitigated by the fact that we make API calls to fetch all subsidies in parallel rather than waterfall. |
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.
[curious] To be clear, this doesn't mean we're removing the enableLearnerPortalOffers
flag, right? Will it still be used to switch old offers on and off?
If not (i.e. we will remove the per-enterprise enableLearnerPortalOffers
flag), does that represent an unmitigated performance impact in the case where it was previously False, but also the enterprise has no redeemable subsidy in new learner credit?
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.
[curious] To be clear, this doesn't mean we're removing the
enableLearnerPortalOffers
flag, right? Will it still be used to switch old offers on and off?
Correct, no current plans to remove the enableLearnerPortalOffers
quite yet (and probably not until we no longer need to support legacy enterprise offers). It may still be used to switch old offers on/off for the time being.
I believe I was trying to communicate here that we won't be relying on a customer config flag to determine whether or not to call the can-redeem
API endpoint; we will always call it even if that customer has no EMET-compatible subsidies.
`EnterpriseOffersSummaryCard` either displays a generic message for max global spend or a user-specific message for max user spend remaining. It does not currently support any enrollment limits (e.g., `maxGlobalApplications`). In the case of max user spend remaining, we sum all remaining user balance for all available learner credit. The expiration date shown is from the learner credit that expires first. | ||
|
||
#### Search | ||
This page route similarly relies on the data provided by the `UserSubsidyContext` in order to display an alert to inform learners of low/no balance remaining. The rationale for this alert in the UX is to help proactively make learners are aware they may not have enough funds available to cover the cost of all content returned in the search results. |
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 context about alerting on low or no balance remaining seems uncovered by the decisions section. What should we do when new learner credit subsidies have low or no balance? How should "low" balance be defined, since we're returning raw balance amounts instead of booleans now? In the name of removing business logic from the frontend, should we change the policy API to return booleans that indicate low balance?
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.
Great questions! The context about the alerting for low/no balance remaining was written before I realized we don't actually need to focus on it for the initial EMET release given we're only tackling use cases where the learners are coming from an external LMS. Given that, the dashboard/search pages are not accessible to learners coming from an LMS so the implications for the dashboard/search page are not being accounted for in the initial EMET release. That's probably why the "Decisions" section doesn't really cover it.
That said, you bring up a great point around whether the API should be making the determination of "low" or "no" balance remaining. The existing business logic in the frontend for this are capturing in the following functions:
I'd be in favor of eventually getting this in to the API layer to further remove business logic from the frontend, but I don't think we necessarily need to take action on it until EMET has a requirement to support non-LMS use cases, too.
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.
Thanks! My only suggestion then would be to add a placeholder section/paragraph in decisions to explicitly defer decisions about low balance UI
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.
Agreed. Will update!
Description
ADR for migrating to new learner credit (preview)
For all changes
Only if submitting a visual change