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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You’re right. sorry for that.</p>
<p>I haven’t used any frameworks, but I have used <a href="https://github.com/commanded/eventstore" class="inline-onebox" rel="noopener nofollow ugc">GitHub - commanded/eventstore: Event store using PostgreSQL for persistence · GitHub</a> in the past, and I’ve built a small eventstore library on top of sqlite which for works for my use cases but I’m not going to recommend it for general public use <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>I don’t think I’m the intended audience for a library like Must. So not sure I’m going to be able to give you much feedback.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="390398" 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/must-rfc-event-sourcing-simplified/75699/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-390398" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="390398"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="390399" data-post-id="390399">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mudasobwa" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mudasobwa/120/5298_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mudasobwa
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Cure</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="tcoopman" data-post="12" data-topic="75699">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tcoopman/48/8112_2.png" class="avatar"> tcoopman:</div>
<blockquote>
<p>I have used <a href="https://github.com/commanded/eventstore" rel="noopener nofollow ugc">GitHub - commanded/eventstore: Event store using PostgreSQL for persistence · GitHub</a> in the past</p>
</blockquote>
</aside>
<p>What bugs me most in all the implementations of ES so far, is the necessity to explicitly issue an event. All these <code>MyEventStore.append_to_stream/3</code> in Commanded, or <code>ChangeStore.save_change!/2</code> in Must, or anything else.</p>
<p>In <code>persistomata</code> I mentioned above I abstracted data and made each and every data change an event, that’s it. I strongly believe that ES had been invented to diminish a hassle about persistence, ideally to zero. I can live with <code>@side_effect</code> annotation, or <code>@intermediate_store [target: :result]</code>, but explicit calls to functions exported from the store implementation ditch the purpose of ES completely IMHO. If I need to write a code keeping in mind that I have to store it here and there, I am good with Postgres, ain’t I?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="390399" data-batch-url="/posts/batch_likers">
                        0
                      </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/must-rfc-event-sourcing-simplified/75699/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-390399" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="390399"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="390402" data-post-id="390402">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m probably going offtopic to the original topic again, so <a class="mention" href="/u/lostkobrakai" rel="nofollow">@LostKobrakai</a> feel free to split this up.</p>
<aside class="quote no-group" data-username="mudasobwa" data-post="13" data-topic="75699">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mudasobwa/48/5298_2.png" class="avatar"> mudasobwa:</div>
<blockquote>
<p>What bugs me most in all the implementations of ES so far, is the necessity to explicitly issue an event.</p>
</blockquote>
</aside>
<p>I can agree with the storing part, but not with the issuing an event.</p>
<aside class="quote no-group" data-username="mudasobwa" data-post="13" data-topic="75699">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mudasobwa/48/5298_2.png" class="avatar"> mudasobwa:</div>
<blockquote>
<p>I strongly believe that ES had been invented to diminish a hassle about persistence, ideally to zero. I can live with <code>@side_effect</code> annotation, or <code>@intermediate_store [target: :result]</code>, but explicit calls to functions exported from the store implementation ditch the purpose of ES completely IMHO. If I need to write a code keeping in mind that I have to store it here and there, I am good with Postgres, ain’t I?</p>
</blockquote>
</aside>
<p>I don’t think that was the original goal, but it might have been an intended side-effect.<br>
But I don’t agree with some of the other things - or I’m misunderstanding stuff.<br>
Emitting domain events allows you to very clearly and explicitly capture decisions made in a system / in a process and base your next decisions on the past ones.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># this is based on a real domain I worked in but hugely simplified
DocumentSubmittedForAproval
FourEyesApprovalRequested
DocumentReceivedApproval(person1)
DocumentReceivedApproval(person2)
DocumentApproved
# Now something changes and the rules is that after a change we need 1 of the 
# initial pair of 4 eyes to take another look - in reality it depends on the type  of change.
DocumentChanged
NewApprovalRequestedFrom(person1 or person2)
DocumentRecievedApproval(person 1)
DocumentApproved
</code></pre>
<p>In reality a document consists of multiple lines and each line has specific approval rules on changing things sometimes only the one line needs to be re-approved, sometimes mutliple.<br>
Modelling this on top of a regular postgres state based system is possible, but with a stream of events it really tells the story of what happened to this document and what is allowed to happen right now.</p>
<p>So the choice of emitting an event is really valuable - again - it explicitly captures the domain/business decision.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="390402" data-batch-url="/posts/batch_likers">
                        0
                      </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/must-rfc-event-sourcing-simplified/75699/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-390402" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="390402"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="390403" data-post-id="390403">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mudasobwa" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mudasobwa/120/5298_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mudasobwa
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Cure</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="tcoopman" data-post="14" data-topic="75699">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tcoopman/48/8112_2.png" class="avatar"> tcoopman:</div>
<blockquote>
<p>So the choice of emitting an event is really valuable - again - it explicitly captures the domain/business decision.</p>
</blockquote>
</aside>
<p>Sure. I cannot agree more.</p>
<p>But if you think about this in a more abstract way, how often do you want to capture the domain/business decision without amending any data? What kind of a business decision is not mirrored by any data change, leaving the whole system in the state which cannot be distinguished from the state <em>before</em> this decision?</p>
<aside class="quote no-group" data-username="tcoopman" data-post="14" data-topic="75699">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tcoopman/48/8112_2.png" class="avatar"> tcoopman:</div>
<blockquote>
<p>In reality a document consists of multiple lines and each line has specific approval rules on changing things sometimes only the one line needs to be re-approved, sometimes mutliple.</p>
</blockquote>
</aside>
<p>This is to be handled by an FSM instance, it has nothing to do with the ES per se. Add listeners to data changes and make one of these listeners writing to ES—and you are all set. You code the business logic, and ES happens to appear automagically. Alongside with materialized views in ClickHouse—you get the latest snapshot, the full events history, and whatnot. The consistency of business processes is guaranteed by an FSM. Voilà.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="390403" data-batch-url="/posts/batch_likers">
                        0
                      </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/must-rfc-event-sourcing-simplified/75699/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-390403" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="390403"
                     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>