<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[ToolTime]]></title><description><![CDATA[Engineering and technology blog ]]></description><link>https://tooltime.tech/</link><image><url>https://tooltime.tech/favicon.png</url><title>ToolTime</title><link>https://tooltime.tech/</link></image><generator>Ghost 5.59</generator><lastBuildDate>Tue, 07 Apr 2026 08:00:19 GMT</lastBuildDate><atom:link href="https://tooltime.tech/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[I can sleep through the storm.]]></title><description><![CDATA[<p>For workaholics like myself, the prospect of a holiday can feel akin to the impending doom of a critical system outage. The thought of being offline, disconnected from the digital pulse of the business, is enough to trigger anxiety. For years, I made sure that even on vacation, I could</p>]]></description><link>https://tooltime.tech/i-can-sleep-through-the-storm/</link><guid isPermaLink="false">66c336ebaf09e20064734edf</guid><dc:creator><![CDATA[Slawomir Smiechura]]></dc:creator><pubDate>Tue, 20 Aug 2024 12:41:25 GMT</pubDate><media:content url="https://tooltime.tech/content/images/2024/08/19515856459_9df46fea0b_c.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://tooltime.tech/content/images/2024/08/19515856459_9df46fea0b_c.jpg" alt="I can sleep through the storm."><p>For workaholics like myself, the prospect of a holiday can feel akin to the impending doom of a critical system outage. The thought of being offline, disconnected from the digital pulse of the business, is enough to trigger anxiety. For years, I made sure that even on vacation, I could log in, check the logs, and ensure everything was humming along - at least for a couple of hours each day. That was until recently when I embarked on a long-awaited camping trip, kayaking through a remote national park. Naturally, there was no internet, and I could barely get a bar of signal. To my surprise, after a week of disconnection, I returned to find everything in perfect order. The team had thrived, the system was running smoothly, and nothing had gone catastrophically wrong.</p><p>But how could this be? How could the gears keep turning without my constant oversight?</p><h3 id="the-first-and-foremost-the-people">The first and foremost: The People. </h3><p>Let&apos;s start with the most critical component - our people. At ToolTime, it&apos;s the mindset that makes the difference. Our engineering culture is built on proactivity and pragmatism. We&#x2019;ve removed the term &quot;Tech Debt&quot; from our vocabulary, not because we ignore it, but because we refuse to let it become an excuse to chase unnecessary perfection at the expense of delivering what&apos;s needed. The emphasis is always on pragmatic engineering - <em>solving the right problems, not every possible problem.</em></p><p>We also did away with the archaic concept of a &quot;release&quot; as an extraordinary event. Deployments are just another part of our daily routine, as mundane as grabbing a coffee. When things inevitably go wrong, we do have robust safety mechanisms in place to minimize the impact, reducing the fear of making mistakes to near zero. This has fostered a culture <em>where failure is viewed as an opportunity to learn rather than a cause for blame</em>. Engineers at ToolTime aren&#x2019;t just cogs in a machine; they&#x2019;re empowered decision-makers, backed by a culture that encourages growth through trial and error.</p><p>Our Engineering Leads deserve a special mention here. They aren&#x2019;t just figureheads - they&apos;re enablers, providing the guidance necessary for engineers to make informed decisions. Whether it&#x2019;s a complex architectural question or a subtle coding nuance, our leads are there to help, ensuring that even in times of doubt, the team has a clear path forward.</p><h3 id="the-second-the-tech">The second: The Tech</h3><p>But people alone can&#x2019;t carry the entire load. The technology stack at ToolTime is designed to support rapid development without sacrificing stability.</p><p>Let&apos;s begin with our Continuous Integration (CI) systems, the heart of modern software development. These systems catch errors at the earliest possible stage - before they even make it to build time. Who doesn&apos;t love a good linter pointing out your coding sins? Every commit triggers a battery of tests, providing immediate feedback and building confidence in the code we write.</p><p>Our deployment pipeline is a well-oiled machine, powered by a GitOps approach with ArgoCD at its core. This setup doesn&apos;t just deploy code; it controls and monitors the entire process, ensuring that if an application fails to start, it never sees the light of day. Rollbacks? They&#x2019;re as painless as Ctrl+Z in your favourite text editor. The system&apos;s modular architecture is designed with graceful degradation in mind. We write contracts first, then code to those contracts, creating well-defined boundaries that limit the blast radius when things go wrong.</p><p>Kubernetes handles the heavy lifting when it comes to deployments, scalability, and redundancy. It&#x2019;s like having an army of robots working tirelessly behind the scenes, ensuring that our applications remain resilient and responsive. And then there&apos;s Terraform, the command-line magician that can create and wipe out our entire cloud infrastructure with just three commands (<code>terraform apply</code>, <code>helm install</code>, and <code>terraform apply</code> again). We&apos;ve migrated entire EKS clusters in production with zero downtime&#x2014;yes, zero-during normal working hours. It&#x2019;s like swapping out the engine of a car while speeding down the highway, and somehow, nobody in the car notices.</p><p>For observability, Datadog is our all-seeing eye. It gives us deep insights into system performance and has enough bells and whistles to alert us the moment something starts to go south. It&#x2019;s like having a smoke detector that also monitors your pulse, blood pressure, and probably even your mood.</p><h3 id="and-the-last-the-process">And the last: The process</h3><p>The process - a necessary evil, but at ToolTime, we&apos;ve distilled it down to the essentials. Think of it as a lean, mean, agile machine. The guiding principle is simple: &quot;Do what&apos;s right.&quot; We have a few core guidelines to keep us on track:</p><ul><li><strong>The backlog governs priorities.</strong> If it&#x2019;s on top, it&#x2019;s what we&#x2019;re working on.</li><li><strong>Work on one ticket at a time.</strong> Multitasking is just a fancy word for doing multiple things poorly.</li><li><strong>Bugs always take precedence.</strong> They go straight to the top of the backlog.</li><li><strong>When there&apos;s a fire, everyone drops what they&apos;re doing.</strong> No exceptions. It&#x2019;s all hands on deck.</li><li><strong>Draw the architecture before you code the feature.</strong> Because a picture is worth a thousand lines of code.</li></ul><h3 id="the-storm">The storm</h3><p>In short, I just wanted to take a moment to appreciate how far ToolTime has come. We&#x2019;re not just prepared for storms; we&#x2019;re accepting them with a calm confidence that would have seemed impossible a few years ago. The shutters are secured, the tools are stored away but ready for action, and the team is more than capable of handling whatever the elements throw at us.</p><p>The storm, much like our daily releases, has become a routine part of life&#x2014;no longer something to fear but something we&#x2019;re well-prepared for. Not that we&#x2019;re recklessly seeking out the eye of the cyclone, but we&#x2019;re no longer intimidated by its presence. We&#x2019;re ready, and with that readiness comes the peace of mind that allows me to do something I never thought possible: take a nap.</p>]]></content:encoded></item><item><title><![CDATA[How we collaborate with our design team]]></title><description><![CDATA[<p>At ToolTime we have (at the time of writing this post) a team of 20 Software Engineers and 3 Product Designers. Smooth collaboration is always a challenge when a team consists of more than, ehm, 1 person &#x1F600;. And more problems can become prominent when the collaboration is cross-functional.</p><p>Product</p>]]></description><link>https://tooltime.tech/how-we-collaborate-with-our-design-team/</link><guid isPermaLink="false">61d2de4c18c1ec00c5a859cb</guid><category><![CDATA[culture]]></category><category><![CDATA[process]]></category><category><![CDATA[web]]></category><category><![CDATA[team]]></category><dc:creator><![CDATA[Anastasios Skotidas]]></dc:creator><pubDate>Sun, 30 Jan 2022 16:12:08 GMT</pubDate><content:encoded><![CDATA[<p>At ToolTime we have (at the time of writing this post) a team of 20 Software Engineers and 3 Product Designers. Smooth collaboration is always a challenge when a team consists of more than, ehm, 1 person &#x1F600;. And more problems can become prominent when the collaboration is cross-functional.</p><p>Product Designers (PDs) and Software Engineers (SEs) work and think in a quite different way. We (SE) naturally tend to focus on technical solutions and code. Sure, at ToolTime we take part in the whole lifecycle of a feature, but at the end of the day, as SEs we provide a solution using our programming skills. On the other hand, PDs look for ways to provide value to the user by making the features visible, understandable and intuitive via UI/UX.</p><p>These two different approaches lead to different vocabulary and processes. Let&#x2019;s take a look at what tools and environments each uses. PDs at ToolTime use Figma for creating mockups and the design system. SEs use code and they see the visual result of their code in the actual app. This comes with a question: What is the source of truth for the design? The Figma mockups or the actual code that is deployed to production?</p><p>Figma comes with the disadvantage that it&#x2019;s quite distant to the SEs, as it&apos;s not their everyday&apos;s tool. Same applies to code, where PDs struggle. Moreover, it may take quite some time for PDs to be able to review the implemented design since they have to wait for a preview URL and use the entire product in order to check the design of one feature or design system component.</p><p>We decided to solve this problem by adding something in between that is easy for both sides to use and making the source of truth for the design that is deployed to production. We chose Storybook as our tool that displays our design system and we feel very justified by this choice.</p><h2 id="why-storybook">Why Storybook</h2><p>Storybook is a widely known tool, test-proof and fits our purpose very well. We can run it both locally and have it on the cloud for easier access as well via Chromatic. In addition, it is not opinionated and we can give it any shape we need, in close collaboration with our PDs.</p><figure class="kg-card kg-image-card"><img src="https://tooltime.tech/content/images/2022/01/Screenshot-2022-01-03-at-12.37.26.png" class="kg-image" alt loading="lazy"></figure><p>Another advantage of Storybook is its stories files. They can be used as a reference for our SEs as we can, most of the times, just copy/paste the code from a story to our actual code.</p><h2 id="chromatic-reviews">Chromatic reviews</h2><p>Every time we push code to a git branch on Github, Chromatic checks if there were any changes that resulted to different design in Storybook. If that&#x2019;s the case, a design review is required, which can be performed only by our PDs. They can see the changes, comment, accept or reject them. This way we make sure that any design system change is approved by our product team first.</p><figure class="kg-card kg-image-card"><img src="https://tooltime.tech/content/images/2022/01/Screenshot-2022-01-03-at-12.39.28.png" class="kg-image" alt loading="lazy"></figure><h2 id="what-s-the-result">What&#x2019;s the result?</h2><p>The quality of the developed UI as well as consistency in the product increased by a lot. The collaboration between our design and engineering teams improved and became smoother and more efficient. Most notably:</p><ul><li>The vocabulary became consistent</li><li>The source of truth for design system components isn&#x2019;t on either team&#x2019;s side, but in the middle</li><li>We can implement and review our design system independently from the product</li><li>With Chromatic, PDs are in control of new implementations and changes</li><li>SEs can use the stories as reference for their code</li><li>Easy and transparent cross-functional collaboration &#x1F389;</li></ul>]]></content:encoded></item><item><title><![CDATA[2 seconds build time with ESbuild (bye Webpack)]]></title><description><![CDATA[<h2 id="foreword">Foreword</h2><p>Like so many applications out there, our WebApp MVP was initially generated with the popular <code>create-react-app</code> command-line tool. It makes things very easy at first: no need to think about how to set up a local server, a bundler, a compiler, typescript config, how to support multiple content types,</p>]]></description><link>https://tooltime.tech/2-seconds-build-time-with-esbuild/</link><guid isPermaLink="false">61d424a518c1ec00c5a85a08</guid><category><![CDATA[web]]></category><category><![CDATA[esbuild]]></category><category><![CDATA[technology]]></category><category><![CDATA[react]]></category><category><![CDATA[typescript]]></category><dc:creator><![CDATA[Yves Van Goethem]]></dc:creator><pubDate>Mon, 17 Jan 2022 18:42:33 GMT</pubDate><media:content url="https://tooltime.tech/content/images/2022/01/tooltime_banner.png" medium="image"/><content:encoded><![CDATA[<h2 id="foreword">Foreword</h2><img src="https://tooltime.tech/content/images/2022/01/tooltime_banner.png" alt="2 seconds build time with ESbuild (bye Webpack)"><p>Like so many applications out there, our WebApp MVP was initially generated with the popular <code>create-react-app</code> command-line tool. It makes things very easy at first: no need to think about how to set up a local server, a bundler, a compiler, typescript config, how to support multiple content types,&#x2026; and their documentation describes it very nicely:</p><blockquote>You <strong>don&#x2019;t</strong> need to install or configure tools like webpack or Babel. They are preconfigured and hidden so that you can focus on the code.</blockquote><p>With time, however, &#xA0;applications increase in complexity, consumers require more features, and developers raise different needs. What was initially a great &quot;all-in-one&quot; solution to us, now feels like a black box of technologies smashed together&#x2026; and nobody really knows how and what it does.</p><p>All we know is that it affects us. On an everyday basis, it impacts how multiple teams work, how quick we can ship changes to our customers, and ultimately how developers feel.</p><p>So, let&apos;s look at Webpack and what problems we faced.</p><h2 id="issues-we-faced-with-webpack">Issues we faced with Webpack</h2><p>A bit of context first: Our TypeScript codebase contains around 150 000 lines of code, we don&apos;t have a fancy code-splitting strategy, nor caching strategy, nor do we do any heavy transformations in the build or on the local dev server.</p><h3 id="dev-server">Dev server</h3><p>The first problem we faced daily was the startup time of the webpack/babel/typescript black box on our computers.</p><blockquote>3 minutes</blockquote><p>That&apos;s the time it takes on my Intel MacBook Pro from 2020 to run <code>yarn start</code>.</p><p>While slow, it&apos;s not a command we would run many times per day, so the feeling of frustration was limited to the morning. And these 3 minutes would usually allow me to get a cup of coffee. However, when things needed to go quick&#x2026; we were forced to wait.</p><h3 id="production-build">Production build</h3><p>This was the real pain point. Building our App with Webpack took:</p><blockquote>45 minutes</blockquote><p>Yes, <strong>45 frigging minutes.</strong></p><p>In practice, this meant that, for example, bug fixes required an extra 45 minutes from merged (and solved locally) to being solved in production.</p><p>This was a very frustrating situation for our engineering team, so we had a good reason to experiment with alternatives.</p><p>We had a look at solutions such as Vite, Snowpack, and others,&#x2026; but <strong><a href="https://esbuild.github.io/?ref=tooltime.tech">esbuild</a></strong> blew us away from the very first try.</p><h2 id="esbuild">ESbuild</h2><p>The main problem we tried to solve was the build time, therefore, we tried it out locally with the <strong>ESbuild CLI.</strong> What we witnessed was beyond our wildest dreams.</p><p>Here is what I typed in my terminal:</p><pre><code class="language-sh">npx esbuild src/app/App.tsx --loader:.svg=file --loader:.png=file --bundle --outfile=build2/out.js</code></pre><p> And here is the output:</p><pre><code>  build2/out.js                      18.6mb &#x26A0;&#xFE0F;
  build2/intros-RE7GI7PZ.svg         56.9kb
  build2/footer-XMLWO6FL.svg         39.6kb
  build2/question-HHFNHGW3.svg        773b 
  ...and 56 more output files...

