<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Kantz</title>
    <description>The latest articles on DEV Community by Michael Kantz (@mkantz84).</description>
    <link>https://dev.to/mkantz84</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F405026%2F0707b09e-9c87-4d69-9971-4187958f90ac.jpeg</url>
      <title>DEV Community: Michael Kantz</title>
      <link>https://dev.to/mkantz84</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mkantz84"/>
    <language>en</language>
    <item>
      <title>Cracking The Time Estimation</title>
      <dc:creator>Michael Kantz</dc:creator>
      <pubDate>Fri, 20 Nov 2020 19:57:49 +0000</pubDate>
      <link>https://dev.to/mkantz84/cracking-the-time-estimation-4pkn</link>
      <guid>https://dev.to/mkantz84/cracking-the-time-estimation-4pkn</guid>
      <description>&lt;h4&gt;
  
  
  My take on how to master Time Estimation (TE) in a full stack software development.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wv8awUb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y9janwxesxrb8dpd2qwa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wv8awUb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y9janwxesxrb8dpd2qwa.jpg" alt="story-points-estimating"&gt;&lt;/a&gt;&lt;/p&gt;
Source: &lt;a href="https://rubygarage.org/blog/3-reasons-to-estimate-with-story-points"&gt;Story Points vs Hours&lt;/a&gt;&lt;a&gt;&lt;/a&gt;



&lt;p&gt;My belief is that estimating time for a new feature could be harder mission than developing one.&lt;br&gt;
Understanding that there is a timeline creation for different features is something that needs to take in a closer consideration, and as one gain more experience it's easier to be handled.&lt;/p&gt;

&lt;p&gt;We all know how important is being accurate in time estimations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pricing determination.&lt;/li&gt;
&lt;li&gt;Setting a feature (or a sprint) deadline.&lt;/li&gt;
&lt;li&gt;Understanding the next milestone timeline&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Personally looking on my journey, it took me quite a while, ~4 years, to find a platform that kept me satisfied and was able to support my tasks at a high level, I also believe that this system may support other developers concurring this issue.&lt;/p&gt;

&lt;p&gt;In this article I will explain the system, and I'll demonstrate a live TE breakdown&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;em&gt;The System&lt;/em&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Separate the task for multiple (and &lt;strong&gt;very&lt;/strong&gt;) small subtasks.&lt;/li&gt;
&lt;li&gt;Each task should be time measured.&lt;/li&gt;
&lt;li&gt;The minimum time estimating per subtask should be 0.5 day. Even if you think the subtask is less than hour, make it 0.5 day.&lt;/li&gt;
&lt;li&gt;Always round the time 0.5 day up. (1.1 days will become 1.5 days).&lt;/li&gt;
&lt;li&gt;Combine the subtasks time estimation.&lt;/li&gt;
&lt;li&gt;Add 10% collateral time. (Do not round time here). &lt;/li&gt;
&lt;li&gt;If you didn't consider tests - Add 20% time. (Do not round time here).&lt;/li&gt;
&lt;li&gt;Add 20% time for personal QA. &lt;/li&gt;
&lt;li&gt;Round Time up if needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4_bM-VNC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f1sar7y5ducx4687kzvg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4_bM-VNC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f1sar7y5ducx4687kzvg.jpg" alt="girs"&gt;&lt;/a&gt;&lt;/p&gt;
Source: &lt;a href="https://legacy.www.8x8.com/blog/business-voip-enterprise-megatrend"&gt;8x8&lt;/a&gt;&lt;a&gt;&lt;/a&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Use-Case Demonstration&lt;/em&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Lets take a simple full stack task and estimate its time
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Task
&lt;/h5&gt;

&lt;p&gt;Show a list of all users in the software.&lt;br&gt;
Show maximum of 10 users and add pagination if needed.&lt;br&gt;
Give the option to filter between different users (admin, premium, etc...).&lt;/p&gt;

&lt;h5&gt;
  
  
  Time Estimation
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Subtasks separation:

