Remix.run Logo
lmm 2 hours ago

Sometimes you really can't separate the business logic from the imperative operations; in that case you use monads and at least make it a bit more testable and refactorable (e.g. https://michaelxavier.net/posts/2014-04-27-Cool-Idea-Free-Mo...).

That said:

> It pulls customer metadata, checks the customer type, and then based on that it computes their latest usage charges, and then based on that it may trigger automatic balance top-ups or subscription overage emails (again, depending on the customer type).

So compute those things, and store them somewhere (if only an in-memory queue to start with)? Like, I can already see a separation between an ETL stage that computes usage charges, which are probably worth recording in a datastore, and then another ETL stage that computes which top-ups and emails should be sent based on that, which again is probably worth recording for tracing purposes, and then two more stages to actually send emails and execute payment pulls, which it's actually quite nice to have separated from the figuring out which emails to send part (if only so you can retry/debug the latter without sending out actual emails)