&#x26A1; Done in 1336ms</code></pre><p>At this moment, my colleague (&#x1F44B; hello Hamed) and I looked at each other very confused, we both assumed the same: ESbuild did absolutely nothing, what could it possibly have built in <strong>1336ms?</strong></p><p>Turns out, it built absolutely everything, I ran a <code>cat build2/out.js</code> and our confusion turned into disbelief. Everything was there. Not only the code but also the SVG &amp; PNG assets were present in the <code>build2</code> folder. </p><p>We then ran a few more tries in the CLI to experiment with the ESbuild features, and then eventually decided to write a Node script with their <strong><a href="https://esbuild.github.io/api/?ref=tooltime.tech#build-api">Build API.</a></strong> Eight hours later we had a staging environment running ESbuild with at its core this simple code:</p><pre><code class="language-js">esbuild
  .build({
    logLevel: &apos;info&apos;,
    publicPath: &apos;/&apos;,
    entryPoints: [&apos;src/index.tsx&apos;],
    bundle: true,
    minify: true,
    outfile: &apos;build/out.js&apos;,
    define: { global: &apos;window&apos; },
    sourcemap: true,
    loader: {
      &apos;.png&apos;: &apos;file&apos;,
      &apos;.svg&apos;: &apos;file&apos;,
    },
    target: [&apos;firefox90&apos;, &apos;chrome90&apos;, &apos;safari13&apos;],
  })
  .catch(() =&gt; process.exit(1))