&lt;ul&gt;
&lt;li&gt;Creating API in the server side, including routes, controllers, interactors, database calls - 0.5 days.&lt;/li&gt;
&lt;li&gt;Creating a network call from client to server. Make sure it works properly - 0.3 days -&amp;gt; 0.5 days.&lt;/li&gt;
&lt;li&gt;Updating the server to get page number, filter phrase, and collect the relevant 10 users from DB + Update the client network call + Check the API - 0.6 days -&amp;gt; 1 days.&lt;/li&gt;
&lt;li&gt;Creating a new page in the client side and show all the users - 0.5 days.&lt;/li&gt;
&lt;li&gt;Adding filtering section and update calls - 0.5 days.&lt;/li&gt;
&lt;li&gt;Adding pagination section and update calls - 1-1.2 days -&amp;gt; 1.5 days.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Combining time estimations - 4.5 days.&lt;/li&gt;
&lt;li&gt;Adding 10% collateral time - 4.9 days.&lt;/li&gt;
&lt;li&gt;Adding tests 20% - 5.9 days.&lt;/li&gt;
&lt;li&gt;Adding self QA 20% - 7.1 days.&lt;/li&gt;
&lt;li&gt;Rounding - 7.5 days.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iZpCSMt9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aj37gv8jfro4eu7ai98k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iZpCSMt9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/aj37gv8jfro4eu7ai98k.png" alt="clock"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes - 7.5 days.&lt;br&gt;
It may look a lot, but let me tell you this - After this TE you either deliver it sooner, either deliver with small/non QA rejections, and you'll have the confidence of delivering a good quality task on time.&lt;/p&gt;




&lt;p&gt;Hope this will help someone out there :)&lt;br&gt;
Thanks for reading ✌🏼&lt;/p&gt;

</description>
      <category>estimation</category>
      <category>fullstack</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I've just enhanced performance from 21sec to 0.4sec with this one single change</title>
      <dc:creator>Michael Kantz</dc:creator>
      <pubDate>Fri, 23 Oct 2020 06:55:32 +0000</pubDate>
      <link>https://dev.to/mkantz84/i-ve-just-enhanced-performance-from-21sec-to-0-4sec-with-this-one-single-change-45i0</link>
      <guid>https://dev.to/mkantz84/i-ve-just-enhanced-performance-from-21sec-to-0-4sec-with-this-one-single-change-45i0</guid>
      <description>&lt;h3&gt;
  
  
  This is the only thing that I've done to decrease my network call time dramatically.
&lt;/h3&gt;




&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.tutorialspoint.com/mysql/mysql-indexes.htm"&gt;SQL indexes.&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  OK, OK, I know what you think
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Who doesn't know indexes are very important in all forms of SQL databases??&lt;/em&gt;&lt;br&gt;
&lt;em&gt;How come you ended up having a 21 seconds loader??&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  You're right
&lt;/h4&gt;

&lt;p&gt;You're right, but it can be missed. I mean, we've missed it when we've started our MySQL architecture.&lt;br&gt;
I always knew the role of indexes, but it's hard to notice the real importance of it when your SQL tables are small sized.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Indexes are used to find rows with specific column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows. The larger the table, the more this costs." &lt;br&gt;
&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/mysql-indexes.html"&gt;How MySQL Uses Indexes&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So as a Time To Market Startup, we just forgot to add some really important indexes to our tables.&lt;/p&gt;
&lt;h4&gt;
  
  
  How things escalated
&lt;/h4&gt;

&lt;p&gt;In the beginning, there weren't any performance issues.&lt;br&gt;
But when the data and the DB scaled up, then things started to slow down.&lt;br&gt;
One day we've noticed that one network call is taking 21 seconds (!). &lt;br&gt;
That was the trigger to start digging into the code, trying to find performance issues.&lt;br&gt;
Very quickly we found the time consuming source, and it was just one DB query. &lt;br&gt;
We also noticed that this query is &lt;a href="https://www.mysqltutorial.org/mysql-join/"&gt;joining&lt;/a&gt; two large tables, and none of the fields in the &lt;a href="https://www.tutorialspoint.com/mysql/mysql-where-clause.htm"&gt;query &lt;code&gt;where&lt;/code&gt; clause&lt;/a&gt; were indexed.&lt;/p&gt;
&lt;h4&gt;
  
  
  The solution
