<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Tech'n bolts</title>
 <updated>2015-08-28T17:55:34+00:00</updated>
 <id>http://github.com/Arnauld</id>
 <author>
   <name>Arnauld</name>
 </author>

 
 <entry>
   <title>Il y a peut être une option pour continuer ¡¿ (réflexion sur la programmation par continuation)</title>
   <link href="http://arnauld.github.com/blog/2012/12/05/Programmation-Par-Continuation.html"/>
   <updated>2012-12-05T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2012/12/05/Programmation-Par-Continuation</id>
   <content type="html">&lt;p&gt;C&amp;#8217;est là bas que c&amp;#8217;est publié: &lt;a href=&quot;http://www.arolla.fr/blog/2012/12/option-maybe-continuation/&quot;&gt;Il y a peut être une option pour continuer ¡¿ (réflexion sur la programmation par continuation)&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>AMQP 101 ~ Part I</title>
   <link href="http://arnauld.github.com/blog/2012/11/06/AMQP-101-Part1.html"/>
   <updated>2012-11-06T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2012/11/06/AMQP-101-Part1</id>
   <content type="html">&lt;p&gt;C&amp;#8217;est là bas que c&amp;#8217;est publié: &lt;a href=&quot;http://www.arolla.fr/blog/2012/11/amqp-101-part-1/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; 101 ~Part I&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Le BDD mis en oeuvre avec JBehave</title>
   <link href="http://arnauld.github.com/blog/2012/06/21/Le-BDD-mis-en-oeuvre-avec-JBehave.html"/>
   <updated>2012-06-21T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2012/06/21/Le-BDD-mis-en-oeuvre-avec-JBehave</id>
   <content type="html">&lt;p&gt;C&#39;est là bas que c&#39;est publié: &lt;a href=&quot;http://www.arolla.fr/blog/2012/06/bdd-mise-en-oeuvre-avec-jbehave/&quot;&gt;Le BDD mis en oeuvre avec JBehave&lt;/a&gt;&lt;/p&gt;



</content>
 </entry>
 
 <entry>
   <title>Le BDD, qu’est ce que c’est?</title>
   <link href="http://arnauld.github.com/blog/2012/06/15/Le-BDD-qu-est-ce-que-c-est.html"/>
   <updated>2012-06-15T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2012/06/15/Le-BDD-qu-est-ce-que-c-est</id>
   <content type="html">&lt;p&gt;C&amp;#8217;est là bas que c&amp;#8217;est publié: &lt;a href=&quot;http://www.arolla.fr/blog/2012/06/bdd-c-est-quoi-donc/&quot;&gt;Le &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt;, qu’est ce que c’est?&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Twitter quotes: Business Components versus Bounded Contexts</title>
   <link href="http://arnauld.github.com/ddd/2012/02/14/Business-Components-vs-Bounded-Contexts.html"/>
   <updated>2012-02-14T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/ddd/2012/02/14/Business-Components-vs-Bounded-Contexts</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&amp;mdash; Last updated 2012/02/15&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Twitter exchange on &amp;#8220;Business Components versus Bounded Contexts&amp;#8221; after the blog post: &lt;a href=&quot;http://www.udidahan.com/2012/02/10/udi-greg-reach-cqrs-agreement&quot; title=&quot;Udi &amp;amp; Greg Reach CQRS Agreement&quot;&gt;Udi &amp;amp; Greg Reach &lt;span class=&quot;caps&quot;&gt;CQRS&lt;/span&gt; Agreement&lt;/a&gt;&lt;/p&gt;
&lt;style&gt;
.small,
.small a,
.small a:visited {
  font-size: 10px;
  font-weight: 300;
  color: #BFBFBF;
}

&lt;/style&gt;&lt;h2&gt;Eric Evans&lt;/h2&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;fr&quot;&gt;&lt;p&gt;Fundamentally, in &lt;a href=&quot;https://twitter.com/search/%2523DDD&quot;&gt;#&lt;span class=&quot;caps&quot;&gt;DDD&lt;/span&gt;&lt;/a&gt;, a Bounded Context is linguistic: a part of the system/project where language is consistent and rules agree.&lt;/p&gt;&lt;p&gt;&amp;mdash; Eric Evans (@ericevans0) &lt;a href=&quot;https://twitter.com/ericevans0/status/168423757696872448&quot; data-datetime=&quot;2012-02-11T19:58:47+00:00&quot;&gt;Février 11, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;fr&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://t.co/4Rt01ljt&quot; title=&quot;http://bit.ly/udigreg&quot;&gt;bit.ly/udigreg&lt;/a&gt; says &amp;#8216;Business Component&amp;#8217; is in 1 Bounded Context. Def of B Ctxt doesn&amp;#8217;t say this IS so. In good design &lt;span class=&quot;caps&quot;&gt;SHOULD&lt;/span&gt; be so&lt;/p&gt;&lt;p&gt;&amp;mdash; Eric Evans (@ericevans0) &lt;a href=&quot;https://twitter.com/ericevans0/status/168430221442297856&quot; data-datetime=&quot;2012-02-11T20:24:28+00:00&quot;&gt;Février 11, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-in-reply-to=&quot;168433580450656256&quot; lang=&quot;fr&quot;&gt;&lt;p&gt;@&lt;a href=&quot;https://twitter.com/Bemafred&quot;&gt;Bemafred&lt;/a&gt; Distinct concepts. Good separation of concerns allows you to deal with diff concerns in diff contexts. Must see contexts as-is&lt;/p&gt;&lt;p&gt;&amp;mdash; Eric Evans (@ericevans0) &lt;a href=&quot;https://twitter.com/ericevans0/status/168435813489704960&quot; data-datetime=&quot;2012-02-11T20:46:41+00:00&quot;&gt;Février 11, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;h2&gt;thinkb4coding / jeppec&lt;/h2&gt;
&lt;blockquote lang=&quot;fr&quot;&gt;&lt;p&gt;@&lt;a href=&quot;https://twitter.com/thinkb4coding&quot;&gt;thinkb4coding&lt;/a&gt; Seems you have the hands down on Business Components versus Bounded Contexts. Can you clarify on &lt;a href=&quot;http://t.co/Q51As20I&quot; title=&quot;http://www.udidahan.com/2012/02/10/udi-greg-reach-cqrs-agreement/comment-page-1/#comment-38422&quot;&gt;udidahan.com/2012/02/10/udi…&lt;/a&gt; &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/jeppec/status/168691529794330625&quot; data-datetime=&quot;2012-02-12T13:42:49+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;@jeppec&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote lang=&quot;fr&quot;&gt;
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;jeppec&lt;/a&gt; it&amp;#8217;s true Thar there&amp;#8217;s few words about bizcomp on the blogs for now &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/thinkb4coding/status/168821102229991424&quot; data-datetime=&quot;2012-02-12T22:17:41+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;jeppec&lt;/a&gt; from my experience BCtx contains several smaller services that represent Business units that are impl separately &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/thinkb4coding/status/168821518577569792&quot; data-datetime=&quot;2012-02-12T22:19:21+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;jeppec&lt;/a&gt; this are the business components, that have different users, dev/deployment lifecycles.. &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/thinkb4coding/status/168821871729586176&quot; data-datetime=&quot;2012-02-12T22:20:45+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;jeppec&lt;/a&gt; it&amp;#8217;s a level between bounded context and aggregates. They group services that work together to provide a business unit &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/thinkb4coding/status/168822285174718464&quot; data-datetime=&quot;2012-02-12T22:22:24+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;jeppec&lt;/a&gt; the c/q segregation happens at this level. Neither at the top level, neither at the bounded ctx level. It&amp;#8217;s too large &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/thinkb4coding/status/168822830685884416&quot; data-datetime=&quot;2012-02-12T22:24:34+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://twitter.com/thinkb4coding&quot;&gt;@thinkb4coding&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/thinkb4coding&quot;&gt;thinkb4coding&lt;/a&gt; that sounds reasonable and I think most &lt;span class=&quot;caps&quot;&gt;CQRS&lt;/span&gt; users do this. But when did the business component term get defined? &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/jeppec/status/168949042188009472&quot; data-datetime=&quot;2012-02-13T06:46:05+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/thinkb4coding&quot;&gt;thinkb4coding&lt;/a&gt; Such as Usecase specific services (eg. different clients/users might have special needs/flows). Makes sense? &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/jeppec/status/168951843509112832&quot; data-datetime=&quot;2012-02-13T06:57:13+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;@jeppec&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote lang=&quot;fr&quot;&gt;&lt;p&gt;@&lt;a href=&quot;https://twitter.com/jeppec&quot;&gt;jeppec&lt;/a&gt; yep. I think udi talks about it in his course. &lt;span class=&quot;small&quot;&gt;&amp;mdash; (&lt;a href=&quot;https://twitter.com/thinkb4coding/status/168957230048231424&quot; data-datetime=&quot;2012-02-13T07:18:37+00:00&quot;&gt;tweet&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://twitter.com/thinkb4coding&quot;&gt;@thinkb4coding&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Udi Dahan&lt;/h2&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p&gt;Confusion around Bounded Context / Business Component is influenced by the first being solution domain, second being problem domain&amp;#8230;&lt;/p&gt;&lt;p&gt;&amp;mdash; UdiDahan (@UdiDahan) &lt;a href=&quot;https://twitter.com/UdiDahan/status/169505742771068930&quot; data-datetime=&quot;2012-02-14T19:38:13+00:00&quot;&gt;February 14, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-in-reply-to=&quot;169505742771068930&quot; lang=&quot;fr&quot;&gt;&lt;p&gt;@&lt;a href=&quot;https://twitter.com/UdiDahan&quot;&gt;UdiDahan&lt;/a&gt; Subdomain is already used in problem space when doing domain assessment. Why not stick with that and not introduce ambiguous term?&lt;/p&gt;&lt;p&gt;&amp;mdash; Vaughn Vernon (@VaughnVernon) &lt;a href=&quot;https://twitter.com/VaughnVernon/status/169510145720729603&quot; data-datetime=&quot;2012-02-14T19:55:42+00:00&quot;&gt;Février 14, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;DDD&lt;/span&gt; doesn&amp;#8217;t try to enforce alignment between solution and problem domains&lt;/p&gt;&lt;p&gt;&amp;mdash; UdiDahan (@UdiDahan) &lt;a href=&quot;https://twitter.com/UdiDahan/status/169505923788836865&quot; data-datetime=&quot;2012-02-14T19:38:56+00:00&quot;&gt;February 14, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-in-reply-to=&quot;169505923788836865&quot; lang=&quot;fr&quot;&gt;&lt;p&gt;@&lt;a href=&quot;https://twitter.com/UdiDahan&quot;&gt;UdiDahan&lt;/a&gt; Are you saying that problem domain exists inside a Bounded Context? Thought you said Biz Component was inside, sounds solution-y.&lt;/p&gt;&lt;p&gt;&amp;mdash; Vaughn Vernon (@VaughnVernon) &lt;a href=&quot;https://twitter.com/VaughnVernon/status/169515128000221185&quot; data-datetime=&quot;2012-02-14T20:15:30+00:00&quot;&gt;Février 14, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p&gt;That&amp;#8217;s where we get into trouble using &lt;span class=&quot;caps&quot;&gt;DDD&lt;/span&gt; terminology to describe a specific form of &lt;strong&gt;good&lt;/strong&gt; design that enforces alignment&lt;/p&gt;&lt;p&gt;&amp;mdash; UdiDahan (@UdiDahan) &lt;a href=&quot;https://twitter.com/UdiDahan/status/169506092123041792&quot; data-datetime=&quot;2012-02-14T19:39:36+00:00&quot;&gt;February 14, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-in-reply-to=&quot;169506092123041792&quot; lang=&quot;fr&quot;&gt;&lt;p&gt;@&lt;a href=&quot;https://twitter.com/UdiDahan&quot;&gt;UdiDahan&lt;/a&gt; a particular form of good design is supported by aligning Bounded Context 1:1 with Subdomain. But also supports less good design.&lt;/p&gt;&lt;p&gt;&amp;mdash; Vaughn Vernon (@VaughnVernon) &lt;a href=&quot;https://twitter.com/VaughnVernon/status/169512611585601536&quot; data-datetime=&quot;2012-02-14T20:05:30+00:00&quot;&gt;Février 14, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p&gt;It turns out that I didn&amp;#8217;t represent @&lt;a href=&quot;https://twitter.com/ericevans0&quot;&gt;ericevans0&lt;/a&gt; Bounded Context correctly. He allows for them to be a problem or solution domain construct.&lt;/p&gt;&lt;p&gt;&amp;mdash; UdiDahan (@UdiDahan) &lt;a href=&quot;https://twitter.com/UdiDahan/status/169794825862914049&quot; data-datetime=&quot;2012-02-15T14:46:55+00:00&quot;&gt;February 15, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;script src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;</content>
 </entry>
 
 <entry>
   <title>Javascript Libraries</title>
   <link href="http://arnauld.github.com/blog/2012/01/21/Javascript-libraries.html"/>
   <updated>2012-01-21T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2012/01/21/Javascript-libraries</id>
   <content type="html">&lt;p&gt;Javascript Libraries that would require some attention:&lt;/p&gt;
&lt;style&gt;
.col {
	float: left;
	width: 18em;
	padding: 0.5em;
	border-radius: 6px;
	border-color: #EFEFEF;
	border-width: 1px;
	border-style: solid;
	margin: 0.5em;
	box-shadow: 4px 4px 3px #aaa;
}
.clear {
	clear: both;
}
&lt;/style&gt;&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://documentcloud.github.com/backbone/&quot;&gt;Backbone.js&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Backbone supplies structure to JavaScript-heavy applications by providing models with key-value binding and custom events, collections with a rich &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; interface.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://documentcloud.github.com/backbone/&quot;&gt;Backbone.js&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://www.modernizr.com/&quot;&gt;Modernizr&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Modernizr is a small JavaScript library that detects the availability of native implementations for next-generation web technologies, i.e. features that stem from the HTML5 and CSS3 specifications.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.modernizr.com/docs/&quot;&gt;Modernizr&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;clear&quot;/&gt;
&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://documentcloud.github.com/underscore/&quot;&gt;underscore.js&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support&amp;#8230;&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://documentcloud.github.com/underscore/&quot;&gt;underscore.js&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://requirejs.org/&quot;&gt;Require.js&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;RequireJS is a JavaScript file and module loader.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://requirejs.org/&quot;&gt;Require.js&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;clear&quot;/&gt;
&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://emberjs.com/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;EMBER&lt;/span&gt;.JS&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Ember is a JavaScript framework for creating ambitious web applications by eliminating boilerplate and providing a standard application architecture.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://emberjs.com/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;EMBER&lt;/span&gt;.JS&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://lesscss.org/&quot;&gt;{less}&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;The dynamic stylesheet language.&lt;br /&gt;
&lt;span class=&quot;caps&quot;&gt;LESS&lt;/span&gt; extends &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; with dynamic behavior such as variables, mixins, operations and functions. &lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://lesscss.org/&quot;&gt;{less}&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;clear&quot;/&gt;
&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Bootstrap &amp;#8211; Twitter&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Bootstrap is a toolkit from Twitter designed to kickstart development of webapps and sites.&lt;br /&gt;
It includes base &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; for typography, forms, buttons, tables, grids, navigation, and more.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Bootstrap&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;col&quot;&gt;
&lt;h2&gt;&lt;a href=&quot;http://mbostock.github.com/d3/&quot;&gt;D3.js&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Data-Driven Documents.&lt;br /&gt;
D3.js is a small, free JavaScript library for manipulating documents based on data.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://mbostock.github.com/d3/&quot;&gt;D3.js&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;clear&quot;/&gt;
&lt;p&gt;&lt;a href=&quot;http://andyet.net/blog/2010/oct/29/building-a-single-page-app-with-backbonejs-undersc/&quot;&gt;Building a single page app with Backbone.js, underscore.js and jQuery&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Quote of the day</title>
   <link href="http://arnauld.github.com/blog/2011/12/31/Quote-of-the-day.html"/>
   <updated>2011-12-31T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2011/12/31/Quote-of-the-day</id>
   <content type="html">&lt;blockquote&gt;&lt;p&gt;I thought of objects being like biological cells and/or individual computers on a network,only able to communicate with messages&lt;/p&gt;&lt;small&gt;Alan Kay&lt;/small&gt;&lt;/blockquote&gt;

</content>
 </entry>
 
 <entry>
   <title>[T|B|D]DD par la pratique 5 - Persistence et Migrations</title>
   <link href="http://arnauld.github.com/tbd-in-practice/2011/12/12/TBD-DD-par-la-pratique-5-Persistence-Migration.html"/>
   <updated>2011-12-12T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/tbd-in-practice/2011/12/12/TBD-DD-par-la-pratique-5-Persistence-Migration</id>
   <content type="html">&lt;h2&gt;Persistence&lt;/h2&gt;




&lt;p&gt;Interessons-nous à persister nos données afin de pouvoir les conserver d&#39;une session à l&#39;autre.
Afin de démarrer simplement nous utiliserons une base de données &lt;code&gt;postgres&lt;/code&gt; comme unité de stockage. Nous verrons plus tard pour une implémentation type NoSQL: &lt;code&gt;MongoDB&lt;/code&gt; ou &lt;code&gt;CouchDB&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;Nous avons vu que seuls nos évènements devaient être persistés, ce n&#39;est pas tout à fait vrai. Nous allons persister les entités et leurs évènements. Il n&#39;est pas nécessaire de créer une table par type d&#39;entité, mais uniquement les tables nécessaires à stocker les évènements.&lt;/p&gt;




&lt;p&gt;Il existe de nombreux articles sur la création d&#39;un &lt;code&gt;EventStore&lt;/code&gt;, nous prendrons comme base une modélisation décrite par Greg Young dans &lt;a href=&quot;http://cqrsinfo.com/documents/building-event-storage/&quot;&gt;cet article&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Rappellons brièvement cette modélisation d&#39;un point de vue base de données.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;label notice&quot;&gt;Note&lt;/span&gt; bien que ce soit des notions bien différentes, nous utiliserons dans cet article le mot &lt;strong&gt;aggregat&lt;/strong&gt; à la place de &lt;strong&gt;entité&lt;/strong&gt; dans nos descriptions, ceci afin d&#39;être plus en adéquation avec la littérature autour de &lt;code&gt;cqrs&lt;/code&gt;. Pour rappel, chacune de nos entité étend de &lt;code&gt;AggregateRoot&lt;/code&gt;, l&#39;amalgame n&#39;est donc pas si farfelu.
Un aggregat est un concept plus large que le concept d&#39;entités, et définit un contexte d&#39;intégrité de son contenu. Une entité est généralement un aggrégat, l&#39;inverse n&#39;est pas toujours vrai (même si aucun exemple ne me vient en tête à cet instant)&lt;/p&gt;

&lt;p&gt;Nous créérons deux tables, la première &lt;code&gt;Aggregates&lt;/code&gt; sera responsable de maintenir les informations de chaque aggregat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;son identifiant: &lt;code&gt;aggregate_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;le type de l&#39;aggrégat: &lt;code&gt;type&lt;/code&gt;, c&#39;est à dire le type généralement le type de l&#39;entité sous-jacente
par exemple: &lt;code&gt;story&lt;/code&gt;, &lt;code&gt;project&lt;/code&gt;, &lt;code&gt;sprint&lt;/code&gt; ...&lt;/li&gt;
&lt;li&gt;sa &lt;code&gt;version&lt;/code&gt;. La version d&#39;un aggregat sera principalement utilisée pour implémenter le mécanisme de mise à jour optimiste (&lt;code&gt;optimisting locking&lt;/code&gt;). Un point interessant et très simple consiste à utiliser, comme numéro de version, le nombre d&#39;élément contenu dans l&#39;historique. En effet, l&#39;historique d&#39;un aggrégat ne peux que croitre, puisque les évènements sont toujours ajoutés et ne peuvent jamais être supprimés. Tous les changements d&#39;états sont appliqués séquentiellement, il est donc même possible d&#39;utiliser l&#39;index d&#39;un évènement comme identifiant de celui-ci. En conservant, la version sur l&#39;aggrégat on peux ainsi génèrer l&#39;identifiant des prochains évènements sans relire l&#39;intégralité de l&#39;historique. De plus, l&#39;identifiant de l&#39;évènement peut être utilisé pour ordonner et réappliquer l&#39;historique dans le bon ordre. Aussi, une entité peut être mise à jour avec de nouveaux évènements si et seulement si les évènements   s&#39;applique depuis la dernière version persistée de l&#39;entité. [TODO] un example concret.&lt;/li&gt;
&lt;/ul&gt;


&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Nom de colonne&lt;/th&gt;&lt;th&gt;Type de données&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;aggregate_id&lt;/td&gt;&lt;td&gt;varchar(36)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;aggregate_type&lt;/td&gt;&lt;td&gt;varchar(255)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;aggregate_version&lt;/td&gt;&lt;td&gt;integer&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregates&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;      &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_type&lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_version&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INTEGER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;CONSTRAINT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregates_pkey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;La seconde table &lt;code&gt;AggregateEvents&lt;/code&gt; sera responsable de conserver les évènements eux-mêmes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;l&#39;identifiant de l&#39;aggrégat auquel est rattaché l&#39;évènement. Cette colonne est indéxée sur la table précedente.&lt;/li&gt;
&lt;li&gt;l&#39;identifiant de l&#39;évènement: correspondant à sa position dans l&#39;historique&lt;/li&gt;
&lt;li&gt;le type d&#39;évènement afin de simplifier les éventuelles requêtes et analyses futures&lt;/li&gt;
&lt;li&gt;les données de l&#39;évènements sous forme de données brutes. Nous utiliserons dans notre cas la sérialization json de notre évènement.&lt;/li&gt;
&lt;/ul&gt;


&lt;table class=&quot;condensed-table&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Nom de colonne&lt;/th&gt;&lt;th&gt;Type de données&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;aggregate_id&lt;/td&gt;&lt;td&gt;varchar(36)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;event_id&lt;/td&gt;&lt;td&gt;integer&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;event_type&lt;/td&gt;&lt;td&gt;varchar(255)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;event_data&lt;/td&gt;&lt;td&gt;clob / text&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregate_events&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;   &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;event_id&lt;/span&gt;       &lt;span class=&quot;nb&quot;&gt;INTEGER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;event_type&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;event_data&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;TEXT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;CONSTRAINT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregateevts_pkey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;CONSTRAINT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregateevts_fk1&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;FOREIGN&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;REFERENCES&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;INDEX&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregateevts_aggid&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregate_events&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Postgres est une base de données simple mais très complète. Nous ne détaillerons pas son fonctionnement, nous vous recommandons donc de vous familliariser un peu avec et de créer une base de données par l&#39;intermédiaire de pgAdmin (voir &lt;a href=&quot;http://postgresql.developpez.com/cours/&quot;&gt;ici&lt;/a&gt; pour des tutoriaux très simples sur l&#39;installation, la mise en oeuvre et l&#39;utilisation de pgAdmin).&lt;/p&gt;

&lt;p&gt;Nous considérerons désormais qu&#39;un role de connexion dédié a été créé et est disponible pour nous permettre de créer les bases de données dont nous aurons besoin notament pour nos tests d&#39;intégrations et de validation de script SQL. Dans notre cas nous l&#39;avons appellé &lt;code&gt;integration&lt;/code&gt; et son mot de passe est &lt;code&gt;1tegration&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ce que nous allons mettre en place dès maintenant:&lt;/p&gt;

&lt;h3&gt;NodeJS et Postgres, où sont nos tests d&#39;intégrations?&lt;/h3&gt;

