Interesting, we're currently doing something quite like that. It's basically a key-value store that attaches values to fields organized in an open schema, using namespaces to organize access. What made me wonder whether Event Sourcing and DDD are concepts that fit was the size of the data, being some hundred million instances of essentially only two to three Aggregates, which will often be updated and accumulate history fast. Plus, it is a backend service, not designed to attach a UI to it.
Maybe you can still pick up something useful from a short report on how it feels like, and we can ping pong some ideas on the cruddiness of things.
If I look at it now, the CQRS part of it still makes me happy. The flexibility we get from the decoupling has already helped on several occasions, on changing requirements as people thought of downstream use cases for the store. I still struggle here and there, for example the possibilities and different patterns of handling data with Cassandra allow to implement CQRS differently than what my reading made me think is "normal". Still, knowing that I can whip up new read model projections when new use cases pop up make me sleep better. At least as soon as I find a decent way to replay the events from a select * in Cassandra while stuff still getting inserted...
Being CRUD oriented might be the biggest hindrance in also adding DDD to the mix. We started with more fine grained events, like AttributeAdded (declarative, open schema), AttributeValueSet. However, with all folks around us being used to CRUD and data driven applications, this now transforms to being more like Create and Update events, with the finer grained changes embedded. This seems to fit the mental model of our users and data scientists nicely, so I guess it's a good thing.
Just having an automated audit log and history built in was an eye opener for some, and you can really see them delving into the new options there. Sometimes, the biggest benefit for others comes in parts where you didn't expect it.
So in the end, CQRS seems very useful, giving scalability and flexibility of implementation. The DDD part of it is mainly a source for events, and currently has almost no logic in it. Still, it is soothing to know we have a place where we can add it, and we can rip it out if complexity doesn't arrive soon. My gut feeling is that if I had something like "checkout" coming, which smells like a more involved process than updating a couple fields, I would either think of putting it in the domain, or in a downstream service, if you have that option. Unfortunately, I am just beginning to get experience here.
ES, the possibilities it gives you, I wouldn't want to miss. For me, being event-driven is one of the best approaches to link services together. More interesting is the tension between a do-it-yourself implementation and just piggybacking on something like spark, if it's only about CRUD feeding into read models.
I wouldn't worry too much about having to sell the eventual consistency in the UI. Often, people are more used to it than they themselves know, in their daily work, and if you have a way to detecting concurrency issues, reporting them a second or two later than right now is fine, too. Having a conversation about this with some of the potential users should give you a good impression of how much trouble they will have accepting it.
Sorry for sidestepping your more direct questions ;-)