Subscription Email Schedule
MediumSimulation · Stripe
Build the email schedule for a set of subscriptions.
subscriptions: rows[name, plan, start_day, duration]. The subscription ends onend_day = start_day + duration. Names are unique.changes: rows[name, day, new_plan], in no particular order. A change switches that customer's plan fromdayonward. Every change satisfiesstart_day < day < end_day, and a customer has at most one change per day.notice_days: how many days beforeend_daythe expiry warning goes out.
Each customer gets these emails, each written as [day, name, text]:
- On
start_day:"Welcome: <plan>"using the initial plan. - On each change
day:"Changed: <new_plan>". - On
end_day - notice_days, only if that day is strictly afterstart_day:"Expiring soon: <plan>", using the plan in effect that day (a change on the same day counts). - On
end_day:"Expired: <plan>", using the final plan.
Return all emails sorted by day, then by name. If one customer has two emails on the same day, the "Changed" email comes before the "Expiring soon" email.
Example 1
- Input:
- subscriptions = [["ana", "basic", 0, 30], ["bo", "pro", 5, 10]], changes = [["ana", 12, "pro"]], notice_days = 7
- Output:
- [[0, "ana", "Welcome: basic"], [5, "bo", "Welcome: pro"], [8, "bo", "Expiring soon: pro"], [12, "ana", "Changed: pro"], [15, "bo", "Expired: pro"], [23, "ana", "Expiring soon: pro"], [30, "ana", "Expired: pro"]]
- Explanation
- ana switches to pro on day 12, so her warning on day 30 - 7 = 23 and her expiry on day 30 both mention pro. bo ends on day 15; his warning would be on day 8, which is after his start on day 5, so it is sent. Emails are ordered by day, then name.
Example 2
- Input:
- subscriptions = [["cy", "team", 10, 20]], changes = [["cy", 25, "enterprise"], ["cy", 14, "pro"]], notice_days = 5
- Output:
- [[10, "cy", "Welcome: team"], [14, "cy", "Changed: pro"], [25, "cy", "Changed: enterprise"], [25, "cy", "Expiring soon: enterprise"], [30, "cy", "Expired: enterprise"]]
- Explanation
- Changes arrive unsorted; cy is on pro from day 14 and enterprise from day 25. The warning is also on day 25, so the change email comes first and the warning already uses enterprise.
Example 3
- Input:
- subscriptions = [["dee", "basic", 3, 4]], changes = [], notice_days = 7
- Output:
- [[3, "dee", "Welcome: basic"], [7, "dee", "Expired: basic"]]
- Explanation
- The warning day would be 3 + 4 - 7 = 0, which is not after the start day 3, so only the welcome and expiry emails are sent.
Constraints
0 <= subscriptions.length <= 10^40 <= changes.length <= 10^40 <= start_day <= 10^6,1 <= duration <= 10^61 <= notice_days <= 10^6- Each change has
start_day < day < end_dayand refers to an existing name