Design Level Event Storming with examples!

We covered a lot of ground. We started with the domain description and mistakes that I’ve made. Then we did the Big Picture Event Storming (BPES) to get the helicopter view of the whole business process and its events. Finally, we split this process into smaller units in the latest post using the Process Level Event Storming (PLES) technique. Today we are going to propose some designs for our solution. We will use Design Level Event Storming (DLES) to achieve this goal. At the same time, this is the last post about Event Stormings and next time we will be implementing our system.

First of all, I have to admit something: I love abstract thinking, and hardly ever do I have problems with it but this time was different. I have surely been an excellent example of the novice in the Dreyfus model of skill acquisition, no question. I expected some simple rules, flows, and conventions while putting the context and the goal on the back burner. I was looking for some notation at a push. All of that combined with my internal need to name things and abstractions, made me feel pretty confused. Having spent many hours in Miro, trying to create some models, looking at some other examples of DLES, and a couple of calls with Lukasz and Mariusz, eventually, something “clicked”. Well, it turned out that on the Design Level, I should… wait for it… design ;). An Event Storming is a tool used to visualize the business process, and there could be different designs supporting this process. That being said, there are different approaches to visualize those designs. We can choose/create notation or convention based on the project context, the workshop’s goal, or our preferences. The most important thing here is to visualize and propose the model that we think suits our needs best. That’s the difference between PLES and DLES. In the PLES, we were focused on processes, how they should work. Now on DLES, we should focus on models that support those processes. I just couldn’t get it.

The matter of taste

When it comes to modeling, let’s think about how we can use our sticky notes to do it. I’ve seen a couple of different approaches. I want to show you one that I’m going to use here and a few others so you can compare them.

Let’s start with a go-to book when it comes to Event Storming by Alberto Brandolini. Unfortunately, the chapter about DLES has just 10% of its target capacity, so there is not too much information about this workshop phase. The main message here is that we finally need to make decisions about the design. Even if we find something new, we need to develop an idea of how we want to solve that. It could be a bit hard, as in this part of the workshop attendees are often technical people, and we all know that we can talk about different approaches for hours. Nevertheless, we need to focus on proposing some solutions that support our business process.

In DLES, we introduce a yellow sticky note which indicates an aggregate. Brandolini suggests postponing naming it, and I tilt to this suggestion. Sometimes the first name “hides” the actual responsibility of the aggregate. Regarding the general approach in this part of the workshop, Brandolini presents a slightly modified version of the image we’ve already seen in PLES:

Source: Introducing EventStorming – Alberto Brandolini

I think it’s a good moment to share some of my thoughts now. There is not too much said/written about DLES in the book itself, and mainly this picture drew my attention. Unfortunately, I fell into the trap of using this picture as a schema to modify my artifacts from PLES. In other words: I wasn’t thinking about creating design but about putting a yellow sticky note into processes. I think I’m not the only one who was trying to do it this way. When I was looking for examples of DLES, I often met PLES artifacts/thinking with one extra sticky note. That’s why it’s a good idea to participate in the workshop with an experienced facilitator who can explain the difference between DLES and PLES.

Finding aggregate boundaries or proposing other designs/models in places where there are no aggregates will be my goal in DLES. That’s why I will use the notation I used with Lukasz in one of the previous projects but bear in mind that you can modify it to your needs. You need to visualize your models in a way that is easy to understand, even if you get back to the board after some time. It’s you who are going to implement those models, so everything has to be straightforward for you and your team.

Let’s get back to the approach I will use here. In general, I want to gather business rules, commands, and events that “occur together”, no matter where they are in the process (in PLES). I also intuitively know that I usually have some model that aggregates those elements together. That’s why most cases will look as follows:

From the left: we see commands, then business rules, then an aggregate, and finally events that are thrown by the aggregate.

Another approach I’ve seen lately is the one where you have events below the commands. Thanks to that, we can have commands ordered by the time when they occur. So, for example, in this approach the previous case with the advertisement, we could model as follows:

You can see the rectangle that more or less shows the aggregate boundaries, so we know which commands and events are connected with it. 

The different approach I would like to show you is the one from the ddd-by-examples/library repository. Jakub Pilimon and Bartlomiej Slota use the Example Mapping in their DLES:

And the final result looks like that:

The last technique I would like to mention is the one I’ve spotted on  Mariusz Gil’s Miro boards. Mariusz takes modeling a step further, and instead of presenting boundaries, he literally writes code entwined with sticky notes of commands and events. It causes a wow effect, as you can see the code even before sitting to your IDE. I encourage you to take part in Mariusz’s workshops so that you can see this approach in action. 

Let’s get this party started

Now, after discussing all those approaches, we are going to do some work. Finally, we want to propose models that, based on our current knowledge, support processes we defined in PLES.

Advertisement’s preparation

Let me remind you how this process looks after PLES:

I can tell you that you will witness quite a revolution here. Initially, I was thinking about some model of a draft. I wanted to support situations when the user starts filling up the form, leaves it for some time, and gets back to it after a few hours/days. Keeping a draft would prevent starting from scratch. I assumed that I needed some object here that would react to content changes, and if there are none, it will expire after some time. I also had another requirement saying that a draft should work for both: logged-in and logged-out users. It means we would identify drafts based on the id kept in cookies. I did not require support for multiple browsers/computers. Given all that, when I started to design the model I realized, that:

  1. we need to create a read model of the draft on the backend
  2. we need to refresh this model each time a user changes its content on the UI
  3. we need to remember to remove it from DB when there are no changes from UI
  4. we retrieve the draft for the user based on the value kept in the UI/browser

Can you spot what’s wrong here? Firstly, if the UI/browser controls the whole lifecycle of the draft, why do we even need it on the backend? Secondly, all that functionality could be done by a few lines of code on UI with local storage support. What’s interesting here is that we can support the process without the explicit model of the draft. We can just use what the browser gives us out of the box.

When we don’t care about the draft, we can skip everything that is before the payment. When it comes to the payment itself, I have just two requirements:

  1. no matter if the payment succeeded or failed, the advertisement has to be published. It means that we can publish the advertisement when we start the payment process. This decision simplifies the whole process.
  2. if the payment fails we need to send the information about the failure (some details) to the Customer Service

When I wanted to follow the notation I described in the first chapter, I got something like this:

Some of the commands that change the payment’s state are triggered after responses from the payment system. Moreover, we request the payment in the external system after we have created the object of payment. Unfortunately, the readability is not so good here, so in DLES, I decided to not stick to my general notation but to show the chronology:

The difference here is that the sticky note with payment’s aggregate occurs twice. So now it’s easier to see when we change its state. I write about “aggregate” here, but conceptually, it would be the process manager if I were to publish the advertisement only after successful payment. Nevertheless, in both cases, I would probably call it the “Payment”.


During the PLES, we came up with such a publication process:

We call it “publication,” even so it’s about hiding/putting on hold and resuming the advertisement. Maybe you somewhere have seen a similar process under the “availability” name. It’s pretty generic and occurs in this or slightly different form in most of the domains. I’m still not convinced of the “publication” as a name of the Bounded Context, so it can change when I start the implementation. 

When it comes to the model of this part, I would see it like this:


In the previous image (the one with the advertisement’s model), you could notice such a piece:

On the other hand, after the PLES, we had something like this:

You might have noticed that there is usually something more than just the “registration”. This part of the system usually is responsible for user management and grows to a whole module or even a separate service. Initially, I was also thinking about it this way. For example, I was thinking about the case where the Bounded Context responsible for banning recruiters would also communicate with this module.

