<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="365113" data-post-id="365113">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="vasspilka" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vasspilka/120/2026_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  vasspilka
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="garrison" data-post="40" data-topic="70777">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>you need to ensure something is <em>removed</em> from your system?</p>
</blockquote>
</aside>
<p>There are 3 common ways of dealing with this.</p>
<ol>
<li>Most EventStores allow deleting or obfuscating events, this feature exists precisely for dealing with situations like this (or when events were inserted incorrectly).</li>
<li>Encrypt your data and throw away the key on request. Basically if dealing with user or organization data, you can create a key that will be used to encrypt and decrypt the data, if the user requests to delete the data you just throw away the key. Effectively making them inaccessible (I guess personal quantom computers are still some decades away)</li>
<li>Finally, don’t use ES for personal data. Most likely your business does not need to build ES around user emails, credit cards or other personal data. Just store them in seperate tables that are not ES and then use a user id to correlate them, if they need to be deleted you just remove the personal data. If you are building a social network or a public blog where you handle user content then I would be highly skeptical of the need to use ES there. You can just say for example that user XXXX created a blog post or updated it, without storing the contents of the blog post. Effectively just getting the information about the action but no personal information (but again for social media I don’t think ES makes sense). But overall I must admit that this still leaves a lot of vurnerabilities as one could correlate the user ID to a specific user and then use metadata information like dates to determine things about them.</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365113" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ashevents-event-sourcing-made-simple-for-ash/70777/42">Post #41</a>
	                </div>
	            </div>
              <div id="likers-container-365113" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365113"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #41"></div>
  </section>
</div>
    <div class="postbit" id="365130" data-post-id="365130">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="byu" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/byu/120/32032_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  byu
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="vasspilka" data-post="42" data-topic="70777">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/vasspilka/48/2026_2.png" class="avatar"> vasspilka:</div>
<blockquote>
<p>(but again for social media I don’t think ES makes sense)</p>
</blockquote>
</aside>
<p>And this also reminds me of another Greg Young comment – yes, i ended up watching a LOT of youtube from EventStoreDB (Kurrent) and Greg young-- that one doesn’t just build “an Event Sourcing System/Application”, rather that ES is applied as necessary to wrangle the problems it’s good at handling; other parts of an application will apply other traditionally understood software patterns as fit for purpose.</p>
<aside class="quote no-group" data-username="olivermt" data-post="27" data-topic="70777" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/olivermt/48/2354_2.png" class="avatar"> olivermt:</div>
<blockquote>
<p>A bank should use double entry bookkeeping <img src="https://forum.elixirforum.com/images/emoji/apple/stuck_out_tongue.png?v=15" title=":stuck_out_tongue:" class="emoji" alt=":stuck_out_tongue:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>I found <a href="https://www.youtube.com/watch?v=UiV0g8SJnqk" rel="noopener nofollow ugc">Simple Transactions Made Simple in EventStore</a> a very informative video, which covers how to perform the well known “transactional bank account money transfers” using Event Sourcing.</p>
<aside class="quote no-group" data-username="garrison" data-post="39" data-topic="70777">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>I think the same problem applies here, though: a developer could make a mistake on the projection, but they could also make a mistake <em>on the events</em> too. What if the projection was actually correct and the events were bugged? How would you know?</p>
</blockquote>
</aside>
<p>From my perspective as a CQRS/ES novice, I think that because with EventStorming or EventModeling, business subject matter experts are very much involved that it MIGHT be less likely to “get mistakes” in modeling a “Business Event” – not making claim about “Technical Events” … And MAYBE what might be more likely is that business, or understanding of the business, changes and that the Events must evolve to support such change… And this is still a <em>HARD</em> problem from what I gather, a trade-off in adopting ES in these problem domains… And <a href="https://leanpub.com/esversioning" rel="noopener nofollow ugc">Greg Young’s Event Sourcing Versioning book</a> does provide some information, but I personally can’t comment further as I don’t have true expertise/experience when it comes to this kind of evolution.</p>
<p>But if you’re saying that the “bugged event” was a result of committed data that was incorrect… For example, a warehouse management system was keeping track of product inventory based on sales and shipping events which result in “incrementing” or “decrementing” product inventory counts, yet a manual count of product shows a different number… I believe that the suggested practice is that a NEW event be committed into the event stream to reflect the “reality/truth” — example <code>ProductInventoryAdjustment{product_id, count}</code> so the “internal aggregate” will be built to reflect this latest truth to handle the next command.</p>
<aside class="quote no-group" data-username="garrison" data-post="39" data-topic="70777">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>The point I was trying to make was that snapshotting <em>in the limit</em> would just be “using the database normally” plus “keeping an audit log”. That is to say: if you are <em>already</em> doing those things, event sourcing is just “those things but worse”, where by “worse” I mean the materialized view is not always up-to-date or has to be reconciled (expensively) at query time</p>
</blockquote>
</aside>
<p>I’m hearing three topics here:</p>
<ul>
<li>Snapshotting</li>
<li>Eventual Consistency</li>
<li>Application State Management complexity</li>
</ul>
<p>I understand “Snapshotting” is a “technical pattern”, and the blog posts from Kurrent and various other experts in that world say that snapshotting is not recommended unless there is real good reason – since most streams are very short, and even streams of 1000s events is non-materially impacting performance for the purposes of these “enterprisey business entity lifecycle stuff”.</p>
<p>For Eventual Consistency of the “read-model” (aka materialized view), I believe that while the ESDB and CQRS/ES in general lend to an Eventually Consistent Read-Model, I believe that both ESDB/Kurrent and Axon Framework have some sort of projections mechanism that IS transactional-- someone please correct me if I’m wrong.</p>
<p>This <a href="https://www.youtube.com/watch?v=n9ZgIs_6n08" rel="noopener nofollow ugc">What is EventSourcing</a> video provided a few slides clarifying what they consider the four types of “ordered storage patterns” for application state management – command sourcing, change logging, state logging, event sourcing – and the rationale and reasoning of event sourcing.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365130" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ashevents-event-sourcing-made-simple-for-ash/70777/43">Post #42</a>
	                </div>
	            </div>
              <div id="likers-container-365130" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365130"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #42"></div>
  </section>
