Would it be ok to have events in the event stream that does not effect any aggregate in the domain state?
Take for instance an event such as AllCompletedTodosPurged that
No, it wouldn't be ok. A Domain event is generated when the aggregate state changes. If nothing changed, there is no domain event.
You can use events outside the domain as well, but they wouldn't be part of the domain and obviously not part of the event stream.
In your scenario, if the event isn't generated as an effect of aggregate change, why it should be contained by any aggregate? And technically speaking, in what event stream will you add that event if it doesn't belong to anything? Will you add that event for all involved ToDos? It makes no sense.
I'm not sure that purge is part of your Domain, but if it is, it means that all completed todos are alreay 'deleted' i.e each involved aggregate already has the ToDoDeleted
event in its collection. AllCompletedTodosPurged
is just an event that is useful to update the read model, but that's it. It shouldn't affect the domain model.