Those “accounts” modules are often developed from scratch, have additional integrations with external services, and keep users’ data. At the same time, such a module exposes API, used by most services in the company. Even though sometimes the user management itself is delegated to some external service. We could model this case like that:

Nevertheless, this approach has some downsides. First of all, it’s an additional module. Secondly, API has to be implemented in such a way that all other services can use it. That’s why I decided to use another approach in this project. I will probably use something like Keycloak, letting other modules integrate “directly” with it. But, of course, as we don’t have control over Keycloak’s API, each of the Bounded Contexts will have a tiny Anti-corruption Layer (ACL). The advantage of such an adapter is that it’s tailored to BC’s needs. Thanks to that, “Publication” will use the registration functionality, and “Banning” will use only block/unblock functionality.  


For now, we will have here just an ACL that will communicate with the external service. Communication will be synchronous here.


When recruiters find an exciting advertisement, they can make an offer to the developer. The most important rule here, the clue of my whole idea, is two things: 

  1. a recruiter has to accept all developer’s requirements,
  2. a recruiter can make only one offer per advertisement.

Other rules specify primarily who and what can do with the offer. For example, it means only the recipient can reject the offer or add it to favorites. So our offer model could look like this:

“Self verification”

In the first post about Event Storming, you may recall that I totally messed up the idea of this part. I was using events that I had no access to. I mean, those were, in fact, external system events that occurred outside of my domain. Fortunately, it came up quite early. During the PLES, I knew that I just needed to query the external systems about whether the developer solved any tests.

When it comes to the design, it looks like we need two things here. First is a simple CRUD for the links (URLs) to tests in the external system. The second is an integration with the external system that can query it on-demand and give us the list of tests solved by a specific developer. Having those two parts will allow us to manage views with the developer’s badges.

Banning recruiters

Banning is for sure a process that I would skip in the MVP phase. But, nevertheless, we’ve had a lot of discussions about this part, and what’s more, it has one interesting quality: in general, it’s actually a consumer complaint. So that’s why you may already see this process in other domains. Take a look at how I designed it during the DLES:

We can spot two parts here:

  1. On the left – probably some kind of process manager, as it’s quite an asynchronous process. It can be initiated by a developer, who felt scammed in the recruitment process, or contrary – wants to commend the recruiter. The developer fills up the “review form”, where they rate a person who made an offer. We send this review to an external rating system, which recalculates the overall recruiter’s rank. When we get the response and see that the rank drops below some threshold, we create a complaint.
  2. On the right, we have the “complaint” itself and its state management.

Even though we call this part “banning”, you can see that we have two concepts here: ranks and bans. We could split them into two separate contexts, but for now, we are interested only in negative ranks, so we will stay with a single context.

Food for thoughts

As developers, we design every day. We may not be aware of it, but each method, each class, has some design. Unfortunately, we rarely visualize it in any form. Instead, we keep it in our heads, where we build huge models and connections between them. It seems that we understand all that entanglement pretty well, as we notice many implementation details and business rules. But, in fact, all that is usually a misleading impression. We realize that when we start to “dump” all those models from our heads to code. There is always something that doesn’t fit.

Design Level Event Storming gives us the advantage of experimenting with each idea that comes to our mind. There is no doubt that we have forgotten something on the way back from lunch ;). Our models are still on the board in the form we left them there. We can move sticky notes around, check different approaches. Thanks to that, the final models that we’ve decided to move to the code are more thoughtful. Of course, our models can still change during the implementation, and we even have a name for that: modeling whirlpool. But those changes will usually result from a better understanding of the domain than the fragility of our memory. In such a case, we can get back to the original board and evaluate a new idea by moving some sticky notes again. Artifacts of DLES are ideas for models. They are not etched in stone. Sometimes, it’s also good to implement some prototypes during the workshop to have a closed feedback loop.

That’s all that I have for you about Event Stormings. We went through all its stages, and now we are going to move models to the code. In the next post, we are going to start doing it on our fancy tech stack. I may surprise you with some of my choices, especially that it will be an “all-in” approach: DDD, event sourcing, and CQRS!!! Stay tuned! Don’t miss it and subscribe to the newsletter!

* indicates required

Process Level Event Storming: let’s get this process started!

Last time we were talking about Big Picture Event Storming (BPES) and now we have a helicopter view of our business process. Next, we need to climb down and model sub-processes that will address our business requirements and issues. We are going to use Process Level Event Storming (PLES) for that.

Back in the BPES workshop, we could notice some smaller, autonomic sub-processes within the whole process. Now we can focus on each of them and take care of the details. PLES gives us a few additional elements that will help us in this job. 

Together with my guests, we created a part responsible for banning recruiters. Then I decided to do the rest independently as I didn’t want to take more of their time. It turned out that the image from Brandolini’s book was great support for me:

Brandolini calls this image: “the picture that explains everything”, and I can’t agree more.

On the BPES level, we were using only events. Now, we will use a few new elements, which you can notice in the above picture. So let’s take a moment to take a closer look at them and the whole cycle:

  • The user, based on some impulse from the real world, decides to take an action. Usually, their decision is driven by information from the system (read model – the green sticky note).
  • The user is taking action (command – the blue sticky note), which will be handled by the system (the pink note). As a result, the event will be produced (the orange note) – information about the change in the system.
  • When the event occurs, two things can happen:
    • policy/reaction (the purple note) to this type of event, which will result in a new command
    • changes in read models, which in turn can give the user new information to make other decisions.

Ok, let’s use this knowledge in practice now! First, we will take a closer look at the advertisement’s draft process.


After the BPES workshop, this part looks as follows:

Now let’s think how this process should look like. Who should make the decision? What information should this decision be based on? Do events require any reactions? What has to happen to trigger a specific event? To sum it up: we need to use the knowledge we gained from “the picture that explains everything”. Thanks to it, we can design the process here as follows:

Before we go any further, please notice the purple/lilac notes. Those are policies – do not confuse them with a strategy/policy design pattern. Those here are the reactions to some events that should be a trigger for a command. Brandolini, in his book, describes them as follows:

“Of course there has to be some reaction to the event. We can capture reactive logic with (lilac) Policies, like “whenever we receive an order, we add the corresponding pizzas to the backlog.””

Ok, let’s get back to the modeling of the advertisement’s draft. Everything starts when a programmer (candidate) creates a draft by filling up the advertisement’s form (1). That’s the information for the system that it should store this data, in case the user wants to finish the whole process later on. In other words: we create a read model of the form (2). When the user makes any change to the form, the content of the draft will be changed (3). From the domain level, we are not interested in what exactly has been changed. We only care about the fact that it was changed so that we can update the read model. Then, when the user is done with the form and has chosen the payment option, he/she pays for the advertisement (4). Now the external payment system kicks in and eventually gives us the info whether the payment was successful or not (5). Finally, you can notice an interesting business decision: no matter what happens, we publish the advertisement (6). I decided to make this part of the process less complex. I assumed that the failed payment in an external system would be a pretty rare case. It makes no sense to focus on all cases that can go wrong and postpone the publication, at least at the start of the business. For now, let’s publish anyway, and when we eventually get the info that payment failed, we can send this information to the Customer Support. They can decide what to do with the advertisement. Maybe they will retrigger the payment, remove/block the ad or contact the developer to clarify the situation. If we get the information that there are too many such cases, we should solve the problem then. For now, let’s do it the agile way 🙂