</code></pre><h3 id="any-drawbacks">Any drawbacks?</h3><p>One took us a few hours to figure out. <strong>Dynamic exports are not supported. </strong></p><p>This is not really a concern to us, but some of our third-party dependencies are relying on dynamic imports internally. So we started encountering bizarre issues with libraries such as MaterialUI and Amplify.</p><p>The solution to this is very simple: use <code>require</code> to import their modules, instead of relying on <code>import</code>.</p><h3 id="local-server">Local server</h3><p>In addition to the Build API, ESbuild also features a <strong>Serve API, </strong>adapting the build script to run a local server was very easy as it is (nearly) the same API. </p><h2 id="conclusion">Conclusion</h2><p>The build time and the local server boot time now both take <strong>~2 seconds. </strong>Without a doubt the fastest setup I have ever witnessed to run and to build a WebApp.</p><p>We dramatically improved our developer experience, release our changes faster to our customers, and eliminated frustration from our daily work.</p><p>If you have read this far, I urge you to give <strong>ESbuild</strong> a try. Getting started is as simple as running the command above (or similar).</p><p>&#x1F596;</p><h3 id="additional-resources">Additional resources</h3><p>While researching this topic we came across a few things we did not end up using, but found interesting nevertheless:</p><ul><li><strong>Netlify</strong> <a href="https://github.com/netlify/esbuild?ref=tooltime.tech">forked ESbuild</a> to fix the dynamic import problem.</li><li>There is a <a href="https://github.com/pradel/create-react-app-esbuild?ref=tooltime.tech">create-react-app plugin</a> if you haven&apos;t/can&apos;t eject your configuration.</li></ul><hr><p>Working on such experiments is possible due to our weekly recurring <a href="https://tooltime.tech/goodbye-tech-debt-hello-tech-time/">Tech Time</a>, if you like our approach, consider <a href="https://www.tooltime.de/jobs?ref=tooltime.tech">applying at one of our job openings</a>.</p>]]></content:encoded></item><item><title><![CDATA[Hola Microservices. What took us so long?]]></title><description><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://tooltime.tech/content/images/2022/02/Tool-Time-Components---Components.jpg" class="kg-image" alt loading="lazy" width="2000" height="1237" srcset="https://tooltime.tech/content/images/size/w600/2022/02/Tool-Time-Components---Components.jpg 600w, https://tooltime.tech/content/images/size/w1000/2022/02/Tool-Time-Components---Components.jpg 1000w, https://tooltime.tech/content/images/size/w1600/2022/02/Tool-Time-Components---Components.jpg 1600w, https://tooltime.tech/content/images/size/w2400/2022/02/Tool-Time-Components---Components.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>4-tier architecture</figcaption></figure><p>While it&apos;s not something you would want to start with (well, unless you already have all the building blocks) a micro-service oriented architecture comes with more gains than pains. What you are looking at is the current state of TT architecture. Yes, You can probably recognise</p>]]></description><link>https://tooltime.tech/microservices-what-took-us-so-long/</link><guid isPermaLink="false">6198cba218c1ec00c5a858aa</guid><category><![CDATA[technology]]></category><dc:creator><![CDATA[Slawomir Smiechura]]></dc:creator><pubDate>Sat, 27 Nov 2021 09:46:56 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://tooltime.tech/content/images/2022/02/Tool-Time-Components---Components.jpg" class="kg-image" alt loading="lazy" width="2000" height="1237" srcset="https://tooltime.tech/content/images/size/w600/2022/02/Tool-Time-Components---Components.jpg 600w, https://tooltime.tech/content/images/size/w1000/2022/02/Tool-Time-Components---Components.jpg 1000w, https://tooltime.tech/content/images/size/w1600/2022/02/Tool-Time-Components---Components.jpg 1600w, https://tooltime.tech/content/images/size/w2400/2022/02/Tool-Time-Components---Components.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>4-tier architecture</figcaption></figure><p>While it&apos;s not something you would want to start with (well, unless you already have all the building blocks) a micro-service oriented architecture comes with more gains than pains. What you are looking at is the current state of TT architecture. Yes, You can probably recognise the pattern - backend being a monolith application being split into more and more services. But, it&apos;s not what I wanted to write about. <br><br><strong>How long does it take for a new service to be in production? </strong><br>Before we dive into it. How long does it take you to build a new application and ship it to production. Let&apos;s say, only basic server with monitoring and logging, CI/CD pipeline, and 1 test endpoint. How long does it take you from the first command line call to the moment when the app is available? Think about it and we will come back to it at the end.<br><br><strong>Highly aligned</strong><br>First thing that we really wanted to see is how we will ensure that with the growing number of newly created applications we do not have to rebuild existing things over and over again. We agreed on a set of important items that a service needs to have: <br>- centralised logs - here is where <a href="https://www.datadoghq.com/?ref=tooltime.tech">DataDog</a> comes to play<br>- each app is monitored and alerts when there are problems - this is a mix of K<a href="https://kubernetes.io/?ref=tooltime.tech">ubernetes</a> features and DataDog alerts <br>- each build step is available as a command line tool - we decided for <a href="https://www.gnu.org/software/make/manual/make.html?ref=tooltime.tech">Makefile</a><br>- each service defines each own running environment - <a href="https://helm.sh/?ref=tooltime.tech">Helm</a> is our friend here<br>- CI pipeline with steps is defined - <a href="https://circleci.com/?ref=tooltime.tech">CircleC</a>I is our tool of choice<br>- we get CD pipeline out of the box - CI provides Docker images and <a href="https://argoproj.github.io/?ref=tooltime.tech">Argo-Cd</a> takes care of deployments <br>In the end we wanted to get as close to <a href="https://12factor.net/?ref=tooltime.tech">12factor</a> apps as possible. As You can imagine, this level of alignment is not easy to achieve, even more difficult to implement for each service and very hard to maintain. <br><br>So, to the next step<br><br><strong>Single source of truth</strong><br>We have built a <em>single source of truth<strong> </strong></em>project which we could use as a reference point. This is where a lot of discussions around <em>How</em> happened. We have built a simple <a href="https://spring.io/projects/spring-boot?ref=tooltime.tech">Spring Boot</a> application first. The app was exposing a sample endpoint and that&apos;s pretty much it. Then the work around CI added a <em>circleci/config.yaml</em>, a need to have centralised logs pushed us towards D<em>ataDog agents </em>deployed on our Kubernetes, the need to define the environments ended up to be a bunch of Helm files in the project. You get the point. One app to have it all. </p><p>In the end, a developer could clone the repo, rename packages, and run the app locally. <br>Then just fiddle with CircleCI, register an app with our gitops repo, add your DB lib, secrets to Kubernetes. Drink coffee and boom. <br><br>I know what you are thinking... such an effort. We thought the same. This was great but still... not good enough. <br><br><strong>Ease of use</strong><br>The next step was to apply one of the CD rules: <strong>automate everything</strong>. We have created a command line tool which does the following: <br>- creates a new project out of the <em>source of truth </em>repository using the right name<br>- registers a new app with the CI pipeline (CircleCI)<br>- registers a new app with the GitOps continuous delivery (ArgoCD)<br>The only thing the developer needs to do is to push the code to a remote repo and they will see the app. </p><p><strong>The mindset</strong><br>I believe that was the hardest part. It has always been. How do we buy in to something where the pros are not so clearly visible but the issues are &#xA0;obvious from the very beginning? <br>- why lift <em>table joins</em> to code when DB has been successfully doing that for decades <br>- what about transactions?<br>- this will increase the cost of infra, each service comes with a memory footprint <br>- rather than having 1 place to look, we will have to chase the code around in case of problems<br>and many many more which I will not mention here. I guess another article need to be written to fully explain what was blocking us and how we worked around these. I must say that I am very proud of the team here. </p><p><strong>How long does it take for a new service to be in production?</strong><br>We can say this: <br>- 30 seconds to create a new service, it&apos;s just a <strong>1 command line call</strong> <br>- 5 mins to run the CD pipeline (the image creation could be improved)<br>- 40 seconds to deploy and have the service boot up<br><br>So all together <strong>7 mins</strong>. How long does it take you? </p>]]></content:encoded></item><item><title><![CDATA[How joining ToolTime made me a better Software Engineer]]></title><description><![CDATA[<p>Recently, we had our first Hackathon at ToolTime. It was really exciting and gave birth to a large number of ideas that can potentially help ToolTime grow even more. But an idea is worth nothing without the implementation. And as a Software Engineer I was part of that implementation.</p><p>So,</p>]]></description><link>https://tooltime.tech/how-tooltime-made-me-a-better-engineer/</link><guid isPermaLink="false">60c727cf18c1ec00c5a8563c</guid><category><![CDATA[culture]]></category><category><![CDATA[technology]]></category><category><![CDATA[web]]></category><dc:creator><![CDATA[Anastasios Skotidas]]></dc:creator><pubDate>Mon, 14 Jun 2021 20:03:34 GMT</pubDate><media:content url="https://tooltime.tech/content/images/2021/06/tooltime.png" medium="image"/><content:encoded><![CDATA[<img src="https://tooltime.tech/content/images/2021/06/tooltime.png" alt="How joining ToolTime made me a better Software Engineer"><p>Recently, we had our first Hackathon at ToolTime. It was really exciting and gave birth to a large number of ideas that can potentially help ToolTime grow even more. But an idea is worth nothing without the implementation. And as a Software Engineer I was part of that implementation.</p><p>So, it&apos;s Wednesday noon and I start, together with my colleague Maja, writing some code on the backend and later on the frontend. A couple of hours later we realised we were applying proper architecture, we were even writing tests, for a Hackathon. And this was yet another moment that made me realise how much a Software Engineer can grow at ToolTime.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://tooltime.tech/content/images/2021/06/image.png" class="kg-image" alt="How joining ToolTime made me a better Software Engineer" loading="lazy"><figcaption>Other things we did apart from coding during Hackathon</figcaption></figure><h2 id="being-open-minded-and-compromise">Being open minded and compromise</h2><p>Everybody is biased. We have different experiences and ways of working. We have worked in different environments and projects. Bringing people together in order to work on a product is not easy.</p><p>However, at ToolTime we see our personal success through the team&apos;s success. That&apos;s why we try our best to be inclusive and listen to what each one of us has to say. Everybody has something to contribute.</p><p>Whenever we have conflicting opinions we come to a conclusion that is in the best interest of the team. This can mean that we create a mix of what was proposed or we choose only one while at the same time we encourage people to keep being innovative and keep trying to contribute.</p><h2 id="good-code-architecture-leads-to-a-better-product">Good code architecture leads to a better product</h2><p>Ok, we all know that. Books have been written about it and design patterns have been created. But it&apos;s different to have it as part of your every day life. Many teams talk about architecture in theory and as a goal but at ToolTime it is our compass.</p><p>Everything revolves around it. Every little decision we make is part of a living organism that needs a strategic approach in order to maintain it and help it grow the best way.</p><p>A great example is described by my colleague Yves in this <a href="https://tooltime.tech/react-apps-separation-of-concerns/">post</a>.</p><h2 id="but-how-to-support-an-architecture">But how to support an architecture?</h2><p>Here comes the tricky but exciting part.</p><!--kg-card-begin: html--><h3>Use the architecture that makes sense, not what the community wants</h3><!--kg-card-end: html--><p>Most of the time technologies or tools with a big audience (e.g. React) have what we call common or best practices. These usually make sense and they are the result of a lot of trial and error. The problem is that best practices are proposed by a handful of people. Some teams tried something, worked for them and demo it to the community. Eventually, software engineers around the world start following and at the end it becomes a trend.</p><p>However, we often ignore that different teams and projects have different problems to solve. For example, one of the things we wanted to improve in our web application was the big number of bugs we had a year ago. Therefore, our whole strategy was focused to eliminate this issue. And that&apos;s why we aimed for code isolation instead of code (React components) reusability.</p><!--kg-card-begin: html--><h3>Let people talk</h3><!--kg-card-end: html--><p>First of all, we educate our team members about the need of following code architectures and agreed guidelines. At the end of the day, if a team doesn&apos;t buy in a concept, then what&apos;s the point of it.</p><p>We never take architectural decisions without bringing them to the table for discussion. Everyone has time and space to propose, experiment and demo an idea. This usually happens via our three Forums (Frontend, Backend, Mobile) where we suggest topics to discuss. There we can express our ideas and the team can decide whether to make it part of our guidelines or not. Alignment is gold for ToolTime.</p><p>I always look forward to the next Forum to see what is the next step towards our engineering goals.</p><!--kg-card-begin: html--><h3>Tooling</h3><!--kg-card-end: html--><p>Another essential part is tooling. Since architecture defines how code should be split and distributed around the app, patterns start to arise. And patterns mean standardisation.</p><p>With tooling we can apply the patterns our team defines and secure faster development together with alignment.</p><p>Apart from common tools like linters we have created our code generators that create all the necessary files pre-filled with code for:</p><ul><li>Creating models on the Frontend</li><li>Creating React components accompanied with tests and hooks</li><li>Creating microservices</li></ul><h2 id="experimentation-and-staying-curious">Experimentation and staying curious</h2><p>At ToolTime we have a variety of domains and languages we use:</p><ul><li>Frontend (TypeScript, React, Redux, GraphQL)</li><li>Backend (Kotlin, PostgreSQL)</li><li>Mobile (React Native, Redux, GraphQL)</li><li>Infrastructure (AWS, Terraform, Kubernetes, GitOps)</li></ul><p>Even though usually people have different levels of skills in different domains, we highly encourage our team members to have a hands-on experience in any of the mentioned areas.</p><p>Maybe you will be just like me, that I mainly copy paste code on the Backend but still, seeing a different approach and technologies can only be a benefit.</p><h2 id="being-pragmatic">Being pragmatic</h2><p>Here we always try to pick the most balanced solution to a problem. Working on software doesn&apos;t only involve Software Engineers. Product Managers, Designers, Customer Success are also part of the team and have their expectations as well. Hence, coding having in mind only how to fulfil your own technical goals doesn&apos;t sound fair. Being pragmatic is an essential part of our job and at ToolTime we value it highly.</p><p>This means we aim for an implementation that follows our software guidelines but avoids over-engineering and pre-optimisation.</p><h2 id="but-how-all-the-above-made-me-a-better-software-engineer">But how all the above made me a better Software Engineer?</h2><p>All the above are things that most of us have thought about one way or another. The same applies to myself.</p><p>The difference is that at ToolTime they really became part of my core mindset. I used to try to convince myself to apply them. Now, they just come naturally and seem really obvious and reasonable.</p><p>That&apos;s the reason why following code architecture and writing tests lead to a faster implementation for the Hackathon rather than writing something the hacky way.</p><p>And now here I am, being so passionate about it that I want to share it with you.</p>]]></content:encoded></item><item><title><![CDATA[Hello Tech Time, Goodbye Tech Debt]]></title><description><![CDATA[<p>At ToolTime, like in every engineering organisation, we have a lot to do: build new features, scale existing ones, tidy existing code, improve architectures, fix bugs, update tools, research new solutions, imagine the future, et cetera, et cetera&#x2026;</p><p>With this many responsibilities, and the backlog endlessly full of new</p>]]></description><link>https://tooltime.tech/goodbye-tech-debt-hello-tech-time/</link><guid isPermaLink="false">60af60ed2c11fc00ceda8de8</guid><category><![CDATA[process]]></category><category><![CDATA[culture]]></category><category><![CDATA[technology]]></category><category><![CDATA[tech time]]></category><dc:creator><![CDATA[Yves Van Goethem]]></dc:creator><pubDate>Tue, 01 Jun 2021 07:46:00 GMT</pubDate><media:content url="https://tooltime.tech/content/images/2021/05/Screen-Shot-2021-05-31-at-22.16.07.png" medium="image"/><content:encoded><![CDATA[<img src="https://tooltime.tech/content/images/2021/05/Screen-Shot-2021-05-31-at-22.16.07.png" alt="Hello Tech Time, Goodbye Tech Debt"><p>At ToolTime, like in every engineering organisation, we have a lot to do: build new features, scale existing ones, tidy existing code, improve architectures, fix bugs, update tools, research new solutions, imagine the future, et cetera, et cetera&#x2026;</p><p>With this many responsibilities, and the backlog endlessly full of new potential features, teams tend to get trapped into an unhealthy &quot;always busy&quot; mode. This article is about recognising and avoiding this situation in the first place, or if it&apos;s too late, give you the means to get out of it.</p><p>The concept of tech debt is a negatively connoted one, instead, we came up with what we call <strong>Tech Time</strong>. Let&apos;s have a look at how we organically grew <strong>Tech Time</strong> over a year and a half, starting Early 2020.	</p><h2 id="dedicate-time">Dedicate Time</h2><p>The first step we took to avoid the hyper-busy mode, was to provide recurring time for all engineers to work on technical aspects.<br>We started by asking engineers to <strong>dedicate 20% of their week</strong> to it.<br>The weekly recurrence is important, from our experience, the frequency provides time for habits to develop.<br>It resulted in people pairing, organising work into daily solvable problems, and leading to <strong>weekly incremental improvements</strong> to a variety of codebases, conventions, pipelines, processes, etc.</p><h2 id="provide-space">Provide Space</h2><p>After a few weeks, the feedback was clear, engineers loved weekly recurring time to work on something else than features. However, we also discovered that not all engineers were engaged and that the combined time of the group did not get close to 20%.</p><p>While we did provide time, it still felt odd to some engineers to work on a tech task, while the rest of the team was working on the product backlog.<br>We tried to address it like so:</p><ul><li>We periodically reminded each other that tech time is <strong>valuable to the business.</strong></li><li>We presented impactful changes to the wider engineering organisation every two weeks in meetings we call &quot;Tech Forums&quot;.</li><li>Engineers announced their unavailability when they focused on tech time to avoid interruptions.</li></ul><h2 id="enhance-focus">Enhance Focus</h2><p>A few months had passed, and what started as a shy attempt to frequently work on technical topics felt natural by now. Engagement increased and most engineers were contributing.<br>After a retrospective, our squad felt like we could refine the approach, so we decided to experiment with the format, and here is what we did:</p><ul><li>The squad devoted Mondays to tech time, <strong>a fixed day</strong> resulted in more synergy, pairing, and even mob-programming.</li><li>To avoid context switching and interruptions, we asked co-workers to not plan meetings on that day.</li><li>We added a Slack reminder that would notify us every Monday about the opportunity.</li><li>We focused our Monday stand-ups on tech tasks only.</li><li>We momentarily introduced an impact-effort matrix to help us prioritise tasks as a group.</li></ul><p>The outcome became known as &quot;Tech Task Monday&quot;, and engineers enjoyed a <strong>meeting-free day</strong> to collaborate with each other on topics they considered important.</p><p>Other squads started following a more focused approach like ours, and product designers joined the process too, this led to even more opportunities for collaboration.</p><h2 id="coordinate-priorities">Coordinate Priorities</h2><p>From the start, engineers were responsible to pick the tasks they deemed worth prioritising, they know best what is unnecessarily painful, and what requires attention.</p><p>To coordinate on a higher level and to increase the visibility of potentially highly impactful tasks, we introduced a few changes:</p><ul><li>Engineers organise and decide quarterly engineering goals, and we frequently remind ourselves about them.</li><li>On Mondays, the multiple squad stand-ups merged into a single engineering stand-up, this improved awareness of ongoing tasks and enhanced the opportunity for collaboration between all engineers and designers.</li><li>Every third week, we hold a meeting to verify the progress on past post-mortem action points.</li></ul><h2 id="conclusion">Conclusion</h2><p>We are not striving for perfection in our systems, we are not striving for zero legacy code. We are striving for <strong>small frequent improvements every Monday,</strong> to keep things tidy and innovative. We want to avoid desperate situations in which the accumulated tech debt would be so unconquerable that radical solutions, such as rewrites, would seem like a good solution.</p><p>And we also want to enable individuals to learn, grow, experiment. To enable future product initiatives. And to provide the technical means for the business to flourish.</p><p>What did we achieve? Well, a lot: Design systems, ready to boot micro-services, sub 10 minutes pipelines, style libraries, modular software architectures, workshops, CLIs to generate code, bots and tools to support our work, dashboards, better testing, updating libraries, reducing legacy code, embracing Kotlin, improved error detection,&#x2026; and much much more.</p><p>Finally, this process is not carved in stone, we remain curious and open to experiments, and we will keep shaping it as we go.</p><p>Hopefully, this blog post has provided you with an alternative concept to tech debt, and ideas on how to gradually implement <strong>Tech Time</strong>.</p><hr><p>If you like our approach, consider <a href="https://www.tooltime.de/jobs?ref=tooltime.tech">joining us</a>, we are actively hiring for Engineers and other positions.</p>]]></content:encoded></item><item><title><![CDATA[How we implemented Web notifications]]></title><description><![CDATA[<p></p><blockquote>The path to arrive at the goal is more important than the goal itself.</blockquote><p>(Someone said that, probably not Lao Tzu)</p><hr><h3 id="introduction-what-we-had-to-accomplish">Introduction: what we had to accomplish</h3><p>In ToolTime we have currently three autonomous squads, following the Agile principles of self-organising and cross-functional teams. The squad in which I am</p>]]></description><link>https://tooltime.tech/how-we-implemented-web-notifications/</link><guid isPermaLink="false">608680832c11fc00ceda8ae9</guid><dc:creator><![CDATA[engineer]]></dc:creator><pubDate>Tue, 27 Apr 2021 08:47:28 GMT</pubDate><content:encoded><![CDATA[<p></p><blockquote>The path to arrive at the goal is more important than the goal itself.</blockquote><p>(Someone said that, probably not Lao Tzu)</p><hr><h3 id="introduction-what-we-had-to-accomplish">Introduction: what we had to accomplish</h3><p>In ToolTime we have currently three autonomous squads, following the Agile principles of self-organising and cross-functional teams. The squad in which I am working is called &quot;collaboration squad&quot;. The name is not only about our internal collaboration, but mainly indicating our focus on enhancing the collaboration, the teamwork and the workflow for our customers.<br>One of the requested features was to have notifications appearing in the Web application when somebody performs some action. For example, when a field worker (imagine an electrician, a plumber or some other type of craftsman) creates or closes an appointment from the mobile app, the office-located colleagues should see a notification in the Web app.<br>Here below is a screenshot:</p><figure class="kg-card kg-image-card"><img src="https://tooltime.tech/content/images/2021/04/Screenshot-2021-04-27-at-10.41.43.png" class="kg-image" alt loading="lazy"></figure><p>The requirement was just display the notification and don&apos;t store it, because we have another feature of the product, called &quot;activity log&quot;, to store and display the history of events.<br>The flow is: a field worker performs some action using the mobile app, then the backend system, that receives requests form the mobile app, should send a notification to the Web app, that in turn should be listening and display the notification for some time.</p><p></p><h3 id="different-options-on-the-table">Different options on the table</h3><p>We didn&apos;t have any notification system in place so far, therefore we wanted to investigate the possible options available for implementing this mechanism. As always happens in these cases, we don&apos;t want to just pick any solution, but we want to work together to define the best solution for our problem. All the engineers in the squad, five people at that time, contributed with &quot;spikes&quot; to the team knowledge of available options and practically tried some proofs of concept. The process is very democratic: each one contributes with ideas and proofs of concept, we discuss together and take a decision. We think that only a democratic team environment can encourage people&apos;s creativity and we enjoy working this way.<br>Omitting a few ideas for the sake of brevity, the main solutions we tried in our spikes are:</p><ul><li>Firebase Realtime Database.</li><li>GraphQL subscriptions in our backend service.</li><li>GraphQL subscriptions in a new microservice.</li><li>Server-sent events.</li><li>AWS AppSync.</li></ul><p><a href="https://firebase.google.com/products/realtime-database?ref=tooltime.tech">Firebase</a> was one of the most valuable solutions, as it appeared to be easy to implement, especially on the frontend side. It is just about using a DB table, where the backend should write and from where the frontend should read (subscribing to changes). It could have really become our solution, just we had some minor concerns:</p><ul><li>an additional cleanup mechanism was needed. Our business case was not exactly about storing something, but more of the type fire-and-forget. It looked like a valid solution but a bit &quot;artificial&quot; in our asset.</li><li>There was a lack of &quot;contract&quot; between frontend and backend.</li><li>We should have taken care of some other nonfunctional aspects, like security, in an additional cloud environment, as we are currently mainly using AWS.</li></ul><p>Our main backend service is based on GraphQL and the Web app is communicating with it in GraphQL, therefore it looked natural to us to consider <a href="https://graphql.org/blog/subscriptions-in-graphql-and-relay/?ref=tooltime.tech">GraphQL subscriptions</a>, based on the <a href="https://en.wikipedia.org/wiki/WebSocket?ref=tooltime.tech">WebSocket protocol</a>.<br>The first place we considered for adding GraphQL subscriptions was our backend service, but we soon found two cons in doing that:</p><ul><li>It would have forced us to upgrade the GraphQL version, which is something that we would prefer to postpone according to our plans for improving our system.</li><li>It would have added more responsibilities to the backend service, that we want to split instead, as we are currently migrating towards a microservice-based architecture.</li></ul><p>As a consequence, we thought that it would have been better done inside a new microservice, dedicated only to this mission (something like a &quot;notification-service&quot;). Another respectable option, still forcing us to create and maintain a service and to add custom code.</p><p>Yet another respectable idea was to use <a href="https://en.wikipedia.org/wiki/Server-sent_events?ref=tooltime.tech">server sent events</a> instead of WebSocket, considering that our case is mono-directional and not bi-directional as a chat. A small reasonable proof of concept was presented for the backend side, still this was making us develop some custom code inside some service for the purpose.</p><p>At the end, we embraced the serverless idea, that is <a href="https://aws.amazon.com/appsync/?ref=tooltime.tech"><strong>AWS AppSync</strong></a>, that is like saying <strong>a serverless version of the idea of GraphQL subscriptions</strong>, as AppSync is essentially a GraphQL service. AppSync became our notification service.</p><p></p><h3 id="our-solution">Our solution</h3><p>In AppSync we define a small schema reflecting the structure of our notifications (type of action, author of the action, time in which it took place, etc.), with one mutation for sending notifications, to be invoked by the backend service, and one subscription, to be invoked by the frontend app. We used <a href="https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-local-resolvers.html?ref=tooltime.tech">&quot;NONE&quot; data sources</a>, as the data is just in transit inside AppSync, we don&apos;t need to store anything.</p><p>Just a few lines of code (such an &quot;if&quot; condition) were added to the subscription resolver, to check that users are subscribing to events belonging to their company and not another one.<br>Subscribing and getting notifications was easily implemented in the Web application using <a href="https://aws.amazon.com/amplify/?ref=tooltime.tech">Amplify</a>. Similarly for the backend service, it was just about sending a request to AppSync with the data about the event that was triggered by some user action.</p><p>Nothing to do for the mobile app, just sending requests to the backend service as before.<br>We had also fun with some amount of work to be done at infrastructure level, not so difficult, regarding the <a href="https://www.terraform.io/?ref=tooltime.tech">Terraform</a> definition of our resources (infrastructure as software).<br>Notice: this was an effort only at creation time, to define the infrastructure, but not at maintenance time, as we went for a serverless solution, as mentioned.<br>The work was related also to exposing the AppSync subscription with a readable public URL, using AWS CloudFront and Route53, and to security.</p><p>We don&apos;t want to talk in detail about the security aspects of our solution, just for the purpose of security, but we think we obtained a respectable level of security by combining <a href="https://aws.amazon.com/about-aws/whats-new/2019/05/aws-appsync-now-supports-configuring-multiple-authorization-type/?ref=tooltime.tech">different AppSync authentication modes</a>, for the sender of events and the subscriber, and other general AWS features like <a href="https://aws.amazon.com/waf/?ref=tooltime.tech">WAF</a>.</p><p>Here is a diagram summarising our solution:</p><figure class="kg-card kg-image-card"><img src="https://tooltime.tech/content/images/2021/04/diagram.png" class="kg-image" alt loading="lazy"></figure><ul><li>The subscription from the Web app goes through Route53 and CloudFront, reaching AppSync.</li><li>A request arrives from the mobile application to the backend service.</li><li>The backend service sends a notification to AppSync.</li><li>The Web app, that previously subscribed to AppSync, receives the notification.</li></ul><p></p><h3 id="the-result">The Result</h3><p>So far, a few months after the release, we have encountered:</p><ul><li>customer satisfaction,</li><li>zero bugs,</li><li>zero infrastructure issues,</li><li>zero infrastructure maintenance work.</li></ul><p>The initial research work and the infrastructure configuration paid off. The solution respects the nature of our requirements. The &quot;path&quot; to get to the result and the team collaboration were the key. A mainly serverless solution with a very little amount of code means you can just use it and basically forget it from a maintenance point of you, so that you can focus on other features in this fast-paced world.</p>]]></content:encoded></item><item><title><![CDATA[Separation of concerns in React Apps]]></title><description><![CDATA[<p>If your React application is difficult to maintain it might be due to the lack of <strong>separation of concerns, </strong>ToolTime&apos;s Apps were encountering such difficulties a year ago.&#x200C;&#x200C; The newly hired Engineering Team decided to transform an experimental MVP application, which was mixing concerns and therefor</p>]]></description><link>https://tooltime.tech/react-apps-separation-of-concerns/</link><guid isPermaLink="false">5e5f6dae66f1e301278e1998</guid><category><![CDATA[web]]></category><category><![CDATA[react]]></category><dc:creator><![CDATA[Yves Van Goethem]]></dc:creator><pubDate>Tue, 16 Mar 2021 08:00:00 GMT</pubDate><content:encoded><![CDATA[<p>If your React application is difficult to maintain it might be due to the lack of <strong>separation of concerns, </strong>ToolTime&apos;s Apps were encountering such difficulties a year ago.&#x200C;&#x200C; The newly hired Engineering Team decided to transform an experimental MVP application, which was mixing concerns and therefor hard to maintain, into a stable, scalable, modular, and qualitative one, with clear separations.</p><h2 id="what-is-separation-of-concerns">What is separation of concerns?</h2><p>Good question.</p><p>In the late 2000s, Web Developers would identify concerns such as <strong>Content (HTML),</strong> <strong>Styling (CSS)</strong> and <strong>Interactions (JavaScript).</strong> If the website was build using a dynamic language such as PHP, one could identify additional concerns, for example Business Logic, Session Persistence, Database Queries (SQL), and many more.</p><p>It used to be pretty common to write HTML (or PHP) files that would mix multiple, if not all of those concerns in a single file. HTML4 was even enabling developers to define styling with HTML tags such as <code>&lt;font&gt;</code>, <code>&lt;marquee&gt;</code>, or <code>&lt;blink&gt;</code>. Nowadays, if we want to achieve effects such as the <code>&lt;blink&gt;</code> tag offered, we would write a CSS animation and target an HTML element with a CSS selector, if we want to display bold text for purely stylistic reasons, we would use the <code>font-weight</code> CSS property instead of using the <code>&lt;b&gt;</code> tag.</p><p>In React Apps we find many similarities with early days websites. Let us go through some of the concerns we have identified and systematically separated in our apps in order to reduce file length, increase clarity, allow for higher collaboration through modularity, and higher maintainability through conventions.</p><h2 id="concerns-in-react">Concerns in React</h2><p>Before we dive deeper, let us get familiar with the goal of React, by reading the first line in the <a href="https://reactjs.org/docs/getting-started.html?ref=tooltime.tech">React documentation</a>.</p><blockquote><strong>React</strong> is a JavaScript library for building user interfaces.</blockquote><p>Alright, let&apos;s identify the common concerns of a <strong>user interface</strong>: </p><ul><li><strong><a href="#routing">Routing</a></strong></li><li><strong><a href="#content">Content</a></strong></li><li><strong><a href="#styling">Styling</a></strong></li><li><strong><a href="#interactions">Interactions</a></strong></li></ul><p>We will tackle other non-UI concerns, such as business logic or data handling, and dive into concepts such as <strong>single-responsability principle </strong>in future articles.</p><p>So, first of: Routing!</p><h2 id="routing">Routing</h2><p><strong>&#x1F6E3; Routing binds a URL to a React component.</strong></p><p>When we enter a URL in our browser, or when we click on a link, we expect the application to load a page. In a Single Page Application, this is the responsibility of a Router.</p><p>Various React apps introduce complexity by using a mixture of two paradigms: <strong>Application routing</strong> and <strong>Nested routing. </strong></p><p>Let us define these two terms first to create common understanding with the examples of <em>react-router-dom</em>. In these examples we will imagine a simple application that routes to a home page, a user profile, and a user profile edit page.</p><p><strong>Application routing</strong> introduces a unique application-wide Router and associated routes, listening to URL changes, and its responsibility is to render a different page for each route.</p><!--kg-card-begin: markdown--><pre><code class="language-js">// App.jsx
const App = () =&gt; {
  return (
    &lt;Router&gt;
      &lt;Switch&gt;
        &lt;Route path=&quot;/&quot; component={&lt;HomePage /&gt;} /&gt;
        &lt;Route path=&quot;/profile/:username&quot; component={&lt;ProfilePage /&gt;} /&gt;
        &lt;Route path=&quot;/profile/:username/edit&quot; component={&lt;ProfileEditPage /&gt;} /&gt;
      &lt;/Switch&gt;
    &lt;/Router&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p><strong>Nested routing</strong> introduces multiple routers nested within each other. In this example the App.jsx file includes a <code>&lt;Router&gt;</code>, and so does the ProfileWithRouter.jsx file.</p><!--kg-card-begin: markdown--><pre><code class="language-js">// App.jsx
const App = () =&gt; {
  return (
    &lt;Router&gt;
      &lt;Switch&gt;
        &lt;Route path=&quot;/&quot; component={&lt;HomePage /&gt;} /&gt;
        &lt;Route path=&quot;/profile/:username&quot; component={&lt;ProfileWithRouter /&gt;} /&gt;
      &lt;/Switch&gt;
    &lt;/Router&gt;
  );
};

// ProfileWithRouter.jsx
const ProfileWithRouter = () =&gt; { 
  const match = useRouteMatch();
  return (
    &lt;Router&gt;
      &lt;Switch&gt;
        &lt;Route path={`${match.path}/edit`} component={&lt;ProfileEditPage /&gt;} /&gt;
        &lt;Route path={match.path} component={&lt;ProfilPage /&gt;} /&gt;
      &lt;/Switch&gt;
    &lt;/Router&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p>Now, if the <strong>Nested routing</strong> principal follows clear team conventions across the whole application, and is perhaps even enforced through tooling, then this approach is not, per se, a knotty strategy. However, if conventions cannot be enforced or aren&apos;t followed, it can lead to maintainability issues. In our Apps, it led to vague responsibilities, and <strong>obscurity</strong> about which components handle which routes, why, and how, one of the many questions was &quot;should these components also render content?&quot;. We found it made it particularly hard for a new team to take over a project, or for a new colleague to get a quick understanding of the application.</p><p><strong>Application routing</strong> has an advantage in that it offers <strong>centralised clarity</strong> about all reachable parts of the application, if properly isolated it does not even need to live in App.jsx, it can live in its own file, away from other UI concerns. So we moved all routing logic to an <strong>Application routing</strong> strategy and isolated it like so:</p><p><strong>#1</strong> Store routes as an array of objects:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// Routes.js
export const routes = [{
  path: &apos;/&apos;,
  component: HomePage
},{
  path: &apos;/profile/:id&apos;,
  component: ProfilePage
},{
  path: &apos;profile/:id/edit&apos;,
  componentt: ProfileEditPage
}];
</code></pre>
<!--kg-card-end: markdown--><p><strong>#2 </strong>Consume the routes in a router:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// Router.jsx
import { BrowserRouter, Switch, Route } from &apos;react-router-dom&apos;;
import { routes } from &apos;./routes&apos;;

export const Router = () =&gt; {
  return (
    &lt;BrowserRouter&gt;
      &lt;Switch&gt;
        {routes.map({ path, component }) =&gt; { 
          &lt;Route path={path} component={component} /&gt;
        })}
      &lt;/Switch&gt;
    &lt;/BrowserRouter&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p><strong>#3 </strong>Import the router in the App</p><!--kg-card-begin: markdown--><pre><code class="language-js">// App.jsx
import { Router } from &apos;Router&apos;;

export const App = () =&gt; {
  return &lt;Router /&gt;;
};

</code></pre>
<!--kg-card-end: markdown--><p>This solution is not unique to ToolTime, it is already widely used by the React community, and is central to many opinionated frameworks such as Backbone, Vue, or Angular.</p><p>So this is how we solved Routing: we centralised the routing logic, and removed nested routing from components. Developers benefit from clarity, and routing concerns are separated from other concerns.</p><hr><h2 id="content">Content</h2><p>&#x1F4F0; <strong>Content describes the semantics of a component.</strong></p><p>It might be interactive content such as <code>&lt;video&gt;</code>, or <code>&lt;img&gt;</code>. Or actionable content like form elements with <code>&lt;button&gt;</code> or <code>&lt;input&gt;</code>, &#xA0;or a link to another page with an anchor tag <code>&lt;a&gt;</code>. In most cases however, it will be text described as paragraphs with <code>&lt;p&gt;</code>, headings with <code>&lt;h1&gt;</code>, <code>&lt;h2&gt;</code>,&#x2026; unordered lists with <code>&lt;ul&gt;</code>, etc. And other tags such as <code>&lt;main&gt;</code>, <code>&lt;section&gt;</code> to structure the content in a page.</p><p>For this example we will render a blog post with what is known as <strong>divitus,</strong> the excessive usage of <code>&lt;div&gt;</code>, in detriment of semantic HTML tags.</p><!--kg-card-begin: markdown--><pre><code class="language-js">// BlogPost.jsx
export const BlogPost = () =&gt; { 
  return (
    &lt;&gt;
      &lt;div&gt;How much I like banana bread&lt;/div&gt;
      &lt;div&gt;
        I looooove banana bread!&lt;br /&gt;Very very much!
      &lt;/div&gt;
    &lt;/&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p>The above example has no semantic value: a browser, a search engine, or a screen-reader is unable to tell which text is the title, and which text is the post&apos;s content.</p><p>Let&apos;s solve this with semantics:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// BlogPost.jsx
export const BlogPost = () =&gt; { 
  return (
    &lt;&gt;
      &lt;h1&gt;How much I like banana bread&lt;/h1&gt;
      &lt;p&gt;
        I looooove banana bread! &lt;br /&gt;
        Very very much!
      &lt;/p&gt;
    &lt;/&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p>This was easy. Beyond semantics, HTML also provides build-in functionalities, such as form validation, dns pre-fetching, and much more. Check out the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML?ref=tooltime.tech">MDN HTML guide</a> for more.</p><h3 id="-content-anti-patterns">&#x26A0;&#xFE0F; Content anti-patterns</h3><p>Beware of anti-patterns, many React components available throughout the libraries in the community, will provide some functionality without rendering anything. </p><p>While this is accepted by many as &quot;normal&quot;, we do believe that this goes beyond the responsibilities of a UI library. Expressing functionalities, such as data-fetching for example, are better expressed with functions, or with React hooks, than they are with JSX.</p><p>For example we forbid the usage of Apollo&apos;s <code>&lt;Query&gt;</code> component, instead we rely on Apollo&apos;s functional API to fetch data and extract that responsibility to a different file.</p><p>Alright let&apos;s dive into the next topic: Styling. </p><hr><h3 id="styling">Styling</h3><p><strong>&#x1F485; Styling defines the look and feel of a component.</strong></p><p>Many tools such as JSS, CSS Modules, Emotion,&#x2026; can be used to style components. <br>What is also pretty common in various documentations is to &quot;co-locate&quot; styles with the component functionality in the same file, such as this:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// BlogPost.jsx
const styles = {
  title: {
    color: &apos;red&apos;
  }
};

export const BlogPost = () =&gt; { 
  return (
    &lt;h1 className={styles.title}&gt;How much I like banana bread&lt;/h1&gt;
    &lt;p&gt;I looooove banana bread!&lt;/p&gt;
    &lt;p&gt;Very very much!&lt;/p&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p>While this might seem harmless in many cases, it becomes increasingly difficult to maintain when the styles grow in size, and the component grows in complexity.</p><p>The solution we advocate, is to separate these two concerns in different files, no matter how many lines of code, the result then looks somewhat like this:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// BlogPost.styles.js
export const styles = {
  title: {
    color: &apos;red&apos;
  }
};
</code></pre>
<pre><code class="language-js">// BlogPost.jsx
import { styles } from &apos;./BlogPost.styles&apos;;
export const BlogPost = () =&gt; { 
  return (
    &lt;h1 className={styles.title}&gt;How much I like banana bread&lt;/h1&gt;
    &lt;p&gt;I looooove banana bread!&lt;/p&gt;
    &lt;p&gt;Very very much!&lt;/p&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p>Beyond the advantage of creating smaller clearer maintainable files, the next author won&apos;t have to break up a file that grew in complexity.</p><h2 id="interactions">Interactions</h2><p><strong>&#x1F4F2; Interactions describe a components behaviour on user input.</strong></p><p>Let&apos;s imagine we want to render a button that behaves as a toggle for an information to be displayed below (that I love banana bread).</p><!--kg-card-begin: markdown--><pre><code class="language-js">// ButtonWithContent.jsx
export const ButtonWithContent = () =&gt; {
  const [isEnabled, setIsEnabled] = useState(false);
  const clickHandler = () =&gt; {
    setIsEnabled(!isEnabled);
  };
  return (
    &lt;&gt;
      &lt;button onClick={clickHandler}&gt;Toggle information&lt;/button&gt;
      {isEnabled &amp;&amp; &lt;p&gt;I love banana bread&lt;/p&gt;}
    &lt;/&gt;
  );
};
</code></pre>
<!--kg-card-end: markdown--><p>This component contains multiple concerns now: </p><ul><li>A state <code>isEnabled</code> and its setter <code>setIsEnabled</code> expressed via React&apos;s <code>useState</code> hook.</li><li>An event handler <code>clickHandler</code> toggling the state everytime the button is clicked.</li><li>Stateful JSX that will conditionally render the <code>&lt;p&gt;</code> content.</li></ul><p>Again, in many cases this will seem harmless, the file feels small and readable, but as soon as the feature grows in complexity, the next developer will need to decide to keep adding to it, or to move these concerns to a different file.</p><p>Moving behaviours out of the component can be achieved immediately, one way is to use React Hooks like so:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// ButtonWithContent.behaviour.js
export const useButtonWithContentBehaviour = () =&gt; {
  const [isEnabled, setIsEnabled] = useState(false);
  const clickHandler = () =&gt; {
    setIsEnabled(!isEnabled);
  };
  return {
    clickHandler: clickHandler,
    isEnabled: isEnabled
  }
};
</code></pre>
<!--kg-card-end: markdown--><p>Now the concerns of interactions are separated from the component&apos;s rendering concerns. The component calls a hook to retrieve the state and the click handler from the behaviour:</p><pre><code class="language-js">// ButtonWithContent.jsx
import { useButtonWithContentBehaviour } from &apos;./ButtonWithContent.behaviour&apos;;
export const ButtonWithContent = () =&gt; {
  const { clickHandler, isEnabled } = useButtonWithContentBehaviour()
  return (
    &lt;&gt;
      &lt;button onClick={clickHandler}&gt;Toggle information&lt;/button&gt;
      {isEnabled &amp;&amp; &lt;p&gt;I love banana bread&lt;/p&gt;}
    &lt;/&gt;
  );
};
</code></pre><h2 id="finally">Finally</h2><p>We follow these principles because we find that they work for us, not every solution fits every context, you might need to adapt these ideas slightly to fit your needs, or perhaps you will need to look elsewhere for other solutions. </p><p>To us, large intricated software problems, become <strong>small solvable problems </strong>when they are split.<strong> </strong>Defining boundaries and responsibilities helped us refactor large messy files into clearer, smaller, maintainable files ; eventually this discipline has led to more readable, scalable, and testable software.</p>]]></content:encoded></item><item><title><![CDATA[Hiring at ToolTime]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h1 id="idea">Idea</h1>
<p>When I joined ToolTime, heavily influenced by a book called <a href="https://en.wikipedia.org/wiki/The_Five_Dysfunctions_of_a_Team?ref=tooltime.tech">5 dysfunctions of a team</a>, and my previous experience I was convinced that the things I will be optimising for is <strong>how people in a team work</strong>, rather than what single engineers bring to the table. The idea was</p>]]></description><link>https://tooltime.tech/hiring-at-tooltime/</link><guid isPermaLink="false">5e4c3b8266f1e301278e1732</guid><category><![CDATA[hiring]]></category><category><![CDATA[team]]></category><category><![CDATA[culture]]></category><dc:creator><![CDATA[Slawomir Smiechura]]></dc:creator><pubDate>Tue, 02 Mar 2021 18:26:16 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h1 id="idea">Idea</h1>
<p>When I joined ToolTime, heavily influenced by a book called <a href="https://en.wikipedia.org/wiki/The_Five_Dysfunctions_of_a_Team?ref=tooltime.tech">5 dysfunctions of a team</a>, and my previous experience I was convinced that the things I will be optimising for is <strong>how people in a team work</strong>, rather than what single engineers bring to the table. The idea was that I will try to create an emotionally safe environment where people voice ideas without being stigmatised. No shaming, and listening to understand, rather than listening to reply.<br>
We need teams where conflict is creative, where people know and understand diverse approaches to a given problem. This way we can pick one that the business will benefit from the most. What is also important, and many teams I&apos;ve worked with missed that, is that we can create a culture where buy-in is easier to achieve, and the <strong>disagree and commit</strong> is not just a weird way of saying &quot;listen to the boss&quot;.</p>
<h1 id="values">Values</h1>
<p>What we are trying to understand during the interview is the candidate&apos;s <strong>attitude</strong> and <strong>mental model</strong>, secondarily their technical skills. No, it&apos;s not to say that technical skills do not matter. It is just that it is way easier to teach a programming language, technology and tools to a person with the right mindset, than to change the mindset of a really skilled, technical person.<br>
We are looking for people who make everyone around them better engineers, and this way we will only get stronger teams which will ripple this &quot;continuous improvement effect&quot; outside their circle.</p>
<p>The mental model we are looking for can be described in a few words: <strong>the more I know, the less I know</strong>, <strong>many, small problems rather than one and big</strong>,  <strong>no bullshit</strong>, <strong>curious</strong>, <strong>2% grumpy</strong>.</p>
<ul>
<li><strong>the more I know, the less I know</strong> - we want to know what the candidate thinks and why they think that. It&apos;s really unimportant that you do not follow TDD, we are curios to know if you can articulate why you decided to not follow that style.</li>
<li><strong>many small problems</strong> - whether a candidate breaks the issue down, how do they approach the given task. Will they fall into &quot;analysis paralysis&quot;, or will they solve each step in isolation? Can they build a whole picture or do they get lost in details?</li>
<li><strong>no bullshit</strong> - interviews are stressful, and it&apos;s a game where you want to show the best of you to the interviewer. We know! We put a lot of effort to make it as pleasant as possible. However, we really appreciate people who openly say &quot;I don&apos;t know&quot;, or better &quot;I don&apos;t know but what do you think about this approach&quot; rather than trying to tell us everything they know, which seems related.</li>
<li><strong>curious</strong> - will the candidate ask clarifying questions or will they rather burst an answer without really knowing the context. Will they accept that something that worked in a different context, might not work for ToolTime, and will they want to know &quot;<strong>Why?</strong>&quot;</li>
<li><strong>2% grumpy</strong> - this is one of our Company Values, a positive attitude helps the team to a great extent. Just the bare feeling of positivity improves the team morale to the point where people naturally gravitate towards each other and want to help. Of course, everyone has worse moments, use the 2% for that.</li>
</ul>
<h2 id="hiringprocess">Hiring process</h2>
<p>Knowing what mindset we are looking for, our hiring process is organised in the following stages:</p>
<h3 id="cvscreening">CV screening</h3>
<p>We are looking at experience which projects were built with which tools and technologies. It&apos;s really way more important to see the application of a particular framework, rather than see a large list of keywords.</p>
<h3 id="initialcall">Initial call</h3>
<p>We want to give the candidate an idea of what we do as a business, and how we operate. We want to understand a candidate&apos;s situation.</p>
<h3 id="callwiththeheadofengineering">Call with the Head of Engineering</h3>
<p>It&apos;s usually a semi-technical discussion. I explain how engineering at ToolTime works and will ask you to tell me your story and what your principles are. I will listen carefully and you should be ready for a series of open questions largely built from the story you tell. For example, if you say you follow SOLID principles, I might ask you what D stands for in SOLID. If you tell how great TDD is, probably my question will be &quot;what is the biggest value of TDD&quot;.<br>
Answers which indicate subjective thinking (&quot;It&apos;s more readable&quot;, &quot;This is better&quot;) are scored lower.</p>
<h3 id="technicalcall">Technical call</h3>
<p>At this stage, we will want to dive deeper in your technical skills. We will ask you about the technologies we use and what you have experienced in your career. Don&apos;t expect algorithms or data structures here, but more likely we will want to know how well you know ReactJs, what are the things you would change if you could, what are the good parts.</p>
<h3 id="laststage">Last stage</h3>
<p>If you got to this stage, chances are pretty high that you will land a job at TT &#x1F60F;. All it takes now is to show all the things you told us about in practice. We will prepare a little challenge for you and ask you to pair with us and show how you would solve it. If your comfort zone is mobile, we would ask you to implement a single page app in a skeleton of an app using technology you want. One of our engineers will pair with you. What we want to know is how you cooperate with another person, how do you chose tools and solutions for a given problem.<br>
We will also invite you to get to know people who drive and support product development at TT. You will have a series of coffee/tea chats with everyone. As exhausting as it could be this is also an opportunity for you to get a better idea on how it is to be a ToolTimer. Use it and be curious, ask all the questions that you have.</p>
<h2 id="decision">Decision</h2>
<p>We use a very simple, and not an easy system to decide whether a candidate is accepted or not. Every person who participated in the interview gets one vote. They can vote Yes or No, there is no Maybe. Everyone gets a chance to articulate why they voted the way they did. Everyone can change their vote during the discussion. The caveat is <strong>one NO means NO</strong>, and the candidate is not hired. We are really serious about it, and we do not take this process lightly. At the end of the day it is quite an investment, from our side and from a candidate as well.<br>
In order to help with the vote we have 3 ground questions:</p>
<ul>
<li><strong>Is the candidate someone I want to work with every day?</strong></li>
<li><strong>Is the candidate worth our energy to train them in the areas they fall short in, and will they be able to keep up?</strong></li>
<li><strong>Can the candidate move without supervision in at least one area?</strong></li>
</ul>
<p>So really, one no means NO.</p>
<p>But... let&apos;s not forget we are dealing with people here, and we all have worse moments where we just fall short. It could be that the interview was too long, your head was in the wrong place or whatever else happened that made you answer in a silly way. Or, one of our interviewers had one of those moments, is that it? No. We also have a very special function in our process and it&apos;s called The Champion.<br>
Any of the interviewers can become a champion, taking one of the NOs out. And if they do, they become accountable for setting the candidate for success in the team. They prepare, lead and support the candidate in the first 6 months in TT. Even though it&apos;s there, we have not used it since the very beginning. We live by our own rules of listening to understand, be curious and ask, and disagree and commit.</p>
<h2 id="feedback">Feedback</h2>
<p>Remember the YES/NO voting? That is also the moment where we gather notes that we will later on send to you. Whether they are concerns, ideas for improvement or good notes from your interview. These notes are something we send to a candidate. Sometimes we will send you a link to a book we believe will help you, sometimes it&apos;s more general ideas for leveling up. We do not think that failing an interview at ToolTime means you are a bad engineer. Different types of businesses require different types of engineers and that&apos;s the mentality we are trying to keep. Our goal is to make sure you will also benefit from the time you have invested in talking to us.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Meet our engineering team: Ivan Makale]]></title><description><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://tooltime.tech/content/images/2020/05/IvanMakale.JPG" class="kg-image" alt loading="lazy"><figcaption>Ivan Makale, Senior Backend Engineer at ToolTime</figcaption></figure><p><em><strong>ToolTime is the digital home for craftsmen businesses built by a group of curious minds from diverse cultures and backgrounds, working cross-functionally and connected by a shared passion.</strong></em><br></p><p>In this Q&amp;A series you will meet different members of our engineering team,</p>]]></description><link>https://tooltime.tech/meet-our-engineering-team-ivan-makale/</link><guid isPermaLink="false">5ebbd57616b99500faf8d44a</guid><category><![CDATA[team]]></category><dc:creator><![CDATA[Isabel Manrique]]></dc:creator><pubDate>Thu, 14 May 2020 08:46:00 GMT</pubDate><media:content url="https://tooltime.tech/content/images/2020/05/Screenshot-2020-05-20-at-16.23.27.png" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://tooltime.tech/content/images/2020/05/IvanMakale.JPG" class="kg-image" alt="Meet our engineering team: Ivan Makale" loading="lazy"><figcaption>Ivan Makale, Senior Backend Engineer at ToolTime</figcaption></figure><img src="https://tooltime.tech/content/images/2020/05/Screenshot-2020-05-20-at-16.23.27.png" alt="Meet our engineering team: Ivan Makale"><p><em><strong>ToolTime is the digital home for craftsmen businesses built by a group of curious minds from diverse cultures and backgrounds, working cross-functionally and connected by a shared passion.</strong></em><br></p><p>In this Q&amp;A series you will meet different members of our engineering team, get to know them a bit better and hear what they have to say about ToolTime and technology in general. Today we would like to introduce Ivan Makale, one of our software engineers. </p><h3 id="what-do-you-do-what-is-your-position">What do you do? What is your position?</h3><p>Hired as &#x201D;senior backend engineer&#x201D;, mainly working on the backend side of our applications, even if there is not a rigid separation between frontend and backend in ToolTime, as people are encouraged to work full stack.<br></p><h3 id="what-led-you-to-tooltime-why-did-you-join">What led you to ToolTime? Why did you join?</h3><p>Interesting company, promising business. Company in an early stage, in which you have the chance of influencing, shaping the technical approach.</p><p>The business is very solid and not subjected to economic cycles or the fashion of the moment: the work of technicians is always needed, it is mainly about essential services.<br></p><h3 id="what-is-your-favourite-part-about-your-role">What is your favourite part about your role?</h3><p>Designing software solutions. Team collaboration is always encouraged.<br></p><h3 id="where-do-you-see-the-world-of-technology-in-10-years">Where do you see the world of technology in 10 years?</h3><p>I think the move from on-premise infrastructure to cloud services will continue, moving infrastructure more and more to external providers (like AWS, Google, Azure). I would expect the serverless approach to expand significantly, as companies try to delegate the complexities of IT infrastructure if possible, to focus on their business.</p><p>There are parts of the business world that have to catch up with IT adoption, especially small companies, so I would expect IT in those sectors to grow. This is exactly our case, where many small companies of technicians and what is around them have a big room for growing in their IT adoption.</p><p>Also IoT, of course, should be well expanded in 10 years, and it would be interesting if we could take some opportunity also with that in ToolTime.<br></p><h3 id="what-would-your-job-be-if-computers-did-not-exist">What would your job be if computers did not exist?</h3><p>I really don&#x2019;t know. It would be a very different world. For example, I studied physics initially, before joining the IT sector, but it is not clear to me what kind of opportunities I could have had in physics in a world without computers.<br></p><h3 id="what-are-you-listening-reading-watching-at-the-moment">What are you listening/reading/watching at the moment?</h3><p>Mainly something to keep me up to date with IT subjects and to do some exercise in German (readings, movies). I recently subscribed to the Tagesspiegel and I manage to read only a small part of it.</p><h3 id="any-last-thoughts"><br>Any last thoughts?</h3><p>One important thing in my opinion. It is difficult to predict the future, nobody has a crystal ball, but there is one thing that is probably reasonable to expect from the future. The corona-crisis will not be the only one, let&#x2019;s remember that we are also in a bigger context of climate crisis, likely to also cause some financial crisis. I think ToolTime is positioned in a &#xA0;very solid business sector, its mission is to do something really useful, to solve problems. Other sectors that are good but, let&#x2019;s say, less &#x201C;essential&#x201D;, like those related to tourism, travel, entertainment (at least part of it), could suffer much more than our business sector. </p><p><strong>Stay tuned for the next Q&amp;A session and follow us on <a href="https://www.linkedin.com/company/tooltimegmbh?ref=tooltime.tech">LinkedIn</a>, <a href="https://www.facebook.com/de.tooltime/">Facebook</a> and <a href="https://www.instagram.com/tooltime.de?ref=tooltime.tech">Instagram</a>.</strong></p>]]></content:encoded></item></channel></rss>