&lt;p&gt;Afin de distinguer les tests unitaires qui doivent rester rapides et indépendants, nous allons créer un répertoire dédié à nos tests d&#39;intégrations &lt;code&gt;it&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dans &lt;code&gt;conf/sql/postgres&lt;/code&gt; nous placerons les fichiers &lt;code&gt;sql&lt;/code&gt; qui serviront aux différentes migrations de notre application. Nos scripts seront nommés de tels sortes que l&#39;on puisse automatiquement déterminer leur ordre d&#39;application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;conf/sql/postgres/0001-aggregates.sql&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregates&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;      &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_type&lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_version&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INTEGER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;CONSTRAINT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregates_pkey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;conf/sql/postgres/0002-aggregates_events.sql&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregate_events&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;   &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;event_id&lt;/span&gt;       &lt;span class=&quot;nb&quot;&gt;INTEGER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;event_type&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;event_data&lt;/span&gt;     &lt;span class=&quot;nb&quot;&gt;TEXT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;CONSTRAINT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregateevts_pkey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;CONSTRAINT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregateevts_fk1&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;FOREIGN&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;REFERENCES&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;INDEX&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregateevts_aggid&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregate_events&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aggregate_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Créons aussi un fichier d&#39;environement dans lequel on renseignera l&#39;emplacement des binaires de &lt;code&gt;postgres&lt;/code&gt; ainsi que les identifiants d&#39;un role de connexions ayant les droits de créer une base de données (dans la fenêtre &lt;strong&gt;propriétés&lt;/strong&gt; du rôle de connexion, onglet &lt;strong&gt;Droits du rôle&lt;/strong&gt;, cochez la cache &quot;Peux crééer des bases de données).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;conf/env-it.json&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;postgres_bin&amp;quot;&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Library/PostgreSQL/9.0/bin/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;postgres_user&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;integration&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;postgres_pass&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s2&quot;&gt;&amp;quot;1tegration&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;span class=&quot;label important&quot;&gt;Note importante&lt;/span&gt; sur &lt;code&gt;JSON.parse&lt;/code&gt;; La transformation d&#39;une chaîne de caractère au format JSON en son équivalent javascript a été douleureuse, en effet la méthode &lt;code&gt;JSON.parse&lt;/code&gt; est très stricte, et nécessite une syntaxe irréprochable. Voici les déboires, sous forme de tests, que nous avons subit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test/json_test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;JSON issue: key must be quoted&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;throws&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{ name : &amp;quot;mccallum&amp;quot; }&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;JSON issue: key cannot be quoted by single quote&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;throws&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{ &amp;#39;name&amp;#39; : \&amp;quot;mccallum\&amp;quot; }&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;JSON issue: value cannot be quoted by single quote&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;throws&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{ \&amp;quot;name\&amp;quot; : &amp;#39;mccallum&amp;#39; }&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Ce qui est interessant aussi à noter c&#39;est que dans notre approche, les tests servent aussi de terrain d&#39;expérimentation. Et si ceux-ci sont suffisament autonomes, nous pouvons les conserver à titre d&#39;exemple et de non regression sur les outils que nous utilisons à travers notre application.&lt;/p&gt;

&lt;p&gt;Via &lt;code&gt;pgAdmin / Fichier / Ouvrir .pgpass&lt;/code&gt; ajoutons les paramètres de connection de notre utilisateur afin que le mot de passe ne soit pas demandé en ligne de commande, notons l&#39;emplacement de ce fichier et éditons le comme suit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;localhost:5432:*:postgres:postgres
localhost:5432:*:integration:1tegration
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nous utiliserons principalement deux bases de données: &lt;code&gt;dropable_dbname&lt;/code&gt; et &lt;code&gt;persistent_dbname&lt;/code&gt;. La première base de données &lt;code&gt;dropable_dbname&lt;/code&gt; sera supprimée et recrée à chaque fois que les scripts de migration seront testés, afin de valider leurs syntaxes sur une base vierge. La seconde base de données &lt;code&gt;peristent_dbname&lt;/code&gt; quant à elle sera conservée, et considérée comme présente par nos tests.&lt;/p&gt;

&lt;h2&gt;&lt;strike&gt;Quart d&#39;heure&lt;/strike&gt; Soirées &lt;strike&gt;détente&lt;/strike&gt; explorations de l&#39;utilisation de Postgres en mode non bloquant&lt;/h2&gt;

&lt;p&gt;Afin de bien comprendre le fonctionement du module &lt;a href=&quot;https://github.com/brianc/node-postgres&quot;&gt;node-postgres&lt;/a&gt;, nous allons nous écarter quelque peu de notre application pour effectuer un &lt;a href=&quot;http://www.aubryconseil.com/post/2008/03/15/387-des-spikes-dans-les-sprints&quot;&gt;&lt;strong&gt;spike&lt;/strong&gt;&lt;/a&gt; sur l&#39;utilisation de ce module.&lt;/p&gt;

&lt;p&gt;En effet, généralement les requêtes sql sont effectuées de manière séquentiellement et bloquantes, c&#39;est à dire que l&#39;on attend (le fil d&#39;execution est en attente) que notre base de données ait renvoyé le résultat avant d&#39;enchainer avec la prochaine requête.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;create table creatures ( &lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    name CHARACTER VARYING(255) NOT NULL,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;    description TEXT&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// appel bloquant on attend la réponse avant de poursuivre&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert_sql&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;insert into creatures (name, desc) values (?,?)&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Korrigan&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Créature&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;légendaire&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;du&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;folklore&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;de&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bretagne&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;comparable&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;au&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;lutin&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;français&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Mary&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Morgan&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Fées&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;eau&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bretonnes&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;semblables&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;à&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;des&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;femmes&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;qui&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;partagent&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;la&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;symbolique&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;des&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;sirènes&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Il est en effet nécessaire d&#39;attendre que la table &lt;code&gt;creatures&lt;/code&gt; soit créée avant de pouvoir insérer des enregistrements. Le problème de cette approche est de monopoliser une partie des ressources de l&#39;application en attendant la réponse de notre base de données, le traitement est bloqué.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/brianc/node-postgres&quot;&gt;node-postgres&lt;/a&gt; propose une approche différente et un peu déroutante en prime abord. Lorsque la requête sql est soumise à la base de données, il est possible d&#39;y associer une fonction de rappel (&lt;code&gt;callback&lt;/code&gt;) qui sera invoquée lorsque le résultat de notre requête sera disponible. Pendant ce temps, l&#39;application continue son execution et n&#39;est pas bloquée à cette instruction.&lt;/p&gt;

&lt;p&gt;Reprenons l&#39;exemple précédent, celui-ci pourrait ainsi être transformée comme suit:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;postgres://&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_pass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;@localhost:5432/&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;insert_sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;insert into creatures (name, desc) values (?,?)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create_query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create table creatures ( ... )&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;     &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;insert1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Korrigan&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Créature ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;insert1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;         &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;insert2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Mary Morgan&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fées ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;         &lt;span class=&quot;nx&quot;&gt;insert2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;             &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;         &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt;       &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Ligne &lt;code&gt;5&lt;/code&gt;, la requête de création de la table est soumise au serveur, le serveur n&#39;a pas encore répondu que notre application continue de s&#39;executer. Nous enregistrons alors une fonction de rappel ligne &lt;code&gt;7&lt;/code&gt; qui sera invoquée lorsque notre création de table sera terminée (nous ne détaillons pas ici les gestions d&#39;erreurs).
Notre application poursuit alors son execution ligne &lt;code&gt;16&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Lorsque la table est créée, notre fonction de retour est invoquée, et nous poursuivons l&#39;execution de notre code ligne &lt;code&gt;8&lt;/code&gt;. Nous insérons alors notre première valeur, et pendant ce temps, enregistrons une nouvelle fonction de retour (ligne &lt;code&gt;9&lt;/code&gt;) qui sera appellée et nous permettra d&#39;enregistrer notre seconde valeur. Une fois la première valeur insérée, notre fonction sera invoquée, et notre seconde valeur insérée.&lt;/p&gt;

&lt;p&gt;Si l&#39;on regarde de plus près, on peux se rendre compte que seules nos insertions nécessitent d&#39;être effectuées après la création de la table. Dans notre exemple, il n&#39;est pas nécessaire que la seconde insertion ait lieu uniquement si la première a bien été réalisée.&lt;/p&gt;

&lt;p&gt;Nous pouvons donc modifier le code, afin d&#39;executer nos deux insertion de manière asynchrone. La difficulté est alors d&#39;être informé lorsque nos deux insertions ont été réalisées.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/brianc/node-postgres&quot;&gt;node-postgres&lt;/a&gt; nous indique:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Clients are responsible for creating Queries via the factory method Client#query.
The Client can create a new query before the client is connected to the server
or while other queries are executing.
Internally the Client maintains a queue of Query objects which are popped and
executed as the preceding Query completes.
When the Client&#39;s internal query queue is emptied, the Client raises the drain event.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;En s&#39;enregistrant sur l&#39;évènement &lt;code&gt;drain&lt;/code&gt;, il est donc possible d&#39;être informé lorsque toutes nos requêtes seront executées.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// s&amp;#39;assure que même si la `queue` est vide entre temps l&amp;#39;évènement &amp;#39;drain&amp;#39; &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ne sera pas déclenché&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pauseDrain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;drain&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create table creatures ( ... )&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;insert1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Korrigan&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Créature ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;insert2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Mary Morgan&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fées ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;insert2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// maintenant que nous avons effectué notre dernière requête sql,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// si la queue est vide cela signifie bien, que tout est fini&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// rendons possible le déclenchement de l&amp;#39;évènement &amp;#39;drain&amp;#39; &lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resumeDrain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Dans notre cas, les migrations doivent être séquentielles et une migration est conditionnée par la réussite de la précédente. La dernière approche n&#39;est donc pas directement envisageable. Tentons de rendre la première approche plus dynamique en chaînant les &lt;code&gt;on(&#39;end&#39;, function() ...)&lt;/code&gt; de manière recursive.&lt;/p&gt;

&lt;p&gt;Considérons que nos requêtes sql sont dans un tableau &lt;code&gt;statements&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;execute_stmts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;execute_stmts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Si les requêtes sont plus compliquées, au lieu de passer les requêtes SQL, appellons une fonction qui retournera la dernière &lt;code&gt;query&lt;/code&gt; qu&#39;elle aura soumise:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;execute_stmts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;execute_stmts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;avec par exemple&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Korrigan&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Créature ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Mary Morgan&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fées ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Histoire de valider nos connaissances, nous décidons d&#39;écrire un mini-gestionnaire de migration dans le style (mais en moins ambitieux) que &lt;a href=&quot;http://www.liquibase.org/&quot;&gt;Liquibase&lt;/a&gt; ou &lt;a href=&quot;http://code.google.com/p/flyway/&quot;&gt;Flyway&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Celui-ci est responsable d&#39;appliquer les migrations une par une et de conserver la liste des migrations effectuées avec succès. Cela peux paraître un peu compliqué, mais l&#39;experience montre qu&#39;une fois mis en place, ce type de système allège considérablement le travail du support, la remontée des erreurs lors de migration et la reprise sur erreur.&lt;/p&gt;

&lt;p&gt;Nous ajoutons donc une table &lt;code&gt;migrations&lt;/code&gt; qui conservera l&#39;ensemble des migrations qui ont été appliquées. Chaque migration pouvant être composée de plusieurs requêtes &lt;code&gt;sql&lt;/code&gt;, nous conserverons aussi l&#39;index de la dernière requête &lt;code&gt;sql&lt;/code&gt; passée avec succès.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;conf/sql/postgres/0000-migration.sql&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;migrations&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;migration_id&lt;/span&gt;       &lt;span class=&quot;nb&quot;&gt;CHARACTER&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;VARYING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;migration_sequence&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INTEGER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;migration_date&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;TIMESTAMP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;CONSTRAINT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;migrations_pkey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;migration_sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;La première version de notre outils de migration, après quelque refactorings, ressemble à:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;it/postres_migration_it.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;nutil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;util&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;exec&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;child_process&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;fs&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;pg&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;pg&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;utilities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;../lib/utilities&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;migration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;../lib/migration&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;settings_json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;__dirname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/../conf/env-it.json&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;settings_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;db_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dropable_dbname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;command_drop_db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_bin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;dropdb &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;db_name&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; -e&amp;quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//echo the commands&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; -U &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;command_create_db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_bin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;createdb &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;db_name&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; -e&amp;quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//echo the commands&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; -E UTF8&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; -O &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_user&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; -U &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;update_sequence&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Migration [&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;]: updating sequence&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&amp;quot;insert into migrations (migration_id, migration_sequence, migration_date) values($1, $2, $3)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Migration [&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;]: updating sequence &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;execute_statements&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stmt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Migration [&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;]: &amp;lt;&amp;lt;&amp;lt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stmt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;nx&quot;&gt;update_sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;nx&quot;&gt;execute_statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Migration [&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;]: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;execute_migration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;on_last_statement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Migration [&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;] #&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; statements&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// retrieve any previously migration sequence applied&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;start_index_query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;select count(*) from migrations where migration_id = $1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;start_index_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;row&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;execute_statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;on_last_statement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)();&lt;/span&gt;  
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;start_index_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations_table_missing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;utilities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;relation &amp;quot;migrations&amp;quot; does not exist&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;initial_migration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;0000&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// special case migration &amp;#39;0000&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;initial_migration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations_table_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Migration [&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;] &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;rollback&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Starting a new transaction&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;begin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;execute_statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;on_last_statement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//handle the error&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;execute_migrations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;once_last_migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_stmts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_last_migration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;begin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;begin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;on_last_statement&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;commit&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Migration [&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;] commited&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is_last_migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;nx&quot;&gt;once_last_migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;nx&quot;&gt;execute_migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;once_last_migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;    
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

        &lt;span class=&quot;nx&quot;&gt;execute_migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migration_stmts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;on_last_statement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;postgres://&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postgres_pass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;@localhost:5432/&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;migration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vendor_migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;postgres&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;migration_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;execute_migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Releasing connection&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create_db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;command_create_db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;stdout: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;stderr: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;exec error: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;executing migrations&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;migrate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// pkill -f &amp;#39;postgres: postgres &amp;lt;database&amp;gt;&amp;#39;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;command_drop_db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;stdout: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;does not exist&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;stderr: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;exec error: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;create_db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;la commande &lt;code&gt;exec(command_drop_db, ...&lt;/code&gt; lance une commande système (&lt;code&gt;shell&lt;/code&gt;) afin de supprimer notre base de données d&#39;intégration&lt;/li&gt;
&lt;li&gt;en cas de succès, la fonction &lt;code&gt;create_db()&lt;/code&gt; est alors invoquée, et elle-même lance une commande système pour créer notre base de données.&lt;/li&gt;
&lt;li&gt;en cas de succès, la fonction &lt;code&gt;migrate()&lt;/code&gt; est invoquée.&lt;/li&gt;
&lt;li&gt;la fonction &lt;code&gt;migrate()&lt;/code&gt; est le point de départ des appels récursifs afin de chainer les migrations uniquement en cas de succès (comme évoquer précédement). La fonction &lt;em&gt;recursive&lt;/em&gt; d&#39;execution des migrations est la fonction &lt;code&gt;execute_migrations&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;la fonction &lt;code&gt;execute_migrations&lt;/code&gt; est responsable d&#39;executer une migration donnée &lt;code&gt;execute_migration&lt;/code&gt; En cas de succès, la transaction courante est commitée et l&#39;execution de la prochain migration est invoquée de manière récursive.&lt;/li&gt;
&lt;li&gt;la fonction &lt;code&gt;execute_migration&lt;/code&gt; est chargée d&#39;executer les requêtes SQL composant le script de migration. Il commence tout d&#39;abord par recupérer l&#39;index de la dernière requête SQL executée avec succès et execute de manière récursive (&lt;code&gt;execute_statements&lt;/code&gt;) toutes les requêtes SQL manquantes à partir de cet index.&lt;/li&gt;
&lt;li&gt;Après chacune de ces requêtes la table &lt;code&gt;migrations&lt;/code&gt; est mise à jour afin de conserver l&#39;avancement de la migration pour les prochains essais.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;En partant d&#39;une base vierge, notre script test donc l&#39;intégralité de nos migrations.
Lançons le&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;node it/postgres_migration_it.js
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;La console affiche alors:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;stdout: DROP DATABASE nscrum_dropable_itdb&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

stderr: 
stdout: CREATE DATABASE nscrum_dropable_itdb OWNER integration ENCODING &lt;span class=&quot;s1&quot;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

stderr: 
executing migrations
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0000&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;#1 statements&lt;/span&gt;
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0000&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; relation &lt;span class=&quot;s2&quot;&gt;&amp;quot;migrations&amp;quot;&lt;/span&gt; does not exist
Starting a new transaction
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0000, 0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;CREATE TABLE migrations
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  migration_id       CHARACTER VARYING&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; NOT NULL,
  migration_sequence INTEGER NOT NULL,
  migration_date     TIMESTAMP NOT NULL,
  CONSTRAINT migrations_pkey PRIMARY KEY &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;migration_id,migration_sequence&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0000, 0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: updating sequence
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0000&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; commited
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0001&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;#1 statements&lt;/span&gt;
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0001, 0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;CREATE TABLE aggregates
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  aggregate_id      CHARACTER VARYING&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;36&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; NOT NULL,
  aggregate_type    CHARACTER VARYING&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; NOT NULL,
  aggregate_version INTEGER NOT NULL,
  CONSTRAINT aggregates_pkey PRIMARY KEY &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;aggregate_id&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0001, 0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: updating sequence
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0001&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; commited
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0002&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;#2 statements&lt;/span&gt;
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0002, 0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;CREATE TABLE aggregate_events
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  aggregate_id   CHARACTER VARYING&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;36&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; NOT NULL,
  event_id       INTEGER NOT NULL,
  event_type     CHARACTER VARYING&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; NOT NULL,
  event_data     TEXT, 
  CONSTRAINT aggregateevts_pkey PRIMARY KEY &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;aggregate_id, event_id&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;,
  CONSTRAINT aggregateevts_fk1  FOREIGN KEY &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;aggregate_id&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; REFERENCES aggregates&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;aggregate_id&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0002, 0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: updating sequence
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0002, 1&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;CREATE INDEX aggregateevts_aggid ON aggregate_events &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;aggregate_id&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0002, 1&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: updating sequence
Migration &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;0002&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; commited
Releasing connection&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;et le contenu de la table &lt;code&gt;migrations&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;migrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;table class=&quot;condensed-table&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;Sequence&lt;/th&gt;&lt;th&gt;Date&lt;/th&gt;&lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;&quot;0000&quot;&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;&quot;2011-10-18 12:22:05.774&quot;&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;&quot;0001&quot;&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;&quot;2011-10-18 12:22:05.788&quot;&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;&quot;0002&quot;&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;&quot;2011-10-18 12:22:05.803&quot;&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;&quot;0002&quot;&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;&quot;2011-10-18 12:22:05.806&quot;&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;On peux constater que la migration &quot;0002&quot; est bien décomposée en deux sous requêtes: création de la table et création de l&#39;index.&lt;/p&gt;

&lt;p&gt;Nous disposons finalement d&#39;un outil de migration et d&#39;un test d&#39;intégration nous permettant de le valider à chaque ajout de nouvelles migrations ou d&#39;édition de script.&lt;/p&gt;

&lt;p&gt;Dans notre prochain article, nous reviendrons au fonctionnel de notre projet et à la persistence de nos évènements. Nous créerons pour cela la classe qui modélisera notre &lt;code&gt;EventStore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Les sources de notre application à ce stade peuvent téléchargées &lt;a href=&quot;https://github.com/Arnauld/CQRS-Ramblings/zipball/savepoint-05.1-migrations&quot;&gt;ici&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>[T|B|D]DD par la pratique 4 - Backlog et Story</title>
   <link href="http://arnauld.github.com/tbd-in-practice/2011/12/11/TBD-DD-par-la-pratique-4-Backlog-Story.html"/>
   <updated>2011-12-11T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/tbd-in-practice/2011/12/11/TBD-DD-par-la-pratique-4-Backlog-Story</id>
   <content type="html">&lt;p&gt;Le &lt;code&gt;backlog&lt;/code&gt; est directement lié au projet par une relation 1-1: le backlog appartient à un projet et un projet ne possède qu&#39;un backlog. D&#39;un certain point de vue, le backlog existe fonctionnellement, mais créer une entité dédiée n&#39;apporte, à ce stade, pas grand chose: il s&#39;agit plus d&#39;un concept que l&#39;on qualifiera d&#39;affichage qu&#39;un besoin de persistence. Nous nous passerons donc de définir une entité dédiée au backlog.&lt;/p&gt;




&lt;p&gt;En revanche, une &lt;code&gt;story&lt;/code&gt; joue un rôle centrale (certain parle même de &lt;em&gt;ventrale&lt;/em&gt;) dans notre application. Les discussions de travail seront souvent centrées autour d&#39;une &lt;code&gt;story&lt;/code&gt; particulère, bien identifiée par son nom et sa description. Et même si une &lt;code&gt;story&lt;/code&gt; appartient à un projet, nous considérerons plutôt qu&#39;elle est liée à celui-ci, et qu&#39;elle constitue une entité à part entière.&lt;/p&gt;


&lt;p&gt;Rappelez-vous:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;En tant que &lt;strong&gt;membre de l&#39;équipe&lt;/strong&gt;, je peux créer de nouvelles entrées dans
le backlog du projet, si bien que les besoins fonctionnels de notre projet
pourront être récolter. Une &lt;code&gt;story&lt;/code&gt; sera définie par un titre, une description,
une évaluation en points de sa complexité, ainsi que sa valeur cliente &lt;code&gt;business value&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Transcrivons cela dans notre tests fonctionnels:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;specs/story_specs.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;vows&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;assert&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;../lib/story&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{8}/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;vows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Story&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addBatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;A new story&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;topic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;As a developer, I want to known NodeJS so that i increase my knowledge&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;nx&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;By learning NodeJS, the developer will be able to undestand its success&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

        &lt;span class=&quot;s1&quot;&gt;&amp;#39;should return an instance of Story&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;instanceOf&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

        &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have the specified name&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;As a developer, I want to known NodeJS so that i increase my knowledge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

        &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have the specified description&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;By learning NodeJS, the developer will be able to undestand its success&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

        &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have the specified complexity&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

        &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have the specified business value&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

        &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have a generated uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Export the Suite&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Créons aussi notre premier test unitaire:
&lt;code&gt;test/story_test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;../lib/story&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create return a new story&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Un petit tour sur notre console, c&#39;est bien rouge! Definissons notre classe &lt;code&gt;Story&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/story.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Story&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notre test unitaire devient vert, ainsi que le premier test fonctionnel.&lt;/p&gt;

&lt;p&gt;Passons rapidement, et ajoutons alors les tests unitaires suivants:
&lt;code&gt;test/story-test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;../lib/story&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{8}/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create return a new story&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create return a new story with the given name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create return a new story a generated uuid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new story must have an `events` method to retrieve its history&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new story must have a single `event` in its history&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new story must have a single `event` in its history of type &amp;#39;story_created&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;story_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Inspirons nous fortement de notre classe &lt;code&gt;Projet&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;notre classe &lt;code&gt;Story&lt;/code&gt; va hériter de &lt;code&gt;AggregateRoot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;nous ajoutons un évènement &lt;code&gt;StoryCreated&lt;/code&gt; définit comme suit:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;story_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;rajoutons le &lt;code&gt;event_handler&lt;/code&gt; correspondant à l&#39;évènement &lt;code&gt;story_created&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;et nous obtenons alors:&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;code&gt;lib/story.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;node-uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;aroot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./aggregate_root&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;nutil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;util&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;misc&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./utilities&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Events&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;story_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Story&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_story_created&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_desc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_complexity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_business_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_desc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;nutil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aroot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;misc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; 
        &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;La bonne nouvelle c&#39;est que tous nos tests passent. La mauvaise nouvelle c&#39;est que le caractère obligatoire
du nom de la &lt;code&gt;Story&lt;/code&gt; et de l&#39;identifiant du projet ne sont pas du tout vérifiés.
Enrichissons nos tests afin de combler ce manque:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test/story_test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new story must have a &amp;#39;name&amp;#39; and a &amp;#39;project_id&amp;#39; specified&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;throws&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new story must have a &amp;#39;project_id&amp;#39; specified&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;throws&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new story must have a &amp;#39;name&amp;#39; specified&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;throws&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Modifions alors notre &lt;code&gt;Story&lt;/code&gt; afin d&#39;ajouter les vérifications voulues:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Missing story&amp;#39;s &amp;lt;project_id&amp;gt;!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Missing story&amp;#39;s &amp;lt;name&amp;gt;!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;complexity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;business_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;et la, hourra nos tests passent... enfin les nouveaux... parce que les anciens sont tous rouges: il manque le &lt;code&gt;project_id&lt;/code&gt; dans la plupart. Une fois ajouté dans tous ces tests, ils passent tous, eh eh!&lt;/p&gt;