It’s worth noticing that when we create a draft, another parallel process kicks in (7). Its responsibility is to remove all overdue drafts, not to store them too long in our system. So, first, we give them some time to live (TTL). Then, each time the draft is updated, we renew that time (8). Finally, we remove the draft when TTL is exceeded and the developer did not publish the advertisement (9).


Every single app has a registration, right? It’s quite a generic process, so that’s why we didn’t care about it during the BPES. It means that I can’t show you the “before” state. Even after PLES, there is not too much to consider:

Usually, there is a belief that “our project is specific”. That’s why so many applications implement a separate service/app called something like “Accounts”. Nevertheless, in practice, it turns out that a service like Keycloak could often replace it. That being said, we are not going to overcomplicate this part. Even if we don’t use any off-the-shelf solution, we will simplify this process to a single step.

Publication process

After the payment, the advertisement can be viewed and searched in the system. Nevertheless, its life cycle ends when the paid time expires. During that period, the advertisement can be unpublished and published again due to different reasons. That’s why we decided to call this whole process: the publication process. Quite often, when we notice “published” and “unpublished” states, we can try to model the separate availability subdomain. However, we will not do it now, and we will stay with a bigger publication subdomain.

Let’s describe this process step by step. After the payment, we get the request to publish the advertisement (1). We react to this by making it available for searching and viewing (2). When we publish the advertisement, we also start the period when it is available. When it ends, we remove the advertisement from the service (3). To keep this process simple, I again decided to skip the cases where the user could extend this period or create a new advertisement based on the old one.

When the advertisement is published, two things can happen:

  1. A developer can decide about unpublishing it (4). This can happen when there is still some paid time available for the advertisement (it doesn’t make sense to unpublish it when it is already “outdated”). Then we put the ad on hold (5). It means that the user’s list of inactive advertisements is updated. Based on that list, a developer can decide to publish it again (6).
  2. Another case when the ad can be temporarily put on hold is when Customer Support does it. The whole process looks similar to the previous one, but different people make decisions. Moreover, they do it based on other premises or data. Customer Service can put the ad on hold when they get some complaint about it (7). 

It’s noteworthy that we will not decrease the paid time when the advertisement is on hold in both cases. Instead, we will start doing it again when the advertisement resumes.

Just to remind you how this part looked like after the BPES:


It can happen that something that was an event during the BPES isn’t actually an event. An excellent example of it would be the “Advertisements found” event.

Search has nothing in common with the change/modification in our system. That’s just a query. Then, based on the available filters, the recruiter asks the system about the advertisements that meet the selected criteria. That’s why on PLES, we decided to represent this part as follows:


Let’s focus now on the key process – offering. That’s the part that differentiates our solution from the typical approach. First, a recruiter will have to accept all developers’ requirements if they want to offer any. Then, the offer can be read, rejected, or added to favorites.

After a PLES session, this process looks as follows:

Everything starts on the advertisement page. Recruiter, seeing it, can make an offer (1). They need to accept all requirements and give some contact details. Then the offer details are available to the developer on the offers page (2). This page can be a “starting point” for a few different actions. The most interesting one from a modeling perspective is “Mark as opened” (3). Notice that the UI triggers this one. You may ask why.  So UI will present the new offers as… new ones – not “read”. Then, the developer can click any of them to see the details. This action itself doesn’t change the system’s state, as in this case, we just query the system for more information. Even more, we could already have those details fetched but “hidden” by UI. That’s why after displaying (sometimes after 1-2 seconds) those details, UI sends the command to change the offer state to “opened”/”read”. You could see similar functionality in email clients.

A developer triggers the rest of the commands on this page. Those can be: rejecting the offer (4) or adding to favorites (5).

“Self verification”

This process was quite interesting already in the Big Picture Event Storming. That’s because we cleaned up many events specific to the external system and not ours. To remind you how it looks like after the BPES:

The event informs us about the start of the verification process. What we want to achieve is to give the whole process on our side some TTL (time to live). All that sounds a bit… complex. There is also still a significant coupling between us and an external system. It became even more complex during the PLES part. That’s why I ended up with a much simpler solution:

In this approach, we do not rely so much on the external system as in the previous one. Foremost, we don’t assume this system will expose any information about verification progress on their side. The only requirement for integrating with the external system is that it exposes the API with available tests and tests solved by the specific developer. But let’s follow this process from the beginning. First, the developers go to the badges’ page and see badges they can achieve (1). Each of these badges is linked to the appropriate test in the external system. It means the developer gets redirected to the external system and can start solving the test there. The whole process happens there, and we should not even care about what’s going on or how long it takes. When the developer is done with the test, they can get back to our system and initiate the synchronization (2). It means that our system will query the external one to get the tests’ results for a specific user. Based on the response, we can check whether the developer has achieved any new badge (3). If yes, we update two views: developer’s badges and badges to earn (4).

Banning recruiters

Last but not least, we have a process that we found the most interesting. Actually, we were modeling it in the first instance.

This part after BPES:

On PLES, it ended up as follows:

After the recruitment process, we want to give a developer the chance to evaluate the recruiter who has put in an offer. We assume that the trigger for that action could be something outside of our system (1). It could be, for example, a total mismatch between what the recruiter accepted in DevMountJob and the real offer. The developer, based on the experiences during the recruitment process, evaluates the recruiter. Then evaluation gets to some ranking system (2). This system recalculates the overall rating for the recruiter. Suppose the value falls below some predefined threshold. In that case, we should send a complaint to the Customer Support (3). Now process forks into two paths:

  1. The note has some time when it has to be processed (4). If Customer Support doesn’t handle it within this timeframe, we will need to handle it. It will get to the list with overdue notes. Thanks to that, we can monitor how many requests are not handled in a given time. We can introduce some notifications when there are too many of them or whenever the new one appears on that list.
  2. The note is processed in a given timeframe. Customer Support, based on the history of the recruiter and all other evaluations given by the developer that did the last evaluation, can make one of the two decisions:
    1. ban the recruiter (5) – the recruiter will get information (probably via an email) with the contact details to clarify the situation. Then, Customer Support can unlock the account (6)
    2. reject the note (7) – Customer Support can do it after analysis of additional data. For example, some evil developer could intentionally decrease the recruiter scoring by creating a lot of negative notes 😉

This model we got for the banning process is actually quite generic. I mean that there are many processes in other domains that could be designed the same way. For example, the refund process, to name one of them.


We’ve just done a hell of work! We designed step by step one process after another. We introduced new elements so that we could focus on details. Thanks to that, we could also validate previous assumptions.

Good job!

I bet many projects would benefit from designing their processes on Events Storming workshops, so please help me share knowledge about this technique by sharing this post!

Next time we are going to focus on Design Level Event Storming! Don’t miss it! Subscribe to the newsletter, so you will be the first to get to know about it.

* indicates required

This could be the biggest post about Big Picture Event Storming ever! And with examples!

It’s time to dirty our hands. In the last two posts, I presented the failure of the project. I described the idea of the business model and the requirements I had at that time. Now I would like to add a plot twist. Let’s use this business knowledge and practice some modeling techniques and the DDD approach. In this and the next two posts, we will be working on Event Storming. We will take the described domain/idea, and we will use it as a base for the workshop.

Event Storming – why should I even care?

If you saw a picture of a bunch of people standing in a room and putting their colorful sticky notes on the wall, it could be an Event Storming session. It may sound like another soft skill workshop, but we couldn’t have been more wrong in this case. Event Storming is a powerful tool for business process modeling. Not only “business” as there are even stories about people using it for planning their wedding 😉

