Sending emails and notifications

145 views
Skip to first unread message

Jack Snow

unread,
May 19, 2016, 2:10:04 AM5/19/16
to DDD/CQRS
I have a billing context for a subscription service that I want to implement using event sourcing and CQRS. When I mention "application service", it is the same thing as "use-case".

The billing context will go through each customer account, calculate the amount payable (minus credits and refunds), charge the credit card on file and send an email confirmation with a pdf invoice.

I am considering a flow that looks like this:

1. The Billing bounded context has a cron job that sees we need to bill John $50 so it calls the InvoiceCustomerForSubscription() use case.
2. The use case creates an aggregate of the type invoice with the invoice lines, amount due and the tax and saves it to the event store which publishes the CustomerInvoiced event.
3. InvoicePDFConverterService which is an application service sees the CustomerInvoiced event and generates a PDF and emits a CustomerInvoicePDFGenerated event.
4. We then have a ChargeCreditCardService which is an application service that sees the CustomerInvoice event and attempts to charge the credit card on file. It persists either a InvoicePaymentFailed or InvoicePaymentSuccessful event to the eventstore for the AR and publishes the event.
5. EmailCustomerInvoiceService listens for the InvoicePaymentFailed or InvoicePaymentSuccessful event and sends an email with the attached pdf invoice through the email infrastructure service.

Questions:
- Does the model for this process seem sound? Are there too many application services?
- The CustomerInvoicePDFGenerated event does not seem like a domain event at all. I would argue that it belongs in the infrastructure. How should this bit be modelled?
- EmailcustomerInvoiceService needs to wait for (InvoicePaymentFaile OR InvoicePaymentSuccessful) AND CustomerInvoicePDFGenerated to perform its work. I think this can only be implemented using a saga. Is there anyway to avoid having to use a saga to implement this?

As another example, I have an authentication bounded context. I also wish to have this implemented with event sourcing and CQRS for security auditing and data analytic purposes.

I have a use-case where the user requests an email with a special link to reset his password. Should it be modelled like this?

1. The RequestPasswordReset use-case finds the user from the repository using his email. Then it calls user.RequestPasswordReset() and the event is saved to the event store and published.
2. Should the RequestPasswordReset use-case speak to the email infrastructure service directly to send the password reset email? Or should I have a ProcessRequestPasswordResetService listen to the event and send the email?

Thanks!

jarchin

unread,
May 19, 2016, 5:53:58 PM5/19/16
to DDD/CQRS
Hi Jack,

I'll start with your last question.
I'd go with #2, simply because we have all our emailing designed like this.

Whenever there's something that should trigger an email, that event is listened for in the Emailing BC, and code is setup for that, and to prepare the email (maybe listening for other events long before the triggering event).

The first three questions..
1. The model seems sound to me, with some modifications:
In our system, the invoice itself is not an aggregate. Although, "Invoicing" is, - one aggregate for each and every customer.
The invoice PDF generation is a proper bounded context in our system. I admit though that the context boundaries might not be right.
It listens to events from the Invoicing aggregates (among others), and builds up the state of the invoices, before a scheduled cmd triggers the generation and storage of the PDFs.
2. If your domain is about selling subscriptions and billing customers, then the generation of bills in their various representations (emails, PDFs etc) is - IMO - part of the domain.
3. It is said that a properly designed aggregate shall work like a saga. I don't know if the nestors would sign off on that, but I can confirm that I tend to design them more and more like sagas.
Reply all
Reply to author
Forward
0 new messages