&lt;p&gt;Compte-tenu de tout ce que nous avons pu voir jusqu&#39;ici, nous passons rapidement sur l&#39;ajout des méthodes &lt;code&gt;rename&lt;/code&gt;, &lt;code&gt;changeDescription&lt;/code&gt;, &lt;code&gt;changeComplexity&lt;/code&gt; et &lt;code&gt;changeBusinessValue&lt;/code&gt;. Pour chacune de ces méthodes, nous definissons les évènements respectifs suivant: &lt;code&gt;StoryRenamed&lt;/code&gt;, &lt;code&gt;StoryDescriptionChanged&lt;/code&gt;, &lt;code&gt;StoryComplexityChanged&lt;/code&gt; et &lt;code&gt;StoryBusinessValueChanged&lt;/code&gt;. De la même manière que pour la classe &lt;code&gt;Projet&lt;/code&gt;, nous ajoutons la méthode &lt;code&gt;load_from_history&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Faisons une petite pause et revenons quelques instants sur notre modélisation. Voici les étapes (d&#39;un point de vue technique) pour la création d&#39;un &lt;code&gt;Project&lt;/code&gt; et l&#39;ajout de &lt;code&gt;Story&lt;/code&gt; à celui-ci:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;my_app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;MyApplication&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story01&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;my_app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;As a team member, i want to navigate through all the stories of my project.&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;[TODO] méthode story.create est dissociée du projet, et a été ramenée au minimum d&#39;informations requises c&#39;est à dire le &lt;code&gt;project.uuid&lt;/code&gt; ... un &lt;code&gt;project&lt;/code&gt; peux compter plusieurs milliers de &lt;code&gt;story&lt;/code&gt; dans son &lt;code&gt;backlog&lt;/code&gt; c&#39;est pourquoi contrairement à une approche &lt;em&gt;classique&lt;/em&gt; nous ne souhaitons pas faire porter directement par le projet l&#39;intégralité des &lt;code&gt;story&lt;/code&gt; qui y sont rattaché, en d&#39;autre terme nous évitons d&#39;introduire une relation navigable et bidirectionnelle entre ces deux entités.&lt;/p&gt;

&lt;h3&gt;Et les commentaires?&lt;/h3&gt;

&lt;blockquote&gt;&lt;p&gt;En tant que &lt;strong&gt;membre de l&#39;équipe&lt;/strong&gt;, je peux completer une entrée du backlog
en modifiant ses informations ou en ajoutant un commentaire, si bien que
cette entrée disposera de plus amples informations à mesure des reflexions
qu&#39;elle peux suciter.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Définissions dans un premier temps notre test fonctionnel correspondant à la création d&#39;un commentaire.&lt;/p&gt;

&lt;p&gt;La difficulté qui apparait désormais est de vérifier que notre commentaire a bien été ajouté. En effet, si l&#39;on prévoit que le nombre de commentaire peut être conséquent, il est peu probable que nous les conservions tous en mémoire. Ceci nous amène au point suivant: la persistence de nos données. Le soucis que nous voyons avec nos commentaires est en fait déjà présents à travers l&#39;historique de nos entités, devons-nous conserver l&#39;intégralité des évènements en mémoire? La réponse est bien évidemment non! Nous ne devrions conserver en mémoire sur nos entités uniquement les données qui ont une importance métier pour assurer son intégrité à tout instant. Dans ce cas, pourquoi conserver sur une &lt;code&gt;Story&lt;/code&gt;, sa &lt;code&gt;description&lt;/code&gt;, sa &lt;code&gt;business value&lt;/code&gt; et sa &lt;code&gt;complexity&lt;/code&gt; ? Et bien tout simplement parce dans un premier temps, nous ne disposons pas d&#39;autre moyen de vérifier ces valeurs, et que d&#39;autre par il ne devrait pas s&#39;agir d&#39;une consommation mémoire trop importante, en effet il est peu probable que le nom d&#39;un &lt;code&gt;Story&lt;/code&gt; excède les centaines de caractères, et que sa description (même en html) ne soient beaucoup plus importante qu&#39;une page de texte. Il est donc raisonable dans un premier de temps de conserver ces valeurs directement sur l&#39;entité.&lt;/p&gt;

&lt;p&gt;D&#39;autre part, l&#39;intégralité de l&#39;historique de nos entités est lui aussi conservé en mémoire, il va donc falloir remédier à cela aussi. Mais chaque chose en son temps. Plutôt que de conserver les commentaires en mémoires, nous travaillerons sur l&#39;historique directement, et vérifierons que le commentaire est bien présent parmis les évènements de notre entité. Ainsi, lorsque la persistence de l&#39;historique sera résolu, nos commentaires le seront aussi.&lt;/p&gt;

&lt;p&gt;Et c&#39;est la que l&#39;on peux commencer à sentir la souplesse de notre modélisation par évènement: pour ajouter de nouvelles informations ou de nouveaux comportements, nous nous &lt;em&gt;contentons&lt;/em&gt; de rajouter de nouveaux types d&#39;évènements.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;specs/story_specs.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Story&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;topic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cafebabe-3550&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;As a developer, I want to known NodeJS so that i increase my knowledge&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;can be improved by adding comment on it&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CONTENT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;NodeJS looks promising, not only for application but also as a tool to test and learn javascipt&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CONTENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;last_event&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;story_comment_added&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CONTENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;On pourra noter l&#39;ajout de la méthode &lt;code&gt;last_event&lt;/code&gt; sur notre classe &lt;code&gt;AggregateRoot&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/aggregate_root.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// public methods&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// returns &amp;#39;undefined&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// returns &amp;#39;undefined&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Quelques tests unitaires notre &lt;code&gt;Story&lt;/code&gt; est modifiée comme suit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/story.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCommentAdded&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;story_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;story_comment_added&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;content&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;StoryCommentAdded&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCommentAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Story&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_story_comment_added&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;   
    
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;add_comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StoryCommentAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Les sources de notre application à ce stade peuvent téléchargées &lt;a href=&quot;https://github.com/Arnauld/CQRS-Ramblings/zipball/savepoint-04.1-backlog&amp;amp;story&quot;&gt;ici&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;Etats des lieux&lt;/h3&gt;

&lt;p&gt;Dans l&#39;état, notre application permet de&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;créer un &lt;code&gt;Project&lt;/code&gt; et modifier son nom&lt;/li&gt;
&lt;li&gt;créer des &lt;code&gt;Story&lt;/code&gt; rattachées à un projet, modifier leurs descriptions et rajouter des commentaires&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Il nous manque encore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;la gestion des équipes, leurs membres et le rôle de chacun&lt;/li&gt;
&lt;li&gt;la création d&#39;un sprint, et des &lt;code&gt;Task&lt;/code&gt; qui lui sont attachées&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Par conséquent, notre P.O. (&lt;code&gt;Product Owner&lt;/code&gt;) peux dès à présent commencer à enregistrer et préparer les &lt;code&gt;Story&lt;/code&gt; qui viendront plutard alimenter notre &lt;code&gt;Sprint&lt;/code&gt;. Euh... en fait non, notre P.O. ne peux pas le faire et ce pour plusieurs raisons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Il ne dispose pas d&#39;interface utilisateur pour le faire&lt;/li&gt;
&lt;li&gt;Aucune persistence n&#39;est encore assurée&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Nos prochaines étapes consisteront donc remplir ces deux conditions afin que l&#39;on puisse commencer le plutôt possible la saisie des &lt;code&gt;Story&lt;/code&gt; de notre projet.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>La sélection de décembre</title>
   <link href="http://arnauld.github.com/blog/2011/12/11/December-links-selection.html"/>
   <updated>2011-12-11T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2011/12/11/December-links-selection</id>
   <content type="html">&lt;h2&gt;Coding styles&lt;/h2&gt;
&lt;p&gt;So real&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.dodgycoder.net/2011/11/yoda-conditions-pokemon-exception.html&quot;&gt;&amp;#8216;Yoda Conditions&amp;#8217;, &amp;#8216;Pokémon Exception Handling&amp;#8217; and other programming classics&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Web design&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Twitter bootstrap&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Bootstrap is a toolkit from Twitter designed to kickstart development of webapps and sites. It includes base &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; for typography, forms, buttons, tables, grids, navigation, and more.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Twitter bootstrap&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;h2&gt;Event, &lt;span class=&quot;caps&quot;&gt;CQRS&lt;/span&gt;, high-scalability&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://highscalability.com/blog/2011/11/29/datasift-architecture-realtime-datamining-at-120000-tweets-p.html&quot;&gt;DataSift Architecture: Realtime Datamining At 120,000 Tweets Per Second&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://highscalability.com/blog/2011/11/14/using-gossip-protocols-for-failure-detection-monitoring-mess.html&quot;&gt;Using Gossip Protocols For Failure Detection, Monitoring, Messaging And Other Good Things&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.xebia.fr/2011/12/02/kafka/&quot; title=&quot;Xebia-fr&quot;&gt;Kafka&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://krasserm.blogspot.com/2011/11/building-event-sourced-web-application.html&quot;&gt;Building an Event-Sourced Web Application &amp;#8211; Part 1: Domain Model, Events and State&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.wmrichards.com/amqp.pdf&quot;&gt;Understanding the differences between &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; &amp;amp; &lt;span class=&quot;caps&quot;&gt;JMS&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.octo.com/en/complex-event-processing/&quot;&gt;Complex Event Processing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.octo.com/cqrs-larchitecture-aux-deux-visages-partie-1/&quot; title=&quot;partie 1&quot;&gt;&lt;span class=&quot;caps&quot;&gt;CQRS&lt;/span&gt;, l’architecture aux deux visages&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span class=&quot;caps&quot;&gt;DDD&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://dddcommunity.org/library/vernon_2011&quot;&gt;Effective Aggregate Design by Vaughn Vernon&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://dddcommunity.org/sites/default/files/pdf_articles/Vernon_2011_1.pdf&quot;&gt;Effective Aggregate Design by Vaughn Vernon &amp;#8211; Part 1&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://dddcommunity.org/sites/default/files/pdf_articles/Vernon_2011_2.pdf&quot;&gt;Effective Aggregate Design by Vaughn Vernon &amp;#8211; Part 2&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://www.cftl.de/index.php?id=78&quot;&gt;Test-Driven Development: un pacte diabolique ?&lt;/a&gt;&lt;br /&gt;
Traduction de &lt;em&gt;Test-Driven Development A Faustian Bargain&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;Ou comment faire l&amp;#8217;amalgame entre un outil de travail et un process de développement. Le &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;&lt;/em&gt; n&amp;#8217;est pas une méthode de gestion de projet et encore moins une méthode pour diriger ou concevoir un projet de bout en bout. Le &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;&lt;/em&gt; est un outil, parmis d&amp;#8217;autre, pour la phase d&amp;#8217;implémentation et ne se substitue pas à des phases de design, d&amp;#8217;analyse et de conception plus globale de l&amp;#8217;application.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/#!/nmartignole/status/142497996641280000&quot;&gt;Réaction @nmartignole&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://twitter.com/#!/BodySplash/status/142250558286340096&quot;&gt;Réaction @BodySplash&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Response to "Technical Job Interview Questions for Java EE architects"</title>
   <link href="http://arnauld.github.com/blog/2011/12/10/Technical-Job-Interview-Questions-for-Java-EE-architects.html"/>
   <updated>2011-12-10T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2011/12/10/Technical-Job-Interview-Questions-for-Java-EE-architects</id>
   <content type="html">&lt;div class=&quot;toc&quot;&gt;