But why the sticky notes on the wall? Because it is the easiest thing we can do. At the beginning, your only job is to put the past sentence (business event) on the note and stick it on the wall. This together with the subsequent process stages make a quick workshop session that can expose the lack of knowledge about our business process. Moreover, it’s a great way to share domain knowledge between participants. That’s why it is essential to invite domain experts, a dev team, business people, and anyone else who may have an interesting perspective on the topic.

Having a facilitator who has experience in running such workshops can also be a game-changer. They usually have a toolbox full of heuristics (today, you will also learn a few of them), which can help participants think out of the box. Moreover, facilitators usually have a tech background in creating software systems, so they can notice patterns and solve complex problems quickly.

Event Storming session for Poznan’s community, hosts: Mariusz Gil and Grzegorz Nowicki

The Event Storming technique was introduced in 2013 by Alberto Brandolini, who still actively promotes it worldwide. His book is available on Leanpub. Even though it’s 70% finished, it is the best source of knowledge about the technique.

In my local community, we have Mariusz Gil, who promotes Event Storming a lot in the international arena. He will also play a vital role in this post, but we will get back to it later.

Event Storming at the PHPers Summit 2019 conference, host: Mariusz Gil

Event Storming levels off participants’ knowledge, and helps build a common understanding and finding issues in the whole business process. It also enables us to tackle the complexity of the problem and decision making. It is essential because the business process is often split between different components or even departments. Teams working on their “part” focus and make decisions only there – “locally.” Sometimes teams are not on the same page and, as a result, they can harm the whole process. Event Storming is a tool used to avoid such a situation and to give us a big picture. Thanks to that, we can find optimal and global solutions to our problems.

There is another huge advantage of Event Storming – it helps find patterns on a problem level, which is usually harder but brings simpler solutions. As programmers, we have many libs, services, good practices, or patterns that we use daily. In other words, we focus on a solution instead of a problem. That’s why we should know the domain we are working on, and that’s flat. We knew about it already in the 70s while researching cohesion, and nothing has changed since then. The better code you want to write, the better understanding of the process and business model you need to have. There is no one better to ask than business or domain experts. On the other hand, as tech experts, we can help them with improving and automation of some problematic processes.

Event Storming is actually a set of workshops, starting with a Big Picture Event Storming (BPES). On BPES, we want to see, well… a big picture of the business process – we want to catch sight of participants’ perception. BPES is split into a few phases, and the original pizza recipe (Brandolini uses this metaphor) has around 6 of them:

  • Kick-off – describes the workshop’s goals, a quick introduction of participants, and an explanation of how the workshop is going to look. It’s also a time for an optional warm-up. 
  • Chaotic exploration – sticking orange sticky notes to the wall. On each note, there is a past sentence that describes a business event. 
  • Enforcing the timeline – in the previous phase, each of the participants was sticking notes in different places. In this phase, it is important to order them on a timeline so that we see when they really occur in the whole process. Thanks to this, we can spot some duplicates or different namings for the same event.
  • People and systems – events are usually triggered by particular persons, departments, internal or external systems. Now it’s time to show them in our BP.
  • Problems and opportunities – till this phase, as you’ve probably noticed during the workshop, some places/events were problematic or generated disputes between participants. A hotspot is a name for such a piece of the business process. We are looking at each of them and trying to decide whether it’s a problem we should address or the opposite – an opportunity.
  • Pick your problem – as we probably can’t solve all issues straight away, we should vote to prioritize them.

We could split all of those phases into smaller pieces with specific techniques, but we are not going to do it in this post, as even Alberto encourages us to experiment and work with approaches that work for us. He also points out that those phases can be different when we model an existing process, new functionality, or a startup. If you want to know more about the whole technique and go more in-depth, I recommend reading Brandolini’s book.

We will have our pizza recipe there, let’s see how it will turn out. Hopefully, there won’t be any pineapple on top 😉

The next stage after Big Picture Event Storming is Process Level Event Storming (PLES). In PLES, we focus on the solution, and we model things like we would like them to be. Moreover, a few new concepts will pop-up, like commands, read models, and business rules.

The last part of the workshop is the Design Level Event Storming, where we create a final model that can be moved 1:1 to the code. It’s quite a technical part, so usually only developers participate in it. We introduce an aggregate term here. We can also notice one more advantage of the Event Storming – it’s easier to change names or models on sticky notes than in the code. If something just doesn’t sound right to you, you throw it away or replace it with a different sticky note.

Find problems when modeling, not while implementing. Host: Mariusz Gil

Regarding the workshop itself, it’s essential to keep in mind the purpose of doing it in our project. In other words, we should define the goal before running the workshop. Sticky notes on the wall are the visualization of the process and not the goal itself. The goal is what we want to achieve by having such visualization. It may speed up the process, its automatization, or the list of issues that occur in the process.

A titbit about my failed project

I didn’t mention that before, but it relates to this post very well, so I will do it now. From the very beginning, Andrzej Krzywda was supporting me in my idea. He ideally joins the roles of the programmer, entrepreneur, and marketer. I will tell you a bit more about Andrzej later on, but now I just want to say that he showed me how important it is to think about marketing and selling the product and talking with business people. 

One day, we met with Andrzej in his house next to the forest, and he suggested that we could do a quick Event Storming of my idea. We didn’t have any agenda, phases, nor conventions regarding the colors of sticky notes. We just grabbed them, and we started to produce some events. After a few minutes, we had the following result:

You don’t have a wall? Use the door!

I focused only on the system’s events, like “advertisement was created” or “offer was made.” On the other hand, Andrzej was thinking about events that occurred in the developer’s life and pushed him/her to look for a new job. As a result, events like “Toxic PM detected,” “Ruby/Elixir experiment started,” or “Interested in remote” popped up.

Some other ideas appeared as well. For example, we could analyze some events, like the one about adding a new advertisement and notice different types of people on the HR side. Let’s assume that a CTO is looking for some tech leads. He is notified each time an advertisement is added when the developer has finished some architectural courses/certificates. Another idea was to have a widget that could be included in external blogs and display advertisements of developers who have skills matching some post keywords. The reason for that was that people looking for developers to their teams also read blog posts :). Both of those functionalities could be paid.

This session was the biggest Aha moment for me. As a tech person, I was focused only on the system events, which is fine when it comes to Event Storming as we want to model the system, but Andrzej showed me a totally different perspective. He was thinking of how I can sell my product and get some traffic.

I decided to mention this whole story here, as I think it’s a great introduction to the next chapter. Long story short – you don’t have to stick to any strict form of the workshop. It’s also a visualization tool that you can use for different purposes.

Our form of the workshop

Alberto Brandolini says that an Event Storming workshop should not have a fixed form, and he encourages people to experiment with it. Giving it a structure and following some defined steps is a common mistake. For example, if you have something in your domain that is important and deserves its own notation – go for it! There are some default meanings of colors, like orange for events, or blue for commands, but if for some reason, they don’t work for you, don’t let them stop you, and use different colors. To give you an example, Mariusz once ran the workshop where they wanted to visualize the processes of DB operations in the application. To do that, they decided to assign specific statements (INSERT/UPDATE/DELETE/SELECT) to particular colors.

It is worth mentioning that experienced facilitators play an important role because they usually have a rich toolbox of techniques and heuristics. They can use a different set of those tools based on a group of attendees or the project type.