</div>
    <div class="postbit" id="365132" data-post-id="365132">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="byu" data-post="43" data-topic="70777">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/byu/48/32032_2.png" class="avatar"> byu:</div>
<blockquote>
<p>But if you’re saying that the “bugged event” was a result of committed data that was incorrect</p>
</blockquote>
</aside>
<p>What I was expressing was skepticism that materializing state from a set of immutable events at <em>query time</em> has different safety properties than materializing that state at <em>insertion time</em>, the former being “event sourcing” and the latter being, uh, “not event sourcing”. My argument being, if corruption is a concern it could happen anywhere, so it makes no difference.</p>
<p>I then <em>extended</em> that argument to cover corruption induced in the application layer, in response to a counterpoint. But at no point was I referring to data entry errors and so on - that’s a totally different thing. In that case the system is functioning properly.</p>
<aside class="quote no-group" data-username="byu" data-post="43" data-topic="70777">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/byu/48/32032_2.png" class="avatar"> byu:</div>
<blockquote>
<p>I’m hearing three topics here</p>
</blockquote>
</aside>
<p>We are clearly heading down the rabbit hole here, but I was not referring to eventual consistency. I mean I did <em>kind-of</em> allude to stale snapshot reads, but that wasn’t the point I was making either.</p>
<p>What I was getting at (and I realize I am now at attempt <span class="hashtag-raw">#3</span> here) is that materializing the “view” (or “projection”) at regular intervals - that is, taking snapshots - is <em>in the limit</em> equivalent to materializing the view incrementally on every single insert. And <em>that</em> is exactly the thing you’re doing when you’re <strong>not</strong> doing event sourcing. At the end of the day, it’s all equivalent.</p>
<p>But I have, here, learned a few things which cloud this perspective, of course. Mainly around the whole “add projections down the road” idea.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365132" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ashevents-event-sourcing-made-simple-for-ash/70777/44">Post #43</a>
	                </div>
	            </div>
              <div id="likers-container-365132" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365132"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #43"></div>
  </section>
</div>
    <div class="postbit" id="365645" data-post-id="365645">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="felix-starman" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/felix-starman/120/18051_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  felix-starman
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>On the commanded library site of it, there’s a repo of recipes and one of them talks about GDPR.<br>
<a href="https://github.com/commanded/recipes/issues/4" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/commanded/recipes/issues/4</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365645" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ashevents-event-sourcing-made-simple-for-ash/70777/45">Post #44</a>
	                </div>
	            </div>
              <div id="likers-container-365645" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365645"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>