&lt;h2&gt;Table of content&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#database&quot;&gt;Database systems&lt;/a&gt;&lt;p
&gt;&lt;a href=&quot;#heuristic-exceptions&quot;&gt;What are heuristic exceptions?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#acid&quot;&gt;What does &lt;span class=&quot;caps&quot;&gt;ACID&lt;/span&gt; mean?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#base&quot;&gt;What does &lt;span class=&quot;caps&quot;&gt;BASE&lt;/span&gt; mean?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#isolation-level&quot;&gt;What are isolation levels?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#hibernate-cache&quot;&gt;What kind of caches are there in Hibernate &lt;span class=&quot;caps&quot;&gt;ORM&lt;/span&gt;?&lt;/a
&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#modelling&quot;&gt;Modelling and Coding&lt;/a&gt;&lt;p
&gt;&lt;a href=&quot;#anemic&quot;&gt;What are anemic domain models?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#solid&quot;&gt;What are the &lt;span class=&quot;caps&quot;&gt;SOLID&lt;/span&gt; principles?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#code-gen&quot;&gt;What code generation tools do you know?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#dsl&quot;&gt;Which ways of creating your own DSLs do you know?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#uml&quot;&gt;Which &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; diagram types do you know?&lt;/a
&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jvm&quot;&gt;Java VM&lt;/a&gt;&lt;p
&gt;&lt;a href=&quot;#gc-collector&quot;&gt;What kind of garbage collectors are there in Java 6?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#gc-generation&quot;&gt;What is the generational hypothesis concerning garbage collection?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#lock&quot;&gt;What kind of locks in the Java VM do you know?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#mutex-semaphore&quot;&gt;What is the difference between a mutex and a semaphore and similiar questions?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#jvm-language&quot;&gt;What are the most important languages running on a Java VM?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#monitoring&quot;&gt;What monitoring tools do you know?&lt;/a
&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jee&quot;&gt;Java EE&lt;/a&gt;&lt;p
&gt;&lt;a href=&quot;#jee-tech&quot;&gt;What are the most important technologies / specifications in Java EE 6?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#weld&quot;&gt;What is Weld?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#web-framework&quot;&gt;Which Java web frameworks do you know?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#jee-async&quot;&gt;Which ways of making asynchronous calls within a Java EE 6 server do you know?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#web-async&quot;&gt;Which ways of asynchronous communication between web browsers and web servers do you know?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#perf-web&quot;&gt;What are the most important performance issues in Java web applications? &lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#perf-jee&quot;&gt;What are the most important performance issues in Java EE server applications?&lt;/a
&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#distributed-computing&quot;&gt;Distributed Computing&lt;/a&gt;&lt;p
&gt;&lt;a href=&quot;#esb&quot;&gt;What are the advantages and disadvantages of ESBs?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#cap&quot;&gt;What is the &lt;span class=&quot;caps&quot;&gt;CAP&lt;/span&gt; theorem?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#terracotta&quot;&gt;What is Terracotta used for?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#token-bucket&quot;&gt;What is the token bucket algorithm? &lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#rest&quot;&gt;What is &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; used for? What are the advantages and disadvantages?&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#amdahl-law&quot;&gt;What is Amdahls Law? What is Gustafson&amp;#8217;s Law?&lt;/a
&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#other-topics&quot;&gt;Additional topics and tools&lt;/a&gt;&lt;p
&gt;&lt;a href=&quot;#security&quot;&gt;Security&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#tools&quot;&gt;Tools&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#programming-models&quot;&gt;Programming models&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#java-libraries&quot;&gt;Java libraries&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#java-utilities&quot;&gt;Java utilities&lt;/a
&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#lectures&quot;&gt;Recommended Lectures to go further&lt;/a&gt;&lt;p
&gt;&lt;a href=&quot;#lectures-general&quot;&gt;General&lt;/a
&gt; &amp;#8212; &lt;a href=&quot;#lectures-concurrency&quot;&gt;Concurrency&lt;/a
&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/div&gt;
&lt;p&gt;Here is some answers from the questions raised in the article : &lt;a href=&quot;http://java.dzone.com/articles/technical-job-interview&quot;&gt;Technical Job Interview Questions for Java EE architects&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Most answers are quotes taken from various documentations or articles. Links are provided for further informations. Quotes will be a lot more understandable than a translation of what is in my head on this subject.&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;database&quot;&gt;&lt;/a&gt;Database systems&lt;/h2&gt;
&lt;p&gt;First, i strongly encourage you to read the ebook &lt;em&gt;&lt;strong&gt;Java Transaction design strategies&lt;/strong&gt;&lt;/em&gt; available on &lt;a href=&quot;http://infoq.com/books/JTDS&quot;&gt;InfoQ&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;heuristic-exceptions&quot;&gt;&lt;/a&gt;What are heuristic exceptions?&lt;/h3&gt;
&lt;blockquote&gt;&lt;h5&gt;4.1.3. The two-phase XA protocol&lt;/h5&gt;&lt;p&gt;When a transaction is about to be committed, it is the responsibility of the transaction manager to ensure that either all of it is committed, or that all of is rolled back. If only a single recoverable resource is involved in the transaction, the task of the transaction manager is simple: It just has to tell the resource to commit the changes to stable storage.&lt;/p&gt;
&lt;p&gt;When more than one recoverable resource is involved in the transaction, management of the commit gets more complicated. Simply asking each of the recoverable resources to commit changes to stable storage is not enough to maintain the atomic property of the transaction. The reason for this is that if one recoverable resource has committed and another fails to commit, part of the transaction would be committed and the other part rolled back.&lt;/p&gt;
&lt;p&gt;To get around this problem, the two-phase XA protocol is used. The XA protocol involves an extra prepare phase before the actual commit phase. Before asking any of the recoverable resources to commit the changes, the transaction manager asks all the recoverable resources to prepare to commit. When a recoverable resource indicates it is prepared to commit the transaction, it has ensured that it can commit the transaction. The resource is still able to rollback the transaction if necessary as well.&lt;/p&gt;
&lt;p&gt;So the first phase consists of the transaction manager asking all the recoverable resources to prepare to commit. If any of the recoverable resources fails to prepare, the transaction will be rolled back. But if all recoverable resources indicate they were able to prepare to commit, the second phase of the XA protocol begins. This consists of the transaction manager asking all the recoverable resources to commit the transaction. Because all the recoverable resources have indicated they are prepared, this step cannot fail.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://docs.jboss.org/jbossas/admindevel326/html/ch4.chapt.html#d0e8337&quot;&gt;Chapter 4. Transactions on JBoss&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;h5&gt;4.1.4. Heuristic exceptions&lt;/h5&gt;&lt;p&gt;In a distributed environment communications failures can happen. If communication between the transaction manager and a recoverable resource is not possible for an extended period of time, the recoverable resource may decide to unilaterally commit or rollback changes done in the context of a transaction. Such a decision is called a heuristic decision. It is one of the worst errors that may happen in a transaction system, as it can lead to parts of the transaction being committed while other parts are rolled back, thus violating the atomicity property of transaction and possibly leading to data integrity corruption.&lt;/p&gt;
&lt;p&gt;Because of the dangers of heuristic exceptions, a recoverable resource that makes a heuristic decision is required to maintain all information about the decision in stable storage until the transaction manager tells it to forget about the heuristic decision. The actual data about the heuristic decision that is saved in stable storage depends on the type of recoverable resource and is not standardized. The idea is that a system manager can look at the data, and possibly edit the resource to correct any data integrity problems.&lt;/p&gt;
&lt;p&gt;There are several different kinds of heuristic exceptions defined by the &lt;span class=&quot;caps&quot;&gt;JTA&lt;/span&gt;. The javax.transaction.HeuristicCommitException is thrown when a recoverable resource is asked to rollback to report that a heuristic decision was made and that all relevant updates have been committed. On the opposite end is the javax.transaction.HeuristicRollbackException, which is thrown by a recoverable resource when it is asked to commit to indicate that a heuristic decision was made and that all relevant updates have been rolled back.&lt;/p&gt;
&lt;p&gt;The javax.transaction.HeuristicMixedException is the worst heuristic exception. It is thrown to indicate that parts of the transaction were committed, while other parts were rolled back. The transaction manager throws this exception when some recoverable resources did a heuristic commit, while other recoverable resources did a heuristic rollback.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://docs.jboss.org/jbossas/admindevel326/html/ch4.chapt.html#d0e8348&quot;&gt;Chapter 4. Transactions on JBoss&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;acid&quot;&gt;&lt;/a&gt;What does &lt;span class=&quot;caps&quot;&gt;ACID&lt;/span&gt; mean?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;Atomicity:&lt;/b&gt; A transaction must be atomic. This means that either all the work done in the transaction must be performed, or none of it must be performed. Doing part of a transaction is not allowed.&lt;br/&gt;To be compliant with the &amp;#8216;A&amp;#8217;, a system must guarantee the atomicity in each and every situation, including power failures / errors / crashes.&lt;br/&gt;
This guarantees that &amp;#8216;an incomplete transaction&amp;#8217; cannot exist.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Consistency:&lt;/b&gt; When a transaction is completed, the system must be in a stable and consistent condition.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Isolation:&lt;/b&gt; Different transactions must be isolated from each other. This means that the partial work done in one transaction is not visible to other transactions until the transaction is committed, and that each process in a multi-user system can be programmed as if it was the only process accessing the system.&lt;br/&gt;
In other words, it should not be possible that two transactions affect the same rows run concurrently, as the outcome would be unpredicted and the system thus made unreliable.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Durability:&lt;/b&gt; The changes made during a transaction are made persistent when it is committed. When a transaction is committed, its changes will not be lost, even if the server crashes afterwards.&lt;br/&gt;
In other words, every committed transaction is protected against power loss/crash/errors and cannot be lost by the system and can thus be guaranteed to be completed.&lt;br/&gt;
In a relational database, for instance, once a group of &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; statements execute, the results need to be stored permanently. If the database crashes right after a group of &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; statements execute, it should be possible to restore the database state to the point after the last transaction committed.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://docs.jboss.org/jbossas/admindevel326/html/ch4.chapt.html#d0e8259&quot;&gt;Chapter 4. Transactions on JBoss&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://en.wikipedia.org/wiki/ACID&quot;&gt;Wikipedia&lt;/a&gt;&lt;br /&gt;
&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a name=&quot;base&quot;&gt;&lt;/a&gt;What does &lt;span class=&quot;caps&quot;&gt;BASE&lt;/span&gt; mean?&lt;/h3&gt;
&lt;p&gt;Probably a word game from chemistry &lt;a href=&quot;http://en.wikipedia.org/wiki/Acid%E2%80%93base_reaction&quot;&gt;Acid-base reaction&lt;/a&gt; remember your &lt;a href=&quot;http://en.wikipedia.org/wiki/PH&quot;&gt;pH&lt;/a&gt; courses&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;BASE&lt;/span&gt; stands for &lt;em&gt;Basically Available, Soft state, Eventual consistency.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Eventual consistency is one of the consistency models used in the domain of parallel programming, for example in distributed shared memory, distributed transactions, and optimistic replication, it means that given a sufficiently long period of time over which no changes are sent, all updates can be expected to propagate eventually through the system and all the replicas will be consistent. While some authors use that definition (e.g. Vogels), others prefer a stronger definition that requires good things to happen even in the presence of continuing updates, reconfigurations, or failures. In the Terry et al. work referenced above, eventual consistency means that for a given accepted update and a given replica, eventually, either the update reaches the replica, or the replica retires from service.&lt;br/&gt;
In database terminology, this is known as &lt;span class=&quot;caps&quot;&gt;BASE&lt;/span&gt; (Basically Available, Soft state, Eventual consistency), as opposed to the database concept of &lt;span class=&quot;caps&quot;&gt;ACID&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Eventual_consistency&quot;&gt;Wikipedia&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;See also: &lt;a href=&quot;http://www.allthingsdistributed.com/2008/12/eventually_consistent.html&quot; title=&quot;By Werner Vogels&quot;&gt;Eventually Consistent &amp;#8211; Revisited&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;isolation-level&quot;&gt;&lt;/a&gt;What are isolation levels?&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;Read Uncommited&lt;/code&gt;: It is the lowest isolation level. It allows transactions to read non-committed updates made by other transactions prior to those updates being committed to the database.&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;Read Committed&lt;/code&gt;: It allows multiple transactions to access to the same data, but hides non-committed updates from other transactions until they are committed.&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;Repeatable Read&lt;/code&gt;: It keeps all transactions isolated from one another. It ensures that once a set of values is read from the database within a particular transaction, that same set of values will be read every time they are re-queried.&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;Serializable&lt;/code&gt;: It is the highest and most strict level of isolation. It ensures only one transaction is allowed access to the data at a time, other transactions are &amp;#8220;stacked&amp;#8221; until the completion of the current transaction.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More details there: &lt;a href=&quot;http://www.postgresql.org/docs/9.1/static/transaction-iso.html&quot;&gt;Postgresql 9.1 &amp;#8211; Transaction Isolation&lt;/a&gt;, you should especially read about the three phenomena:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Dirty read&lt;/strong&gt;: A transaction reads data written by a concurrent uncommitted transaction.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Nonrepeatable read&lt;/strong&gt;: A transaction re-reads data it has previously read and finds that data has been modified by another transaction (that committed since the initial read).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Phantom read&lt;/strong&gt;: A transaction re-executes a query returning a set of rows that satisfy a search condition and finds that the set of rows satisfying the condition has changed due to another recently-committed transaction.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.postgresql.org/docs/9.1/static/transaction-iso.html&quot;&gt;Postgresql 9.1 &amp;#8211; Transaction Isolation&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;hibernate-cache&quot;&gt;&lt;/a&gt;What kind of caches are there in Hibernate &lt;span class=&quot;caps&quot;&gt;ORM&lt;/span&gt;?&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#architecture-overview-terms&quot;&gt;First level cache&lt;/a&gt;: Session cache&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#performance-cache&quot;&gt;Second level cache&lt;/a&gt;: &lt;quote&gt;Cache of data that is reusable between transactions at a process or cluster level. You can even plug in a clustered cache. Be aware that caches are not aware of changes made to the persistent store by another application.&lt;/quote&gt;. Cache provider should provide replication feature when used in cluster environement (e.g. &lt;a href=&quot;http://ehcache.org/documentation/replication/rmi-replicated-caching&quot;&gt;ehCache replication&lt;/a&gt;).&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#performance-querycache&quot;&gt;Query cache&lt;/a&gt;: &lt;quote&gt;Query result sets can also be cached. This is only useful for queries that are run frequently with the same parameters.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.mchange.com/projects/c3p0/index.html#configuring_statement_pooling&quot;&gt;C3PO statement pooling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Three must read articles:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://blog.dynatrace.com/2009/02/16/understanding-caching-in-hibernate-part-one-the-session-cache/&quot;&gt;Understanding Caching in Hibernate – Part One : The Session Cache&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://blog.dynatrace.com/2009/02/16/understanding-caching-in-hibernate-part-two-the-query-cache/&quot;&gt;Understanding Caching in Hibernate – Part Two : The Query Cache&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://blog.dynatrace.com/2009/03/24/understanding-caching-in-hibernate-part-three-the-second-level-cache/&quot;&gt;Understanding Caching in Hibernate – Part Three : The Second Level Cache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally keep in mind (an underused behavior) that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8230; if you are processing a huge number of objects and need to manage memory efficiently, the &lt;code&gt;evict()&lt;/code&gt; method can be used to remove the object and its collections from the first-level cache.&lt;/p&gt;
&lt;p&gt;&amp;#8230; To evict all objects from the session cache, call &lt;code&gt;Session.clear()&lt;/code&gt;&lt;br /&gt;
For the second-level cache, there are methods defined on &lt;code&gt;SessionFactory&lt;/code&gt; for evicting the cached state of an instance, entire class, collection instance or entire collection role.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-sessioncache&quot;&gt;Managing the caches&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;&lt;a name=&quot;modelling&quot;&gt;&lt;/a&gt;Modelling and Coding&lt;/h2&gt;
&lt;p&gt;I strongly suggests once this part has been read, to learn also about:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/minibooks/domain-driven-design-quickly&quot;&gt;Domain Driven Design&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://martinfowler.com/bliki/CQRS.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;CQRS&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://martinfowler.com/eaaDev/EventSourcing.html&quot;&gt;Event Sourcing&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://dannorth.net/introducing-bdd/&quot;&gt;Behavior Driven Development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;anemic&quot;&gt;&lt;/a&gt;What are anemic domain models?&lt;/h3&gt;
&lt;p&gt;Basically a &lt;span class=&quot;caps&quot;&gt;POJO&lt;/span&gt; without any behavior only data.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://martinfowler.com/bliki/AnemicDomainModel.html&quot;&gt;Martin Fowler &amp;#8211; Anemic Domain Model&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;It mmust be opposed to &lt;a href=&quot;http://martinfowler.com/eaaCatalog/domainModel.html&quot;&gt;Domain Model&lt;/a&gt; or DDD&amp;#8217;s &amp;#8220;Entity&amp;#8221;, where &lt;span class=&quot;caps&quot;&gt;DDD&lt;/span&gt; stands for Domain Driven Design.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;solid&quot;&gt;&lt;/a&gt;What are the &lt;span class=&quot;caps&quot;&gt;SOLID&lt;/span&gt; principles?&lt;/h3&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;SOLID&lt;/span&gt; stands for &lt;b&gt;S&lt;/b&gt;ingle responsibility, &lt;b&gt;O&lt;/b&gt;pen-closed, &lt;b&gt;L&lt;/b&gt;iskov substitution, &lt;b&gt;I&lt;/b&gt;nterface segregation and &lt;b&gt;D&lt;/b&gt;ependency inversion.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Single Responsibility Principle: A class should have one, and only one, reason to change.&lt;/li&gt;
	&lt;li&gt;Open Closed Principle: You should be able to extend a classes behavior, without modifying it.&lt;/li&gt;
	&lt;li&gt;Liskov Substitution Principle: Derived classes must be substitutable for their base classes.&lt;/li&gt;
	&lt;li&gt;Interface Segregation Principle: Make fine grained interfaces that are client specific.&lt;/li&gt;
	&lt;li&gt;Dependency Inversion Principle: Depend on abstractions, not on concretions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod&quot;&gt;Uncle Bob &amp;#8211; The Principles of &lt;span class=&quot;caps&quot;&gt;OOD&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Check also the following principles:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt; (&lt;a href=&quot;http://www.artima.com/intv/dry.html&quot;&gt;Don&amp;#8217;t Repeat Yourself&lt;/a&gt;),&lt;/li&gt;
	&lt;li&gt;&lt;a name=&quot;kiss-principle&quot;&gt;&lt;/a&gt;&lt;span class=&quot;caps&quot;&gt;KISS&lt;/span&gt; (&lt;a href=&quot;http://people.apache.org/~fhanik/kiss.html&quot;&gt;Keep it simple, Stupid!&lt;/a&gt;)&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;YAGNI&lt;/span&gt; (&lt;a href=&quot;http://c2.com/cgi/wiki?YouArentGonnaNeedIt&quot;&gt;You ain&amp;#8217;t gonna need it&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;code-gen&quot;&gt;&lt;/a&gt;What code generation tools do you know? &lt;small&gt;Which ones did you use?&lt;/small&gt;&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.eclipse.org/modeling/emf/docs/&quot;&gt;Eclipse &lt;span class=&quot;caps&quot;&gt;EMF&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;JEF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.eclipse.org/Xtext/&quot;&gt;Eclipse Xtext/Xtend&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.antlr.org&quot;&gt;Antlr&lt;/a&gt; / &lt;a href=&quot;http://www.stringtemplate.org/&quot;&gt;StringTemplates&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://velocity.apache.org/engine/releases/velocity-1.7/&quot;&gt;Velocity&lt;/a&gt; / &lt;a href=&quot;http://freemarker.sourceforge.net/&quot;&gt;Freemarker&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;JSP&lt;/span&gt;&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;dsl&quot;&gt;&lt;/a&gt;Which ways of creating your own DSLs do you know? &lt;small&gt;Which ones did you use?&lt;/small&gt;&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://martinfowler.com/bliki/FluentInterface.html&quot;&gt;Fluent interface&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://groovy.codehaus.org/Writing+Domain-Specific+Languages&quot;&gt;Groovy &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.antlr.org&quot;&gt;Antlr&lt;/a&gt; / Code Generation&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.eclipse.org/Xtext/&quot;&gt;Xtext&lt;/a&gt; is an amazing project, it allows to quickly create a language with its corresponding Eclipse editor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://martinfowler.com/bliki/DomainSpecificLanguage.html&quot;&gt;Martin Fowler &amp;#8211; &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://debasishg.blogspot.com/search/label/dsl&quot;&gt;Debasish Ghosh (author of DSL in action)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For advanced user who wants to create &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt;, i recommend the lectures of:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/tpdsl/language-implementation-patterns&quot;&gt;Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/tpantlr/the-definitive-antlr-reference&quot;&gt;Antlr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;uml&quot;&gt;&lt;/a&gt;Which &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; diagram types do you know? &lt;small&gt;What are &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; stereotypes? What are &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; color standards?&lt;/small&gt;&lt;/h3&gt;
&lt;p&gt;Depending on the organization, it is not necessary to know all about &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt;, just the essential diagrams and convention. For me essentials diagrams are: &lt;strong&gt;class diagram&lt;/strong&gt; / &lt;strong&gt;sequence diagram&lt;/strong&gt; / &lt;strong&gt;activity diagram&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Stereotype is an extension feature allowing to &amp;#8220;tag&amp;#8221; element with a special semantic e.g. an element could be tagged &amp;laquo;Repository&amp;raquo;, &amp;laquo;Entity&amp;raquo;, &amp;laquo;&lt;span class=&quot;caps&quot;&gt;DTO&lt;/span&gt;&amp;raquo;&amp;#8230;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;A stereotype is one of three types of extensibility mechanisms in the Unified Modeling Language (&lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt;). They allow designers to extend the vocabulary of &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; in order to create new model elements, derived from existing ones, but that have specific properties that are suitable for a particular problem domain or otherwise specialized usage.&lt;/p&gt; &lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Stereotype_(UML)&quot;&gt;Wikipedia&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For a nice introduction and to learn what is really necessary read Martin Fowler &lt;a href=&quot;http://martinfowler.com/books.html#uml&quot;&gt;Distilled &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; 3rd Ed.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;#8217;t even known &lt;span class=&quot;caps&quot;&gt;UML&lt;/span&gt; have colors! Here is a &lt;a href=&quot;http://en.wikipedia.org/wiki/UML_colors&quot;&gt;link to them&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;jvm&quot;&gt;&lt;/a&gt;Java VM&lt;/h2&gt;
&lt;p&gt;I must admit i had to read some articles and documentation about garbage collection to have a more precise knowledge of the terms and the type of collectors.&lt;/p&gt;
&lt;p&gt;For a simple introduction read &lt;a href=&quot;http://www.azulsystems.com/sites/www.azulsystems.com/SpringOne2011_UnderstandingGC.pdf&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AZUL&lt;/span&gt; &amp;#8211; Understanding GC&lt;/a&gt; and for a deeper understanding &lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html&quot;&gt;Java SE 6 HotSpot&amp;#8482; Virtual Machine Garbage Collection Tuning&lt;/a&gt;&lt;br /&gt;
You might also read the &lt;a href=&quot;http://www.memorymanagement.org/&quot;&gt;The Memory Management Reference&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;gc-collector&quot;&gt;&lt;/a&gt;What kind of garbage collectors are there in Java 6? &lt;small&gt;What are the differences? Which ones are usually used for Java EE applications? How can you find out which garbage collector should be used for a Java EE application?&lt;/small&gt;&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;A Concurrent Collector&lt;/strong&gt; performs garbage collection work concurrently with the application’s own execution&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;A Parallel Collector&lt;/strong&gt; uses multiple CPUs to perform garbage collection&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;A Stop-the-World collector&lt;/strong&gt; performs garbage collection while the application is completely stopped&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;An Incremental collector&lt;/strong&gt; performs a garbage collection operation or phase as a series of smaller discrete operations with (potentially long) gaps in between&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Mostly&lt;/strong&gt; means sometimes it isn’t (usually means a different fall back mechanism exists)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mark &amp;amp; Sweep // Compact // Copy:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Mark&lt;/strong&gt;
	&lt;ul&gt;
		&lt;li&gt;Start from &amp;#8220;roots&amp;#8221; (thread stacks, statics, etc.)&lt;/li&gt;
		&lt;li&gt;&amp;#8220;Paint&amp;#8221; anything you can reach as &amp;#8220;live&amp;#8221;&lt;/li&gt;
		&lt;li&gt;At the end of a mark pass:
		&lt;ul&gt;
			&lt;li&gt;all reachable objects will be marked &amp;#8220;live&amp;#8221;&lt;/li&gt;
			&lt;li&gt;all non-reachable objects will be marked “dead” (aka &amp;#8220;non-live&amp;#8221;)&lt;/li&gt;
		&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Sweep&lt;/strong&gt;
	&lt;ul&gt;
		&lt;li&gt;Scan through the heap, identify &amp;#8220;dead&amp;#8221; objects and track them somehow&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Compact&lt;/strong&gt;
	&lt;ul&gt;
		&lt;li&gt;Over time, heap will get &amp;#8220;swiss cheesed&amp;#8221;: contiguous dead space between objects may not be large enough to ﬁt new objects (aka &amp;#8220;fragmentation&amp;#8221;)&lt;/li&gt;
		&lt;li&gt;Compaction moves live objects together to reclaim contiguous empty space (aka &amp;#8220;relocate&amp;#8221;)&lt;/li&gt;
		&lt;li&gt;Compaction has to correct all object references to point to new object locations (aka &amp;#8220;remap&amp;#8221;)&lt;/li&gt;
		&lt;li&gt;Remap scan must cover all references that could possibly point to relocated objects&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Copy&lt;/strong&gt;
	&lt;ul&gt;
		&lt;li&gt;Copying collector moves all lives objects from a &amp;#8220;from&amp;#8221; space to a &amp;#8220;to&amp;#8221; space &amp;amp; reclaims &amp;#8220;from&amp;#8221; space&lt;/li&gt;
		&lt;li&gt;At start of copy, all objects are in &amp;#8220;from&amp;#8221; space and all references point to &amp;#8220;from&amp;#8221; space.&lt;/li&gt;
		&lt;li&gt;Start from &amp;#8220;root&amp;#8221; references, copy any reachable object to &amp;#8220;to&amp;#8221; space, correcting references as we go&lt;/li&gt;
		&lt;li&gt;At End of copy, all objects are in &amp;#8220;to&amp;#8221; space, and all references point to &amp;#8220;to&amp;#8221; space&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Available Collectors:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;The serial collector&lt;/b&gt; uses a single thread to perform all garbage collection work, which makes it relatively efficient since there is no communication overhead between threads. It is best-suited to single processor machines, since it cannot take advantage of multiprocessor hardware, although it can be useful on multiprocessors for applications with small data sets (up to approximately 100MB). The serial collector is selected by default on certain hardware and operating system configurations, or can be explicitly enabled with the option -XX:+UseSerialGC.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The parallel collector (also known as the throughput collector)&lt;/b&gt; performs minor collections in parallel, which can significantly reduce garbage collection overhead. It is intended for applications with medium- to large-sized data sets that are run on multiprocessor or multi-threaded hardware. The parallel collector is selected by default on certain hardware and operating system configurations, or can be explicitly enabled with the option -XX:+UseParallelGC.&lt;br/&gt;
New: parallel compaction is a feature introduced in J2SE 5.0 update 6 and enhanced in Java SE 6 that allows the parallel collector to perform major collections in parallel. Without parallel compaction, major collections are performed using a single thread, which can significantly limit scalability. Parallel compaction is enabled by adding the option -XX:+UseParallelOldGC to the command line.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The concurrent collector&lt;/b&gt; performs most of its work concurrently (i.e., while the application is still running) to keep garbage collection pauses short. It is designed for applications with medium- to large-sized data sets for which response time is more important than overall throughput, since the techniques used to minimize pauses can reduce application performance. The concurrent collector is enabled with the option -XX:+UseConcMarkSweepGC.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#available_collectors&quot;&gt;Java SE 6 HotSpot&amp;#8482; Virtual Machine Garbage Collection Tuning&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;Selecting a Collector:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unless your application has rather strict pause time requirements, first run your application and allow the VM to select a collector. If necessary, adjust the heap size to improve performance. If the performance still does not meet your goals, then use the following guidelines as a starting point for selecting a collector.&lt;/p&gt;
&lt;p&gt;If the application has a small data set (up to approximately 100MB), then select the serial collector with -XX:+UseSerialGC.&lt;/p&gt;
&lt;p&gt;If the application will be run on a single processor and there are no pause time requirements, then let the VM select the collector, or select the serial collector with -XX:+UseSerialGC.&lt;/p&gt;
&lt;p&gt;If (a) &lt;em&gt;peak application performance is the first priority&lt;/em&gt; and (b) &lt;em&gt;there are no pause time requirements or pauses of one second or longer are acceptable&lt;/em&gt;, then let the VM select the collector, or select the parallel collector with -XX:+UseParallelGC and (optionally) enable parallel compaction with -XX:+UseParallelOldGC.&lt;/p&gt;
&lt;p&gt;If response time is more important than overall throughput and garbage collection pauses must be kept shorter than approximately one second, then&lt;br /&gt;
select the concurrent collector with -XX:+UseConcMarkSweepGC. If only one or two processors are available, consider using incremental mode, described below.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#available_collectors.selecting&quot;&gt;Java SE 6 HotSpot&amp;#8482; Virtual Machine Garbage Collection Tuning&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;More informations there: &lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html&quot;&gt;Java SE 6 HotSpot&amp;#8482; Virtual Machine Garbage Collection Tuning&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;gc-generation&quot;&gt;&lt;/a&gt;What is the generational hypothesis concerning garbage collection?&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;A generation is a set of objects which have similar expected lifetimes.&lt;/li&gt;
	&lt;li&gt;Objects are gathered together in generations.&lt;/li&gt;
	&lt;li&gt;The heap is divided into generations so that it is possible to eliminate most of the garbage by looking at only a small fraction of the heap.&lt;/li&gt;
	&lt;li&gt;The collector can promote objects into older generations as they survive successive collection cycles.&lt;/li&gt;
	&lt;li&gt;New objects are usually allocated in the youngest or nursery generation, but if we know that particular objects will be long-lived, we might want to allocate them directly in an older generation.&lt;/li&gt;
	&lt;li&gt;Objects within a generation are all roughly the same age.&lt;/li&gt;
	&lt;li&gt;Higher-numbered generations indicate areas of the heap with older objects—those objects are much more likely to be stable.&lt;/li&gt;
	&lt;li&gt;Objects in older generations are condemned less frequently, saving &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; time.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Generational Hypothesis: most objects die young&lt;/li&gt;
	&lt;li&gt;Focus collection efforts on young generation&lt;/li&gt;
	&lt;li&gt;Generally based on a copy collector&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&amp;#8230; memory is managed in generations, or memory pools holding objects of different ages. Garbage collection occurs in each generation when the generation fills up. The vast majority of objects are allocated in a pool dedicated to young objects (the young generation), and most objects die there. When the young generation fills up it causes a minor collection in which only the young generation is collected; garbage in other generations is not reclaimed. Minor collections can be optimized assuming the weak generational hypothesis holds and most objects in the young generation are garbage and can be reclaimed. The costs of such collections are, to the first order, proportional to the number of live objects being collected; a young generation full of dead objects is collected very quickly. Typically some fraction of the surviving objects from the young generation are moved to the tenured generation during each minor collection. Eventually, the tenured generation will fill up and must be collected, resulting in a major collection, in which the entire heap is collected. Major collections usually last much longer than minor collections because a significantly larger number of objects are involved.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#generations&quot;&gt;Java SE 6 HotSpot&amp;#8482; Virtual Machine Garbage Collection Tuning&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;lock&quot;&gt;&lt;/a&gt;What kind of locks in the Java VM do you know?&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;synchronized&lt;/code&gt; keyword&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;ReentrantLock&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;ReadWriteLock&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;CyclicBarrier&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;CountDownLatch&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;Semaphore&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;All kind of &lt;code&gt;BlockingQueue&lt;/code&gt; could also be used as lock in a certain manner&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Check for more information in the corresponding packages: &lt;a href=&quot;http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/package-frame.html&quot;&gt;java.util.concurrent package&lt;/a&gt; and &lt;a href=&quot;http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/package-frame.html&quot;&gt;java.util.concurrent.locks package&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;Concurency &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;AND&lt;/span&gt;&lt;/strong&gt; Parallelism should be high topic with today multi-core systems, i strongly recommend to have a look at the followings:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.ibm.com/developerworks/java/library/j-5things4/index.html&quot;&gt;5 things you didn&amp;#8217;t know about &amp;#8230; java.util.concurrent, Part 1&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.ibm.com/developerworks/java/library/j-5things5/index.html&quot;&gt;5 things you didn&amp;#8217;t know about &amp;#8230; java.util.concurrent, Part 2&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601&quot;&gt;Java Concurrency in Practice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;mutex-semaphore&quot;&gt;&lt;/a&gt;What is the difference between a mutex and a semaphore and similiar questions?&lt;/h3&gt;
&lt;p&gt;Mutexes and semaphores are very similar, with the only significant difference being that semaphores can count higher than one.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html&quot;&gt;Lock&lt;/a&gt; can be viewed as a Mutex implementation in java, and more specifically &lt;a href=&quot;http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html&quot;&gt;ReentrantLock&lt;/a&gt;. Whereas only the &amp;#8220;Write lock&amp;#8221; of the &lt;a href=&quot;http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html&quot;&gt;ReadWriteLock&lt;/a&gt; is a mutex.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Mutexes are typically used to serialise access to a section of  re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Symbian Developer Library&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;p&gt;A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore).&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Symbian Developer Library&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;p&gt;Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it. Each release() adds a permit, potentially releasing a blocking acquirer.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Semaphore.html&quot;&gt;Semaphore &lt;span class=&quot;caps&quot;&gt;JDK&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A nice story to explain the difference &lt;a href=&quot;http://koti.mbnet.fi/niclasw/MutexSemaphore.html&quot;&gt;The Toilet Example&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;jvm-language&quot;&gt;&lt;/a&gt;What are the most important languages running on a Java VM? &lt;small&gt;Which ones did you use? What are their advantages and disadvantages?&lt;/small&gt;&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://groovy.codehaus.org/&quot;&gt;Groovy&lt;/a&gt;: for scripting purpose and some &lt;a href=&quot;http://grails.org/&quot;&gt;Grails&lt;/a&gt; simple applications.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://mvel.codehaus.org/&quot;&gt;Mvel&lt;/a&gt;: simple expression language similar to &lt;span class=&quot;caps&quot;&gt;OGNL&lt;/span&gt; but a lot faster&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.scala-lang.org/&quot;&gt;Scala&lt;/a&gt; for personnal use only, love the compacity, expressiveness and scalability of the language such as the actor stack added by &amp;#8220;Akka&amp;#8221;. It mixes both procedural and functionnal approach, and allow a switch for one approach to another smoothly. I really think it can replace Java as the mainstream &lt;span class=&quot;caps&quot;&gt;JVM&lt;/span&gt; language, evolution are less tied to the &lt;span class=&quot;caps&quot;&gt;JVM&lt;/span&gt; version. Developper is free to choose the scala version he wants to use, simply compile and drop the corresponding jars. Dislike the &lt;span class=&quot;caps&quot;&gt;ASCII&lt;/span&gt; art that emerge for some &amp;#8220;elite coders&amp;#8221;.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt;: never used it, but i should really take a look at it. At least for a better knowledge and way of thinking of &amp;#8220;lisp&amp;#8221;-like language.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.ruby-lang.org/en/&quot;&gt;Ruby&lt;/a&gt; through &lt;a href=&quot;http://jruby.org/&quot;&gt;JRuby&lt;/a&gt; really interesting approach of meta-programming and flexibility. Really easy for day-to-day programming and utilities (see &lt;a href=&quot;http://pragprog.com/book/bmsft/everyday-scripting-with-ruby&quot;&gt;Everyday Scripting with Ruby: for Teams, Testers, and You&lt;/a&gt;). Ever body should take a look at least one day to &lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Rails&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://python.org/&quot;&gt;Python&lt;/a&gt; through &lt;a href=&quot;http://www.jython.org/&quot;&gt;Jython&lt;/a&gt; a single try through the scripting of &lt;a href=&quot;http://grinder.sourceforge.net/&quot;&gt;Grinder&lt;/a&gt; a java load testing framework. I still prefer ruby to python.&lt;/li&gt;
	&lt;li&gt;Javascript through &lt;a href=&quot;http://www.mozilla.org/rhino/&quot;&gt;Rhino&lt;/a&gt;. Javascript is an important language nowadays and shouldn&amp;#8217;t be neglected anymore. &lt;a href=&quot;http://nodejs.org/&quot;&gt;NodeJS&lt;/a&gt; offers a great playground to learn and use javascript without the browser approach. Whereas it is essential in web front end, it also offers a nice scripting environement for server side scripting.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See a more complete list of available &lt;span class=&quot;caps&quot;&gt;JVM&lt;/span&gt; languages &lt;a href=&quot;http://en.wikipedia.org/wiki/List_of_JVM_languages&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note also that two &lt;strong&gt;big&lt;/strong&gt; new languages have appeared recently:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://confluence.jetbrains.net/display/Kotlin/Welcome&quot;&gt;kotlin&lt;/a&gt; by &lt;a href=&quot;http://jetbrains.com/&quot;&gt;JetBrains&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://ceylon-lang.org/&quot;&gt;ceylon&lt;/a&gt; by &lt;a href=&quot;http://www.redhat.com/&quot;&gt;Red Hat&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I strongly recommend every programmer to read the &lt;a href=&quot;http://pragprog.com/book/btlang/seven-languages-in-seven-weeks&quot;&gt;Seven languages in seven weeks&lt;/a&gt; book.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;monitoring&quot;&gt;&lt;/a&gt;What monitoring tools do you know? &lt;small&gt;Which ones did you use in production?&lt;/small&gt;&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://java.sun.com/developer/technicalArticles/J2SE/jmx.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;JMX&lt;/span&gt;&lt;/a&gt; in production too&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://visualvm.java.net&quot;&gt;VisualVM&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Log file analysis // Addition of probes in Code manually or through &lt;a href=&quot;http://www.eclipse.org/aspectj/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AOP&lt;/span&gt;&lt;/a&gt;: in production too&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.ej-technologies.com/products/jprofiler/overview.html&quot;&gt;JProfiler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a name=&quot;jee&quot;&gt;&lt;/a&gt;Java EE&lt;/h2&gt;
&lt;p&gt;I am not fan of the &amp;#8216;EE&amp;#8217; and &amp;#8216;application server&amp;#8217; approach, and really prefer lightweight approach such as spring and web server like &lt;a href=&quot;http://tomcat.apache.org/&quot;&gt;tomcat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Furthermore alternate approach such as &lt;a href=&quot;http://www.playframework.org/&quot;&gt;Play!&lt;/a&gt; is rising and allow really more flexibility, emergent design and up-to-date techniques.&lt;/p&gt;
&lt;p&gt;Remember the &lt;a href=&quot;#kiss-principle&quot;&gt;&amp;#8220;&lt;span class=&quot;caps&quot;&gt;KISS&lt;/span&gt;&amp;#8221;&lt;/a&gt; principle above.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&amp;#8230; the biggest problem is the complexity of IT. If you look at any IT in business, it is so complex it hinders the ability to be agile and efficient. Throughout the history of IT we all have said that we will make it simpler by adding more things to it, but that makes it more and more complex.&lt;br /&gt;
IT departments spend 75% to 85% of their budgets just to keep existing IT environments running; that leaves little capacity for innovation&lt;/p&gt;
&lt;p&gt;(&amp;#8230;)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;What&amp;#8217;s the biggest technology mistake you ever made &amp;#8211; either at work or in your own life?&lt;/b&gt;&lt;br/&gt;
When I was at &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt;, I started a product called Websphere [which helps companies to operate and integrate business applications across multiple computing platforms].&lt;br/&gt;
Because I had come from working on big mission-critical systems, I thought it needs to be scalable, reliable, have a single point of control &amp;#8230; I tried to build something like a mainframe, a system that was capable of doing anything, that would be able to do what might be needed in five years.&lt;br/&gt;
I call it the endgame fallacy. It was too complex for people to master. I overdesigned it.&lt;br/&gt;
Because we were &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt;, we survived it, but if we&amp;#8217;d been a start-up, we&amp;#8217;d have gone to the wall.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.bbc.co.uk/news/business-11944966&quot;&gt;The mantra of CA Technologies&amp;#8217; Donald Ferguson: Simplify&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;jee-tech&quot;&gt;&lt;/a&gt;What are the most important technologies / specifications in Java EE 6?&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Servlet 3.0 and annotation based configuration
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#startAsync(javax.servlet.ServletRequest, javax.servlet.ServletResponse)&quot;&gt;Asynchronous&lt;/a&gt; processing support&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;CDI&lt;/span&gt; think of &lt;a href=&quot;http://code.google.com/p/google-guice/&quot;&gt;Guice&lt;/a&gt; or &lt;a href=&quot;http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html&quot;&gt;Spring &lt;span class=&quot;caps&quot;&gt;IOC&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;JPA&lt;/span&gt; think of &lt;a href=&quot;http://www.hibernate.org/&quot;&gt;Hibernate&lt;/a&gt; as standard implementation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://www.theserverside.com/news/1363662/Java-EE-6-Overview&quot;&gt;Java EE 6 &amp;#8211; Overview&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;weld&quot;&gt;&lt;/a&gt;What is Weld?&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;Weld is the reference implementation (RI) for &lt;a href=&quot;http://jcp.org/en/jsr/detail?id=299&quot;&gt;&lt;span class=&quot;caps&quot;&gt;JSR&lt;/span&gt;-299&lt;/a&gt; : &lt;em&gt;&lt;strong&gt;Java Contexts and Dependency Injection for the Java EE platform (&lt;span class=&quot;caps&quot;&gt;CDI&lt;/span&gt;)&lt;/strong&gt;&lt;/em&gt;. &lt;span class=&quot;caps&quot;&gt;CDI&lt;/span&gt; is the Java standard for dependency injection and contextual lifecycle management, led by Gavin King for Red Hat, Inc. and is a Java Community Process (&lt;span class=&quot;caps&quot;&gt;JCP&lt;/span&gt;) specification that integrates cleanly with the Java EE platform. Any Java EE 6-compliant application server provides support for &lt;span class=&quot;caps&quot;&gt;JSR&lt;/span&gt;-299 (even the web profile).&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://seamframework.org/Weld&quot;&gt;Weld Home&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Think of it as an embedded &amp;#8220;Spring &lt;span class=&quot;caps&quot;&gt;IOC&lt;/span&gt;&amp;#8221;.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;web-framework&quot;&gt;&lt;/a&gt;Which Java web frameworks do you know? &lt;small&gt;What are their advantages and disadvantages?&lt;/small&gt;&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Struts 1 &amp;amp; 2&lt;/li&gt;
	&lt;li&gt;Spring &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;GWT&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;Grails&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;JSF&lt;/span&gt; / Tapestry / Stripes / Wicket : heard of them only&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;jee-async&quot;&gt;&lt;/a&gt;Which ways of making asynchronous calls within a Java EE 6 server do you know?&lt;/h3&gt;
&lt;p&gt;Only read about it: &lt;a href=&quot;http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#startAsync(javax.servlet.ServletRequest, javax.servlet.ServletResponse)&quot;&gt;Asynchronous&lt;/a&gt; processing support.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;web-async&quot;&gt;&lt;/a&gt;Which ways of asynchronous communication between web browsers and web servers do you know?&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Ajax_(programming)&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Comet_(programming)&quot;&gt;Comet or long polling&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.html5rocks.com/en/tutorials/eventsource/basics/&quot;&gt;Event Source&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.html5rocks.com/en/tutorials/websockets/basics/&quot;&gt;Web sockets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;perf-web&quot;&gt;&lt;/a&gt;What are the most important performance issues in Java web applications?&lt;/h3&gt;
&lt;p&gt;I don&amp;#8217;t think main issues are Java related, but are Web related.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Browser still in &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; 1.0&lt;/li&gt;
	&lt;li&gt;Page loading time / Response time&lt;/li&gt;
	&lt;li&gt;Javascript poor performance on some browser&lt;/li&gt;
	&lt;li&gt;Almost no asynchronous feedback for processing: usually blocking call only&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A really powerfull tool to measure such issues: &lt;a href=&quot;http://code.google.com/intl/fr-FR/speed/page-speed/&quot;&gt;Page Speed, the Web Performance Tool and Apache module&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Read some of them here &lt;a href=&quot;http://blog.dynatrace.com/2011/11/23/top-8-performance-problems-on-top-50-retail-sites-before-black-friday/&quot;&gt;Top 8 Performance Problems on Top 50 Retail Sites before Black Friday&lt;/a&gt; and here &lt;a href=&quot;http://blog.dynatrace.com/2010/08/25/top-10-client-side-performance-problems-in-web-2-0/&quot;&gt;Top 10 Client-Side Performance Problems in Web 2.0&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;perf-jee&quot;&gt;&lt;/a&gt;What are the most important performance issues in Java EE server applications?&lt;/h3&gt;
&lt;p&gt;humm&amp;#8230; same as above i guess&lt;/p&gt;
&lt;p&gt;The usage of &lt;strong&gt;Websphere&lt;/strong&gt; may also a notable performance issue&amp;#8230;&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;distributed-computing&quot;&gt;&lt;/a&gt;Distributed Computing&lt;/h2&gt;
&lt;p&gt;I strongly recommend the read of the following articles &lt;a href=&quot;http://horicky.blogspot.com/2009/11/nosql-patterns.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;NOSQL&lt;/span&gt; Patterns&lt;/a&gt; and &lt;a href=&quot;http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html&quot;&gt;Scalable System Design Patterns&lt;/a&gt; in order to grab all the required keywords and basis of distributed database and scalability.&lt;/p&gt;
&lt;p&gt;It would also be a good idea to have a general knowledge of &lt;a href=&quot;http://en.wikipedia.org/wiki/Event-driven_architecture&quot;&gt;Event Driven Architecture&lt;/a&gt; (a really interesting article with many links &lt;a href=&quot;http://elegantcode.com/2010/01/06/event-driven-architecture-publishing-events-using-an-ioc-container/&quot;&gt;Event Driven Architecture: Publishing Events using an &lt;span class=&quot;caps&quot;&gt;IOC&lt;/span&gt; container&lt;/a&gt;) and &lt;a href=&quot;http://en.wikipedia.org/wiki/Message-oriented_middleware&quot;&gt;Message-oriented middleware&lt;/a&gt; (pick at least one of &lt;a href=&quot;http://www.amqp.org/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt;&lt;/a&gt; or &lt;a href=&quot;http://xmpp.org/xmpp-protocols/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;XMPP&lt;/span&gt;&lt;/a&gt;, i would suggest to not spend so much time on &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_Message_Service&quot;&gt;&lt;span class=&quot;caps&quot;&gt;JMS&lt;/span&gt;&lt;/a&gt; since it is strongly tied to java platform).&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;SOA&lt;/span&gt; 2.0 event-driven programming is structured around the concept of decoupled relationships between event producers and event consumers: an event consumer doesn&amp;#8217;t care where or why an event occurs; rather, it&amp;#8217;s concerned that it will be invoked when the event has occurred. Systems and applications that separate event producers from event consumers typically rely on an event dispatcher, or channel. This channel contains an event queue that acts as an intermediary between event producers and event handlers.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Event-driven_SOA&quot;&gt;Wikipedia &amp;#8211; Event-driven &lt;span class=&quot;caps&quot;&gt;SOA&lt;/span&gt;&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;Finally have a look at &amp;#8220;Enterprise Integration Patterns&amp;#8221; &lt;a href=&quot;http://www.eaipatterns.com/&quot;&gt;site&lt;/a&gt; and &lt;strong&gt;read&lt;/strong&gt; the &lt;a href=&quot;http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683&quot;&gt;book&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Presentation on the subject (i&amp;#8217;ve not seen it yet) &lt;a href=&quot;http://www.infoq.com/presentations/Messaging-for-Modern-Applications&quot;&gt;Messaging for Modern Applications&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;esb&quot;&gt;&lt;/a&gt;What are the advantages and disadvantages of ESBs? &lt;small&gt;Which ESBs do you know? Which ones did you use?&lt;/small&gt;&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve never used one of them, and i only know the theory around. &lt;a href=&quot;http://www.amazon.com/Enterprise-Service-Bus-Theory-Practice/dp/0596006756&quot;&gt;Enterprise Service Bus&lt;/a&gt; is a great book on such subject.&lt;/p&gt;
&lt;p&gt;Have a look to the following article for an introduction of their usage:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.ibm.com/developerworks/webservices/library/ws-esbscen/&quot;&gt;Understand Enterprise Service Bus scenarios and solutions in Service-Oriented Architecture, Part 1&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.ibm.com/developerworks/webservices/library/ws-esbscen2/&quot;&gt;Understand Enterprise Service Bus scenarios and solutions in Service-Oriented Architecture, Part 2&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.ibm.com/developerworks/webservices/library/ws-esbscen3/&quot;&gt;Understand Enterprise Service Bus scenarios and solutions in Service-Oriented Architecture, Part 3&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;cap&quot;&gt;&lt;/a&gt;What is the &lt;span class=&quot;caps&quot;&gt;CAP&lt;/span&gt; theorem? &lt;small&gt;(Now that&amp;#8217;s quite important)&lt;/small&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;CAP&lt;/span&gt; theorem is becomming known due to the increase hype around NoSQL database.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;the &lt;span class=&quot;caps&quot;&gt;CAP&lt;/span&gt; theorem, also known as Brewer&amp;#8217;s theorem, states that it is impossible for a distributed computer system to simultaneously provide all three of the following guarantees:&lt;br /&gt;
* &lt;strong&gt;Consistency&lt;/strong&gt; (all nodes see the same data at the same time)&lt;br /&gt;
* &lt;strong&gt;Availability&lt;/strong&gt; (a guarantee that every request receives a response about whether it was successful or failed)&lt;br /&gt;
* &lt;strong&gt;Partition tolerance&lt;/strong&gt; (the system continues to operate despite arbitrary message loss)&lt;br /&gt;
According to the theorem, a distributed system can satisfy any two of these guarantees at the same time, but not all three.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/CAP_theorem&quot;&gt;Wikipedia&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Read more here: &lt;a href=&quot;http://en.wikipedia.org/wiki/CAP_theorem&quot;&gt;Brewers &lt;span class=&quot;caps&quot;&gt;CAP&lt;/span&gt; Theorem&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;terracotta&quot;&gt;&lt;/a&gt;What is Terracotta used for?&lt;/h3&gt;
&lt;p&gt;Distributed VM with shared memory through datagraph of objects.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.terracotta.org/&quot;&gt;Terracota&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I recommend to have a look to it when it is required to have really big &lt;span class=&quot;caps&quot;&gt;JVM&lt;/span&gt;. But don&amp;#8217;t forget that hidding the underlying distributed infrastructure may have some bad drawbacks afterwards. I usually prefer to be aware that i&amp;#8217;m acting on a local object or a remote one.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;token-bucket&quot;&gt;&lt;/a&gt;What is the token bucket algorithm?&lt;/h3&gt;
&lt;p&gt;Humm&amp;#8230; never heard about it. Let&amp;#8217;s do some research.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The token bucket is an algorithm used in packet switched computer networks and telecommunications networks to check that data transmissions conform to defined limits on bandwidth and burstiness&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Token_bucket&quot;&gt;Wikipedia&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8230; ok&amp;#8230; may be not really &lt;strong&gt;Software&lt;/strong&gt; but more &lt;strong&gt;Network&lt;/strong&gt; consideration.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s continue:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The algorithm can be conceptually understood as follows:&lt;br /&gt;
A token is added to the bucket every 1 / r seconds.&lt;br /&gt;
The bucket can hold at the most b tokens. If a token arrives when the bucket is full, it is discarded.&lt;br /&gt;
When a packet (network layer &lt;span class=&quot;caps&quot;&gt;PDU&lt;/span&gt;) of n bytes arrives, n tokens are removed from the bucket, and the packet is sent to the network.&lt;br /&gt;
If fewer than n tokens are available, no tokens are removed from the bucket, and the packet is considered to be non-conformant.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Token_bucket&quot;&gt;Wikipedia&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt; Essentially, token bucket algorithms are metering engines that keep track of how much traffic can be sent to conform to the specified traffic rates. A token permits the algorithm to send a single bit (or, in some cases, a byte) of traffic. These tokens are granted at the beginning of some time increment, typically every second, according to the specified rate referred to as the committed information rate (&lt;span class=&quot;caps&quot;&gt;CIR&lt;/span&gt;). The &lt;span class=&quot;caps&quot;&gt;CIR&lt;/span&gt; is the access bit rate contracted with a service provider or the service level to be maintained.&lt;br /&gt;
For example, if the &lt;span class=&quot;caps&quot;&gt;CIR&lt;/span&gt; is set to 8000 bps, then 8000 tokens are placed in a “bucket” at the beginning of the time period. (Note that this description represents a simplified view of the algorithm and might not be strictly true in all cases, but it illustrates the general operation of the policing mechanism.) &lt;br /&gt;
Each time a bit of traffic is offered to the policer, the bucket is checked for tokens. If there are tokens in the bucket, the traffic is passed. One token is removed from the bucket for each bit of traffic that is passed. Therefore, traffic is viewed to conform the rate, and the specified action for conforming traffic is taken. (Typically, the conforming traffic is transmitted.) When the bucket runs out of tokens, any additional offered traffic is viewed to exceed the rate, and the exceed action is taken. (The exceeding traffic typically either is re-marked or is dropped.)&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://my.safaribooksonline.com/book/networking/network-management/1587051761/policing-and-shaping-tools/ch04lev1sec1&quot;&gt;End-to-End QoS Network Design &amp;#8211; Safari book&lt;/a&gt;&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.juniper.net/techpubs/en_US/junos/topics/concept/policer-algorithm-single-token-bucket.html&quot;&gt;Single Token Bucket Algorithm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;rest&quot;&gt;&lt;/a&gt;What is &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; used for? What are the advantages and disadvantages?&lt;/h3&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; is a so big subject, it would be hard to explain fully here. I strongly recommend to read the book &lt;a href=&quot;http://www.amazon.com/Restful-Web-Services-Leonard-Richardson/dp/0596529260&quot;&gt;Restful Web Services&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An really nice introduction here : &lt;a href=&quot;http://tomayko.com/writings/rest-to-my-wife&quot;&gt;How I Explained &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; to My Wife&lt;/a&gt;&lt;br /&gt;
A more technological approach there &lt;a href=&quot;http://www.ibm.com/developerworks/webservices/library/ws-restful&quot;&gt;RESTful Web services: The basics&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some of the main ideas behind &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Rely on and exploit &lt;code&gt;HTTP&lt;/code&gt; protocol&lt;/li&gt;
	&lt;li&gt;use already known &lt;a href=&quot;http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; methods&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;code&gt;GET&lt;/code&gt; or &lt;code&gt;HEAD&lt;/code&gt; to query data or part of it&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;POST&lt;/code&gt; to modify data&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;PUT&lt;/code&gt; to create data&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;DELETE&lt;/code&gt; to &amp;#8230; delete data&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;Use &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; parameters, &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; or body to provides the required parameters for the wanted action to be executed. For example a &lt;code&gt;GET&lt;/code&gt; with &lt;code&gt;http://somewh.ere/person/24&lt;/code&gt; to retrieve the data relative to the &lt;code&gt;person&lt;/code&gt; with id &lt;code&gt;24&lt;/code&gt;, &lt;code&gt;HTTP&lt;/code&gt; headers could contains required credentials for example.
	&lt;ul&gt;
		&lt;li&gt;There is no predefined protocol except &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; to transmit data, it is up to the application to define it as opposed to &lt;span class=&quot;caps&quot;&gt;SOAP&lt;/span&gt;. Usually xml or json is used.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;All actions should be stateless: no client context is being stored on the server between requests, all requests should be self-sufficient to execute&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Whenever data is returned, it is nice to retrieve the url to access to linked data as opposed to its raw id. So that the entry points are not predefined. For example:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  	&lt;span class=&quot;s2&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;person&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  	&lt;span class=&quot;s2&quot;&gt;&amp;quot;uuid&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;550e8400-e29b-41d4-a716-446655440000&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  	&lt;span class=&quot;s2&quot;&gt;&amp;quot;first_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Sherlock&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  	&lt;span class=&quot;s2&quot;&gt;&amp;quot;last_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Holmes&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  	&lt;span class=&quot;s2&quot;&gt;&amp;quot;organisation&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://somewh.ere/organisation/550e8400-f34d-41d4-a716-876543211234&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;&lt;a name=&quot;amdahl-law&quot;&gt;&lt;/a&gt;What is Amdahls Law? What is Gustafson&amp;#8217;s Law?&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;For the past 30 years, computer performance has been driven by Moore&amp;#8217;s Law; from now on, it will be driven by Amdahl&amp;#8217;s Law. Writing code that effectively exploits multiple processors can be very challenging. &lt;/p&gt;&lt;p&gt;&lt;small&gt;Doron Rajwan &amp;#8211; Research Scientist, Intel Corp&lt;/small&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The speedup of a program using multiple processors in parallel computing is limited by the time needed for the sequential fraction of the program. For example, if a program needs 20 hours using a single processor core, and a particular portion of 1 hour cannot be parallelized, while the remaining promising portion of 19 hours (95%) can be parallelized, then regardless of how many processors we devote to a parallelized execution of this program, the minimum execution time cannot be less than that critical 1 hour. &lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Amdahl&amp;#39;s_law&quot;&gt;Amdahl&amp;#8217;s law&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;p&gt;Gustafson&amp;#8217;s Law (&amp;#8230;) says that problems with large, repetitive data sets can be efficiently parallelized. Gustafson&amp;#8217;s Law contradicts Amdahl&amp;#8217;s law, which describes a limit on the speed-up that parallelization can provide.&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Gustafson&amp;#39;s_law&quot;&gt;Gustafson&amp;#8217;s Law&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;&lt;a name=&quot;other-topics&quot;&gt;&lt;/a&gt;[Added] Additional topics and tools&lt;/h2&gt;
&lt;p&gt;Here is some additional topics that should require some attention and personal interests&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;security&quot;&gt;&lt;/a&gt;Security&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Web Security: &lt;a href=&quot;http://code.google.com/intl/fr-FR/edu/security/index.html&quot;&gt;Google Code University&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Single_sign-on&quot; title=&quot;SSO&quot;&gt;Single Sign On&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://docs.oracle.com/javaee/5/tutorial/doc/bnbwj.html&quot;&gt;Java EE security&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://static.springsource.org/spring-security/site/features.html&quot;&gt;Spring security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;tools&quot;&gt;&lt;/a&gt;Tools&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Revision_control&quot;&gt;Version control system&lt;/a&gt;: &lt;del&gt;&lt;span class=&quot;caps&quot;&gt;CVS&lt;/span&gt;&lt;/del&gt; / &lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt; / &lt;a href=&quot;http://git-scm.com/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;GIT&lt;/span&gt;&lt;/a&gt; &amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;programming-models&quot;&gt;&lt;/a&gt;Programming models&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/MapReduce&quot;&gt;Map Reduce&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/intl/fr-FR/edu/parallel/mapreduce-tutorial.html&quot;&gt;Introduction to Parallel Programming and MapReduce&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Software_transactional_memory&quot; title=&quot;STM&quot;&gt;Software Transactional Memory&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Actor_model&quot;&gt;Actor&lt;/a&gt; (see &lt;a href=&quot;http://akka.io/docs/akka/1.2/scala/actors.html&quot;&gt;Akka&lt;/a&gt; or &lt;a href=&quot;http://www.erlang.org/doc/reference_manual/processes.html&quot;&gt;Erlang process&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;java-libraries&quot;&gt;&lt;/a&gt;Java libraries&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://hadoop.apache.org/&quot;&gt;Hadoop&lt;/a&gt;: &lt;quote&gt;The Apache Hadoop software library is a framework that allows for the distributed processing of large data sets across clusters of computers using a simple programming model. It is designed to scale up from single servers to thousands of machines, each offering local computation and storage.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://lucene.apache.org/java/docs/index.html&quot;&gt;Lucene&lt;/a&gt;: &lt;quote&gt;Apache Lucene&amp;#8482; is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://mahout.apache.org/&quot;&gt;Mahout&lt;/a&gt; &lt;quote&gt;The Apache Mahout&amp;#8482; machine learning library&amp;#8217;s goal is to build scalable machine learning libraries.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://camel.apache.org/&quot;&gt;Camel&lt;/a&gt;: &lt;quote&gt;Apache Camel is a powerful open source integration framework based on known Enterprise Integration Patterns with powerful Bean Integration.&lt;/quote&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;java-utilities&quot;&gt;&lt;/a&gt;Java utilities&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/guava-libraries/&quot;&gt;Guava: Google Core Libraries&lt;/a&gt;: &lt;quote&gt;The Guava project contains several of Google&amp;#8217;s core libraries that we rely on in our Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://joda-time.sourceforge.net/&quot;&gt;Joda Time&lt;/a&gt;: &lt;quote&gt;Joda-Time provides a quality replacement for the Java date and time classes.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/mockito/&quot;&gt;Mockito&lt;/a&gt;: &lt;quote&gt;simpler &amp;amp; better mocking&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/powermock/&quot;&gt;PowerMock&lt;/a&gt;: &lt;quote&gt;Writing unit tests can be hard and sometimes good design has to be sacrificed for the sole purpose of testability. Often testability corresponds to good design, but this is not always the case. For example final classes and methods cannot be used, private methods sometimes need to be protected or unnecessarily moved to a collaborator, static methods should be avoided completely and so on simply because of the limitations of existing frameworks.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://jbehave.org/&quot;&gt;JBehave&lt;/a&gt;: &lt;quote&gt;Behaviour-driven development in Java&amp;#8230;&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/selenium/wiki/GettingStarted&quot;&gt;Selenium Webdriver&lt;/a&gt;: &lt;quote&gt;WebDriver is a tool for automating testing web applications, and in particular to verify that they work as expected.&lt;/quote&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a name=&quot;lectures&quot;&gt;&lt;/a&gt;[Added] Recommended Lectures to go further&lt;/h2&gt;
&lt;h3&gt;&lt;a name=&quot;lectures-general&quot;&gt;&lt;/a&gt;General&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420&quot;&gt;Patterns of Enterprise Application Architecture&lt;/a&gt; &lt;quote&gt;The main topic areas are: how to layer an enterprise application, how to organize domain logic, how to tie that logic to a relational database, how to design a web based presentation, some important principles in distributed design, and handling of what we call &amp;#8220;offline concurrency&amp;#8221; &amp;#8211; concurrency that spans transactions.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683&quot;&gt;Enterprise Integration Patterns&lt;/a&gt; &lt;quote&gt;The book Enterprise Integration Patterns provides a consistent vocabulary and visual notation to describe large-scale integration solutions across many implementation technologies. It also explores in detail the advantages and limitations of asynchronous messaging architectures. You will learn how to design code that connects an application to a messaging system, how to route messages to the proper destination and how to monitor the health of a messaging system.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Camel-Action-Claus-Ibsen/dp/1935182366&quot;&gt;Camel in Action&lt;/a&gt; &lt;quote&gt;Camel lets you create the Enterprise Integration Patterns to implement routing and mediation rules in either a Java based Domain Specific Language (or Fluent &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;), via Spring or Blueprint based Xml Configuration files or via the Scala &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt;. This means you get smart completion of routing rules in your &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; whether in your Java, Scala or &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; editor.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215&quot;&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software&lt;/a&gt; &lt;quote&gt;It provides a broad framework for making design decisions and a technical vocabulary for discussing domain design. It is a synthesis of widely accepted best practices along with the author&amp;#8217;s own insights and experiences. Projects facing complex domains can use this framework to approach domain-driven design systematically.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Enterprise-Service-Bus-Theory-Practice/dp/0596006756&quot;&gt;Enterprise Service Bus&lt;/a&gt; &lt;quote&gt;Enterprise Service Bus offers a thorough introduction and overview for systems architects, system integrators, technical project leads, and &lt;span class=&quot;caps&quot;&gt;CTO&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;CIO&lt;/span&gt; level managers who need to understand, assess, and evaluate this new approach.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0321768221/&quot;&gt;Event Centric: Finding Simplicity in Complex Systems&lt;/a&gt; (coming soon)&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff650706.aspx&quot;&gt;Microsoft Application Architecture Guide, 2nd Edition&lt;/a&gt; &lt;quote&gt;The guide provides an overview of the underlying principles and patterns that provide a solid foundation for good application architecture and design. On top of this foundation, the guide provides generally applicable guidance for partitioning an application’s functionality into layers, components, and services. It goes on to provide guidance on identifying and addressing the key design characteristics of the solution and the key quality attributes (such as performance, security, and scalability) and crosscutting concerns (such as caching and logging)&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;And finally have a look to the site part of &lt;a href=&quot;http://97things.oreilly.com/wiki/index.php/97_Things_Every_Software_Architect_Should_Know_-_The_Book&quot;&gt;97 Things Every Software Architect Should Know&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;lectures-concurrency&quot;&gt;&lt;/a&gt;Concurrency&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601&quot;&gt;Java Concurrency in Practice&lt;/a&gt; &lt;quote&gt;This book covers a very deep and subtle topic in a very clear and concise way, making it the perfect Java Concurrency reference manual. Each page is filled with the problems (and solutions!) that programmers struggle with every day.&lt;small&gt;&amp;mdash; Cliff Click&lt;/small&gt;&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/jaerlang/programming-erlang&quot;&gt;Programming Erlang: Software for a Concurrent World&lt;/a&gt; &lt;quote&gt;Learn how to write truly concurrent programs—programs that run on dozens or even hundreds of local and remote processors. See how to write high reliability applications—even in the face of network and hardware failure—using the Erlang programming language.&lt;/quote&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://pragprog.com/book/btlang/seven-languages-in-seven-weeks&quot;&gt;Seven languages in seven weeks&lt;/a&gt; &lt;quote&gt;You should learn a programming language every year, as recommended by The Pragmatic Programmer. But if one per year is good, how about Seven Languages in Seven Weeks? In this book you’ll get a hands-on tour of Clojure, Haskell, Io, Prolog, Scala, Erlang, and Ruby. Whether or not your favorite language is on that list, you’ll broaden your perspective of programming by examining these languages side-by-side.&lt;/quote&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a name=&quot;conclusion&quot;&gt;&lt;/a&gt;[Added] Conclusion&lt;/h2&gt;
&lt;p&gt;Whenever you want to claim yourself as an architect, be aware that you never know enough. Technologies, patterns, frameworks and even paradigms are living creatures, that born, grow, change and some times died replaced by new ones or killed by their children. You can&amp;#8217;t stay with what you learnt, you have to train and discover every times. It is quite hard to be efficient on all technics, the most important is to know they exists, and to know how to learn about when necessary.&lt;/p&gt;
&lt;p&gt;I would personnally change most of these questions by&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;have you heard about &amp;#8230; do you know how to learn about it &amp;#8230; what are the usecases ?&lt;/li&gt;
	&lt;li&gt;how do you stay tuned to industry and computer science change? what kind of blogs are you reading?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Furthermore, a broader attention must be paid to the fact that you can&amp;#8217;t work anymore with a unique technology such as Java. &lt;a href=&quot;http://memeagora.blogspot.com/2006/12/polyglot-programming.html&quot;&gt;Polyglot programming&lt;/a&gt; (a five years old article) is becommig more and more present, Martin Fowler even speaks about &lt;a href=&quot;http://martinfowler.com/bliki/PolyglotPersistence.html&quot;&gt;Polyglot Persistence&lt;/a&gt;&lt;br /&gt;
I personnally think it is more efficient to know about &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt;&lt;/strong&gt; than &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;JMS&lt;/span&gt;&lt;/strong&gt;. If you have an architecture big enough to have a distributed computing infrastructure, maybe you&amp;#8217;ll have a better software experience with &lt;strong&gt;MapReduce&lt;/strong&gt; or &lt;strong&gt;NoSQL&lt;/strong&gt; database. Maybe it would be more efficient to have a &lt;strong&gt;ruby&lt;/strong&gt; frontend with a &lt;strong&gt;scala&lt;/strong&gt; backend linked to a cluster through &lt;strong&gt;RabbitMQ&lt;/strong&gt;&amp;#8230;&lt;/p&gt;
&lt;p&gt;Architect in Java is not enough!&lt;/p&gt;
&lt;p&gt;The good intention of the article (&lt;a href=&quot;http://java.dzone.com/articles/technical-job-interview&quot;&gt;Technical Job Interview Questions for Java EE architects&lt;/a&gt;), or at least the goal it achieved, is not to define the right questions for an interview, but it gives a general overview of the points an architect may have to deal with. It can also be viewed as a check list: what else should i learn ? All questions does not require the right response to be a good architect, it all depends on the application you are working on or the team you are part of, and knowing that those things exist are usually enough.&lt;br /&gt;
It is a good opportunity to learn or re-adjust your knowledge, that what i felt writing this article.&lt;/p&gt;
&lt;p&gt;And the final quote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a Scrum Master, my struggle with architects is that they often want to slow things down to &amp;#8220;do it right&amp;#8221; which inhibits releasing early and often.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;InfoQ comment &lt;a href=&quot;http://www.infoq.com/articles/softwarearch-assessment#view_79319&quot;&gt;trust?&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Last minute link: have a look at the presentation &lt;a href=&quot;http://www.infoq.com/presentations/We-Dont-Need-No-Stinkin-Architects&quot;&gt;Architects? We Don&amp;#8217;t Need No Stinkin’ Architects!&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ancien blob et anciens messages</title>
   <link href="http://arnauld.github.com/blog/2011/12/01/Previous-blog.html"/>
   <updated>2011-12-01T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2011/12/01/Previous-blog</id>
   <content type="html">&lt;p&gt;Le nouvel hébergement de ce blog s&amp;#8217;accompagnera d&amp;#8217;une migration de certains seulement de mes anciens messages. Pour les autres je vous invite à retourner là: &lt;a href=&quot;http://technbolts.tumblr.com/&quot;&gt;Ancien blog&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Jekyll - Le site web des développeurs</title>
   <link href="http://arnauld.github.com/blog/2011/11/30/Jekyll-le-site-web-des-developpeurs.html"/>
   <updated>2011-11-30T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2011/11/30/Jekyll-le-site-web-des-developpeurs</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt; est un générateur de pages statiques particulièrement adapté aux développeurs. Il permet de générer un site complet à partir de pages statiques ou de post, et de le publier. Développé par un des cofondateurs de Github, il est même directement intégré à Github. Il est donc possible de stocker, versionner, travailler ses articles ou ses pages statiques, et de les publier automatiquement sur un simple commit.&lt;/p&gt;
&lt;p&gt;Envie de travailler sur un article: hop une branche dédiée et l&amp;#8217;article n&amp;#8217;apparaitra pas tant qu&amp;#8217;il ne sera pas transféré sur le master. Pas besoin d&amp;#8217;une connection internet pour travailler sur son article, pas d&amp;#8217;interface utilisateur scabreuse (ou de pseudo éditeur html) pour éditer le contenu: vous utilisez l&amp;#8217;éditeur de texte que vous voulez. Envie de rajouter une feuille de style ou une image, plus besoin d&amp;#8217;aller dans les entrailles des templates et de trouver une enième façon de les herberger (bon ok ça à bien changé depuis ;)), tout est au même endroit: dans &lt;b&gt;votre&lt;/b&gt; repository Github.&lt;/p&gt;
&lt;p&gt;Une vraie infrastructure de développeur et de déploiement continu simplement: pas de base de données, pas de paramètres compliqués, une écriture simplifiée par des syntaxes adaptées: markdown, textile ou même html&amp;#8230; De plus, moyennant quelques options, l&amp;#8217;intégration d&amp;#8217;extrait de code dans les articles se fait naturellement et la coloration syntaxique automatiquement. Stocké par Github, généré par Github et publié par Github! Et vous n&amp;#8217;êtes pas encore inscrit au fan club Github !?!&lt;/p&gt;
&lt;p&gt;Du Ruby:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Public: Duplicate some text an abitrary number of times.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# text  - The String to be duplicated.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# count - The Integer number of times to duplicate the text.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Returns the duplicated String.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;multiplex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Du scala:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;&lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Leaf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sumLeaves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sumLeaves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sumLeaves&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Leaf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Voila, c&amp;#8217;est tout ça qui m&amp;#8217;aura définitivement fait basculer. Au revoir tumblr, bonjour github et merci &lt;a href=&quot;https://github.com/mojombo&quot;&gt;Tom Preston-Werner&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PS.: Premiers pas, premiers déboires! voir &lt;a href=&quot;https://github.com/mojombo/jekyll/issues/422&quot;&gt;Issue#422&lt;/a&gt; pour des problèmes de traitements lors de la coloration syntaxique (&lt;code&gt;Liquid error: undefined method `join’ for #&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Voir aussi:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Passer de wordpress jekyll &lt;a href=&quot;http://jeremy.tagada.hu/passer-de-wordpress-jekyll-premiere-partie/&quot;&gt;premiere-partie&lt;/a&gt; et &lt;a href=&quot;http://jeremy.tagada.hu/passer-de-wordpress-jekyll-deuxieme-partie/&quot;&gt;deuxième partie&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://developmentseed.org/blog/2011/09/09/jekyll-github-pages/&quot;&gt;Jekyll Github Page&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://klepas.org/jekyll-a-static-site-generator/&quot;&gt;Jekyll a static site generator&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.jacquesf.com/2011/03/creating-excerpts-in-jekyll-with-wordpress-style-more-html-comments/&quot;&gt;Creating Excerpts in Jekyll with Wordpress-style &amp;lt;!&amp;#8212;more&amp;#8212;&amp;gt; &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; Comments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>[T|B|D]DD par la pratique ou la decouverte de NodeJS</title>
   <link href="http://arnauld.github.com/tbd-in-practice/2011/10/19/TBD-DD-par-la-pratique-ou-la-decouverte-de-NodeJS.html"/>
   <updated>2011-10-19T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/tbd-in-practice/2011/10/19/TBD-DD-par-la-pratique-ou-la-decouverte-de-NodeJS</id>
   <content type="html">&lt;p&gt;Après reflexion, la série aurait tout aussi bien pu s&#39;appeller:&lt;/p&gt;

&lt;p&gt;&quot;Découverte de NodeJS et de CQRS dirigée par [T|B|D]DD&quot;&lt;/p&gt;

&lt;p&gt;&quot;Développement d&#39;une application NodeJS de A à Z selon une approche CQRS&quot;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>[T|B|D]DD par la pratique 3 - AggregateRoot</title>
   <link href="http://arnauld.github.com/tbd-in-practice/2011/10/18/TBD-DD-par-la-pratique-3-AggregateRoot.html"/>
   <updated>2011-10-18T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/tbd-in-practice/2011/10/18/TBD-DD-par-la-pratique-3-AggregateRoot</id>
   <content type="html">&lt;h2&gt;Echauffement&lt;/h2&gt;




&lt;p&gt;Un peu de refactoring pour s&#39;échauffer.
Au lieu de définir tout notre domaine dans le fichier &lt;code&gt;domain.js&lt;/code&gt;, associons chaque élément de notre
domaine à un fichier spécifique:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;le fichier &lt;code&gt;lib/domain.js&lt;/code&gt; est alors renomé en &lt;code&gt;lib.project.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;la fonction &lt;code&gt;create_project&lt;/code&gt; en &lt;code&gt;create&lt;/code&gt; puisque le fichier sera dédié à notre classe projet&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Les corrections à apporter sont alors les suivantes dans les fichiers &lt;code&gt;specs/project_specs.js&lt;/code&gt; et
&lt;code&gt;test/project_test.js&lt;/code&gt; :&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;modifier &lt;code&gt;var domain = require(&#39;../lib/domain&#39;)&lt;/code&gt; par &lt;code&gt;var prj = require(&#39;../lib/project&#39;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;et tous les appels de méthode &lt;code&gt;domain.create_project&lt;/code&gt; par &lt;code&gt;prj.create&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Relançons les tests, et oh miracle ils passent tous.&lt;/p&gt;


&lt;h3&gt;Renommer un projet&lt;/h3&gt;

&lt;p&gt;Afin de completer un peu notre projet ajoutons une méthode &lt;code&gt;rename&lt;/code&gt; afin de pouvoir modifier le nom
de notre projet. On peux remarquer que l&#39;intention est bien de &lt;strong&gt;renomer&lt;/strong&gt; le projet et non pas de
définir son nom comme pourrait l&#39;indiquer un &#39;setter&#39; standard du type &lt;code&gt;set_name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Successivement nous:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ajoutons le test suivant (&lt;code&gt;test/project_test.js&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;renaming a project must change its name according to new one&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;travis&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;travis&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;vérifions que notre test échoue à cause de l&#39;absence de la méthode &lt;code&gt;rename&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ajoutons ensuite la méthode &lt;code&gt;rename&lt;/code&gt; sur notre project (&lt;code&gt;lib/project.js&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;ajoutons le test indiquant que le changement de nom doit entrainer la création d&#39;un nouvel évènement (&lt;code&gt;test/project_test.js&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;renaming a project must add an `event` in its history of type &amp;#39;project_renamed&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;travis&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_renamed&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;vérifions que notre test échoue&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;modifions finalement la méthode &lt;code&gt;rename&lt;/code&gt; pour générer un nouvel évènement et sa gestion
dans la méthode apply (&lt;code&gt;lib/project.js&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// wrapping functions to make values *immutables*&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;project_renamed&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_renamed&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unknown event type: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// still there means, the event was correctly handled, thus keep it!&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;   
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Projet et Event Sourcing: le phoenix!&lt;/h3&gt;

&lt;p&gt;Bon, nous avons désormais deux types d&#39;évènements différents. Interessons-nous à la reconstruction
d&#39;un projet à partir de ses évènements, rappellez-vous l&#39;&lt;a href=&quot;http://technbolts.tumblr.com/post/11317032794&quot;&gt;Event sourcing&lt;/a&gt;!
Faire renaître un projet de ses cendres euh... de son historique!&lt;/p&gt;

&lt;p&gt;Exportons les classes de nos deux évènements afin qu&#39;elles soient disponibles depuis les autres
modules.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/project.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Le test correspondant à la relecture peut alors s&#39;écrire:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test/project_test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a project can be reload from a simple history&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;history&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;travis&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;travis&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Rajoutons progressivement la méthode &lt;code&gt;load_from_history&lt;/code&gt; sur notre module et sur notre classe &lt;code&gt;Projet&lt;/code&gt;.
La méthode sur notre module servira de méthode de construction &lt;code&gt;factory method&lt;/code&gt;, dans un premier temps,
pour créer un projet à partir de son historique.
Nous obtenons alors:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/project.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Un coup d&#39;oeil sur notre console, et hop tout le monde est vert, c&#39;est pas géant ça?&lt;/p&gt;

&lt;p&gt;Le code complet de &lt;code&gt;lib/project.js&lt;/code&gt; est à ce stade:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/project.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;node-uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Events&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// wrapping functions to make values *immutables*&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// wrapping functions to make values *immutables*&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;project_renamed&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Project&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_renamed&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unknown event type: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// still there means, the event was correctly handled, thus keep it!&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;   
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Un peu de technique dans un monde de brutes!&lt;/h2&gt;

&lt;p&gt;Si l&#39;on devait effectuer le même travail sur une autre entité de notre domaine - comme un &lt;code&gt;User&lt;/code&gt; (qui décrit
un utilisateur de notre application: un &lt;code&gt;developer&lt;/code&gt;, un &lt;code&gt;scrum master&lt;/code&gt; ou encore un &lt;code&gt;product owner&lt;/code&gt;)
ou une &lt;code&gt;Story&lt;/code&gt; -  on peux constater la redondance de code dans la gestion des évènements et de l&#39;identifiant.&lt;/p&gt;

&lt;p&gt;Nous allons donc nous interesser à généraliser ce code dans une classe (que l&#39;on manipulera comme un
&lt;a href=&quot;http://www.scala-lang.org/node/126&quot;&gt;&lt;code&gt;trait&lt;/code&gt;&lt;/a&gt; ou &lt;code&gt;mixin&lt;/code&gt; compte-tenu de l&#39;aspect dynamique du javascript)
dédiée que l&#39;on pourra étendre ensuite afin de bénéficier de cette infrastructure technique.&lt;/p&gt;

&lt;p&gt;En regardant le code de gestion de l&#39;évènement (méthode &lt;code&gt;apply&lt;/code&gt;), on voit aussi que notre &lt;code&gt;switch&lt;/code&gt; risque
de rapidement devenir in-maintenable et illisible. Commençons donc par utiliser l&#39;aspect dynamique de javascript
pour retrouver une méthode succeptible de pouvoir gérer un évènement en fonction de son type.&lt;/p&gt;

&lt;p&gt;Après quelques tatonements (voir les méthodes &lt;code&gt;apply&lt;/code&gt; et &lt;code&gt;call&lt;/code&gt; de javascript &lt;a href=&quot;http://www.coursweb.ch/javascript/apply-call.html&quot;&gt;ici&lt;/a&gt;
et comment le &lt;code&gt;this&lt;/code&gt; est une notion particulière en javascript!) et les tests aux verts, voici les
changements que nous avons faits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;notre méthode &lt;code&gt;apply&lt;/code&gt; a été renommé en &lt;code&gt;apply_event&lt;/code&gt; pour éviter toute confusion avec la
méthode &lt;code&gt;apply&lt;/code&gt; de javascript.&lt;/li&gt;
&lt;li&gt;la fonction capable de gérer un évènement est récupérer à partir de son type via un tableau
de fonction dont la clé de chaque élément correspondont aux types d&#39;évènements: &lt;br/&gt;
&lt;code&gt;var handler = this.event_handlers[&quot;on_&quot;+event.event_type()];&lt;/code&gt; &lt;br/&gt;&lt;/li&gt;
&lt;li&gt;le tableau des fonctions est définit comme suit: &lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_project_created&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_project_renamed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;la fonction ainsi récupérée est alors invoquée via la fonction &lt;code&gt;call&lt;/code&gt; de javascript: &lt;br/&gt;
&lt;code&gt;handler.call(this, event);&lt;/code&gt; le &lt;code&gt;this&lt;/code&gt; passé en paramètre de la fonction correspond à notre
instance de projet, et sera ainsi vu comme le &lt;code&gt;this&lt;/code&gt; dans l&#39;éxecution de la fonction.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Tout ceci nous amène finalement à:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Project&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_project_created&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_project_renamed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;on_&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unknown event type: &amp;lt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// still there means, the event was correctly handled, thus keep it!&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;applyEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Nos fonctions &lt;code&gt;uuid&lt;/code&gt;, &lt;code&gt;events&lt;/code&gt;, &lt;code&gt;apply_event&lt;/code&gt; et &lt;code&gt;load_from_history&lt;/code&gt; ne sont finalement plus liées au côté fonctionnel
du &lt;code&gt;Projet&lt;/code&gt; et n&#39;ont aucune dépendance vers celui-ci.
Déplaçons les dans une nouvelle classe que nous appellerons &lt;code&gt;AggregateRoot&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;dans &lt;code&gt;lib/aggregate_root.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Aggregate Root&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;on_&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unknown event type: &amp;lt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// still there means, the event was correctly handled, thus keep it!&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Un petit tour sur la documentation de &lt;code&gt;nodeJS&lt;/code&gt; et nous trouvons notre fonction magique:
&lt;a href=&quot;http://nodejs.org/docs/latest/api/util.html#util.inherits&quot;&gt;&lt;strong&gt;inherits&lt;/strong&gt;&lt;/a&gt;. Après de nombreuses
maladresses et d&#39;erreur de javascript, notre classe &lt;code&gt;Project&lt;/code&gt; a bien changé.&lt;/p&gt;

&lt;p&gt;Tout d&#39;abord, voyons &lt;strong&gt;les erreurs de javacript que nous trainons depuis le début&lt;/strong&gt;. En écrivant:
&lt;code&gt;Project.prototype = { ... }&lt;/code&gt; on ne fait &lt;strong&gt;pas que&lt;/strong&gt; rajouter des comportements à notre classe &lt;code&gt;Project&lt;/code&gt;
mais on remplace carrément son prototype, ce qui n&#39;est pas problèmatique au premier abord. En revanche,
dès que l&#39;on fait hériter notre classe &lt;code&gt;Projet&lt;/code&gt; de &lt;code&gt;AggregateRoot&lt;/code&gt;
&lt;code&gt;require(&#39;util&#39;).inherits(Project, aroot.AggregateRoot);&lt;/code&gt; en redefinissant notre prototype on perd
tout ce que notre héritage avait ajouté.
Nous choisissons donc de definir nos méthodes publiques une par une et non plus dans un bloc objet.&lt;/p&gt;

&lt;p&gt;Nous avons pas mal galérer à &lt;em&gt;importer&lt;/em&gt; notre nouveau module &lt;code&gt;aggregate_root&lt;/code&gt; situé pourtant dans le
même dossier que notre module &lt;code&gt;projet.js&lt;/code&gt;. Il suffisait simplement d&#39;écrire
&lt;code&gt;require(&quot;./aggregate_root&quot;)&lt;/code&gt; au lieu de &lt;code&gt;require(&quot;aggregate_root&quot;)&lt;/code&gt;, cette dernière écriture est,
semble-t-il, réservée aux modules &quot;externes&quot; de notre application.&lt;/p&gt;

&lt;p&gt;Enfin, en regardant le code de notre classe &lt;code&gt;Project&lt;/code&gt; on constate que nous avons deux constructeurs,
à deux endroits différents de notre code. Nous simplifions donc en un unique constructeur (vide) et
déléguons à notre méthode &lt;code&gt;create&lt;/code&gt; le soin de générer l&#39;appel initial requis.&lt;/p&gt;

&lt;p&gt;Enfin, nous enlevons nos commentaires farfelu &lt;code&gt;// wrapping functions to make values *immutables*&lt;/code&gt;
puisque il est toujours possible en javascript de redefinir la fonction. Il n&#39;est donc, à ma
connaissance pas possible de figer l&#39;état d&#39;un objet.&lt;/p&gt;

&lt;p&gt;Au final, notre nouvel classe &lt;code&gt;Projet&lt;/code&gt; devient:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;node-uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;aroot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./aggregate_root&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;nutil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;util&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Events&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;project_renamed&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to_f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Project&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;nutil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aroot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// public methods&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;on_project_created&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;on_project_renamed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load_from_history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Un petit tour sur notre console, et nos tests sont toujours verts. Notre classe &lt;code&gt;Project&lt;/code&gt; s&#39;est bien
allégée et ne contient pratiquement plus que le code fonctionnel de notre entité.&lt;/p&gt;

&lt;p&gt;La déclaration des méthodes nous paraissant désormais un peu verbeuse, nous décidons de notre créer un petit
utilitaire afin de revenir à une syntaxe un plus compact.&lt;/p&gt;

&lt;p&gt;Retour aux tests!
&lt;code&gt;test/utilities_test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;utilities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;../lib/utilities&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mixin provides a simple way to declare methods&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// defines a basic class with a single method &amp;#39;value()&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// defines the methods, one want to plug into our class&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// add new methods &amp;amp; property&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;utilities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// make sure original method is still there&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mixin provides a simple way to add properties&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// defines a basic class with a single method &amp;#39;value()&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// defines the methods, one want to plug into our class&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cafebabe-3550-1i3105&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// add new methods &amp;amp; property&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;utilities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// make sure original method is still there&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cafebabe-3550-1i3105&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;et notre utilitaire s&#39;écrit&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/utilities.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;functions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;functions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;functions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasOwnProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;functions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mixin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Ok, rien de bien exceptionnel et du code qui existe certainement ailleurs.
Mis en place, notre classe &lt;code&gt;Project&lt;/code&gt; devient:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/project.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;misc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;./utilities&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; *  Project&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// public methods&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;event_handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_project_created&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;on_project_renamed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;rename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply_event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectRenamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;new_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;nutil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aroot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AggregateRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;misc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Une séance plutôt technique de préparation, avant une grande ligne droite de fonctionnel.
Après s&#39;être fait un peu la main sur notre entité de projet, nous nous interesserons la prochaine
fois au &lt;code&gt;backlog&lt;/code&gt; et aux &lt;code&gt;story&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>[T|B|D]DD par la pratique 2 - Installation et mise en place</title>
   <link href="http://arnauld.github.com/tbd-in-practice/2011/10/15/TBD-DD-par-la-pratique-2-Installation-et-mise-en-place.html"/>
   <updated>2011-10-15T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/tbd-in-practice/2011/10/15/TBD-DD-par-la-pratique-2-Installation-et-mise-en-place</id>
   <content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;




&lt;p&gt;Commençons par glaner à gauche et à droite les modules dont nous aurons besoin, nous voulons:&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;un module pour faire du BDD&lt;/li&gt;
&lt;li&gt;un module pour faire du TDD&lt;/li&gt;
&lt;li&gt;un module pour la persistence de notre modèle, nous prendrons dans un 1er temps une base de données postgres&lt;/li&gt;
&lt;li&gt;un module pour effectuer des tâches asynchrones (~actor)&lt;/li&gt;
&lt;li&gt;un module pour générer les uuid de nos entités&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Preparation&lt;/h2&gt;

&lt;h3&gt;Installer &lt;strong&gt;nodejs&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Voir &lt;a href=&quot;http://nodejs.org/&quot;&gt;NodeJS&lt;/a&gt; et &lt;a href=&quot;https://github.com/joyent/node/wiki/Installation&quot;&gt;Installation&lt;/a&gt;.
Pour ma part, j&#39;ai suivi le lien &lt;a href=&quot;https://sites.google.com/site/nodejsmacosx/&quot;&gt;precompiled package for MacOS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Assurons-nous que le simple &quot;Hello world&quot; marche:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;node -v
    v0.4.11
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;console.log(&amp;#39;Hello World&amp;#39;);&amp;quot;&lt;/span&gt; &amp;gt; hello.js
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;node hello.js
    Hello World
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;_&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Installer &lt;strong&gt;Webworker&lt;/strong&gt; (for actor like)&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/pgriess/node-webworker&quot;&gt;node-webworker&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;A WebWorkers implementation for NodeJS&lt;/p&gt;&lt;/blockquote&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;npm install webworker
    webworker@0.8.4 ./node_modules/webworker
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;_&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Installer &lt;strong&gt;vows&lt;/strong&gt; (for BDD)&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://vowsjs.org/&quot;&gt;VowsJS&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Asynchronous behaviour driven development for Node.&lt;/p&gt;&lt;/blockquote&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;npm install vows
    vows@0.5.11 ./node_modules/vows 
    └── eyes@0.1.6
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;_&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Installer &lt;strong&gt;nodeunit&lt;/strong&gt; (for TDD)&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/caolan/nodeunit&quot;&gt;nodeunit&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;npm install nodeunit
    nodeunit@0.5.5 ./node_modules/nodeunit 
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;_&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Installer &lt;strong&gt;node-postgres&lt;/strong&gt; (Non-blocking PostgreSQL client)&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/brianc/node-postgres&quot;&gt;node-postgres&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;npm install pg
    ...
    Checking &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; node prefix                 : ok /usr 
    Checking &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; program pg_config           : not found 
    .../node_modules/pg/wscript:16: error: The program &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;pg_config&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; is required
    pg@0.5.8 ./node_modules/pg 
    └── generic-pool@1.0.6
    &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;_&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;&lt;p&gt;In the mean time if you get a compilation failure during installation you
have still successfully installed the module; however, you cannot use the
native bindings -- only the pure javascript bindings.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Très bien, prenons ça pour argent comptant dans un premier temps, et nous nous contenterons de la version
pure javascript (qui devrait suffir amplement pour démarrer).&lt;/p&gt;

&lt;h3&gt;Installer &lt;strong&gt;node-uuid&lt;/strong&gt; (Generation de UUID de type 4)&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/broofa/node-uuid&quot;&gt;node-uuid&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;npm install node-uuid
   node-uuid@1.2.0 ./node_modules/node-uuid
   &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;_&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Simplifions et centralisons les dépendences...&lt;/h2&gt;

&lt;p&gt;Installer toutes ces dépendances une à une devient rapidement fastidieux, surtout s&#39;il faut le répéter à chaque fois
que le projet est récupérer depuis les sources. Heureusement, il existe un moyen de centraliser et conserver ces
dépendances en créant un fichier &lt;code&gt;package.json&lt;/code&gt;. Ce fichier est très similaire au fichier &lt;code&gt;pom.xml&lt;/code&gt; de Maven.
Il décrit de manière succinte l&#39;appplication ainsi que ses dépendances.
Voir &lt;a href=&quot;http://howtonode.org/introduction-to-npm&quot;&gt;Introduction To npm&lt;/a&gt; pour plus d&#39;information.&lt;/p&gt;

&lt;p&gt;Par example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;author&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Arnauld&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;scrum-board&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Scrum board: rambling around [D|T|B]DD&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;0.0.1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;repository&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;engines&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;node&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;dependencies&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;webworker&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;vows&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;nodeunit&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;pg&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;node-uuid&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;devDependencies&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;app.js&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Du coup, la récupération des dépendances est beaucoup plus immédiate grâce à la commande &lt;code&gt;npm install&lt;/code&gt;.
Toutes les dépendances sont ainsi installées en une unique commande.&lt;/p&gt;

&lt;h2&gt;Structure du projet&lt;/h2&gt;

&lt;p&gt;Le projet prendra la forme suivante:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;project_dir&amp;gt;/
  +-- lib/
  |     +-- domain.js
  |     +-- event_store.js
  |     +-- repository.js
  |     +-- ...
  +-- node_modules/
  |     ...
  +-- samples/
  |     +-- hello.js
  |     +-- ...
  +-- specs/
  |     +-- project_specs.js
  |     +-- user_specs.js
  |     +-- ...
  +-- test/
  |     +-- user_test.js
  |     +-- domain_test.js
  |     +-- ...
  +-- package.json
  +-- watchr-conf.rb
  +-- ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;C&#39;est à dire que&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dans &lt;code&gt;lib/&lt;/code&gt; sera contenu le code de notre application&lt;/li&gt;
&lt;li&gt;dans &lt;code&gt;node_modules&lt;/code&gt; les modules requis et installés pour NodeJS&lt;/li&gt;
&lt;li&gt;dans &lt;code&gt;samples/&lt;/code&gt; des snippets et autres petits tests sans importance&lt;/li&gt;
&lt;li&gt;dans &lt;code&gt;specs&lt;/code&gt; les tests fonctionnels (BDD)&lt;/li&gt;
&lt;li&gt;dans &lt;code&gt;test&lt;/code&gt; les tests unitaires (TDD)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Tests des &lt;em&gt;specs&lt;/em&gt;: executer tous les tests fonctionnels présents dans le dossier &lt;code&gt;specs/&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;node_modules/.bin/vows --spec specs/*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Tests unitaires: executer tous les tests unitaires présents dans le dossier &lt;code&gt;test/&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;node_modules/.bin/nodeunit &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Test en continue&lt;/h2&gt;

&lt;p&gt;Préparons désormais notre environement de test de continue. Il s&#39;agit de mettre en place des &lt;code&gt;jobs&lt;/code&gt; qui seront
régulièrement déclenchés (sur modification d&#39;un fichier par exemple). Il est ainsi possible de tester
continuellement l&#39;application, en relançant les tests à chaque fois qu&#39;un fichier source est modifié.
Lorsque notre base de tests commencera à être conséquente, nous essaierons alors de rendre le mécanisme un peu
plus malin afin de ne pas pénaliser notre environement en lançant l&#39;intégralité des tests à chaque changement.&lt;/p&gt;

&lt;p&gt;Parmis ces &lt;code&gt;jobs&lt;/code&gt; nous allons aussi mettre en place un outil de vérification de syntaxe. L&#39;execution du javascript
étant relativement permissive dans certains environements d&#39;execution, nous aurons ainsi une syntaxe plus propre,
et plus portable. Cette vérification sera faite via la bibliothèque &lt;code&gt;jslint&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;L&#39;outils que nous allons utilisé est un script Ruby appellé &lt;a href=&quot;https://github.com/mynyml/watchr&quot;&gt;&lt;code&gt;watchr&lt;/code&gt;&lt;/a&gt;. Il permet de brancher des appels de
fonctions à chaque fois qu&#39;un fichier &lt;em&gt;surveillé&lt;/em&gt; est modifié. La liste des fichiers surveillés est déterminée
par une expression régulière.&lt;/p&gt;

&lt;p&gt;Installation de &lt;a href=&quot;https://github.com/mynyml/watchr&quot;&gt;&lt;code&gt;watchr&lt;/code&gt;&lt;/a&gt; (sous entend que ruby et rubygem soit correctement installé)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gem install watchr
    gem install ruby-fsevent&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Installation de jslint (module NodeJS) afin de tester en continue la syntaxe javascript;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;npm install jslint&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Le fichier de configuration de &lt;code&gt;watchr&lt;/code&gt; indique:
* que nous surveillons tous les fichiers &lt;code&gt;js&lt;/code&gt; du dossier &lt;code&gt;lib&lt;/code&gt; et pour chacun d&#39;eux, en cas de modification,
  nous déclenchons l&#39;execution du program &lt;code&gt;jslint&lt;/code&gt; sur le fichier détecté, lançons les tests unitaires,
  et les tests fonctionels.
* que nous surveillons tous les fichiers &lt;code&gt;js&lt;/code&gt; du dossier &lt;code&gt;test&lt;/code&gt; et pour chacun d&#39;eux,
  en cas de modification, nous vérifions sa syntaxe et déclenchons l&#39;execution de tous tests.
* que nous surveillons tous les fichiers &lt;code&gt;js&lt;/code&gt; du dossier &lt;code&gt;specs&lt;/code&gt; et pour chacun d&#39;eux,
  en cas de modification, nous vérifions sa syntaxe et déclenchons l&#39;execution des tests fonctionnels.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;watchr-conf.rb&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;^(lib/(.*)\.js)&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;jslint_check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;specs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;^(test/(.*)\.js)&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;jslint_check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;watch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;^(specs/(.*)\.js)&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;jslint_check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;specs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;jslint_check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files_to_check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#system(&amp;#39;clear&amp;#39;)&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Checking &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files_to_check&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;node_modules/.bin/jslint &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files_to_check&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Start tests&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;node_modules/.bin/nodeunit test&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;specs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Start behavior tests&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;node_modules/.bin/vows --spec specs/*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;start watchr:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;watchr watchr-conf.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Pour plus de détails, je vous invite à consulter le livre &lt;a href=&quot;http://pragprog.com/book/rcctr/continuous-testing&quot;&gt;Continuous Testing&lt;/a&gt; qui -
même s&#39;il traite essentiellement de Ruby, Rails et Javascript - donnent de bonne idées pour l&#39;étendre à
d&#39;autres technologies.&lt;/p&gt;

&lt;h1&gt;Un démarrage en douceur&lt;/h1&gt;

&lt;p&gt;Dans une console, démarrons notre script de test continu &lt;code&gt;watchr watchr-conf.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Commençons par le test fonctionnel de création d&#39;un projet, nous voulons que la création d&#39;un projet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retourne un objet de type &lt;code&gt;Project&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;retourne un projet dont le nom est bien celui fournit&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;code&gt;specs/project_specs.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;vows&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;assert&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;../lib/domain&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;vows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Project&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addBatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;&amp;#39;A new project created with a given name&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;topic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
              &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

          &lt;span class=&quot;s1&quot;&gt;&amp;#39;should return an instance of Project&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;instanceOf&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

          &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have the specified name&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mccallum&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Export the Suite&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Après la sauvegarde, on obtient la sortie suivante sur la console:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Checking specs/project_specs.js

  specs/project_specs.js
  /*jslint node: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;, es5: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; */
    &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; 4,39: Expected &lt;span class=&quot;s1&quot;&gt;&amp;#39;;&amp;#39;&lt;/span&gt; and instead saw &lt;span class=&quot;s1&quot;&gt;&amp;#39;vows&amp;#39;&lt;/span&gt;.
      var &lt;span class=&quot;nv&quot;&gt;domain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; require&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;../lib/domain&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; 9,53: Expected &lt;span class=&quot;s1&quot;&gt;&amp;#39;;&amp;#39;&lt;/span&gt; and instead saw &lt;span class=&quot;s1&quot;&gt;&amp;#39;}&amp;#39;&lt;/span&gt;.
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; domain.create_project&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  Start behavior tests

  node.js:134
          throw e&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; // process.nextTick error, or &lt;span class=&quot;s1&quot;&gt;&amp;#39;error&amp;#39;&lt;/span&gt; event on first tick
          ^
  Error: Cannot find module &lt;span class=&quot;s1&quot;&gt;&amp;#39;../lib/domain&amp;#39;&lt;/span&gt;
      at Function._resolveFilename &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;module.js:317:11&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      at Function._load &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;module.js:262:25&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      at require &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;module.js:346:19&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;On remarquera que notre javascript n&#39;est pas tout à fait valide et qu&#39;il manque deux &lt;code&gt;;&lt;/code&gt; aux lignes 4 et 9.
Par ailleurs, nos tests échouent dû à l&#39;absence de notre fichier &lt;code&gt;lib/domain.js&lt;/code&gt;, ce qui est normal puisque
nous ne l&#39;avons pas encore écrit!&lt;/p&gt;

&lt;p&gt;Après quelques tatonements (comment fait-on l&#39;&lt;a href=&quot;https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript&quot;&gt;OOP en javascript&lt;/a&gt;...), on obtient le fichier suivant:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/domain.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;   *  Project&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;   */&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// tells nodeJS to make the `Project` visible from outside this file&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// when using `require`&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Après sauvegarde:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Checking lib/domain.js

  lib/domain.js
  /*jslint node: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;, es5: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; */
    &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; 12,26: Expected &lt;span class=&quot;s1&quot;&gt;&amp;#39;;&amp;#39;&lt;/span&gt; and instead saw &lt;span class=&quot;s1&quot;&gt;&amp;#39;(end)&amp;#39;&lt;/span&gt;.
      exports.Project &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; Project

  Start tests

  Start behavior tests

  ♢ Project

    A new project created with a given name
      ✓ should &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; an instance of Project
      ✗ should have the specified name
      TypeError: Object &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;object Object&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; has no method &lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;
      at Object.&amp;lt;anonymous&amp;gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;/Users/arnauld/Projects/cqrs-ramblings/node-app/specs/project_specs.js:17:35&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      at runTest &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;/Users/arnauld/Projects/cqrs-ramblings/node-app/node_modules/vows/lib/vows.js:93:26&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      at EventEmitter.&amp;lt;anonymous&amp;gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;/Users/arnauld/Projects/cqrs-ramblings/node-app/node_modules/vows/lib/vows.js:71:9&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      at EventEmitter.emit &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;events.js:81:20&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      at Array.0 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;/Users/arnauld/Projects/cqrs-ramblings/node-app/node_modules/vows/lib/vows/suite.js:150:58&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      at EventEmitter._tickCallback &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;node.js:126:26&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
   
  ✗ Errored » &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; honored ∙ &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; errored &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.008s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Un de nos tests fonctionnel passe et l&#39;autre échoue lamentablement.
Le projet créé est bien une instance de &lt;code&gt;Projet&lt;/code&gt; en revanche il ne dispose pas de la méthode &lt;code&gt;name&lt;/code&gt; qui devrait
permettre de renvoyer son nom. Fixons encore une fois le &lt;code&gt;;&lt;/code&gt; qui manque, et rajoutons la méthode manquante.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/domain.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Nous obtenons finalement la sortie suivante:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Checking lib/domain.js

  lib/domain.js
  /*jslint node: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;, es5: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; */
  No errors found.

  Start tests

  Start behavior tests

  ♢ Project

    A new project created with a given name
      ✓ should &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; an instance of Project
      ✓ should have the specified name
   
  ✓ OK » &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; honored &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.006s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Hourra!!&lt;/p&gt;

&lt;p&gt;Je passe rapidement sur la génération automatique d&#39;un &lt;code&gt;uuid&lt;/code&gt; pour notre projet (nous utilisons pour cela
le module &lt;code&gt;node-uuid&lt;/code&gt; qui fournit, via la variable uuid definie par le &lt;code&gt;require&lt;/code&gt;, une méthode de génération),
et notre code ressemble désormais à:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/domain.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;node-uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;   *  Project&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;   */&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// *public* methods&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;generated_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ask `node-uuid` to generate a new one&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Des tests unitaires ont été ajoutés avant chaque ajout de méthode sur notre &lt;code&gt;classe&lt;/code&gt; &lt;code&gt;Project&lt;/code&gt; et ressemble
désormais à:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test/project_test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;../lib/domain&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{8}/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create_project return the specified name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create_project generate a valid uuid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notre fichiers de tests fonctionnels c&#39;est aussi enrichi de quelques assertions supplémentaires notament
sur l&#39;unicité de notre &lt;code&gt;uuid&lt;/code&gt; et sa représentation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;specs/project_specs.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;vows&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;assert&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;../lib/domain&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{8}/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;vows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Project&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addBatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;&amp;#39;A new project created with a given name&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;topic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

          &lt;span class=&quot;s1&quot;&gt;&amp;#39;should return an instance of Project&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;instanceOf&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

          &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have the specified name&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mccallum&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

          &lt;span class=&quot;s1&quot;&gt;&amp;#39;and a generated uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UUID_PATTERN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;&amp;#39;New projects&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;topic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
              &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

          &lt;span class=&quot;s1&quot;&gt;&amp;#39;should have differents uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;notEqual&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Export the Suite&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notre console affiche donc fièrement:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Start tests
  --------------------------

  project_test
  ✔ create_project &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; the specified name
  ✔ create_project generate a valid uuid

  OK: &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; assertions &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;15ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

  Start behavior tests
  --------------------------

  ♢ Project

    A new project created with a given name
      ✓ should &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; an instance of Project
      ✓ should have the specified name
      ✓ and a generated uuid
    New projects
      ✓ should have differents uuid
   
  ✓ OK » &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt; honored &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.003s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h1&gt;Et l&#39;Event Sourcing dans tout ça ??&lt;/h1&gt;

&lt;p&gt;Tout ça c&#39;est bien mais ce n&#39;est pas très conforme avec notre idée de l&#39;[Event Sourcing][event-sourcing].
En effet, la création du projet consiste bien en une transition d&#39;état de &lt;em&gt;rien&lt;/em&gt; vers &lt;em&gt;un nouveau projet&lt;/em&gt;,
et nous ne conservons aucune données de cette transition. Qui plus est, le projet est porteur de son état,
il n&#39;est donc pas possible de suivre les modifications qu&#39;il subit, comme un changement de nom.&lt;/p&gt;

&lt;p&gt;Rajoutons donc un évènement &lt;code&gt;ProjectCreated&lt;/code&gt;, cet évènement sera porteur du nom du projet. Mais que devient
notre &lt;code&gt;uuid&lt;/code&gt; ? sa valeur est portée par le projet, et nous souhaitons qu&#39;un projet puisse être reconstruit
uniquement à partir de ses évènements. Nous déplaçons donc la génération du &lt;code&gt;uuid&lt;/code&gt; et considérons que celui-ci
est un attribut de notre évènement.&lt;/p&gt;

&lt;p&gt;Commençons par écrire les tests unitaires qui décrivent ce que nous souhaitons:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test/project_test.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;create_project must generate an event of type &amp;#39;project_created&amp;#39; in history&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Et la console nous affiche un échec dû à l&#39;absence de notre méthode &lt;code&gt;events()&lt;/code&gt; utilisée pour récupérer l&#39;historique:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Checking &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/project_test.js
  --------------------------

  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/project_test.js
  /*jslint node: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;, es5: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; */
  No errors found.

  Start tests
  --------------------------

  project_test
  ✔ create_project &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; the specified name
  ✔ create_project generate a valid uuid
  ✖ create_project must generate an event of &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;project_created&amp;#39;&lt;/span&gt; in &lt;span class=&quot;nb&quot;&gt;history&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;  &lt;/span&gt;TypeError: Object &lt;span class=&quot;c&quot;&gt;#&amp;lt;Object&amp;gt; has no method &amp;#39;events&amp;#39;&lt;/span&gt;
      at /Users/arnauld/Projects/cqrs-ramblings/node-app/test/project_test.js:20:26
      ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Après quelques cycles (red+green+refactor) où nous rajoutons la méthode &lt;code&gt;events&lt;/code&gt; qui renvoie systématiquement un
tableau vide, puis un objet bidon.&lt;/p&gt;

&lt;p&gt;Notre fichier de tests resemblent à:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new project must have an `events` method to retrieve its history&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new project must have a single `event` in its history&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a new project must have a single `event` in its history of type &amp;#39;project_created&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mccallum&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Et notre console affiche désormais que nous bloquons désormais sur le type de notre évènement.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Start tests
  --------------------------

  project_test
  ✔ create_project &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; the specified name
  ✔ create_project generate a valid uuid
  ✔ a new project must have an &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;events&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt; method to retrieve its &lt;span class=&quot;nb&quot;&gt;history&lt;/span&gt;
  ✔ a new project must have a single &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;event&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt; in its &lt;span class=&quot;nb&quot;&gt;history&lt;/span&gt;
  ✖ a new project must have a single &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;event&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt; in its &lt;span class=&quot;nb&quot;&gt;history &lt;/span&gt;of &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;project_created&amp;#39;&lt;/span&gt;

  TypeError: Object dummy_event has no method &lt;span class=&quot;s1&quot;&gt;&amp;#39;event_type&amp;#39;&lt;/span&gt;
      at /Users/arnauld/Projects/cqrs-ramblings/node-app/test/project_test.js:38:23
  ...  
  FAILURES: 1/8 assertions failed &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;11ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Modifions notre méthode de création de projet en passant non plus le nom et l&#39;identifiant du projet mais l&#39;évènement
souhaité. Dans la foulée nous rajoutons la méthode &lt;code&gt;apply&lt;/code&gt; qui va appliquer cet évènement à notre projet. De la même
manière que si l&#39;on rejouait l&#39;historique du projet.
Notre code ressemble désormais à (je passe toutes les petites galères de syntaxes javascript, jslint étant là pour
me rappeller à l&#39;ordre à chaque sauvegarde):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/domain.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;node-uuid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;   *  Project&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;   */&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// wrapping functions to make values *immutables*&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ProjectCreated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;dummy_event&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unknown event type: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create_project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Après sauvegarde, on vérifie que les tests précédents continuent de fonctionner correctement, même
après notre refactoring.
Hourra!! même nos tests fonctionnels continuent de passer.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Start behavior tests
  --------------------------

  ♢ Project

    A new project created with a given name
      ✓ should &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; an instance of Project
      ✓ should have the specified name
      ✓ and a generated uuid
    New projects
      ✓ should have differents uuid
   
  ✓ OK » &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt; honored &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.002s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Nous avons toujours le même test unitaire qui ne passe pas puisque nous n&#39;avons pas modifié la gestion de
l&#39;historique encore.&lt;/p&gt;

&lt;p&gt;Ajoutons désormais l&#39;historique à notre projet.
Et tous nos tests passent! un peu de refactoring et voila finalement notre code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/domain.js&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// public method&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;project_created&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Unknown event type: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;// still there means the event was correctly handled, thus keep it!&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Restons sur un succès, et arrêtons nous là pour aujourd&#39;hui.&lt;/p&gt;

&lt;p&gt;Dans notre prochain article, nous généraliserons la gestion de l&#39;historique afin de pouvoir la réutiliser
dans nos autres entités. Nous nous inspirerons du design des &lt;code&gt;AggregateRoot&lt;/code&gt; tel que généralement décrit dans
les articles autours &lt;code&gt;cqrs&lt;/code&gt; et dans &lt;a href=&quot;http://github.com/gregoryyoung/m-r&quot;&gt;Super Simple CQRS Example - github&lt;/a&gt;.
Pour plus d&#39;information, je vous invite à consulter les liens &lt;a href=&quot;http://technbolts.tumblr.com/post/11317032794&quot;&gt;ici&lt;/a&gt;.
Enfin nous mettrons en place la reconstruction du projet par son historique.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>[T|B|D]DD par la pratique</title>
   <link href="http://arnauld.github.com/tbd-in-practice/2011/10/14/TBD-DD-par-la-pratique-1.html"/>
   <updated>2011-10-14T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/tbd-in-practice/2011/10/14/TBD-DD-par-la-pratique-1</id>
   <content type="html">&lt;p&gt;Dans cette série, nous allons tenter de mettre en pratique la théorie autour des notions d&amp;#8217; &lt;a href=&quot;http://technbolts.tumblr.com/post/11317032794&quot;&gt;Event Sourcing&lt;/a&gt; et de &lt;a href=&quot;http://martinfowler.com/bliki/CQRS.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;CQRS&lt;/span&gt;&lt;/a&gt; (pour plus d&amp;#8217;informations voir &lt;a href=&quot;http://technbolts.tumblr.com/post/10529825424&quot;&gt;&lt;span class=&quot;caps&quot;&gt;CQRS&lt;/span&gt; links&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Pour ce faire, nous allons développer une nouvelle application selon les principes du Test Driven Developpement, du Behavior Driven Developpement et du Domain Driven Developpement.&lt;/p&gt;
&lt;p&gt;Dans &lt;a href=&quot;http://pragprog.com/refer/pragpub24/titles/tpp/the-pragmatic-programmer&quot;&gt;The Pragmatic Programmer&lt;/a&gt;, il est conseillé que &amp;#8220;l&amp;#8217;on apprenne au moins un langage de programmation chaque année&amp;#8221; (&lt;strong&gt;&amp;#8220;Learn at least one new language every year&amp;#8221;&lt;/strong&gt;) et il paraitrait que le &lt;code&gt;javascript&lt;/code&gt; soit un vrai langage, hummm&amp;#8230; nous allons donc lui donner sa chance, et plus précisement utiliser la plateforme &lt;b&gt;NodeJS&lt;/b&gt; comme infrastructure de notre application. Il s&amp;#8217;agira pour moi de découvrir NodeJS et une tentative de se reconcillier avec le javascript.&lt;/p&gt;
&lt;h2&gt;Notre domaine et notre langage commun (Ubiquitous language)&lt;/h2&gt;
&lt;p&gt;Le but de notre application d&amp;#8217;example est de facilité la mise en place et la pratique de Scrum dans une équipe. Nous souhaitons ainsi fournir un moyen de:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;crééer les tâches qui constitueront notre backlog&lt;/li&gt;
	&lt;li&gt;pouvoir définir un sprint sur une periode de temps donnée&lt;/li&gt;
	&lt;li&gt;pouvoir associer certaines cartes à un sprint&lt;/li&gt;
	&lt;li&gt;permettre aux membres de l&amp;#8217;équipes de déplacer les cartes d&amp;#8217;un sprint à mesure de l&amp;#8217;avancement des tâches&lt;/li&gt;
	&lt;li&gt;&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Afin de formaliser un peu plus le contexte de notre application, et les fonctionnalités requises, décrivons nos besoins sous forme de &lt;code&gt;User Story&lt;/code&gt;. Nous definirons ainsi par la même occasion notre langage commun, c&amp;#8217;est à dire la terminologie employée pour décrire notre domaine. En definissant un language commun, nous limitons les confusions et, ensemble, nous utilisons les mêmes mots pour décrire les mêmes idées. Nous pousserrons jusqu&amp;#8217;au bout l&amp;#8217;idée de ce langage commun en l&amp;#8217;utilisant même dans le code de notre application. Ce langage doit être omniprésent (Ubiquitous Language), et ce, dans nos discussions et notre code. Le code reflètera ainsi directement les concepts de l&amp;#8217;application, ce qui devrait le rendre d&amp;#8217;autant plus compréhensible pour quiconque connait notre langage commun. Ceci a aussi pour conséquence, que même en tant que développeur je parle le même langage que mon client.&lt;/p&gt;
&lt;h3&gt;Le contexte&lt;/h3&gt;
&lt;p&gt;Nous allons faire un bref rappel de la terminologie et des différents concepts que nous utiliserons dans le cadre notre application (pour un présention plus poussées et plus précise se référer à &lt;a href=&quot;ftp://ftp-developpez.com/henrik-kniberg/agile/scrum/ScrumAndXpFromTheTrenchesFrench.pdf&quot;&gt;Scrum et XP depuis les Tranchées&lt;/a&gt;.&lt;br /&gt;
En précisant, le cadre de notre langage nous definissons ainsi son contexte d&amp;#8217;application (Bounded Context) ainsi, même si dans d&amp;#8217;autre situation les mots ont une autre signification, voici ici la leur. Et si la théorie de scrum a une autre définition ou une autre terminologie, nous sommes protégé par notre contexte, qui défini les frontières d&amp;#8217;application de notre vocabulaire à notre application.&lt;/p&gt;
&lt;p&gt;Afin de limiter les confusions, nous utiliserons essentiellement les termes anglais relatifs à scrum.&lt;/p&gt;
&lt;p&gt;Notre application devra permettre de gérer plusieurs &lt;b&gt;projets&lt;/b&gt;. A chaque &lt;b&gt;projet&lt;/b&gt; sera associé un &lt;b&gt;backlog&lt;/b&gt;, une &lt;b&gt;équipe&lt;/b&gt; et un ensemble de &lt;b&gt;sprint&lt;/b&gt;. Le &lt;b&gt;backlog&lt;/b&gt; servira à récolter les besoins fonctionnels ou techniques émis par le client, à chaque besoins correspondra une entrée dans le backlog, et seront appellées &lt;b&gt;story&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;Une &lt;b&gt;équipe&lt;/b&gt; sera constituée d&amp;#8217;un &lt;b&gt;product owner&lt;/b&gt;, d&amp;#8217;un &lt;b&gt;scrum master&lt;/b&gt; et de plusieurs &lt;b&gt;developers&lt;/b&gt;. Le &lt;b&gt;product owner&lt;/b&gt; ainsi que le &lt;b&gt;scrum master&lt;/b&gt; pourront définir des &lt;b&gt;sprints&lt;/b&gt; et leurs associés des tâches (&lt;b&gt;task&lt;/b&gt;). Ces &lt;b&gt;tâches&lt;/b&gt; pourront être attachées à une &lt;b&gt;story&lt;/b&gt; mais ce n&amp;#8217;est pas obligatoire, et ce, afin d&amp;#8217;avoir une plus grande souplesse d&amp;#8217;organisation, notament concernant les tâches techniques. En revanche, il est quasi systématique qu&amp;#8217;une &lt;b&gt;story&lt;/b&gt; ait une ou plusieurs &lt;b&gt;tâches&lt;/b&gt; qui lui soit rattachées. En effet, une &lt;b&gt;story&lt;/b&gt; complexe pourra-t-être découpées en plusieurs &lt;b&gt;tâches&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;L&amp;#8217;état d&amp;#8217;une tache pourra (et devra!) évoluer au cours d&amp;#8217;un sprint à mesure de son avancement dans sa réalisation, sa validation et son acceptation par le &lt;b&gt;product owner&lt;/b&gt;. Par défaut, les différents états que peux prendre une tâche seront: &lt;code&gt;ready for developpement&lt;/code&gt;, &lt;code&gt;in developpement&lt;/code&gt;, &lt;code&gt;ready for testing&lt;/code&gt;, &lt;code&gt;in testing&lt;/code&gt;, &lt;code&gt;ready for signoff&lt;/code&gt;, &lt;code&gt;accepted&lt;/code&gt;. Seul le &lt;b&gt;product owner&lt;/b&gt; pourra associer l&amp;#8217;état &lt;code&gt;accepted&lt;/code&gt; à une tâche.&lt;/p&gt;
&lt;p&gt;Les différentes transitions entre états ne seront pas dans un premier temps soumis à des rêgles particulières. Il devra être possible &lt;b&gt;plus tard&lt;/b&gt; de rajouter des rêgles, indiquant qu&amp;#8217;il n&amp;#8217;est pas possible de démarrer le développement d&amp;#8217;une carte si trop de carte sont déjà en &lt;b&gt;cours&lt;/b&gt; par exemple (voir &lt;a href=&quot;http://www.infoq.com/resource/news/2010/01/kanban-scrum-minibook/en/resources/KanbanAndScrum-French.pdf&quot;&gt;Kanban et Scrum&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Afin de décrire nos propres &lt;code&gt;User Story&lt;/code&gt; nous utiliserons le modèle &lt;strong&gt;standard&lt;/strong&gt; (&amp;#8220;As a&amp;#8230; I want&amp;#8230; so that&amp;#8230;&amp;#8221;):&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;En tant que  &amp;lt; Rôle d’utilisateur &amp;gt;,&lt;/li&gt;
	&lt;li&gt;Je peux  &amp;lt; But &amp;gt;,&lt;/li&gt;
	&lt;li&gt;Si bien que  &amp;lt; Justification &amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&amp;#8217;est parti!! voici en vrac quelques idées de stories pour notre application.&lt;/p&gt;
&lt;h3&gt;Generalités: Projet, Equipe&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;En tant qu&amp;#8217; &lt;b&gt;administrateur (de l&amp;#8217;application)&lt;/b&gt;, je peux créer un nouveau projet si bien que je pourrais regrouper les besoins fonctionnels du produit.&lt;/li&gt;
	&lt;li&gt;En tant qu&amp;#8217; &lt;b&gt;administrateur&lt;/b&gt;, je peux associer une équipe à un projet si bien que son activité pourra être suivie par l&amp;#8217;application.&lt;/li&gt;
	&lt;li&gt;En tant qu&amp;#8217; &lt;b&gt;administrateur&lt;/b&gt;, je peux définir les membres de l&amp;#8217;équipes si bien que l&amp;#8217;on pourra définir les rôles scrum de chaque membre.&lt;/li&gt;
	&lt;li&gt;En tant qu&amp;#8217; &lt;b&gt;administrateur&lt;/b&gt;, je peux assigner à chaque membre de l&amp;#8217;équipe un rôle parmis &lt;code&gt;scrum master&lt;/code&gt;, &lt;code&gt;product owner&lt;/code&gt; ou &lt;code&gt;developper&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Backlog&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;En tant que &lt;b&gt;membre de l&amp;#8217;équipe&lt;/b&gt;, je peux créer de nouvelles entrées dans le backlog du projet, si bien que les besoins fonctionnels de notre projet pourront être récolter. Une &lt;code&gt;story&lt;/code&gt; sera définie par un titre, une description, une évaluation en points de sa complexité, ainsi que sa valeur cliente &lt;code&gt;business value&lt;/code&gt;.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;membre de l&amp;#8217;équipe&lt;/b&gt;, je peux completer une entrée du backlog en modifiant ses informations ou en ajoutant un commentaire, si bien que cette entrée disposera de plus amples informations à mesure des reflexions qu&amp;#8217;elle peux suciter.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Sprint&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;En tant que &lt;b&gt;product owner&lt;/b&gt;, je peux definir des nouveaux sprint si bien que je pourrais planifier mes releases, et organiser les tâches à developper à chaque itération.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;product owner&lt;/b&gt;, je peux modifier l&amp;#8217;intervalle de temps couvert par un sprint non commencé, si bien que je peux ajuster et réorganiser mes sprints dans le temps.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;product owner&lt;/b&gt; ou &lt;b&gt;scrum master&lt;/b&gt;, je peux associer une entrée du backlog à une tâche du sprint si bien que cette entrée pourra être développée au cours du sprint.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;membre de l&amp;#8217;équipe&lt;/b&gt;, je peux ajouter une tâche a faire dans un sprint si bien qu&amp;#8217;il est possible de rajouter des tâches techniques qui n&amp;#8217;apparaissent pas forcément directmement dans le backlog.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;membre de l&amp;#8217;équipe&lt;/b&gt;, je peux associer une tâche du sprint à une entrée du backlog, si bien qu&amp;#8217;il est possible de décomposer les entrées du backlog en sous-tâches.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;membre de l&amp;#8217;équipe&lt;/b&gt;, je peux lister l&amp;#8217;ensemble des tâches associées à une entrée du backlog si bien que je serais capable de déterminer si le développement de cette entrée est terminé.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;membre de l&amp;#8217;équipe&lt;/b&gt;, je peux changer l&amp;#8217;état d&amp;#8217;une tâche du sprint, si bien qu&amp;#8217;il sera possible de suivre son avancement.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;product owner&lt;/b&gt; ou &lt;b&gt;scrum master&lt;/b&gt;, je peux déclarer le début d&amp;#8217;un sprint si bien que ce sprint sera considéré comme le sprint courant.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;product owner&lt;/b&gt; ou &lt;b&gt;scrum master&lt;/b&gt;, je peux déclarer la fin d&amp;#8217;un sprint si bien que ce sprint ne sera  plus considéré comme le sprint courant.&lt;/li&gt;
	&lt;li&gt;En tant que &lt;b&gt;membres de l&amp;#8217;équipe&lt;/b&gt;, je peux consulter la liste des sprints terminés mais je ne peux pas les modifier si bien que je peux toujours consulter les archives.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans notre prochain article, nous mettrons en place notre environement de développement que nous nous empresserons de solliciter!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>L'Event sourcing c'est quoi?</title>
   <link href="http://arnauld.github.com/blog/2011/10/11/Event-sourcing.html"/>
   <updated>2011-10-11T00:00:00+00:00</updated>
   <id>http://arnauld.github.com/blog/2011/10/11/Event-sourcing</id>
   <content type="html">&lt;p&gt;Martin Fowler décrit l&amp;#8217;Event Sourcing comme:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Captures all changes to an application state as a sequence of events.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;En bref, au lieu de conserver le dernier état d&amp;#8217;un objet, on conserve toutes les transitions qui ont amené à cet état. En conservant l&amp;#8217;ensemble de ces transitions, il est ainsi possible de rejouer les différents états pris par l&amp;#8217;objet au cours de son cycle de vie. Plus important encore, ce n&amp;#8217;est pas seulement le changement d&amp;#8217;état qui est conservé, mais l&amp;#8217;intention de l&amp;#8217;utilisateur qui a provoqué ce changement.&lt;/p&gt;
&lt;p&gt;&lt;!--more--&gt;&lt;/p&gt;
&lt;p&gt;Supposons que l&amp;#8217;on se promène sur amazon. A chaque fois que l&amp;#8217;on tombe sur un livre qui nous plait, on l&amp;#8217;ajoute à notre panier. Au bout d&amp;#8217;un moment, notre panier pourrait ressembler à cela:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&amp;quot;Domain-Driven Design: Tackling Complexity in the Heart of Software&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&amp;quot;Applying Domain-Driven Design and Patterns: With Examples in C# and .NET&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&amp;quot;Event Centric: Finding Simplicity in Complex Systems&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&amp;quot;Streamlined Object Modeling: Patterns, Rules, and Implementation&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Quand on se décide finalement à passer notre commande, oh stupeur! on en a pour $201.20. Notre budget ne le permettant pas, après une sélection drastique, notre panier se déleste de deux livres et devient:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&amp;quot;Domain-Driven Design: Tackling Complexity in the Heart of Software&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&amp;quot;Streamlined Object Modeling: Patterns, Rules, and Implementation&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le montant s&amp;#8217;élève alors à $97.66, ce qui est acceptable pour notre budget actuel. La commande passée, il ne reste plus rien des deux livres que nous souhaitions acheter et que nous avons dû mettre de côté faute de moyen.&lt;/p&gt;
&lt;p&gt;Si maintenant, on conserve l&amp;#8217;intégralité des changements d&amp;#8217;états, l&amp;#8217;historique de notre panier (vu d&amp;#8217;un point de vue technique) pourrait être similaire à:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Domain-Driven Design: Tackling Complexity in the Heart of Software&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Patterns of Enterprise Application Architecture&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Applying Domain-Driven Design and Patterns: With Examples in C# and .NET&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookRemoved&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Patterns of Enterprise Application Architecture&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Event Centric: Finding Simplicity in Complex Systems&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Streamlined Object Modeling: Patterns, Rules, and Implementation&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookRemoved&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Event Centric: Finding Simplicity in Complex Systems&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookRemoved&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Streamlined Object Modeling: Patterns, Rules, and Implementation&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En conservant, l&amp;#8217;ensemble des changements d&amp;#8217;états on se rend compte que le livre &amp;#8220;Patterns of Enterprise Application Architecture&amp;#8221; a fait une apparition aussi dans le panier, ainsi que les deux livres enlevés à la fin.&lt;/p&gt;
&lt;p&gt;Maintenant en conservant l&amp;#8217;historique des intentions de l&amp;#8217;utilisateurs on obtient:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Domain-Driven Design: Tackling Complexity in the Heart of Software&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;PeopleAlsoBought&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Patterns of Enterprise Application Architecture&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Patterns of Enterprise Application Architecture&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;PeopleAlsoBought&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Applying Domain-Driven Design and Patterns: With Examples in C# and .NET&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Applying Domain-Driven Design and Patterns: With Examples in C# and .NET&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookRemoved&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Patterns of Enterprise Application Architecture&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;Search&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;event centric&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Event Centric: Finding Simplicity in Complex Systems&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookAdded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Streamlined Object Modeling: Patterns, Rules, and Implementation&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookRemovedOnBilling&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Event Centric: Finding Simplicity in Complex Systems&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;BookRemovedOnBilling&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Streamlined Object Modeling: Patterns, Rules, and Implementation&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On peux désormais constater que les deux derniers livres ont été enlevés du panier au moment du paiement.&lt;/p&gt;
&lt;p&gt;D&amp;#8217;autre part, on constate que le choix de certains livres a été fait en cliquant sur les livres présentés dans la section &amp;#8220;Les clients ayant acheté cet article ont également acheté&amp;#8221;, ce qui renforce l&amp;#8217;interêt de cette section. Ceci est très instructifs, et va permettre de cibler les prochaines suggestions d&amp;#8217;achats en privilégiant ces livres. En effet, s&amp;#8217;ils ont déjà suscité de l&amp;#8217;interêt jusqu&amp;#8217;au moment de l&amp;#8217;achat, il est fort probable que cela se reproduise.&lt;/p&gt;
&lt;p&gt;Ce qui est interessant, c&amp;#8217;est que même si l&amp;#8217;on ne dispose pas encore de notre mécanique de suggestions ou de nos outils d&amp;#8217;analyse, l&amp;#8217;information est présente et pourra être analysée lorsque nous aurons les outils adéquats.&lt;/p&gt;
&lt;p&gt;D&amp;#8217;autre part, on dispose de toutes les informations pour &amp;#8220;rejouer&amp;#8221; la constitution de notre panier, notre modèle est beaucoup plus riche que précédement et peux permettre une bien plus grande flexibilité. En effet, on a pu ajouter les évènements PeopleAlsoBought et Search sans que cela ait d&amp;#8217;impact sur la constitution finale de notre panier.&lt;/p&gt;
&lt;p&gt;Enfin, l&amp;#8217;un des points les plus importants est que l&amp;#8217;état final de notre panier importe peu. Cet état n&amp;#8217;a plus besoin d&amp;#8217;être conservé, puisqu&amp;#8217;il est possible de le reconstruire à partir des évènements qui le décrivent. Chaque évènement décrit une transition vers l&amp;#8217;état a atteindre. En conservant uniquement les évènements, il est possible de reconstruire l&amp;#8217;objet.&lt;/p&gt;</content>
 </entry>
 
 
</feed>