Although we don’t have to run all phases of BPES, two of them almost always occur: chaotic exploration and enforcing the timeline. We decided to go just with them to run BPES of the domain of this posts’ series. I wrote “we” because I invited three other people to support me with it. Each of them has huge experience in programming and gathering business requirements from customers. Ladies and gentlemen, may I present to you:

  • Mariusz Gil – I told you he is going to play an important role here ;). Mariusz has been in the IT industry for over 20 years. He is passionate about designing and implementing systems with complex business requirements, machine-learning, and solutions that give real business value to his customers. Mariusz takes to conferences like a duck to water and is extremely outgoing. If you meet him at a conference, don’t be surprised that you will be talking about totally different things than IT after a few mins, and you will feel like you’ve known him forever 🙂
  • Łukasz Szydło – he is one out of three mentors in a best-selling ($3M) online course for software architects in Poland. Programmer, architect, trainer, and consultant. He shares his knowledge at conferences. I’ve known Łukasz since my start in IT – he was my first mentor, and I’m delighted that I can still work with him sometimes in various projects. 
  • Andrzej Krzywda – founder of the Arkency software house, which is well-known in the Ruby community all over the world, organizer of wroclove.rb conference, speaker, writer, blogger. As ardent OOP enthusiasts, we like to whine about its current state, even though our points of view may differ a bit. Usually, we do it while hiking together. Lately, we did a live code review session of the Rails app, and you can watch it here.

As we know each other, our Event Storming sessions were quite casual. Thanks to them, we also had a chance to talk and share some thoughts and experiences, which was cool in those COVID times. Sometimes we were drifting and touching different topics, but as a result, we shared a lot of knowledge, and now you, my dear reader, will gain from it.

Before the workshop, I had some business requirements, and you probably know them if you read previous posts. Nevertheless, because I want to give you as much technical and practical knowledge as possible, I was open to different approaches/solutions. Considering our experience, I was pretty sure that the original idea could change a lot. That’s actually one of the most significant advantages of Event Storming – depending on how open we are, it can lead us to changes/improvements/optimization, even on the level of the whole organization.

Due to COVID, all workshops had to move online. Before COVID, there were discussions about whether it makes sense to run such a workshop remotely. Now it is a new norm. It turned out that thanks to great tools, it works pretty well. In our sessions, we used Miro, which became the standard tool for the purposes of Event Storming. 

If you want to listen more about the remote aspect of ES, you can listen to one of Mariusz’s podcast episode. He is talking there with Alberto Brandolini, and I encourage you to listen to it (the episode starts in Polish, but around 04:55 it switches to English).

OK, let me show you in great detail our ES sessions now.

Ready, steady, go!

Before our first session, I sent the domain description to the guys, and I uploaded some original wireframes to our Miro board. We had them for reference, so I could quickly explain the flows on the example. 

Then we started chaotic exploration. Each of us was putting events on the board. First questions, ideas, and discussions popped up. We decided to mark “nice to have ideas” as green notes. It’s a good practice as it usually unleashes creativity. After a while, our board looked as follows:

Please take a look at it and try to refer to the domain description from the first post. You can spot here that some events are organized into some kind of batches/groups. That’s the result of using a “Bulk Mode” feature in Miro. It is a useful functionality in the early phase of a workshop because it allows participants to add a few events at once. You add them as rows in a separate modal form, and after a submit, they are added as “sticky notes” to the board. 

All events were added in quite random order at this stage, so we started the next phase – enforce the timeline. My task was to narrate the whole story. At the same time, I could add some additional information about some pieces, so we had a few extra discussions. Then, Mariusz presented a heuristic that he calls “fantastic four” or “0, 50, 100, 150”. We can usually use it when we observe a  “binary” event – something either happened (100%) or something didn’t happen (0%). Sometimes we have two additional cases: something happened partially (50%) or there was too much of it (150%). In our case, such an event was “Advertisment’s requirements were accepted.” I had a yes/no mindset here: the recruiter accepts or disapproves the requirements. Mariusz suggested that we could try to use the “fantastic four” heuristic because in the real world, in such a situation, there is a place for negotiation. For example: “we don’t allow remote work, but you can bring your pets into work.” We wrote down this idea to consider it in a later part of the workshop.

Another typical example when this heuristic can be used is a payment process. Intuition tells us that we have only two options here: payment succeeded or payment failed. In fact, in the real world, we can have at least four cases:

  • 0% – payment failed
  • 50% – only a part of the payment was paid – due to some typo
  • 100% – payment succeeded as it should
  • 150% – user paid more than needed (typo?) – now we need to trigger a process of some refund

OK, let’s get back to the rest of our events now. We have them in the correct order now. We didn’t remove any duplicates nor needless events yet. Nevertheless, we marked some smaller, quite independent parts of the whole process, telling us about the possible subdomains. It will help us focus on smaller pieces in the Process Level .

At this stage, the board looked as follows:

Below you can also see our 90-minute session in a 90-second video:

In the next step, we put a line to separate from the results of our work. We started to put only domain events under this line – events that cause some real changes in our system’s state. At the same time, we removed some duplicates. We also agreed to skip events from functionalities that will not be implemented in the first iterations. As a result, we were able to visualize our first business process and business model.

To remove all “unnecessary” events, we used another helpful heuristic that concentrates on the event types. Mariusz told us that in his workshops, he distinguishes between 4 types of events:

  • environmental events – exist outside the system – in the real-world, for example, a person entering the shop. Usually, they are not crucial for the workshop, but they help to get the context.
  • UI events – we are clicking/using the UI, but we don’t “submit” our choices. We don’t change the state of the system. As an example: we can choose between pricing plans on UI as many times as we want, but until we confirm our decision, nothing actually happens in our system.
  • infrastructural events – refer to technical things and don’t impact the system at all: “Event to Kafka sent”, “Metric increased”.
  • domain events – the heart of the Event Storming. We should focus only on those in our workshops.

Using the above assumptions and heuristic, we changed the Big Picture as follows:

Let’s go now piece by piece, from left to right, and see what changed. 

At first, we removed all events connected with lead generation: 

You won’t find them in the After section because they don’t belong to our system (at least the one where we have advertisements). They happen “before”, so they can occur in the funnel. They will be essential for the marketing/sales department. We can think of another small app that measures the level of developers’ burnout. When the app recognizes that you should change your job, it can lead you to DevMountJob. 😉

Now I’d like to draw your attention to an interesting reduction of events:

Here you see in action the second heuristic I mentioned – the one about different types of events. We removed all UI events. Notice that “Added a certificate” or “Marked remote job as required” don’t change the system state at all. Those are only actions on UI. In other words, we are working on a draft of the advertisement – we are preparing it. We can describe all those events as one: “Draft was modified”. Actually, we could have no events here if we decided to have no draft concept in our system. Nevertheless, we want to have it because we want users to continue the preparation process even if they leave it for a while. Otherwise, we could remove all draft-related events, handle everything by the UI, and have only a single event when the form is submitted, and the advertisement gets to the system.

When the advertisement is ready, we get to the payment and publication process:

We have some changes here as well. When reading the domain description and my requirements, you could have the impression that I didn’t have a clear idea as for that part. That’s why we had a long discussion. Lukasz pointed out that if the advertisement is available for some period, maybe instead of going on with some pricing plans, we should sell time. If a user wants the advertisement to stay longer in the search results, then they pay a few extra dollars. We liked it, and that’s how the first business model was born. Thanks to that, we could skip all that part with pricing plans. By the way, we also put the hotspot (pink sticky note) here just to mark the place where we had some concerns.