&lt;/h4&gt;

&lt;p&gt;I added a single column index for each one of those fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE `table_name`
    ADD INDEX `fieldName` (`fieldName`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WOW, the speed!&lt;br&gt;
Suddenly the network call took 0.4 seconds. This change just blew our minds.&lt;/p&gt;




&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Do not underestimate the importance of SQL Indexes, and do not forget to add them to your SQL tables. &lt;br&gt;
One day you may end up with the query time of 21 seconds. It's not fun and it's embarrassing.&lt;/p&gt;

</description>
      <category>database</category>
      <category>webperf</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Inherit function parameters in TS</title>
      <dc:creator>Michael Kantz</dc:creator>
      <pubDate>Tue, 23 Jun 2020 06:54:52 +0000</pubDate>
      <link>https://dev.to/mkantz84/inherit-function-parameters-in-ts-16kd</link>
      <guid>https://dev.to/mkantz84/inherit-function-parameters-in-ts-16kd</guid>
      <description>&lt;p&gt;This article is relevant for all &lt;code&gt;typescript&lt;/code&gt; users. &lt;br&gt;
Though, I haven't encountered this issue in &lt;code&gt;Node.js&lt;/code&gt; yet..&lt;br&gt;
If you want you can skip the background part, and jump straight to the code examples.&lt;/p&gt;


&lt;h3&gt;
  
  
  Motivation
&lt;/h3&gt;

&lt;p&gt;Recently I faced a new challenge with &lt;code&gt;typescript&lt;/code&gt;, in my &lt;code&gt;react-redux&lt;/code&gt; app.&lt;/p&gt;

&lt;p&gt;One of the fundamental principles of &lt;code&gt;react-redux&lt;/code&gt; is &lt;a href="https://medium.com/@abhinav_jain123/react-redux-architecture-part-1-separation-of-concerns-812da3b08b46"&gt;separation of concerns&lt;/a&gt;.&lt;br&gt;
As a result of this separation we might need to pass a lot of parameters to an &lt;a href="https://redux.js.org/basics/actions"&gt;action creator&lt;/a&gt;.&lt;br&gt;
In addition, we might want to use this &lt;code&gt;action creator&lt;/code&gt; from different &lt;code&gt;components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Until now everything sounds normal.&lt;/p&gt;

&lt;p&gt;Now lets add &lt;code&gt;Typescript&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Adding &lt;code&gt;typescript&lt;/code&gt; to &lt;code&gt;react-redux&lt;/code&gt; app, forces us to define every &lt;code&gt;action creator&lt;/code&gt; function that we use in our component.&lt;br&gt;
of-course some of the functions can be defined as &lt;code&gt;Function&lt;/code&gt; type, but there are a lot of places that we need the full function signature.&lt;br&gt;
This boilerplate can be frustrating sometimes, especially when the team is getting bigger, and more people are starting to touch the code.&lt;/p&gt;

&lt;p&gt;Me and my teammate &lt;a href="https://medium.com/@lidorlevy"&gt;Lidor Levy&lt;/a&gt; looked for a solution for this problem and found resolution in this &lt;a href="https://github.com/Microsoft/TypeScript/issues/26019"&gt;Github issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Typescript is giving the option to inherit the parameters of a function!!&lt;/p&gt;


&lt;h3&gt;
  
  
  This is how we do it
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Define your function wherever you want&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const YOUR_FUNCTION_NAME = (
  param1: number,
  param2: Array&amp;lt;SOME_INTERFACE&amp;gt;,
  param3: string,
  param4: boolean
): YOUR_FUNCTION_TYPE =&amp;gt; {
  // some logic, or even keep empty
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In your function type definition&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;YOUR_FUNCTION_NAME: (
    ...YOUR_FUNCTION_NAME_Params: Parameters&amp;lt;
      typeof YOUR_FUNCTION_NAME
    &amp;gt;
) =&amp;gt; YOUR_FUNCTION_TYPE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to &lt;code&gt;import&lt;/code&gt; your function definition.&lt;/p&gt;




&lt;p&gt;Now, when you use the function, &lt;code&gt;typescript&lt;/code&gt; will know the parameter types, and your IDE code-completion can help you regularly. &lt;br&gt;
Enjoy!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>react</category>
      <category>redux</category>
    </item>
    <item>
      <title>Feature Toggle/Flag Design in React.js and Node.js</title>
      <dc:creator>Michael Kantz</dc:creator>
      <pubDate>Thu, 14 May 2020 07:29:45 +0000</pubDate>
      <link>https://dev.to/mkantz84/feature-toggle-flag-design-in-react-js-and-node-js-4a5k</link>
      <guid>https://dev.to/mkantz84/feature-toggle-flag-design-in-react-js-and-node-js-4a5k</guid>
      <description>&lt;h4&gt;
  
  
  A use case for implementing FTDD in a Full Stack JS application
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kii3q3hxr10vaub3rou.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kii3q3hxr10vaub3rou.jpeg" width="780" height="490"&gt;&lt;/a&gt;source of idea: &lt;a href="https://dzone.com/articles/a-new-way-to-beta-test" rel="noopener noreferrer"&gt;DevOps Zone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.martinfowler.com/articles/feature-toggles.html" rel="noopener noreferrer"&gt;FTDD (Feature/Flag toggle driven design)&lt;/a&gt; is a design pattern that helps teams to deliver new functionality to users rapidly but safely. Basically, it show/ hide features depends on the users role/ group/ whatever distinguishes the features set.&lt;br&gt;&lt;br&gt;
This pattern is the foundation basis of A/B testing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For instance, with this ability, you may upload a feature to production in the Beginning of the development, hide it from anyone but you, keep working.&lt;br&gt;&lt;br&gt;
When you feel good enough about the feature, you may reveal it to the QA team only, and when they approve, you may reveal the feature to whoever else you want.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Motivation and struggling&lt;/em&gt;&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Before we dive into the code, let me share with you what motivated me to write this article.&lt;br&gt;&lt;br&gt;
In &lt;a href="https://www.3dcastor.com/" rel="noopener noreferrer"&gt;Castor&lt;/a&gt;, the company I work for, we are aiming for a full CI/CD.&lt;br&gt;&lt;br&gt;
As a small &lt;a href="https://startupxplore.com/en/blog/types-startup-investing/" rel="noopener noreferrer"&gt;seed stage startup&lt;/a&gt;, with large scale system, its not an easy task. So we are always trying to find new ways and approaches for reaching this goal.&lt;/p&gt;

&lt;p&gt;Few months back, I participated a &lt;strong&gt;very&lt;/strong&gt; interesting lecture delivered by &lt;a href="https://medium.com/u/c5c145af7ccf" rel="noopener noreferrer"&gt;Igal Steklov&lt;/a&gt; about FTDD.&lt;br&gt;&lt;br&gt;
That was my very first experience with this pattern, and I swore to myself that I’ll implement this in my company.&lt;/p&gt;

&lt;p&gt;It occurred to me that this design may benefit all our departments for a more optimized deployment. From the Development by deploying with less fear of major bugs, to the Product and the QA, by checking their new features in the production environment, prior to exposing them to the customers, and of-course, the managers technological mind set.&lt;/p&gt;

&lt;p&gt;When I started to dive deep in the community for implementation approaches, I found myself with too many question marks. I found a lot of built in packages, small or big, free or not, but with a learning curve and code adjustments.&lt;br&gt;&lt;br&gt;
In addition, I found many tutorials and documentation about the design algorithm, but without enough code and architecture references, especially not in my stack.&lt;br&gt;&lt;br&gt;
And in the end, I realized that it would be much faster to build it by myself, without third party packages.&lt;/p&gt;

&lt;p&gt;That’s why I decided to build it on my own, and share with all of you what I came up with.&lt;br&gt;&lt;br&gt;
My simple ask for you guys, is to have your feedback on my architecture design and code, please feel more than welcome to share with me your inputs, as we will ever be in a learning curve :)&lt;/p&gt;

&lt;p&gt;In this article I will show my solution for implementing it in my React app.&lt;br&gt;&lt;br&gt;
In addition, I will show the implementation in the server side (Node), and the DB structure.&lt;/p&gt;
&lt;h3&gt;
  
  
  CODE !!
&lt;/h3&gt;

&lt;p&gt;The code order will be according to the development order, but you may jump wherever you want:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;DB&lt;/li&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  DB Structure
&lt;/h4&gt;

&lt;p&gt;So the first thing I've done is creating my tables in the DB. i’m working with MySQL DB, and I created 3 relevant tables for this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;feature.sql&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7fcafuzd1a6qzsxar8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7fcafuzd1a6qzsxar8q.png" width="626" height="170"&gt;&lt;/a&gt;&lt;strong&gt;feature.sql&lt;/strong&gt;. every new feature gets his name, ON/OFF toggle property, description and &lt;code&gt;componentId&lt;/code&gt; for future use.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;role.sql&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3i09uqyocqm0mfk9260.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3i09uqyocqm0mfk9260.png" width="383" height="231"&gt;&lt;/a&gt;&lt;strong&gt;role.sql&lt;/strong&gt;. list of roles to give for a user or for a group of users&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;role_feature.sql&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuulqegnbjkse7qg7vmkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuulqegnbjkse7qg7vmkz.png" width="442" height="131"&gt;&lt;/a&gt;&lt;strong&gt;role_feature.sql&lt;/strong&gt;. assign features to roles and set the’re toggle (ON/OFF)&lt;/p&gt;

&lt;p&gt;With this 3 tables I can specify features for different users.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Example: lets say user ‘x’ is an &lt;code&gt;enterprise&lt;/code&gt; (role id: 7) user.&lt;br&gt;&lt;br&gt;
We can see in &lt;code&gt;role_feature&lt;/code&gt; table that this role has 2 features assigned to him, with specific properties- &lt;code&gt;feature1&lt;/code&gt; (feature id: 1), and &lt;code&gt;feature2&lt;/code&gt; (feature id: 2). Each feature has different toggle property (&lt;code&gt;on&lt;/code&gt; field). One is &lt;code&gt;on&lt;/code&gt; and the other is &lt;code&gt;off&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
So, eventually, user ‘x’ should see the &lt;em&gt;&lt;code&gt;feature1&lt;/code&gt;&lt;/em&gt; feature but shouldn’t see &lt;em&gt;&lt;code&gt;feature2&lt;/code&gt; feature.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Node
&lt;/h4&gt;

&lt;p&gt;The server side is responsible of 2 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Arranging the list of features with there toggle properties, for the user.&lt;/li&gt;
&lt;li&gt;Block &lt;code&gt;off&lt;/code&gt; features controllers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lets see how I managed to arrange those features:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The above code shows the arrangement of features for the user.&lt;br&gt;&lt;br&gt;
The method returns an array of features, some of the are &lt;code&gt;on&lt;/code&gt;, some of them &lt;code&gt;off&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
This list will be sent to the client side, and will be used here, for the controller blocking.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;These logic above shows the blockage of the controllers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;policies.js&lt;/code&gt; is responsible for every logic you want to add prior to the controller. For example, checking user authentication.&lt;br&gt;&lt;br&gt;
I added there a feature validation, &lt;code&gt;isFeatureOpenPolicy&lt;/code&gt;, which checks if the feature that relates to the controller is &lt;code&gt;on&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
If it is &lt;code&gt;on&lt;/code&gt;, continue regularly (&lt;code&gt;next()&lt;/code&gt;).&lt;br&gt;&lt;br&gt;
If it is &lt;code&gt;off&lt;/code&gt;, return forbidden response.&lt;/p&gt;
&lt;h4&gt;
  
  
  React (+ Redux)
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;You may play with the features and see the code of the client side, in this&lt;/em&gt; &lt;a href="https://codesandbox.io/s/ftdd-react-g7jyf" rel="noopener noreferrer"&gt;&lt;em&gt;codesandbox&lt;/em&gt;&lt;/a&gt;&lt;em&gt;:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/ftdd-react-g7jyf"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In the client side of the application I used a very simple methodology by using &lt;a href="https://reactjs.org/docs/higher-order-components.html" rel="noopener noreferrer"&gt;HOC (Higher Order Component)&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
This methodology allowed me to toggle features very easily by adding HOC to component.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To make it work we create a component for every feature.&lt;br&gt;&lt;br&gt;
Its not must, and I will show how I toggled features that are not a component and/or in other component or service&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, we need to store the list of &lt;code&gt;features&lt;/code&gt; that we got from the server.&lt;br&gt;&lt;br&gt;
I work with &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux state management&lt;/a&gt;, so the right place for me to store was the &lt;code&gt;user&lt;/code&gt; &lt;code&gt;reducer&lt;/code&gt; (that’s where I store all the initial user state)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OK,&lt;/em&gt; &lt;em&gt;lets see the HOC:&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This HOC is very simple:&lt;br&gt;&lt;br&gt;
It gets 2 arguments: &lt;code&gt;WrappedComponent&lt;/code&gt;, which is the component that wrapped with the HOC, and &lt;code&gt;featureComponentId&lt;/code&gt;, which is the feature id of the component.&lt;br&gt;&lt;br&gt;
It checks if this feature is &lt;code&gt;on&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
If it is &lt;code&gt;on&lt;/code&gt;, it returns the &lt;code&gt;WrappedComponent&lt;/code&gt;, like nothing happened.&lt;br&gt;&lt;br&gt;
If it is &lt;code&gt;off&lt;/code&gt;, it returns nothing (&lt;code&gt;&amp;lt;div/&amp;gt;&lt;/code&gt;), so the user wont see that component.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The HOC is connected to the &lt;code&gt;user&lt;/code&gt; &lt;code&gt;reducer&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;&lt;code&gt;isFeatureOn:&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Very similar to the server side, &lt;code&gt;isFeatureOn&lt;/code&gt; method is checking whether the feature we’re looking for is &lt;code&gt;on&lt;/code&gt; / &lt;code&gt;off&lt;/code&gt; / doesn’t exist.&lt;br&gt;&lt;br&gt;
What interesting here is the imported &lt;code&gt;redux&lt;/code&gt; &lt;code&gt;store&lt;/code&gt;. By that, we don’t need to pass &lt;code&gt;features&lt;/code&gt; to the method, only the relevant &lt;code&gt;featureId&lt;/code&gt;, which is much easier.&lt;br&gt;&lt;br&gt;
We can default &lt;code&gt;features&lt;/code&gt; argument with the user &lt;code&gt;features&lt;/code&gt; from the &lt;code&gt;user&lt;/code&gt; &lt;code&gt;reducer&lt;/code&gt;, just like that: &lt;code&gt;store.getState().user.features&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now we can finally see a feature component:&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The interesting stuff here is where we &lt;code&gt;export&lt;/code&gt; the component.&lt;br&gt;&lt;br&gt;
That’s where we wrap our component with the HOC, and use FTDD!&lt;/p&gt;

&lt;p&gt;Now for those of you who remember that I promised to show a non feature component case. &lt;em&gt;here it is:&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Very simple, just use the &lt;code&gt;isFeatureOn&lt;/code&gt; method wherever you want.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The next and following article will be on how I created the admin panel for the toggles management&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That was my way of using FTDD in my full stack app. I hope some off you out there would find it useful somehow.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