Initially, I also had an idea that after the publication, the advertisement is read-only. I simply wanted to prevent the situation when the recruiter accepts the developer’s requirements, but then they are changed, and we have some inconsistency. In practice, the read-only mode could be really annoying. Imagine that you made a typo and want to fix it after a day or two. The first idea to solve this issue was to give a user X mins after publication to edit the advertisement. That’s why you can see a “Time for adv. edit expired” event in the first version. But then we realized that the recruiter accepts the developer’s requirements that he/she has at a given moment in time. It led us to the idea of something like “snapshot” – an offer made to the specific requirements. 

Now let’s move to the offering:

Do you remember the idea of negotiations? Well, the business didn’t get it 😉 and decided that the recruiter needs to accept all developer’s requirements. We left a note about that and we could move to the last two processes: banning recruiters and developers’ skills verification. It’s important to mention that you can see them as the last ones on the time axis if you look at the whole picture. Nevertheless, each of them can occur at any time in the entire process. Sometimes it’s good to mark such a process with an indicator, but we didn’t do it.

We are going to take a closer look at banning now:

Notice that only the wording of two events has changed:

“Ban request sent” was changed to “Ban requested”

“Unban request sent ” was changed to “Unban requested”

Word “sent” slightly suggests a form of the activity. In the first version, we meant here some kind of HTTP request sent from the HTML form. In practice, in such situations, we should be opened to other options. For example, a ban request could also be made via mail, phone call, Slack, or fax, you name it. It is a small detail but often helps to notice approaches we’ve never thought about.

Now it’s time for the last process – candidate’s verification:

I decided to include this process in the first version of the product, as it shows how to integrate with the external system. Moreover, it is a long-running process. As advertisements are anonymous, I wanted to give developers some optional possibility to show their skills. In other words, they could get badges after solving some tests in the external systems like DevSkiller. You can notice a reduction of events specifying readiness and the start of the test. That’s because those events are outside of our domain, and they belong to the external system. We would only want to start the verification on our part and get the test result when it’s solved.

That would be it when it comes to our Big Picture Event Storming. In the next post, we will do a Process Level Event Storming and model each of the processes in detail – solution space. Now a quick summary and the homework 🙂


Even though the Event Storming workshop has a simple form, it’s not easy itself. It requires business thinking, which may be totally different from what we have in code or UI. It helps us to notice real business events that occur in our domain and change the state. 

It’s a good idea to participate in the Event Storming workshops led by an experienced facilitator (like my guests). I encourage you to do so!

Now it’s your turn!

I hope we’ve piqued your interest with this technique and that you want to experiment on your own now, so it’s time for a call to action 🙂

Conduct a Big Picture Event Storming workshop. You can even do it alone, but the more people you convince, the better. For modeling, use the business process that you support daily. If you don’t want to use this one, you can use mine – there is enough information to do it in this and the previous posts. No excuses! 🙂

Enjoyed reading this? If you would like to see Domain-Driven Design and Event Stormings on a real-life example, don’t miss the next posts. Subscribe to the newsletter, so you will be the first to get to know about them.

* indicates required

The story of how to NOT start a project.

In the previous post, I described in great detail what we are going to do in the next few months. Today I would like to give you some insights into what was going on in my head when I was trying to launch that SaaS idea. This post is some kind of “behind the scenes” type of text. I’m going to show you how the idea was born, how I “validated” it, how much time and effort I invested in it, and finally how I failed. To sum it up, I will show you how to probably not start the project.

An idea was born

Like a lot of great ideas in this world, also this one had its dawn of time in… a drunk night. Well, I met my friend after a few months, and he said it would be cool to have a headhunter company. That company would verify developers and put them on their website in some kind of “auctions.” You may think of it as Amazon or eBay with developers ;). The idea popped up after I told him about the money I earned from recommending my friends for some job offers. As you can imagine, after a few shots, we were really optimistic about our great business model. We even talked about it a few times after that night. But an idea without execution is nothing, so suddenly it failed for its first time.

Later on, I was working on a project where such a reversed model of search used to work pretty well. That gave me extra energy to try one more time. I changed the idea quite drastically, as I wanted to remove everything, to skip the verification process and the need to run a headhunter company. The new idea was to just give developers the ability to add new advertisements – a simple CRUD application. On the other hand , there would be a search feature that recruiters would use. A few days of work and I could live my rich life ;).

At the same time, I read articles and listened to podcasts that were talking about problems in the hiring process. After “research,” I got to some conclusions that you can find in the previous post, so if you haven’t read it yet, catch up with it :). The idea was born at that stage, and my side project got the “DFS” codename, which stands for “Developers For Sale.” Yup, I know, sounds scary, but I can assure you – I was not objectifying developers ;). I had to think about a new name, and we will get to that soon. First, I would like to show you my business validation.

The idea’s “validation”

A real entrepreneur knows that before doing anything, the business idea should be validated. As an aspiring entrepreneur, I decided to create a pool. The problem was that I was pretty fixed on my vision of the final product, and I didn’t want to change it in any way. Instead of asking about pains in the hiring process, I asked users to anonymously leave their skills, desired location of work, and how much they would like to earn. Thanks to this, I was able to validate whether people are not afraid of sharing such a piece of information.

Ok, so at that point, I was set about what I was going to ask, but I had no idea where I could let people know about the pool. I had no audience at all. Asking people directly or on any Internet groups was a blocker for me. Luckily, a friend of mine is an IT blogger/vlogger, and he allowed me to put a short video on his vlog. That was actually an excellent idea, but at the same time, that’s the end of my entrepreneurial skills… Any business-oriented person would grab a smartphone to record a 2-min video, then would take some tool for creating surveys and create one in the next 5 mins. But no, I know better, I have to go “professional.” I need a name, a logo, designs. Moreover, a video had to be recorded by another friend of mine who does this daily. There had to be music in the background, my name popping-up, and a big logo, at the end of the video.

As a result, the survey itself ended up looking as follows:

After filling in the form and submitting it, a user was redirected to a “thank you” page. There were social media widgets to allow sharing, and a form to leave an email address. You may think now that something is not right here – I was talking about anonymity, and now I ask people to leave their email. Believe me or not, but I was really serious about the anonymity of users in that product. That said, I can assure you, that email form on the thank you page was not connected in any way to the survey. The only purpose was to build a mailing list of people interested in what was going on.

When all that was ready, my video was added to the vlog’s episode. There were no details about the product itself, just asking people to take part in the survey. I don’t recall exactly, but the numbers were around: 300 took part in the survey, and 100 subscribed to the mailing list. That was a great success for me.

First things first

Now let’s focus on “the most important” things in running your own business: the name and the logo. How are people going to fill in the form if there is no logo and name? Yup… That was me thinking about business back then ;). Nevertheless, the story is quite interesting, so I will describe it here.

Some time ago, I was working on a small side project with a guy who got his Ph.D. in History of Art. He came up with the name and designs for that project. I really liked them and the whole idea behind them. That’s why I asked him for help, as “Developers For Sale” doesn’t sound good ;). As he is also a Linux user, after a few days, he got back to me with the idea of “mounting a new job by developer” from a command line. Like you would mount a resource in Linux. It would look like this in CLI:

I was delighted. This was not only because of a reference to a command line but also as there was a “$” sign. Moreover, “mount” can bring to mind mountains (Mount Everest), which may be a reference to the career path. Mind blown, isn’t it?

Then I described the whole idea to the designer, and after a few days, I got such visualizations:

The first one got my attention, but now when I look at them, maybe I would choose the second one, as it’s a bit retro. Which one do you like better?

Both of them refer to a command line, and both have a “$” sign. Maybe its meaning is not so obvious when you take a look at it for the first time, but I was really proud of it. In case of earning millions of dollars on my new SaaS, I was prepared to explain this deep meaning in interviews ;).


I knew what kind of views/pages I wanted to have, so I prepared quite detailed mockups. I sent them and a project description to the designer, and,  after a few days, I had the first version that I accepted. You can see them below:

We are almost there…

Now the fun begins. Long story short, while working on designs, I asked the designer to also prepare designs for the survey form. Everyone knows it has to be custom, with a logo, etc. Instead of taking some out of the box survey tool, I decided to develop it from scratch and host on Elastic Beanstalk, as I really like AWS services. So I did…

A few days later, the survey was deployed and was ready for traffic. Results I showed you a few chapters earlier.

The “post-survey” era

After initial success, I was thinking about how to get my great product even more traffic. I thought that content marketing would do the job there. My thinking was as follows: 

  1. write an article (mentioned in the previous post, link here),
  2. submit it to Hacker News,
  3. watch the mailing list grow to thousands of emails.

Well, as you can expect – it didn’t happen.

Writing an article took me quite a lot of time. I had some doubts that people reading it would hear my Central European accent, so I sent it to review to a friend of mine who is a great philologist. Fortunately, it was quite good, and only a few more natural collocations were added. Moreover, I thought that instead of stock photos, I would like to have some eye-catching sketches, so I asked a drafter to do them. Then everything was ready, I could submit my article about changing the world to HN and… nothing happened. I saw in Medium’s statistics that people were reading it, but only a few subscribed to the mailing list. Then I was sending back the link to the article in reply messages to job offers that I was getting at that time. It turned out that recruiters were quite interested in the idea. I was noting their contact details to let them know when I was ready with my product as I was supposed “to start soon.” As an idea without execution is nothing, I’ve never got back to them.

We got to the stage when I got really tired of all that “entrepreneurial life.” I was thinking of delegating the implementation of the prototype to another friend of mine. He wanted to play a bit with AWS, so we cut a deal pretty quickly as it was a win-win situation. A month later, I had a clickable prototype that I didn’t show to anybody. I think that besides personal reasons for not launching it, I also lost faith in its success. Some kind of excuses appeared, that probably would be better identified here by some coaching gurus, so let’s leave it here for them 😉

What went wrong?

You probably already know what went wrong, but let me say that loudly. I focused on totally not important things, instead of focusing on my potential clients, getting to know their pains, observing them, analyzing their behavior, supporting them, and building a community. I did research supposedly, but that’s like with any other research – you can come up with such results that will support any thesis. Worst of all, I was defending the idea only because I wanted to do it.

With the benefit of hindsight and after seeing some success stories, I can admit that those totally unnecessary activities were: logo, designs, video, drawings, article, overthinking… All that consumed too much of my time, energy, and money. As a result, nothing was left for delivering real value and solving other people’s problems. That’s why I’d advise against taking such an approach in launching your side projects. Nevertheless, every cloud has a silver lining – at least we have a lot of resources and an exciting business domain to model.

If you have any questions about any of the fragments of this post, feel free to ask in the comments section, and I will reply. I also encourage you to share your experiences as I know that I’m not alone in such an approach to side projects 😉

Last but not least, there is some really great stuff coming in the next posts about Event Stormings and Domain-Driven Design, so don’t miss it and subscribe to the newsletter below.

* indicates required

See how I failed at my SaaS idea and what you will gain from it.

Today I have a story for you. A story that would never appear in any of popular business or marketing books, because it’s a story of my failure. In other words – I didn’t do it. My idea for the great SaaS product has never come through. Nevertheless it recovers in my head from time to time. Likewise this time, but now it’s different. Instead of creating the SaaS in my basement without showing it to anyone until it’s done, I will share with you the whole process with all technical and business details. But that’s not all – hold your breath – it will be an Open Source project! That’s because I want to share with you a lot of practical knowledge about software design, software architectures, Domain-Driven Design in general, and its building blocks. Moreover, I’m going to show you how to efficiently gather business knowledge and requirements by running Event Storming sessions.
As a side effect, you will also get to know about how I wanted to make my living by selling the SaaS product to you and HR departments. You will see my motivations and how I was thinking about monetization and people’s behavior.
In the end, as this is going to be an Open Source project, I will encourage you to contribute to it by fixing bugs or forking it and implementing your own approaches. What’s more, you will be able to use it for your own purposes. If you have always wanted to be a marketing expert or an entrepreneur, feel free to take, deploy and run it as your own business. I don’t mind.

You may ask now why I want to show you everything and what I will gain from it. There are a couple of reasons for that.
First of all, it will help me to close that chapter in my life, and I will do it by creating my own Open Source project! Thanks to that, I will bump up some of my stats ;). Teaching others is the best way to learn, and more exercises equal more experience. After the whole project is done, I will gain +5 to wisdom on my character’s card ;).
I really like the business domain and the whole idea behind the project itself. Moreover, I also like the technical approach that I’m going to use here.

Second of all, I want you to learn new things from the areas of software design, architecture, and DDD. Those are usually techniques that can totally change your way of thinking about software design and business modeling, and I would like to share this knowledge with everyone.

Thirdly, it may be that the business model/idea itself is attractive only in my opinion. Some product validation would be required here, and if it failed, there would be no point in implementing it. But implementation itself is the most exciting part for me, so – no validation at all ;).

Last but not least, I actually had a prototype of the product, but I’ve never launched it. At that point in time quite a big change in my priorities happened, so building the audience and marketing of the product fell all way down on my list :). Launching and maintaining such a project is a huge responsibility, and I couldn’t afford that. One can say those are excuses, but I don’t really care. I told you at the beginning of our adventure – you would not read this story in any coaching/marketing book. You are here to learn a load of new technical and modeling stuff, so let’s go.

Our schedule

I will show you now what is going to be included in the whole post series. A small disclaimer that the order of the topics can change as well as the area of expertise will probably stretch as with me thinking about it every day, new ideas pop up :). For now, it looks as follows:

  1. Domain description. This is the post you are reading right now. The idea of it is to explain to you the whole business model. Also, my motivation to create such a project back then as well as now. I highly recommend you should read this post as it is the starting point of our journey – you need to know the domain of the problem to have a good understanding of what’s going on later on.
  2. Genesis. In the second post of the series, I will be brutally honest with you. I will show you how to probably not start such a project. You will see how much energy I put in places where I could simply do nothing. To sum it up, I will show you how the logo and designs were created, how I “validated” the idea, and my ineffective attempts at content marketing.
  3. Big Picture Event Storming. I will show you there my first event storming on that project, and you will see how cool it is to do it with a person that has a lot more business experience than you.
  4. Design Level Event Storming, where we will split the business model into Bounded Contexts and Subdomains.
  5. Architecture or even architectures’ style pick 😉
  6. Documentation – general one and for architecture decisions.
  7. Project’s setup, which in this case means package structure, VCS, and CI.
  8. Aggregates, strategies, repositories, services, etc. This one will be split into a few separate posts as there is a lot to say about each of those DDD building blocks.
  9. Commands and their infrastructure.
  10. Events and their infrastructure.
  11. Deployment.

Domain description

The domain we are going to work on is an initial phase of devs’ hiring process. To be precise, turning it upside down, so developers, instead of browsing job offers would create their own, anonymous, time-limited advertisements. They would put their expectations there and wait for recruiters with offers. To sum it up: “I’m a strong and agile/waterfall (dad joke alert) developer for sale.” I know – may sound like I was objectifying and treating developers as regular resources. Well, please forgive me – I was young and needed money ;). But if you think about it, it was actually the opposite as it was going to give everyone the same start – more on that later.

The detailed genesis of that idea will be presented in the next post, but for now, I will just say that the final form of it developed based on research I did in this area. There were, and actually still are, a lot of new articles/podcasts/videos every few weeks that point out what is wrong with the hiring process. Moreover, I was directly asking devs and people from HR departments about their experiences. It turned out that recruitment-related problems are not solely bound to the interview but start ahead of it. The issues were reported on both sides — both the developers’ and the recruiters’.

Developers’ side:

  • If not looking for a job, they would not like to keep being informed about new possibilities of employment.
  • Job adverts are unstructured – form reigns supreme over content, terms, and conditions of employment are not presented clearly enough.
  • Talking about the salary is the stressful part of every job interview. Candidates fear their demands might scare a potential employer away. On the other hand, they are also concerned they may not be sufficiently appreciated and end up underpaid.
  • There are concerns that should they come across as underqualified, they may be tempted to lower their expectations with regard to the pay during the actual interview, compared to their pre-interview estimates. Let’s connect it with the imposter syndrome here ;).
  • Another concern is that by presenting your thorough profile, you may end up being discriminated against or being offered relatively poor terms of employment due to certain characteristics (such as your gender or background).
  • Lack of information about the salary bracket in numerous ads, which makes even ballpark estimates as regards a company’s financial capabilities impossible.

Recruiters’ side:

  • A lack of a selected target group — knowing who is available would make it possible for them to come up with much more personalized offers.
  • Annoyance with no response whatsoever to either social media- or e-mail- based job offers. In other words, recruiters often end up addressing people who may not be interested in changing jobs at that given moment.
  • Having a set budget for salaries at certain positions while not being allowed to openly present it in job adverts.
  • Candidates’ demands as presented during the interview, which does not tie in with what the company can offer.

Possibly some of them have already been addressed, thanks to new job boards that present job offers in a structured way and exposing, for example, salary information. I’m not up to date with it. Nevertheless, I still find the business domain/model exciting as it is still some kind of reverse flow, so it’s a perfect candidate to model and implement it together with you. The domain is complex enough not to be another example of a pet store project.

I’ve already mentioned that my idea to solve the above problems would be reverting the initial phase of the hiring process by handing it over to developers. This could improve the process in a few areas:

  • Isolating the target group, or the developers searching for work, from the total number of developers on the market. Thanks to this, recruiters will only direct their offers to those actually interested in them.
  • Developer advertisements would be standardized and stripped down to basics, such as financial expectations or the location of your employment. It is also crucial that the candidate’s technical profile be presented in a lucid way.
  • Clarity with regard to conditions from the word go – even before the interview. Thanks to the suggested approach, both sides are on the same page right from the start. This also improves communication between them further on into the process. Additionally, it eliminates cases of developers being tempted to undersell their talent following an interview that did not go according to plan.
  • Developer anonymity. Apart from the obvious reason which is wanting to keep your current employer in the dark about being on the lookout for some new prospects, there are countless others. An example of these would be equalizing the ground rules for all involved — you present your skill set and requirements, thus creating the basis for a preliminary assessment. It ensures that those offering a job are not taking into consideration things they shouldn’t be. Thanks to this, the interview is solely based on your merits.
  • No needless networking. A notice with your offer is only displayed for a set period of time. There is no room for standardized profiles or networking here. You choose to use this tool only when you really need to.
  • Speeding up the recruitment process. Through a clear set of candidate’s demands, recruiters can see right from the start whether or not these can be met. Then all they need to decide is whether to accept the conditions and make an offer or to keep on searching for the right person.

Now we come to the point when I would like to present my business requirements regarding the new flow of the hiring process: 

1. A developer creates an advertisement:

  • The advertisement is time-limited just so as not to hang there forever.
  • A few adverts can be active for the same developer at the same time. There can be a few reasons for that. For example, a developer is a Ruby developer and looks for a job in Ruby. Still, he/she would also like to check whether with that experience they can get any offer as an Elixir developer. Then a second advertisement could be created.
  • Each of the advertisements can be temporarily unpublished at any time. For example, when we get a lot of job offers and don’t want to get more of them. On the other hand, permanent removal should also be possible. That’s in case we reach the limit of free advertisements but want to create a new one. And now we move to monetization $$$.
  • The initial idea was to charge for each advertisement. The assumption is, that if you are looking for a job, you will be willing to pay $5 for that. Nevertheless, there is one problem with such an approach – you will not pay if you totally don’t know the product and its potential. That leads me to two solutions:
    • Limit for free advertisements, and each one above this limit is chargeable.
    • Tiered pricing, where the first tier is “free” with 2-3 advertisements. Higher tiers allow you to add more of them and give you extra features. Regarding those features themselves, they are not defined at all. But I’m thinking about some advertisement’s highlighting and showing statistics. You know – a developer seeing charts equals a happy developer ;).

Because I still consider the first approach some kind of edge case, I decided to go with the second option. The other advantage of it is that tiers usually should increase your revenue, and if people have 3 options, some of them will take the lowest tier (free in this case), some the middle one, and there is also a part that goes for the most expensive one.

As the tiered approach requires some features defined and I have no idea what they could be, it would be great to make this piece of process flexible enough to support both options (or more). We will start with free advertisements and the limit for the number of them, just to postpone the decision of the final approach.

2. When an advertisement is published, it’s also available in the search component. That’s the most interesting part for headhunters and HR departments. When a developer decides to unpublish or delete an advertisement, it should also disappear from search results.

3. A recruiter can make an offer to an advertisement. A few interesting requirements kick in here:

  • A concrete recruiter can make only a single offer to the specific advertisement. That’s because we want to prevent spam – sending the same offer multiple times to the same advertisement.
  • If a recruiter wants to make an offer, he/she needs to accept all of the developer’s expectations, which are marked by the developer as required ones.
  • While making an offer, it’s required to fill in contact and company data.

4. Developers can see all offers in their admin panel. Each offer can be deleted. In this case, the developer will not get the same offer again, as recruiters can make an offer only once to the specific advertisement (requirement from point 3). On the other hand, if a developer finds any offer interesting, they can use contact details and take the rest of the communication process outside of our SaaS app. That’s actually the intended operation as we want to be as anonymous as we can, so we don’t want to have any communication or storing any sensitive data (CVs) within our app.

That’s it when it comes to the domain description and requirements. You should know now what kind of problems I have spotted in the hiring process and what my brand new idea to solve them is. I described it some time ago in a different article that you can find here. Its purpose was to do some content marketing, so I submitted it to Hacker News, but as you can suspect – it didn’t go viral ;). I leave it here for you just as a fun fact, because the most important one for our upcoming adventure is still the one you are reading right now. We have here the domain description and business requirements in greater detail. That’s an excellent base for Event Stormings that I will describe in the next few posts.

I gave you my word that I was going to show you literally everything and to be brutally honest. Speaking of which, in the next still non-technical post, I will describe to you the whole genesis of the idea. I will show you how the logo and designs were created, how I was gathering information from developers and recruiters, and finally, how I failed. To sum it up: I will show you how NOT to start such a project. All this can give you an even better context of the situation and can help you in your side projects. That will be the last non-technical post, and later on, we’ll jump directly into domain modeling.

I would really like to spread the word with the idea of such an Open Source project, so if you, too, find this idea interesting, please help me and share it with your friends.

If you would like to see Domain-Driven Design and Event Stormings on a real-life example, don’t miss the next posts. Subscribe to the newsletter, so you will be the first to get to know about them.

* indicates required