<?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>Forem: Yuliya Haranok</title>
    <description>The latest articles on Forem by Yuliya Haranok (@yuliagaranok).</description>
    <link>https://forem.com/yuliagaranok</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%2F451509%2F4fc1fd00-7784-49d8-9c7f-f7cfa5c49205.png</url>
      <title>Forem: Yuliya Haranok</title>
      <link>https://forem.com/yuliagaranok</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/yuliagaranok"/>
    <language>en</language>
    <item>
      <title>Handled 300k users for a $30 million deal in 48 Hours and other contributions - Fintech Case Study</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Mon, 11 Dec 2023 09:18:19 +0000</pubDate>
      <link>https://forem.com/datarockets/handled-300k-users-for-a-30-million-deal-in-48-hours-and-other-contributions-fintech-case-study-494d</link>
      <guid>https://forem.com/datarockets/handled-300k-users-for-a-30-million-deal-in-48-hours-and-other-contributions-fintech-case-study-494d</guid>
      <description>&lt;p&gt;This article is a collaborative look back at the key contributions we’ve delivered to our clients’ &lt;a href="https://datarockets.com/case-studies/legal-fintech-software/" rel="noopener noreferrer"&gt;Legal Fintech project&lt;/a&gt; over the past three years&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dealmaker.tech/" rel="noopener noreferrer"&gt;DealMaker&lt;/a&gt; has been on an aggressive growth trajectory.&lt;/p&gt;

&lt;p&gt;Recently ranked as one of the &lt;a href="https://www.theglobeandmail.com/business/rob-magazine/top-growing-companies/article-canadas-top-growing-companies-2023/" rel="noopener noreferrer"&gt;fastest-growing companies in Canada&lt;/a&gt; by three-year revenue growth, DealMaker is disrupting the way capital is raised, making the once complex activity of selling shares as easy as selling shoes. They’re a cloud-based platform built to help Founders digitall raise capital and turn their customers into shareholders. In just the first three years, they’ve powered over 400 companies with their digital capital raises, from seed to IPO, already surpassing over $1 billion in capital raised.&lt;/p&gt;

&lt;p&gt;Back in 2020, the CTO of DealMaker reached out to datarockets to assist their team in developing their Ruby on Rails application. The datarockets team would help own, lead and tackle the following challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resolving slow pages loading + significantly improve app performance.&lt;/li&gt;
&lt;li&gt;Setting up development practices and code quality standards fit for a fast-growing startup environment.&lt;/li&gt;
&lt;li&gt;Developing new integrations + implementing a host of new features.&lt;/li&gt;
&lt;li&gt;Tackling technical debt, making infrastructure changes &amp;amp; necessary upgrades.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the fun and unique challenges to this project was the nature of the industry itself, which included a diverse range of entities such as investors, brokers, brokerages/brokerage syndicates, enterprises/companies (issuers), shareholders, lawyers, co-signers, various document types, etc. Navigating this, our team was challenged with delivering large pieces of new functionality, and in tandem, help monitor and manage their drastic product growth.&lt;/p&gt;

&lt;p&gt;One of the capital-raising transactions that we witnessed, saw over $30 million raised in under 48 hours – demonstrating the type of landmark transactions that DealMaker helps facilitate. That was a fun one as our developers got to monitor in real time and help ensure seamless experiences given abnormally high load activity.&lt;/p&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%2Fz40twknlp432lujtbzdr.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%2Fz40twknlp432lujtbzdr.png" alt="laptop screen" width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Approach &amp;amp; Highlights&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DealMaker has an in-house development team, which is split into pods – smaller sub-divisions that work on the specific area of the application. Developers from datarockets would assist with various pods, affecting different parts of the application. To keep communication tight, the teams used Slack and Google Meet to interact and Jira as a Product Management tool.&lt;/p&gt;

&lt;p&gt;Datarockets improved the performance of the app and completed various infrastructure changes. We helped migrate the frontend from jQuery to Svelte. Brought some better design decisions and restructured long-loading pages into a more efficient layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Red October deal: The Race to onboard a high-profile client&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In 2021, Dealmaker secured a large-scale client who would be joining the platform within 2-3 months time (October). Given the October deadline and the fact that this news was shrouded in high confidentiality, this project was given the codename “Red October”.&lt;/p&gt;

&lt;p&gt;It was estimated that this client, and their capital raise, would draw in ~300,000 investors. We knew that given the current form of the application, it simply wouldn’t be able to handle such an influx. Strategy never moves in a linear path, and so with this new objective, datarockets shifted our focus to support the Dealmaker team in ensuring that they’d be well-prepared for this deal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;developed new functionality &amp;amp; teamed up on critical optimizations needed to scale the platform&lt;/li&gt;
&lt;li&gt;closely identified, analyzed and improved areas that were slow and inefficient &lt;/li&gt;
&lt;li&gt;created scripts for load testing, which would emulate the activity of thousands of users, and resolve performance bottlenecks identified in that process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Red October” is an example of the scaling challenges always accompanying rapid growth. During this period, our teams carried out tight-knit collaboration and kept the performance &amp;amp; output high. &lt;/p&gt;

&lt;p&gt;The capital raise was another landmark transaction and as expected (after a lot of hard work) the platform handled the high-loads elegantly, ultimately helping make this the sixth historic offering in the organization’s history. You can read more about it &lt;a href="https://www.dealmaker.tech/content/dealmakers-technology-powers-over-1-billion-in-online-capital-raises" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&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%2Fiyvc8hg6jpenb446a359.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%2Fiyvc8hg6jpenb446a359.png" alt="DealMaker investor flow embedded to the business website" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delivered DealMaker API and embeddable flow&lt;/strong&gt;&lt;br&gt;
Our team helped DealMaker to implement functionality that allows their clients (deals and enterprises) to integrate with them: Dealmaker API and the embeddable flow. &lt;/p&gt;

&lt;p&gt;This flow allows Dealmaker to embed their investor flow directly onto the client’s (issuer’s) site in an iframe, helping increase trust and creating ease in accepting investors right on the business’ website. &lt;/p&gt;

&lt;p&gt;The API itself is much more flexible. It maintains public documentation powered by ReDoc, and has the functionality to subscribe for webhooks. Our dev team used Ruby Grape, OAuth2, and DoorKeeper for Dealmaker’s API. &lt;/p&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%2F49ztq1ic916nuefbtw9n.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%2F49ztq1ic916nuefbtw9n.png" alt="Project updates from Slack" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since DealMaker is a capital-raising platform, our team had to work on integrations with various payment services. These included integrations with services such as WorldPay, Aeropay, FundAmerica, and Stripe. Currently, most payments go through Stripe, including ACH and ACSS payments with microdeposits, card, and mobile wallet payment methods, which allows investors to pay in seconds using Google Pay and Apple Pay.&lt;/p&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%2Fe4z63fjyh56p8nucfqkm.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%2Fe4z63fjyh56p8nucfqkm.png" alt="Clutch review" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Introducing Efficiency and Safety of Payments through VCR tests&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As stated earlier, the Payments part of the app included a lot of integrations. These integrations are usually either SDKs (Stripe) or simple APIs (Aeropay). One problem encountered was that these SDKs and APIs were constantly being updated, which led to breaking changes from time to time. Payments and money transfers are the most important parts of a Fintech application, therefore, it was important that we automate the testing of payment integrations.&lt;/p&gt;

&lt;p&gt;Regular unit tests just aren’t as helpful in these situations. E2E (End-to-End) tests written by the QA team could help catch something just before a release, but identifying a problem at this stage of the game would be too late. DealMaker had suggested using &lt;a href="https://github.com/vcr/vcr" rel="noopener noreferrer"&gt;VCR tests&lt;/a&gt;. The essence of VCR is that it allows tests to make real requests using the SDK or API and record real responses. We did the SPIKE and POС, and after discussions, it was decided that we would integrate it. &lt;/p&gt;

&lt;p&gt;It didn’t take long to see the benefits. At that time, we had a 5-point ticket to update Stripe to the latest version and check everything manually. Normally, a task like that could take up to a week or longer, but after we integrated VCR and wrote VCR tests for all flows, the Stripe version was updated in half a day (!), and all the tests were checked by the CI. In other words, what was once a 5-point task could now be completed in a half-day task. &lt;/p&gt;

&lt;p&gt;Efficiency gains like this are important as they compound over time, creating the space for companies to supercharge into rapid growth.&lt;/p&gt;

&lt;p&gt;Now we’re able to update all third-party SDKs and APIs with every new version because their functionality testing is automated. It took some time to set everything up and update existing tests, but now it is as simple to write a VCR as to write a regular test, and the benefits of VCR tests are significantly greater.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delivered numerous fixes and new features
&lt;/h2&gt;

&lt;p&gt;Throughout our time, we helped the DealMaker’s team deliver loads of new functionality. An example of such features include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;White-labeling&lt;/strong&gt;&lt;br&gt;
White-labeling allows clients to represent their own brands on DealMaker. Deal pages are served under a specified subdomain, brand colors, logos etc are put into various aspects of their deals, on emails, and specific pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-onboarding&lt;/strong&gt;&lt;br&gt;
Self-onboarding automated the process of deal generation, making managers’ lives easier. We implemented this completely new feature to experiment with one type of user and collect feedback, it was positive and the self-onboarding was applied to the rest of the clients.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refunds&lt;/strong&gt;&lt;br&gt;
Refunds have proven to be highly beneficial as they have significantly expedited the time of processing a single refund from approximately 5 minutes to a mere couple of seconds. This improvement has greatly alleviated the workload for DealMaker managers, who often needed to process hundreds of refunds manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Investor and issuer insights dashboard&lt;/strong&gt;&lt;br&gt;
The feature provides investors and issuers with their funds’ data in accessible graphs. Quick calculations of graphs and numbers are achieved with Snowflake Data Warehouse and ELT integration.&lt;/p&gt;

&lt;p&gt;Our longstanding collaboration with DealMaker has been carried out with well-established processes, which allowed both sides to work conveniently in a consistent rhythm. Throughout this time, we have been receiving positive feedback from DealMaker highlighting our high technical level.&lt;/p&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%2Frnyx843am78ukdp1fr7h.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%2Frnyx843am78ukdp1fr7h.png" alt="Sharing feedback from a client" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Datarockets had the pleasure of partnering with DealMaker for over 3 years. At different stages of cooperation, the datarockets’ dev team consisted of three to five Ruby on Rails developers of different seniority levels.&lt;/p&gt;

&lt;p&gt;Our team played a significant role in optimizing the application, improving the infrastructure, integrating new payment methods, and participated in designing and implementing new functionality such as white-labeling, self-onboarding, refunds, investor/issuer insights, etc. Our team had a hand in bringing VCR tests to the project and building DealMaker API.&lt;/p&gt;

&lt;p&gt;Along with this, datarockets helped improve development processes, added tests and linter coverage, and shared our expertise with new developers through code review and pair-programming practices. &lt;/p&gt;

&lt;p&gt;Datarockets helped the client keep technical standards high during the intensive team growth, and we’re proud to have helped play a part in the journey of DealMaker as they continue to experience success, recently ranked as &lt;a href="https://www.dealmaker.tech/content/dealmaker-announced-as-the-3rd-fastest-growing-company-in-canada" rel="noopener noreferrer"&gt;the 3rd fastest-growing company in Canada&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;One of the most detailed reviews about our work on DealMaker can be found on &lt;a href="https://clutch.co/profile/datarockets#review-2221017" rel="noopener noreferrer"&gt;Clutch&lt;/a&gt;.&lt;/p&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%2Fqa5r3igy6sfm98kokjt4.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%2Fqa5r3igy6sfm98kokjt4.png" alt="Clutch review" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>startup</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Feedback and Tips for Junior developers</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Thu, 08 Jul 2021 16:02:23 +0000</pubDate>
      <link>https://forem.com/datarockets/feedback-and-tips-for-junior-developers-1hog</link>
      <guid>https://forem.com/datarockets/feedback-and-tips-for-junior-developers-1hog</guid>
      <description>&lt;p&gt;Quality feedback is an essential part of professional growth and we love sharing it not only within our team but also with candidates who get interviewed. In this article, we collected some &lt;a href="https://datarockets.com/blog/code/tips-junior-developers/" rel="noopener noreferrer"&gt;tips from the real feedback&lt;/a&gt; given by our CTO Dima and Lead developer Andrew to junior developers. But we also believe that these thoughts can be a good checklist for more experienced developers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Learn the tools – git, command line, docker, and interpret errors correctly
&lt;/h1&gt;

&lt;p&gt;Before asking for help, you should read the error messages carefully and understand them. However, there’s nothing bad about accepting the fact that you don’t understand something. &lt;/p&gt;

&lt;p&gt;If you don’t understand the error message, you can tell honestly about this. It is a bad habit to send a screenshot with the text “I have an error here.” Instead, you can send an error message and write: “I’m rebasing and have resolved the conflicts but the git says that something needs to be committed while there’s nothing to commit. It says that I can skip the commit, but I don’t understand what it means to skip the commit.”&lt;/p&gt;

&lt;p&gt;As the very first step, we advise you to study git so deeply that you understand every word in every command you write. We suggest you read the &lt;a href="https://git-scm.com/book/en/v2" rel="noopener noreferrer"&gt;ProGit book&lt;/a&gt; or watch our CTO's &lt;a href="https://www.youtube.com/watch?v=Se-4Mf2m5uE" rel="noopener noreferrer"&gt;talk about git&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It will be very helpful to learn the command line and CLI tools. What happens when you write a command in Linux terminal? How does Linux know what binary file to execute? How is it different if you run the same command on Windows? You can watch a video about shell on datarockets YouTube.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ask for help properly and describe the problem in words
&lt;/h1&gt;

&lt;p&gt;Junior developers often share many lines of code to chat or, much worse, a screenshot, with the comment “it doesn’t work, can we have a call”. However, they don’t say what exactly isn’t working. In such situations, it is impossible to help without a call and a pair debugging session. &lt;/p&gt;

&lt;p&gt;Instead of asking for a call, it would be much more useful if you describe the problem in words, without pictures or screenshots. A good example, “after line 7 I was expecting to see , but  occurred instead”, from the guide &lt;a href="http://catb.org/~esr/faqs/smart-questions.html" rel="noopener noreferrer"&gt;“How to ask questions the smart way”&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;When you describe the problem in words, sometimes it happens that a good assumption about the problem’s cause pops up in your head and you may realize how to fix the problem yourself.&lt;/p&gt;

&lt;h1&gt;
  
  
  Learn how to deal with errors and problems
&lt;/h1&gt;

&lt;p&gt;If you don’t understand how something works, read the error message, see exactly where it occurred, try to isolate it so you know exactly which piece of code is causing the error. Make a guess as to why the error might have occurred and try to fix it. &lt;/p&gt;

&lt;p&gt;Your first inclination could be to fix the error as quickly as possible in any way you can, without getting to the root of the problem. Even though it might work sometimes it’s hard to learn from this experience and we may leave some hidden bugs unfixed.&lt;/p&gt;

&lt;p&gt;Ideally, for every single word in the code you write, you should be able to answer why you wrote it. For example, in the code below, what for the CSS class “layout” is here? Where is the code for this CSS class written?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Layout className={`layout ${css.layout}}&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a great &lt;a href="https://www.amazon.com/Debugging-Indispensable-Software-Hardware-Problems/dp/0814474578/" rel="noopener noreferrer"&gt;book about debugging&lt;/a&gt;, which we highly recommend. One of our favorite tech writers, Julia Evans might publish a zine about debugging soon: &lt;a href="https://jvns.ca/blog/2021/06/08/reasons-why-bugs-might-feel-impossible/" rel="noopener noreferrer"&gt;Reasons why bugs might feel “impossible”&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Get more practice in the review of other developers’ code
&lt;/h1&gt;

&lt;p&gt;Code review will help you to learn faster, think critically and adopt coding standards. It is a necessary element of developing your solution-design taste, it brings room for knowledge sharing as well.&lt;/p&gt;

&lt;p&gt;Read about &lt;a href="https://blog.palantir.com/code-review-best-practices-19e02780015f" rel="noopener noreferrer"&gt;Code Review Best Practices&lt;/a&gt; and start following them. The &lt;a href="https://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073" rel="noopener noreferrer"&gt;Clean Coder book&lt;/a&gt; will tell you everything about writing maintainable code. The ideas from it will help you in code review as well. &lt;/p&gt;

&lt;h1&gt;
  
  
  Take more ownership of the feature delivery process
&lt;/h1&gt;

&lt;p&gt;There’s a more advanced level, but if you pump it up, it will make you a self-sufficient engineer who doesn’t need any guidance to complete features.&lt;/p&gt;

&lt;p&gt;It includes discussing a feature with a client, breaking it down into tasks, self-assigning to the tasks, suggesting what you could do instead of asking others what to do next, and delivering with final deploy – the full thing. &lt;/p&gt;

&lt;h1&gt;
  
  
  Take on tasks of higher complexity
&lt;/h1&gt;

&lt;p&gt;Improve your architectural skills by facing technical challenges of higher complexity and learn more about design patterns. There’s no growth without a challenge, so don’t be afraid to take a more complex task even if it requires some support to complete. &lt;/p&gt;

&lt;h1&gt;
  
  
  Be curious and ask questions
&lt;/h1&gt;

&lt;p&gt;One of the important skills for developers and engineers is curiosity. Curiosity drives us to learn new things and improve our skills.&lt;/p&gt;

&lt;p&gt;Be curious about colleagues’ work. Do you know how they debug programs? Do they use UI debugger or debug output? What do they look first at during the code review? What do they dislike about the language you use and why?&lt;/p&gt;

&lt;p&gt;Be curious about the tech you hear or read about. Did someone mention Kotlin Multiplatform Mobile? Try to learn how it works and what it offers. Apple released the M1 chip that you heard uses ARM architecture but you don’t know what ARM means and what other architectures exist? Ask your colleagues about this and engage them in communication. Saw that the output of git log looks different on your colleague’s computer? Ask them to share how they configured this.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>learning</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>The datarockers’ codex – company core values</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Wed, 19 May 2021 15:03:20 +0000</pubDate>
      <link>https://forem.com/datarockets/the-datarockers-codex-company-core-values-3fa0</link>
      <guid>https://forem.com/datarockets/the-datarockers-codex-company-core-values-3fa0</guid>
      <description>&lt;p&gt;In 2014, our founders wrote a codex for everyone who wanted to join the datarockets’ team, so that the candidates could check if they shared the same &lt;a href="https://datarockets.com/blog/company/datarockets-codex-core-values/" rel="noopener noreferrer"&gt;core values&lt;/a&gt; as ours. Since then, we have transformed our processes a lot, but this document still stays relevant as it presents our company principles and culture.&lt;/p&gt;

&lt;p&gt;The original version was written in Russian and now we decided to make it accessible for everyone by translating it into English. If you know Russian, we highly recommend you to read the &lt;a href="https://docs.google.com/document/d/1DojRoGnl-J0Ku0B9tjK_-HUMbKQDPoueoYr645dYA-4/edit" rel="noopener noreferrer"&gt;original text&lt;/a&gt; from 2014 :).&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro from the founders
&lt;/h2&gt;

&lt;p&gt;The goal of datarockets is to bring ideas into life, delve into client’s businesses and contribute to their development. Our personal goal is to gather a cohesive team that will turn the company into an intellectual hub, which will result in both money and pleasure. Besides, we love sharing our knowledge with other people and bringing value to the whole industry. &lt;/p&gt;

&lt;p&gt;We have an individual attitude and an approach to everyone: we put a piece of our heart, invest our time and money and make sure that each datarocker comes to our company for a good reason. &lt;/p&gt;

&lt;p&gt;We value honesty, self-development, and professionalism. We believe that it will help us to attract like-minded people. Thus, when hiring a new datarocker, we first look at their attitude rather than knowledge. Having said that, there are no random people at datarockets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creation
&lt;/h2&gt;

&lt;p&gt;Datarockers tend to find a healthy and productive way to express themselves. As a company, we create a safe space for it.&lt;/p&gt;

&lt;p&gt;Self-expression is an essential part of everyone’s life. When people don’t express themselves, they repress the important parts of who they are and cause themselves considerable struggle and lasting mental and emotional pain (&lt;a href="https://rrtampa.com/therapy/need-self-expression" rel="noopener noreferrer"&gt;source&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Therefore, every datarocker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chooses the path of creation,&lt;/li&gt;
&lt;li&gt;cares about personal mental state,&lt;/li&gt;
&lt;li&gt;is driven by curiosity,&lt;/li&gt;
&lt;li&gt;has the desire to invent things,&lt;/li&gt;
&lt;li&gt;gets the pleasure from finding elegant and brilliant solutions to complex problems,&lt;/li&gt;
&lt;li&gt;and loves adding values to anything he or she does.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Responsibility
&lt;/h2&gt;

&lt;p&gt;Datarockers are responsible for everything that happens in both personal life and at work. They do not try to limit their responsibility and do not seek excuses. &lt;/p&gt;

&lt;p&gt;Datarockers always pick up the phone and do not hide from problems and stressful meetings. They don’t disappear at the most critical moment — even if they make mistakes, they tell the truth and offer solutions to resolve the problem.&lt;/p&gt;

&lt;p&gt;Usually, people are forced to work at the office and monitored by managers behind their backs. However, at datarockets, the traditional micromanagement does not exist. In our company, we have processes that help set up the routine, but flexible schedule and remote work are not for everyone. Datarockers decide on their own how much and how to work, where to live, and when to rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Money
&lt;/h2&gt;

&lt;p&gt;Datarockers don’t always work for money, even though they understand that the quality of their lives depends on money. They consider their time as capital and invest it wisely.&lt;/p&gt;

&lt;p&gt;Additionally, datarockers never talk about personal salary and the company’s remuneration. Any relationship of datarockets with clients is confidential information, and remuneration is not a subject of public negotiations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Personal development
&lt;/h2&gt;

&lt;p&gt;Datarockers are ambitious life-long learners. They read books, listen to podcasts, and keep up with what’s new in the IT world. You can meet a datarocker at the conference, and later — with a glass of beer at the after-party. Our teammates share their experience in &lt;a href="https://datarockets.com/blog" rel="noopener noreferrer"&gt;articles&lt;/a&gt;, contribute to &lt;a href="https://github.com/datarockets/" rel="noopener noreferrer"&gt;open source&lt;/a&gt;, organize and speak at &lt;a href="https://youtube.com/playlist?list=PLXylrdLh4cnA6mY_YgFOT1DKmH1xqINbm" rel="noopener noreferrer"&gt;conferences &amp;amp; meetups&lt;/a&gt; for engineers.&lt;/p&gt;

&lt;p&gt;Datarockers do not stick to one framework or library; they are willing to adopt other technologies. Frontend developers at datarockets understand how the backend works and can make some changes themselves. Backend developers can lay out or move a block on a page without having to ask the frontend team. Datarockers understand the fundamental programming concepts, which helps them quickly master any new technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Professionalism
&lt;/h2&gt;

&lt;p&gt;Every single datarocker is a conscientious person. They do their job as best as possible, never sacrifice quality nor hesitate to speak out their own opinions. Achieving the result is professional responsibility, and datarockers know the right path to it.&lt;/p&gt;

&lt;p&gt;The quality of work does not depend on a personal relationship or feelings towards a client or a project. A datarocker understands that the best product is a workable product that is launched on time. Striving for perfectionism doesn’t justify missing deadlines.&lt;/p&gt;

&lt;p&gt;Datarockers are team players who understand that by working together, they can maximize their productivity and efficiency. They respect the opinions of their colleagues and help datarockets’ newbies to understand the industry.&lt;/p&gt;

&lt;p&gt;Datarockers always move up their career ladder. As soon as datarockers start feeling self-sufficient and can teach others, they delegate tasks and take over new responsibilities to benefit the team and clients.&lt;/p&gt;

&lt;p&gt;There are no boring tasks for datarockers. We develop products for various businesses, from finance and logistics to nightclubs and bars. Even when solving trivial tasks, we automate the routine, try new approaches and create useful tools. We never know in advance what knowledge will be helpful in the future. In our business, knowledge about the whole world is always important.&lt;/p&gt;

&lt;p&gt;Datarockers constantly look for different ways of improving themselves and optimizing time to complete their tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relationships with clients
&lt;/h2&gt;

&lt;p&gt;Datarockers always remember that they are providing a service. When making decisions, the client’s benefits and their product are always our top priority. In the eyes of our clients, datarockets is not a faceless team of developers hidden behind the manager. When a client chooses our services, they expect to work with us as a single team. &lt;/p&gt;

&lt;p&gt;Human relationships are built on expectations, therefore, we understand that high expectations can turn into disappointments. It is better to underpromise and overdeliver rather than overpromise but then fail to deliver the tasks on time.&lt;/p&gt;

&lt;p&gt;The datarockets team always ensures confidentiality and respects the client’s privacy and their business decisions. We delve into the client’s business, put ourselves in the client’s shoes, and suggest the best possible solutions in any given situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reputation and attitude towards datarockets
&lt;/h2&gt;

&lt;p&gt;Datarockers are tactful and self-aware of their reputation. Not only do they always speak about their colleagues and clients with honor, they never criticize or disrespect the previous companies they have worked at either, despite any grievances.&lt;/p&gt;

&lt;p&gt;A professional who has become an entrepreneur does not entice customers and employees if the other side has not taken the initiative. Instead, an ex-datarocker would rather train new employees and find clients — it is a matter of reputation and honor.&lt;/p&gt;

&lt;p&gt;At datarockets, we always recognize and value people, as well as their achievements. We motivate them to speak at conferences and write articles to share their experience with other fellows from the tech community. Experienced datarockers train the team, gain authority and recognition among colleagues.&lt;/p&gt;




&lt;p&gt;If these thoughts are appealing to you and you want to learn more about datarockets’ culture, check out our &lt;a href="https://www.instagram.com/datarockets/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; page. It’s about fun, pets, remote work within a multinational team, and programming, of course 😉&lt;/p&gt;

</description>
      <category>culture</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How we created a human analytics platform for teams instead of using Google Sheets</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Thu, 04 Feb 2021 16:14:01 +0000</pubDate>
      <link>https://forem.com/datarockets/how-we-created-a-human-analytics-platform-for-teams-instead-of-using-google-sheets-20kn</link>
      <guid>https://forem.com/datarockets/how-we-created-a-human-analytics-platform-for-teams-instead-of-using-google-sheets-20kn</guid>
      <description>&lt;p&gt;Vital is a human analytics platform, currently in the &lt;a href="https://datarockets.com/blog/business/mvp-app-development-lean-startup-way/" rel="noopener noreferrer"&gt;MVP stage&lt;/a&gt;. With Vital, you can track your personal data such as book readings, time spending, daily vices, and rituals. The platform makes data tracking social with teams engaging and commenting. It also provides a simple visualization of your data and data analytics that helps people to understand their feelings and behaviors better.&lt;br&gt;
The datarockets team built this platform from scratch and participated in the product strategy, which resulted in several features that have been implemented &amp;amp; adopted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenge
&lt;/h2&gt;

&lt;p&gt;The ultimate goal of VITAL is to improve individual productivity and increase self-awareness when working with teams. Our client, the &lt;a href="https://pixeldreams.com/" rel="noopener noreferrer"&gt;Pixel Dreams&lt;/a&gt; team, started with simple journaling using Google Spreadsheets in order to validate their concept. They started logging their productivity on a daily basis as well as the factors that influenced this intending to try to find correlations between their personal data and the entries of their teammates. Here is how the proof of concept looked in Google Spreadsheets:&lt;/p&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%2Fkzq7fdj6xwzcr3nu16z3.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%2Fkzq7fdj6xwzcr3nu16z3.png" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The guys have already proved to themselves that their data was valuable but they were struggling a lot with the spreadsheets. It took hours of work to set up spreadsheets for new members as well as initiate data entry for new time periods. Moreover, the spreadsheet solution wasn’t scalable at all and it wasn’t possible to share VITAL’s ideas with new people while the application was based on spreadsheets. So, we had to solve the following 2 challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Making the data entry process more convenient&lt;/li&gt;
&lt;li&gt;Providing value from data entry to teams - giving some motivation to fill in data every day&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Our Approach
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First version release
&lt;/h3&gt;

&lt;p&gt;We couldn’t utilize spreadsheets anymore and decided to implement a &lt;a href="https://datarockets.com/capabilities/" rel="noopener noreferrer"&gt;custom web application&lt;/a&gt; that would fulfill the data tracking needs. First of all, we focused on the data entry UI.  Being a creative agency, Pixel Dreams provided us with the first version of the design, which looked like the following screenshot:&lt;/p&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%2F7awnvoyobcxodwcw1npw.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%2F7awnvoyobcxodwcw1npw.png" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application required instant data updates w/o page reload so we decided to use a reactive framework on the frontend, and at that time, React.js was growing popular. We picked &lt;a href="https://datarockets.com/blog/code/react-quick-start/" rel="noopener noreferrer"&gt;React.js&lt;/a&gt; + &lt;a href="https://datarockets.com/blog/code/structure-redux-applications/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt; for the frontend and &lt;a href="https://datarockets.com/blog/business/why-ruby-on-rails/" rel="noopener noreferrer"&gt;Ruby on Rails&lt;/a&gt; for the backend. For the design, we utilized bootstrap to release the first version of the product fast.&lt;/p&gt;

&lt;p&gt;In order to motivate people to track their data, we decided to introduce a concept of teams and data sharing. As a result of the first iteration, the users were able to transition from their spreadsheets to the app and the following features were implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Journaling (Daily entry: Win, Loss or Draw + text log)&lt;/li&gt;
&lt;li&gt;Teams and dashboard for teams configurable by team admins&lt;/li&gt;
&lt;li&gt;Team members’ management, invites via email&lt;/li&gt;
&lt;li&gt;Shared and private logs&lt;/li&gt;
&lt;li&gt;Additional data types as checklists and counters&lt;/li&gt;
&lt;li&gt;Ability to comment on data entries of your teams&lt;/li&gt;
&lt;li&gt;Graphs that visualize Win Lose or Draw metrics within teams&lt;/li&gt;
&lt;/ul&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%2Fwmk7uziuccpgj7ophyyr.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%2Fwmk7uziuccpgj7ophyyr.png" width="800" height="466"&gt;&lt;/a&gt;&lt;br&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%2F3820qfea7norknay4v4w.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%2F3820qfea7norknay4v4w.png" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And Kal (the founder of Pixel Dreams) &lt;a href="https://youtu.be/qTwE3DfFkk8" rel="noopener noreferrer"&gt;invited first platform users for beta testing&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mobile app implementation and improving UI
&lt;/h3&gt;

&lt;p&gt;After some time of using the app, we gathered feedback from the early adopters and learned that now when they have an app for data tracking, they preferred to use mobile devices to fill it in. Also, we noticed that the early adopters of the platform were using the commenting feature a lot to support each other and ask questions.&lt;br&gt;
Therefore, we decided to run another iteration and create a mobile version of the web application plus add extra social features such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A social feed where users can see the logs of their teammates and comment on them w/o switching to the databoard screen&lt;/li&gt;
&lt;li&gt;Notifications about new comments so that users could continue their discussions in the comments section
We allocated 4 more weeks in order to implement the mobile version and social feed and, as a result, we implemented the following screens:&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%2Flxrzj21hksks2cdlzvco.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%2Flxrzj21hksks2cdlzvco.png" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing analytics as a value prop
&lt;/h3&gt;

&lt;p&gt;At this point, we already had a working proof of the concept being used by employees and early adopters of our client on a regular basis. But together with them, we started thinking about bringing this product to other companies and teams and the ways it could be monetized. Tracking data, sharing it and discussing it wasn’t enough in our opinion to try selling this product. So, we made an assumption that the teams that have enough discipline to track their data could find it valuable to receive insights from it. We then came up with simple analytics that could help in &lt;a href="https://datarockets.com/validate-idea/" rel="noopener noreferrer"&gt;validating this assumption&lt;/a&gt;. The page consisted of 4 sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your weekly average&lt;/li&gt;
&lt;li&gt;how you stand compared to your friends&lt;/li&gt;
&lt;li&gt;your spiritual buddy last week&lt;/li&gt;
&lt;li&gt;top contributing vital (the one that influences your mood the most and correlates with it)&lt;/li&gt;
&lt;/ul&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%2Fpscapx82u2glvm4lk4g2.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%2Fpscapx82u2glvm4lk4g2.png" width="800" height="674"&gt;&lt;/a&gt;&lt;br&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%2Fuu4krrol92i393mxeyk7.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%2Fuu4krrol92i393mxeyk7.png" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;During the whole development process, 1 part-time Project Manager and 2 full-time middle engineers (frontend and backend) were working from the datarockets side. The PM was involved in the product strategy discussion apart from managing the dev team. Our engineering team participated in feature discussions and suggested ways to make things simpler/faster.&lt;br&gt;
Together with the Pixel Dreams team, we implemented a web application that allows the tracking of personal data such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Journaling (day results, WIN LOSE or DRAW)&lt;/li&gt;
&lt;li&gt;Variety of counters (Book readings, daily calorie intake, etc.)&lt;/li&gt;
&lt;li&gt;Daily checklists (useful routine items, taboos)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, we’ve built social features for the teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teams configuration&lt;/li&gt;
&lt;li&gt;Roles&lt;/li&gt;
&lt;li&gt;Data sharing&lt;/li&gt;
&lt;li&gt;Commenting&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Social feed&lt;/li&gt;
&lt;li&gt;Insights and analytics of vitals that affect / correlate with your mood.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently, VITAL is in closed BETA. Together with Pixel Dreams, we are evaluating different &lt;a href="https://datarockets.com/blog/business/startup-stages-business-models/" rel="noopener noreferrer"&gt;business models&lt;/a&gt; in order to find a product-market fit and define what improvements we are going to build next.&lt;br&gt;
On the whole, the MVP building process with the implementation of new features and a mobile web app took us 18 weeks (~4.5 months) of development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technology Stack
&lt;/h2&gt;

&lt;p&gt;Ruby on Rails, Rspec, Mandrill API, Google oAuth, React.js, Chart.js, Redux, Postgres&lt;/p&gt;

&lt;p&gt;Originally published on the &lt;a href="https://datarockets.com/case-studies/vital/" rel="noopener noreferrer"&gt;datarockets' website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>startup</category>
      <category>portfolio</category>
      <category>mvp</category>
    </item>
    <item>
      <title>MVP development. Idea Validation process</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Thu, 12 Nov 2020 17:06:10 +0000</pubDate>
      <link>https://forem.com/datarockets/mvp-development-idea-validation-process-46i9</link>
      <guid>https://forem.com/datarockets/mvp-development-idea-validation-process-46i9</guid>
      <description>&lt;p&gt;Entrepreneurs are known to run into dozens of ideas on a daily basis, if not more. While most of them seem to border on absurdity in the beginning, it is often difficult to determine whether or not they would work out in the long run. That’s why the best way of ensuring your idea is worth developing is to learn at the fastest possible pace and have the willingness to try out different experiments.&lt;/p&gt;

&lt;p&gt;Based on our proven knowledge on product development and experience, we have developed a template document relating to the process of idea validation, and wrote the guide to explain each question and step in a simple, understandable manner.&lt;/p&gt;

&lt;p&gt;Get the &lt;a href="https://datarockets.com/blog/validate-startup-idea/" rel="noopener noreferrer"&gt;Idea Validation template&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  How’s this helpful?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Avoid wasting time and resources on something that’s certainly not worth it. &lt;/li&gt;
&lt;li&gt;Learn proactively and pivot your idea at a much quicker pace.&lt;/li&gt;
&lt;li&gt;Validate your product idea without actual budget/coding skills.&lt;/li&gt;
&lt;li&gt;Answering all the questions posed in this guide means it can serve as a worthwhile investor deck. Couple this with running some experiments and you’re well poised to raise money from investors!&lt;/li&gt;
&lt;li&gt;Most critically, it provides a credible framework to separate good ideas from bad ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  List of contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Value Proposition&lt;/li&gt;
&lt;li&gt;Existing Solutions Research&lt;/li&gt;
&lt;li&gt;Market Analysis&lt;/li&gt;
&lt;li&gt;Business Model Assumptions&lt;/li&gt;
&lt;li&gt;Growth Assumptions&lt;/li&gt;
&lt;li&gt;Competitor Analysis&lt;/li&gt;
&lt;li&gt;Experimental Plan Definition&lt;/li&gt;
&lt;li&gt;Experimenting&lt;/li&gt;
&lt;li&gt;MVP Scope Definition&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Value Proposition &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h4&gt;
  
  
  What important truth does your idea uncover that is not mainstream?
&lt;/h4&gt;

&lt;p&gt;The following would be a business version of this question: what is that valuable company that nobody is building? Every correct answer is necessarily a secret: something important and unknown, something hard to do but doable (&lt;a href="https://genius.com/Peter-thiel-zero-to-one-chapter-8-secrets-annotated" rel="noopener noreferrer"&gt;by Peter Thiel&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;It is important for your idea to reveal some unknown, unconventional truth in order to create something of value. Something nobody chooses to talk about aloud, but will become evident to all after it’s unraveled. &lt;/p&gt;

&lt;p&gt;For more interesting nuggets and insights on &lt;a href="https://datarockets.com/blog/startups-that-look-attractive-for-vc-investors/#great_ideas" rel="noopener noreferrer"&gt;startups that attract VC investors&lt;/a&gt; read &lt;a href="https://www.amazon.com/Zero-One-Notes-Startups-Future/dp/0804139296" rel="noopener noreferrer"&gt;Zero to One&lt;/a&gt; book. &lt;/p&gt;

&lt;h3&gt;
  
  
  Define fundamental value assumptions
&lt;/h3&gt;

&lt;p&gt;Here at datarockets, we classify three kinds of assumptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Value assumptions&lt;/strong&gt;: To define the value of your idea and future product. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business model assumptions&lt;/strong&gt;: This affects the manner in which you get your product monetized.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Growth assumptions&lt;/strong&gt;: How you’ll ensure growth of your product and continue to attract new customers. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s begin with the basics: the value assumptions!&lt;/p&gt;

&lt;h4&gt;
  
  
  What are your fundamental value assumptions? How does it help to resolve real-world problems?
&lt;/h4&gt;

&lt;p&gt;On the basis of the previous chapter’s statement, it’s best to define the fundamental value assumptions and experiment with them in the fastest possible manner. &lt;a href="https://datarockets.com/blog/mvp-app-development-lean-startup-way/" rel="noopener noreferrer"&gt;Leap of faith assumptions&lt;/a&gt; is another popular term for fundamental value assumptions. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;If your leap of faith assumptions are not true, the whole idea is not viable&lt;/em&gt;. This means that if your failed assumption won’t end up ruining the whole idea, then it’s not vitally important to begin with, thus implying that it can no longer be your fundamental value assumption.&lt;/p&gt;

&lt;h3&gt;
  
  
  Growth evaluation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Does your idea grow with the advancements of supporting technologies (durability)?
&lt;/h4&gt;

&lt;p&gt;Before taking the next step, confirm whether a new, upcoming technology won’t kill your promising idea. &lt;br&gt;
Ex: If you’re intending to develop a startup that teaches people how to drive vehicles, it may make sense to assume that with the advance of self-driving cars your business might get destroyed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Existing Solutions Research &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h4&gt;
  
  
  Has anyone implemented your idea / tried to implement it before?
&lt;/h4&gt;

&lt;p&gt;Although a typical process begins with communicating with people whose pain points will be addressed with your product/service, it makes a lot of sense to first research your idea and determine if similar services/solutions are already available in the market. After ensuring that the competition is not excessively intense or your idea provides breakthrough value with its uniqueness, it’s time to proceed further.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Find communities that may potentially be facing the problem you’re looking to resolve. Ask how they’re currently dealing with it and if they’d be interested in trying out your way.
&lt;/h4&gt;

&lt;p&gt;More often than not, other people may already be solving the problem you plan to solve. They may be doing that using some tricks or manual solutions. Identify and talk to them about how they tackle such challenges, what is it that they struggle with, and whether or not they’d like to explore your way of doing that.&lt;br&gt;
Based on who your target audience is, join Facebook groups where your target audience is likely to assemble, gather feedback from your own network, or even consider talking to people on the streets. &lt;br&gt;
Remember, whenever you wish to solve someone's problem or fulfil an unmet need in the market, the first step is to get people to stop using other solutions or make changes in lifestyles. After ensuring the problem is worthy of being solved and something that people wouldn’t mind paying for, you’re ready to take the next step.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why do you think your solution is better?
&lt;/h4&gt;

&lt;p&gt;After taking the above steps, focus on the advantages and the distinguishing features of your solutions that set them apart from others. List them in a logical order and then explain why people will find more value in your solution. What value will it bring to them?&lt;/p&gt;

&lt;h1&gt;
  
  
  Market Analysis &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Previously, we’d been assessing and validating our &lt;strong&gt;Value Assumptions&lt;/strong&gt;. Ensuring the viability of your idea was their core purpose. Unfortunately, merely having a good idea to create a long-term profitable product does not suffice. Think about the different ways in which you make money out of your solution via &lt;strong&gt;Market Analysis&lt;/strong&gt; and &lt;strong&gt;Business Model Assumptions&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define your potential target market
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Narrow down your potential target market. Who is your ideal customer? Why should they pay for your solution?
&lt;/h4&gt;

&lt;p&gt;Targeting everyone essentially means that you’re not targeting anyone in particular. Concentrating on the appropriate target market is a good approach because it lets you maximize your returns on the time, money and energy you’ve invested. Secondly, it’s far easier to conduct  experiments in a narrow market.&lt;br&gt;
Try and define specific groups you wish to target with your service/product alongside their potential sources of revenue. Depending on your idea, you can even group them by job, interests, demographics, etc. Ensure that your target audience will be able to buy your products as the revenue source of each target will be different.&lt;br&gt;
Now, there are some industries where people are very unlikely to pay for additional services. As a case in point, the probability of people paying to use social media for communication purposes is very low. In such scenarios, use your discretion and prepare a draft of your monetization strategy. While it needn’t be your final blueprint, it will greatly simplify your task by helping you select more attractive markets.&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Google Trends/Semrush to see how many people google solutions for the problem you are trying to solve
&lt;/h4&gt;

&lt;p&gt;Tools like Google Trends or Semrush give you an accurate picture of just how many people are seeking solutions to the problem you’re attempting to resolve. Most importantly, such tools allow you to check who these people are, know what their trends are, and provide a reasonable accurate estimate of the size of your target market.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reach out to five well-known people in the market and ask for feedback on your idea
&lt;/h4&gt;

&lt;p&gt;After gathering the necessary information based on the previous steps, select a market (or a couple of them) that seems most promising. The next step in this phase is to gather feedback from specific groups of people relevant to your market. Doing this will give you plenty of actionable insights and the opportunity to further examine your idea from different perspectives. &lt;/p&gt;

&lt;h3&gt;
  
  
  Create a portrait of your target audience
&lt;/h3&gt;

&lt;p&gt;In this phase, try to be as specific as possible about all relevant attributes of your target audience that describe them/their lives accurately and narrow them down further - age, gender, interests, position, personality, daily schedule, reading patterns, etc.&lt;/p&gt;

&lt;p&gt;Regardless of whether you describe a person or a company, depending on your sales model (B2B or B2C), the approach will remain unchanged. Consider the example from the &lt;a href="https://www.amazon.com/1-Page-Marketing-Plan-Customers-Money-ebook/dp/B01B35M3SM" rel="noopener noreferrer"&gt;"1-Page Marketing Plan" book&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conduct target user interviews
&lt;/h3&gt;

&lt;p&gt;According to Eric Migicovsky, a Y Combinator partner, the best firms are those whose founders establish a direct connection with their users. If you happen to be a founder, consider talking directly to the users of your product or solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/MT4Ig2uqjTc" rel="noopener noreferrer"&gt;In his talk&lt;/a&gt;, Eric cites a useful example of a structure that can be used to hold your user interviews. After tailoring the structure based on our needs and priorities, this is what we’ve come up with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What makes the problem difficult for them?&lt;/li&gt;
&lt;li&gt;When did they last face it?&lt;/li&gt;
&lt;li&gt;What have they done to solve the problem?&lt;/li&gt;
&lt;li&gt;What are the things about existing solutions that they don’t like?&lt;/li&gt;
&lt;li&gt;How much would they pay to resolve the problem?&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Business Model Assumptions &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h4&gt;
  
  
  List your business model assumptions (based on the assumptions on what you assume your customers are going to pay and how much)
&lt;/h4&gt;

&lt;p&gt;After defining the problem to be solved, doing user interviews and knowing more about the target audience, it’s now time to brainstorm ways of monetizing your product. &lt;/p&gt;

&lt;p&gt;It’s a good idea to first get better informed about various &lt;a href="https://datarockets.com/blog/startup-stages-business-models/" rel="noopener noreferrer"&gt;types of business models&lt;/a&gt; before jotting down your assumptions about how your customers would be paying and how much. Put every idea on your mind on the table. &lt;/p&gt;

&lt;h1&gt;
  
  
  Growth Assumptions &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h4&gt;
  
  
  List your growth assumptions (what is your plan to rope in new users and how much cost would that involve)
&lt;/h4&gt;

&lt;p&gt;To survive and thrive, it’s critical to ensure your product grows smoothly and plan out ways in which you’ll attract new users or enter into new deals (partnerships). You’ll have a far better picture of your future marketing investment by writing down all possible growth hacking and marketing ideas. (prepare to get startled by the fact that budgets for marketing are often bigger than those for development purposes ;))&lt;/p&gt;

&lt;h4&gt;
  
  
  Does your growth engine generate new users from the actions of existing users? List out your acquisition loops.
&lt;/h4&gt;

&lt;p&gt;Getting new users effortlessly without spending any money is always a pleasant feeling. In that context, consider exploring &lt;a href="https://nogood.io/2019/10/01/growth-acquisition-loops-funnel/" rel="noopener noreferrer"&gt;acquisition loops&lt;/a&gt; which will make a great addition for your monetization strategies.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The core idea behind acquisition loops is as follows: The more users you have, the more users are attracted.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can implement acquisition loops in the form of referral programs (e.g. Airbnb and Uber offer free coupons/rides for each referred user) or content loops that are user generated (Reddit, social networks, etc.).&lt;br&gt;
Natural acquisition loops are extremely important when you’re planning to execute an Ad-based business model, because the average revenue per user (ARPU) of ad-based models are lower in comparison to let’s say SaaS. That's why they must acquire new users cheaply to generate sustainable profits and reap massive profits.&lt;/p&gt;

&lt;h4&gt;
  
  
  What’s your assumed revenue source? How would your profits/expenses grow as the number of customers grows (scalability assumption)?
&lt;/h4&gt;

&lt;p&gt;Needless to say, it’s not easy to accurately predict your expenses and profits. Some startups have funding to cover their expenses for two years or so until the venture starts making profits. If that’s not your case, pay close attention to this aspect and foresee your potential scalability issues and expenses.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Competitor Analysis &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h4&gt;
  
  
  High-level SEO analysis
&lt;/h4&gt;

&lt;p&gt;This step needs us to continue working with product positioning and simultaneously address several key questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How many people are interested in this? &lt;/li&gt;
&lt;li&gt;How difficult is it to rank on the first page of Google?&lt;/li&gt;
&lt;li&gt;What keywords should I use to promote my product or service? &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you begin to answer these questions, it will become crystal clear that some keywords are more popular as compared to others. Some find it really hard to attain a high ranking on Google. Here, our objective is to compare word combinations that translate your business model to identify keywords with a balanced volume and keyword difficulty (KD).  &lt;/p&gt;

&lt;p&gt;Utilize tools like Semrush, Ahrefs Keyword Finder, Google Ads Keyword tool, etc. to collect the information about &lt;strong&gt;Volume, CPC, KD and leading websites that rank by these keywords&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Competitor overview
&lt;/h4&gt;

&lt;p&gt;Competitor overview is an extremely important step to undertake before proceeding further and it requires you to gather information about your competitors’ users, business models, revenue, etc. We this guide, we want to draw your attention to three attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your Advantage&lt;/li&gt;
&lt;li&gt;How Hard to Replicate Your Advantage&lt;/li&gt;
&lt;li&gt;Why Should Customers Buy from You&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From these characteristics, it’s clear that you’ll compare your value proposition with your competitors and know what your unique selling proposition is.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learn more about your competitors
&lt;/h4&gt;

&lt;p&gt;Usually, you’ll get more insights from personal interaction with your rivals than from conducting a basic competitor overview. It’s a good idea to reach out to them and know more about how their business is shaping up and the struggles they’re going through. Some effective ways of doing this include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scheduling a demo as a user. When it comes to small startups, you’re more likely to be able to engage in a personal talk with product owners that are very in tested in collecting user feedback. &lt;/li&gt;
&lt;li&gt;Contact product owners directly as their competitor. Generally, experienced startup owners are not opposed to the idea of talking to competitors and others from within the same industry. In most cases, they’ll frankly talk about their experiences/struggles, caution you about some pitfalls and share some additional information that you may find relevant.&lt;/li&gt;
&lt;li&gt;Conduct in-depth research on their personal pages and blogs. In some rare cases, founders openly reveal all the information about the product and its metrics such as conversions, active users, revenue, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Experimental Plan Definition &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Until now, you’re likely to have collected several interesting ideas of business models as well as growth assumptions. Now is the time to get them tested.&lt;/p&gt;

&lt;h4&gt;
  
  
  How are you going to test your business and product positioning assumptions?
&lt;/h4&gt;

&lt;p&gt;Let’s face it. It’s not viable to build MVPs for every different assumption. Do the smart thing, instead. There are many tricks that you can implement to test ideas without actual development. We covered some of them in our blog post on the Lean Startup approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Landing page. After using builders to develop simple websites with your value proposition, collect early-bird invites or sign-ups for testing the app. This is an effective way of evaluating the interest of users. &lt;/li&gt;
&lt;li&gt;Demo video. Several startups received funding only for the video that explained their vision because the product had already been built.
&lt;/li&gt;
&lt;li&gt;Crowdfunding platform. This can be a useful option not only to validate your ideas, but also to identify early adopters and receive payments before you actually develop the product. &lt;/li&gt;
&lt;li&gt;Concierge MVP. Sometimes, you can test the idea manually rather than having a web platform or application. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Where can you find your early adopters?
&lt;/h4&gt;

&lt;p&gt;Now you must locate people who’re facing the problem you plan to solve and get them to test your product/solution. They will not only give you valuable feedback, but also spread the word. By now, you should know how to find them because you’ve already talked to them in the Value Proposition stage.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crowdfunding platforms&lt;/li&gt;
&lt;li&gt;Facebook / Reddit / Telegram groups&lt;/li&gt;
&lt;li&gt;Current clients (if your business is running offline for now), etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How are you going to collect feedback?
&lt;/h4&gt;

&lt;p&gt;Put differently, how will you communicate with your early adopters?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feedback forms&lt;/li&gt;
&lt;li&gt;Facebook groups / Telegram channels&lt;/li&gt;
&lt;li&gt;Email campaigns&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Experimenting &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Experimentation time! At this stage, you would have every information you need to test the assumptions and begin data collection to identify your product positioning and go-to-market business model. &lt;br&gt;
After launching your demo videos/ landing pages, go ahead and collect some data. Not every idea is explained in the same way, so you may want to quickly run a couple of Google ads to see people’s reaction to various keywords for product positioning. &lt;/p&gt;

&lt;p&gt;Putting the metrics on the table will let you see what experiment turned out to be most successful. Although we offer to check these metrics, it’s your call on whether or not to make changes in this list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Impressions&lt;/li&gt;
&lt;li&gt;CTR&lt;/li&gt;
&lt;li&gt;Visits&lt;/li&gt;
&lt;li&gt;Signups&lt;/li&gt;
&lt;li&gt;Conversion rate&lt;/li&gt;
&lt;li&gt;Cost per Signup&lt;/li&gt;
&lt;li&gt;Assumed Average Revenue per User&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may also want to check our massive, extremely helpful guide on &lt;a href="https://datarockets.com/blog/ultimate-startup-metrics-guide/" rel="noopener noreferrer"&gt;Startup Metrics&lt;/a&gt;. &lt;/p&gt;

&lt;h1&gt;
  
  
  MVP Scope Definition &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;If you’ve successfully reached this stage, congratulate yourself for making good progress! You now have a very good reason to believe that your idea is worth developing. Time to define the scope of work by preparing for MVP building:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define your go-to-market business model.&lt;/li&gt;
&lt;li&gt;Conduct interviews with customers who have signed up. Ask about their expectations and top-3 features they’re looking to implement in the product. Match their expectations with your pricing model.&lt;/li&gt;
&lt;li&gt;Do a cross-analysis of the interviews in order to find out most desirable features. Consider writing simple User Stories.&lt;/li&gt;
&lt;li&gt;Predict revenues for 100/1000/10000 paying customers and calculate your business model’s unit-economics&lt;/li&gt;
&lt;li&gt;Obtain estimates on the numerous features and determine the ones you wish to include in the MVP. Make it a point to only include the most important features that help validate your key assumptions. You can always add the rest at a later stage. Ensure that your budget for MVP is less than 30k-40k.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Yeah, it does look like a long, tedious process. But here’s the good news for you! You can test your ideas quickly and effectively after gaining some experience. &lt;/p&gt;

&lt;p&gt;Another piece of good news: if you happen to fail at any stage, there’s no reason to be upset about it, because it basically means that you successfully prevented your money from being wasted on developing a product that was likely to fail in the first place. Sometimes, a back-up option for a not-so-strong idea is to pivot it and repeat the cycle. &lt;/p&gt;

&lt;p&gt;Besides, we’re always ready to help in whatever way we can with the &lt;a href="https://datarockets.com/blog/validate-startup-idea/" rel="noopener noreferrer"&gt;idea validation&lt;/a&gt; process and product development insights. All you need to do is to drop us a line and we’ll be happy to talk!&lt;/p&gt;

</description>
      <category>startup</category>
    </item>
    <item>
      <title>Interview with CEO - Providing estimates on fixed price projects dev teams have to lie</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Fri, 21 Aug 2020 12:09:58 +0000</pubDate>
      <link>https://forem.com/datarockets/interview-with-ceo-providing-estimates-on-fixed-price-projects-dev-teams-have-to-lie-94</link>
      <guid>https://forem.com/datarockets/interview-with-ceo-providing-estimates-on-fixed-price-projects-dev-teams-have-to-lie-94</guid>
      <description>&lt;p&gt;datarockets founders, Pavel and Dmitry, worked for leading outsourcing companies in the industry before they started their own company that develops &lt;a href="https://datarockets.com/capabilities/" rel="noopener noreferrer"&gt;web and mobile applications of any complexity&lt;/a&gt;. They observed the ecosystems that lacked transparency, were indifferent towards the success of clients’ projects, and there was a certain unwillingness to invest in the personal growth of the engineering teams. This compelled them to build a place for like-minded people where they can integrate with clients as a single team, based on a transparent development process.&lt;/p&gt;

&lt;p&gt;To further understand datarockets’ vision, GoodFirms has &lt;a href="https://datarockets.com/blog/interview-ceo/" rel="noopener noreferrer"&gt;interviewed datarockets CEO&lt;/a&gt;, Pavel as part of their interview series. The following information is an extract from that conversation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduce your company and give a brief about your role within the company
&lt;/h1&gt;

&lt;p&gt;datarockets is an experienced team of product developers with offices in Toronto, Canada, and Minsk, Belarus.&lt;/p&gt;

&lt;p&gt;We know how to build successful web &amp;amp; mobile applications and do our best to share that experience with our clients. I believe we have a very special approach when building relationships with our customers, which results in productive partnerships that last for years.&lt;/p&gt;

&lt;p&gt;At datarockets, we use &lt;a href="https://www.holacracy.org/" rel="noopener noreferrer"&gt;Holacracy&lt;/a&gt; to distribute roles between people, so my roles are constantly evolving. In short, I have the pleasure to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define the future of the company by researching new business opportunities&lt;/li&gt;
&lt;li&gt;Give product strategy advice to our customers&lt;/li&gt;
&lt;li&gt;Share our knowledge writing articles about &lt;a href="https://datarockets.com/blog/mvp-app-development-lean-startup-way/" rel="noopener noreferrer"&gt;startups and product development&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What was the idea behind starting this organization?
&lt;/h1&gt;

&lt;p&gt;The idea behind starting datarockets was to create an intellectual hub where engineers come to learn product development skills from one hand, and clients come to create products for their businesses and startups from another hand.&lt;br&gt;
Together with Dmitry Zhlobo (the CTO and co-founder at datarockets), we had been working for leading outsourcing companies in the industry and seen their processes from the inside. We didn’t like many things, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;the lack of transparency.&lt;/strong&gt; Typical outsourcing companies were trying to “build a fence” between their developers and clients with the help of project managers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;indifferent attitude towards the success of their projects.&lt;/strong&gt; Our managers were more concerned about clients paying their bills rather than our ideas on how to improve things around.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;unwillingness to invest in the personal growth of their engineering teams.&lt;/strong&gt; We were working in a typical corporate culture embracing overtimes and trying to squeeze as much as possible from their employees.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We couldn’t find a place for ourselves, and that’s why we started datarockets. We were lucky to find 25 more like-minded individuals who joined our team and now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We integrate closely&lt;/strong&gt; with our clients and work with them as a single team using an extremely transparent development process&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We communicate a lot&lt;/strong&gt; and share our ideas on how to make things faster/better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Our company organizes tech conferences&lt;/strong&gt; across Europe, and our engineers perform there as speakers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is your company’s business model–in house team or third party vendors/ outsourcing?
&lt;/h1&gt;

&lt;p&gt;Our business model is called “Dedicated Team”. We don’t outsource and prefer to rely on our own resources.&lt;br&gt;
Working as dedicated teams means a close integration into our clients’ businesses and their teams. We bring our communication and development processes, automate routine work, and exchange best practices. This way, we create a productive environment where we grow together with our customers.&lt;/p&gt;

&lt;h1&gt;
  
  
  How is your business model beneficial from a value addition perspective to the clients compared to other companies’ models?
&lt;/h1&gt;

&lt;p&gt;Apart from actual coding, &lt;strong&gt;we bring our ideas to the table&lt;/strong&gt;. Writing high-quality code is what we do by default, but there are many good engineers out there, and we go the extra mile to stand out. We contribute to our projects by sharing our culture, bringing our processes, and providing our ideas on how to make things faster/better.&lt;/p&gt;

&lt;p&gt;Our major strength is &lt;strong&gt;transparency and simplicity&lt;/strong&gt;. datarockets’ clients don’t worry about the technical part of their products anymore – we handle that. We set up clear &lt;a href="https://datarockets.com/blog/transparent-development-process/" rel="noopener noreferrer"&gt;work and communication processes&lt;/a&gt;, so our clients can see what we discuss, how we make decisions, and what issues we experience in real-time. Our team lets our customers focus on what really matters to them: overall product strategy, finances, and marketing.&lt;/p&gt;

&lt;p&gt;We try to automate as much routine work as possible. Our engineers don’t really enjoy the work that can be done by robots/scripts, and that always turns out to be very beneficial for our customers.&lt;/p&gt;

&lt;h1&gt;
  
  
  What industries do you generally cater to? Are your customers repetitive?
&lt;/h1&gt;

&lt;p&gt;We don’t stick to a specific industry. Our team consists of people who are fond of complex architectures, like to resolve complex problems and create something really useful. We never stop learning. The best way to use all this knowledge and learn more is to take different kinds of projects. &lt;/p&gt;

&lt;p&gt;For the last 6 years, we have been building products for the following industries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FinTech&lt;/li&gt;
&lt;li&gt;Ride Sharing&lt;/li&gt;
&lt;li&gt;Entertainment&lt;/li&gt;
&lt;li&gt;Social Media&lt;/li&gt;
&lt;li&gt;Social Network&lt;/li&gt;
&lt;li&gt;Real Estate&lt;/li&gt;
&lt;li&gt;Human Resources&lt;/li&gt;
&lt;li&gt;SaaS&lt;/li&gt;
&lt;li&gt;Marketing&lt;/li&gt;
&lt;li&gt;Healthcare&lt;/li&gt;
&lt;li&gt;IoT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost all of our clients come back to us with new projects and refer their business partners/friends to us. &lt;/p&gt;

&lt;h1&gt;
  
  
  Mention the objectives or the parameters critical in determining the time frame of developing software and applications.
&lt;/h1&gt;

&lt;p&gt;To provide as accurate as possible estimate, we need to know as much as possible. Usually, before we give an estimate, we try to determine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Functional business requirements.&lt;/strong&gt; What kind of features we need to build and how they help the users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical business requirements.&lt;/strong&gt; For example, if we need Internet Explorer browser support, it can add some extra work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product strategy.&lt;/strong&gt; Before taking on a project, we need to believe in the idea behind it as well as its strategy. We need to know why exactly we build a certain feature to share our insights and suggest improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing strategy.&lt;/strong&gt; Nowadays, marketing matters even more than development, and we need to ensure that our prospective clients are aware of that. We need to know their marketing strategy to suggest our own ideas and share relevant experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget&lt;/strong&gt;. Depending on the budget, we can offer alternative technology stack or suggest our vision on the scope of work/priorities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legacy Code.&lt;/strong&gt; If a project is not from scratch, we need to perform an initial code review to assess its current state and provide estimates based on what has been done already.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  How much effort in terms of time goes into developing the front end and back end of a web application?
&lt;/h1&gt;

&lt;p&gt;It really depends. In our portfolio, we have some API-only projects that didn’t involve any frontend and at the same time, some frontend-only projects without any backend.&lt;br&gt;
Our estimation process is collaborative and transparent. Our prospective clients see how much time we plan to spend on each feature/change and free to share their questions/concerns during the process.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are the key parameters to be considered before selecting the right framework for developing software?
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Common use cases.&lt;/strong&gt; Every framework/technology is aimed to resolve a particular class of tasks, and you need to be aware of that. For example, it’s possible to develop a simple website &amp;amp; blog with C++, but with Wordpress, it’s gonna be 1000 times faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical limitations.&lt;/strong&gt; Each framework has its own limits and they need to match your technical business requirements. Otherwise, at some point, you will need to switch to another framework, which can be extremely expensive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility.&lt;/strong&gt; At some point, you may need to make a strategic pivot and be sure your current framework can handle that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem.&lt;/strong&gt; When using a popular framework with a highly developed ecosystem, you almost always can find an open source library that does exactly what you need. For example, the Ruby ecosystem has thousands of open-source libraries that you can plug &amp;amp; play. That significantly cuts down the total cost and timeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License.&lt;/strong&gt; Not every framework is free, and some of them are authorized to be used in certain conditions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community.&lt;/strong&gt; Your development team should be able to find the necessary information fairly easy. Moreover, there should be a community behind the framework which is able to answer questions, fix bugs, and patch security breaches as they get discovered.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Which languages &amp;amp; frameworks do you prefer to use in development of web and mobile applications?
&lt;/h1&gt;

&lt;p&gt;For the backend we prefer to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby / Rails&lt;/li&gt;
&lt;li&gt;Javascript / Node.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the frontend, it’s usually JavaScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React.js&lt;/li&gt;
&lt;li&gt;Vue.js.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Talking about mobile apps, we use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;Kotlin/Java&lt;/li&gt;
&lt;li&gt;Swift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are 2 reasons why we use these technologies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;They fit our needs the best.&lt;/strong&gt; The technologies listed above give enough flexibility and at the same time, speed up web/mobile app development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Our team has the most experience&lt;/strong&gt; with them and enjoy using those languages/frameworks.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  What kind of payment structure do you follow to bill your clients?
&lt;/h1&gt;

&lt;p&gt;We bill for our time only. When a project needs to be done in a certain budget and time, we usually apply the FFF approach (Fixed Price, Fixed Time, Flexible Scope). What we do in this case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break down the scope of work into User Stories and sort them based on their priorities&lt;/li&gt;
&lt;li&gt;Work on the User Stories iteratively based on their priority.&lt;/li&gt;
&lt;li&gt;Release new functionality as soon as it’s ready, sometimes we make multiple releases per week.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This way, at any time, we have a working version of the product. When we get closer to the deadline, we can stop and skip some minor features, but deliver the most crucial functionality under the budget. &lt;/p&gt;

&lt;p&gt;We don’t like fixing the overall project/milestone cost for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Providing estimates on fixed price projects development teams have to lie.&lt;/strong&gt; If they provide positive estimates – their companies inevitably lose money. If negative – they kind of lie to their clients.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After a fixed price project is signed, the client has no flexibility&lt;/strong&gt; as the scope of work is fixed for that price. Requesting even a minor feature turns into the bureaucracy hell when project managers need to re-assess the scope of work, get updated estimates from the team, and re-sign the budget agreement. We strongly believe that it’s a waste of everyone’s time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There is not enough freedom&lt;/strong&gt; for teams working on fixed price projects. Engineers don’t have time to suggest their ideas, improve processes, and automate routine work. Such atmosphere embraces poor productivity, low-quality code, and reluctant attitude to the project in general.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Do you take in projects which meet your basic budget requirement? If yes, what is the minimum requirement?
&lt;/h1&gt;

&lt;p&gt;In practice, the minimum budget we can work with is $20k. The reason is that we don’t build simple websites that can be done with CMS like Wordpress, we take on the projects that require custom solutions. Having a budget less than $20k is pretty challenging to kick off something like that, even an MVP.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the price range (min and max) of the projects that you catered to in 2018?
&lt;/h1&gt;

&lt;p&gt;$30k - $220k&lt;br&gt;
I have to note here that we always build long-term relationships with our clients. The medium project duration with us is approximately 12 months. Our clients work with us for years; for some of them, we become their exclusive software development partners.&lt;/p&gt;




&lt;p&gt;datarockets’ product vision, transparency with clients, and strong development culture have resulted in a high place amongst the top software development companies in Canada and Belarus.&lt;/p&gt;

</description>
      <category>interview</category>
      <category>remote</category>
      <category>career</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>MVP development. The Lean Startup Way</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Thu, 20 Aug 2020 16:09:07 +0000</pubDate>
      <link>https://forem.com/datarockets/mvp-development-the-lean-startup-way-2kp5</link>
      <guid>https://forem.com/datarockets/mvp-development-the-lean-startup-way-2kp5</guid>
      <description>&lt;p&gt;When you establish your own startup the important thing you need to understand as soon as possible that there is no some kind of a ready-to-use business plan you can utilize. Startups try to create innovative products and discover new markets. On one hand, it might give you some freedom due to lack of competition when you create something unique, but on another hand, you get in the atmosphere of extreme uncertainty.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lean Startup approach
&lt;/h1&gt;

&lt;p&gt;Because startups often accidentally build something nobody wants, it doesn’t matter much if they do it on time and budget. The only thing that matters is &lt;strong&gt;how fast a startup learns and makes strategical pivots&lt;/strong&gt; in order to achieve the product-market fit point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Groupon was started as a social network for activists&lt;/li&gt;
&lt;li&gt;Instagram originally was called “Burbn” – an extremely overcomplicated location-based iOS application for check-ins&lt;/li&gt;
&lt;li&gt;Youtube was a video dating site from the beginning&lt;/li&gt;
&lt;/ul&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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2Flean-startup-business-3.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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2Flean-startup-business-3.png" title="MVPs of popular projects looked like this" alt="MVPs of popular projects looked like this" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Surprising, huh?&lt;/p&gt;

&lt;p&gt;MVP goes from “Minimum Viable Product” and the keyword here is &lt;strong&gt;MINIMUM&lt;/strong&gt;. Many entrepreneurs forget about this particular word or feel ashamed of releasing simple non-stable versions of their product. Successful entrepreneurs consider MVP app development as an entry to their learning lifecycle and try to &lt;strong&gt;launch their products as soon as possible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As a real example, read our case study about &lt;a href="https://datarockets.com/case-studies/toronto-experts/" rel="noopener noreferrer"&gt;launching a quick MVP project&lt;/a&gt; to validate an idea.&lt;/p&gt;

&lt;h1&gt;
  
  
  Determine Leap of Faith Assumptions
&lt;/h1&gt;

&lt;p&gt;Before building a new feature or a product ask yourself 3 simple questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do your target audience recognize that they have the problem you are trying to solve?&lt;/li&gt;
&lt;li&gt;If there a solution, would they buy it?&lt;/li&gt;
&lt;li&gt;Would they buy it from you, but not from someone else?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While answering these questions you will create a list of assumptions (because nobody can be 100% sure about that).&lt;/p&gt;

&lt;p&gt;After that, define the &lt;a href="https://datarockets.com/blog/mvp-app-development-lean-startup-way/" rel="noopener noreferrer"&gt;leap of faith assumptions&lt;/a&gt;. It is pretty easy to recognize them: if your leap of faith assumptions fail, the overall product idea seems not to be working.&lt;/p&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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2Fleap-of-faith-assumptions-4.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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2Fleap-of-faith-assumptions-4.png" title="How to define the leap of faith assumptions" alt="How to define the leap of faith assumptions" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! Now, you know the goal of your MVP: to check your leap of faith assumptions in the quickest possible way.&lt;/p&gt;

&lt;h1&gt;
  
  
  Assume Your Growth Engine
&lt;/h1&gt;

&lt;p&gt;Growth Engine is another kind of assumptions that define how your product will attract new users. You can make product growth assumptions based on the following Growth Engine types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Viral&lt;/strong&gt;. A good example here is Facebook or any other social network. Their growth engine is based on the assumption that existing users will bring new users as a side effect of product usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paid&lt;/strong&gt;. One of the most popular ways to attract new users. Super Bowl commercials, Google Ads or any other advertising is a part of Paid Engine growth strategy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky&lt;/strong&gt;. SaaS subscriptions, magazines, and web hosting are all examples of this engine. Sticky Engine assumes repetitive purchases, so in order to grow your product may not require new users, but needs the existing users to continue using it.&lt;/li&gt;
&lt;/ul&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%2F7u4axml812io08etsgbi.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%2F7u4axml812io08etsgbi.png" width="800" height="259"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Of course, due to startup uniqueness, you can find your own Growth Engine. The only advice here is to focus on only one Growth Engine assumption in your MVP and test it as soon as possible.&lt;/p&gt;

&lt;h1&gt;
  
  
  Set Up Metrics Tracking
&lt;/h1&gt;

&lt;p&gt;Let’s assume that your happy day has come. You launched your MVP and what’s next? How successful your MVP is? What should you do to attract more users? How many people use feature A and how many use feature B?&lt;/p&gt;

&lt;p&gt;The truth is that I have never seen in my life an MVP launch that got successful right away. Almost all MVPs get pretty pessimistic numbers in the beginning, but experienced entrepreneurs do not fall into despair. They learn from user behavior data and steer their product strategy in the right direction.&lt;/p&gt;

&lt;p&gt;Visitors/sessions/pageviews number and other metrics provided by Google Analytics out-of-the-box are nice to have, but they don’t give you any actionable insights. &lt;strong&gt;What you need to define is your actionable metrics&lt;/strong&gt;.&lt;/p&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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2FScreen-Shot-2018-10-05-at-11.07.55-AM-1536x758.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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2FScreen-Shot-2018-10-05-at-11.07.55-AM-1536x758.png" title="Example of actionable metrics" alt="Example of actionable metrics" width="800" height="394"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;First of all, analyze your leap of faith assumptions and define the useful effect of your MVP. This can be represented as a chain of actions that you assume your users should do in order to get value from the product. Then, &lt;strong&gt;set up Google Analytics Goals and Conversion Funnel&lt;/strong&gt; based on your vision. After the MVP product launch you will be able to see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If your users agree with you on what the useful effect of your product is&lt;/li&gt;
&lt;li&gt;At what step of the conversion funnel you lose how many users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Such data will allow you to make new assumptions on how you can improve your initial numbers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Analyze your Growth Engine assumption and define what to track
&lt;/h1&gt;

&lt;p&gt;For the examples of Growth Engines above you need to track the following data:&lt;/p&gt;

&lt;h2&gt;
  
  
  Viral Engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Viral Coefficient. It is the number of new users an existing user generates. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If it more than 1, it means that your product is growing naturally. If it less than 1, you need to put all your efforts to increase this number&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sticky Engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Customer Acquisition Rate. Defines how many users start using your product.&lt;/li&gt;
&lt;li&gt;Customer Churn Rate. How many users discontinue using your product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your product is growing if the Churn Rate is less than Acquisition Rate&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paid Engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Customer Lifetime Value. How much an average user acquisition brings.&lt;/li&gt;
&lt;li&gt;Cost Per Acquisition. How much it costs to acquire a new user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your product grows if Customer Lifetime Value is more than Cost Per Acquisition&lt;/strong&gt;.&lt;/p&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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2Fleap-of-faith-assumptions-9.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%2Fdatarockets.com%2Fwp-content%2Fuploads%2F2018%2F10%2Fleap-of-faith-assumptions-9.png" title="Growth Engine parameters" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, it usually requires additional efforts to define and set up appropriate metrics tracking in an MVP. Feel free to cut the functionality during your MVP app development as much as possible, but metrics gathering should be there 100%.&lt;/p&gt;

&lt;h1&gt;
  
  
  Find Early Adopters
&lt;/h1&gt;

&lt;p&gt;If you are about to build an MVP, that means that you have a solution for a certain problem and there are many people out there having that problem. Find those, who are struggling with it. Speak to them and describe your solution, get a feedback before actual implementation.&lt;/p&gt;

&lt;p&gt;After your MVP product development is completed, share it with the early adopters. The thing is that a massive market user is pretty picky. If they don’t like your product they won’t use it – simple as it is. Early adopters are the opposite: they will provide you a feedback. They are interested in improving your product. They will spread the word about it among their friends.&lt;/p&gt;

&lt;h1&gt;
  
  
  Be Smart
&lt;/h1&gt;

&lt;p&gt;For you, as an entrepreneur, it is even more important to get a feedback on your assumptions rather than provide a solution based on them to your users. There is a number of tricks that allow you to do that without actual MVP product development.&lt;br&gt;
Lean startup development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concierge MVP
&lt;/h2&gt;

&lt;p&gt;Zappos, acquired by Amazon for $1.2 billion in 2009, was started as a concierge MVP. Nick Swinmurn had an assumption that people would buy shoes online and decided to test it in a pretty simple way. He went to one of closest shoe stores and made photos of shoes there. Then, he created a very simple website with just photos of those shoes and prices.&lt;/p&gt;

&lt;p&gt;As soon as he got the first order, he went to the store, bought the shoes for his own money and shipped them to the customer. He was operating this way for some time in order to speak to his customers and learn from them. After 5 years Zappos had annual sales of more than $1 billion.&lt;/p&gt;

&lt;p&gt;Concierge MVP seems to be a horrible idea from the classic business perspective: no automation, it doesn’t scale and etc. But it allows learning from your target audience quickly w/o additional investments into infrastructure, which is more important in the startup world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video MVP
&lt;/h2&gt;

&lt;p&gt;Can you imagine how hard and pricy it was to build something like Dropbox? It was one of the pioneers in cloud data storage supporting different operating systems. Even a simple MVP to showcase Dropbox could cost insane money, so the Dropbox founders decided to start from a simple video that shows how the product works.&lt;/p&gt;

&lt;p&gt;The trick here is that they didn’t have the product working at that time – just a prototype. But they managed to record that video and create a landing page in order to get a feedback before actual implementation. The result was overwhelming: 75 000 people joined their waiting list overnight.&lt;/p&gt;

&lt;p&gt;What can be a better proof of interest?&lt;/p&gt;

&lt;h2&gt;
  
  
  Community MVP
&lt;/h2&gt;

&lt;p&gt;It is closely connected with &lt;a href="https://datarockets.com/blog/mvp-app-development-lean-startup-way/#find-early-adopters" rel="noopener noreferrer"&gt;Find Early Adopters&lt;/a&gt;. The idea behind this is to create online communities in Telegram, Slack, Facebook, and gather there the people who are struggling with the problem you are trying to solve. Talk to them, share your assumptions, and collect feedback.&lt;/p&gt;

&lt;p&gt;This approach is pretty popular in the crypto space these days: every ICO tries to create a community around that can provide feedback, participate in beta testing, and crowdfund further development of their product.&lt;/p&gt;

&lt;h1&gt;
  
  
  MVP development summary
&lt;/h1&gt;

&lt;p&gt;MVP is always a guess. The faster you present it to people, the less time and resources you spend to get into the learning lifecycle. Any additional work beyond what is required to start learning is a waste.&lt;/p&gt;

&lt;p&gt;Observe users’ behavior, speak to early adopters, and make data-driven decisions to achieve the product-market fit point.&lt;/p&gt;

&lt;p&gt;If you’re up to building an MVP, we’re insisting on reading &lt;a href="https://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898" rel="noopener noreferrer"&gt;“The Lean Startup” by Eric Ries&lt;/a&gt;. Good luck with your lean startup development!&lt;/p&gt;




&lt;p&gt;Originally written by CEO of datarockets Pavel Demeshchik for the &lt;a href="https://datarockets.com/blog/" rel="noopener noreferrer"&gt;datarockets' blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>startup</category>
    </item>
    <item>
      <title>Easy integration Rails with AdminLTE template using bower or npm</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Mon, 17 Aug 2020 19:20:19 +0000</pubDate>
      <link>https://forem.com/datarockets/easy-integration-rails-with-adminlte-template-using-bower-or-npm-3d3d</link>
      <guid>https://forem.com/datarockets/easy-integration-rails-with-adminlte-template-using-bower-or-npm-3d3d</guid>
      <description>&lt;p&gt;&lt;a href="https://adminlte.io/" rel="noopener noreferrer"&gt;AdminLTE&lt;/a&gt; is an open-source admin dashboard &amp;amp; control panel theme based on Bootstrap 3. It provides a range of responsive, reusable, and commonly used components. In this post, I’ll integrate AdminLTE to Rails application using &lt;strong&gt;Bower&lt;/strong&gt; and &lt;strong&gt;Node package manager (npm)&lt;/strong&gt;.&lt;/p&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%2Fc3zn2ifl3pq4ku4o0dhy.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%2Fc3zn2ifl3pq4ku4o0dhy.png" alt="AdminLTE dashboard" width="760" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Checklist
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Install package using npm&lt;/li&gt;
&lt;li&gt;General instruction for integration themes&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Install application
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails new admin_lte_todo --skip-turbolinks
$ cd admin_lte_todo
$ rails g controller dashboard index

config/routes.rb
root 'dashboard#index'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Let’s install slim
&lt;/h1&gt;

&lt;p&gt;Usually, in development, I use &lt;a href="http://slim-lang.com/" rel="noopener noreferrer"&gt;slim&lt;/a&gt; as a templating language. So let’s install slim in our application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gemfile
gem 'slim-rails'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And change .erb templates to .slim. To make that we can use &lt;a href="https://github.com/slim-template/html2slim" rel="noopener noreferrer"&gt;html2slim utility&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bower Rails config
&lt;/h1&gt;

&lt;p&gt;1.Install bower using node package utility.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install -g bower`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Configure bower to install packages to valid /vendor path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.bowerrc
{
“directory” : “vendor/assets/components”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Initialize bower.json file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bower.json
{
“name”: “admin_lte_todo”, “dependencies”: {
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.Configure rails application to work with bower.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config/initializers/assets.rb
Rails.application.config.assets.paths &amp;lt;&amp;lt; Rails.root.join(‘vendor’, ‘assets’, ‘components’)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To deploy the application with bower’s assets, we can use &lt;a href="https://github.com/platanus/capistrano-bower" rel="noopener noreferrer"&gt;capistrano-bower&lt;/a&gt; gem.&lt;/p&gt;

&lt;h1&gt;
  
  
  Install AdminLTE with Bower
&lt;/h1&gt;

&lt;p&gt;Time to install &lt;a href="https://github.com/ColorlibHQ/AdminLTE" rel="noopener noreferrer"&gt;AdminLTE plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add AdminLTE to &lt;strong&gt;bower.json&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bower.json
"dependencies": {
  "admin-lte": "*"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of “*” you can set the latest release version. On the date of publishing, it was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bower.json
  "admin-lte": "2.3.6"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install AdminLTE plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ bower install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Node package manager
&lt;/h1&gt;

&lt;p&gt;Also, you can install AdminLTE template using &lt;strong&gt;Node package manager (npm)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;1.Initialize package.json file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Configure rails application to work with npm libs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config/initializers/assets.rb
Rails.application.config.assets.paths &amp;lt;&amp;lt; Rails.root.join(‘node_modules’) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To deploy the application with npm, use &lt;a href="https://github.com/capistrano/npm" rel="noopener noreferrer"&gt;capistrano/npm gem&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Install AdminLTE with NPM
&lt;/h1&gt;

&lt;p&gt;You should add dependencies to package.json file to install AdminLTE with NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package.json
"dependencies": {
  "admin-lte": "2.3.5"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Integrate AdminLTE assets to Rails application
&lt;/h1&gt;

&lt;p&gt;When integrating some template the first thing you should start with is dependencies configuration.&lt;/p&gt;

&lt;p&gt;For the AdminLTE theme, dependencies are described in the &lt;a href="https://adminlte.io/themes/AdminLTE/documentation/index.html#dependencies" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;They are &lt;a href="https://getbootstrap.com/docs/3.3/" rel="noopener noreferrer"&gt;Bootstrap 3&lt;/a&gt; and &lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt;. jQuery is installed by default in each Rails application and you can verify it in the default &lt;strong&gt;application.js&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application.js
//= require jquery
//= require jquery_ujs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s include Bootstrap 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application.js
//= require admin-lte/bootstrap/js/bootstrap

application.css
 *= require admin-lte/bootstrap/css/bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After including dependencies, we can include &lt;strong&gt;AdminLTE assets&lt;/strong&gt; to the project. Usually, template sources are stored in the &lt;code&gt;dist&lt;/code&gt; path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application.js
//= require admin-lte/dist/js/app.js

application.css
 *= require admin-lte/dist/css/AdminLTE
 *= require admin-lte/dist/css/skins/skin-blue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In AdminLTE &lt;code&gt;skins&lt;/code&gt; path saved the color theme for a template. One project can include any theme.&lt;/p&gt;

&lt;p&gt;After all the action we get the following assets files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application.js
//= require jquery
//= require jquery_ujs
//= require admin-lte/bootstrap/js/bootstrap
//= require admin-lte/dist/js/app.js

application.css
 *= require admin-lte/bootstrap/css/bootstrap
 *= require admin-lte/dist/css/AdminLTE
 *= require admin-lte/dist/css/skins/skin-blue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Integrate AdminLTE template
&lt;/h1&gt;

&lt;p&gt;For example, &lt;a href="https://adminlte.io/themes/AdminLTE/starter.html" rel="noopener noreferrer"&gt;use this link&lt;/a&gt; to integrate AdminLTE template.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;application.html&lt;/code&gt; file with the source code of starter page.&lt;br&gt;
Change &lt;code&gt;application.html.slim&lt;/code&gt; file using this template, for that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert &lt;code&gt;application.html&lt;/code&gt; to &lt;code&gt;application.html.slim&lt;/code&gt; using html2slim utility.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ html2slim app/views/layouts/application.html app/views/layouts/application.html.slim`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;2.Change header on &lt;code&gt;application.html.sli&lt;/code&gt; template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application.html.slim
    head
    title AdminLTE example
    = stylesheet_link_tag “application”, media: “all”
    = javascript_include_tag “application”
    = csrf_meta_tags
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Remove &lt;code&gt;app/views/layouts/application.html&lt;/code&gt; file.&lt;br&gt;
4.Remove scripts on end of &lt;code&gt;app/views/layouts/application.html.slim&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Now we can &lt;strong&gt;start rails server&lt;/strong&gt; and check AdminLTE rails template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At last, fixing icons and fonts. For this, add styles to &lt;code&gt;application.html.slim&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application.html.slim
= stylesheet_link_tag "https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"
= stylesheet_link_tag "http://code.ionicframework.com/ionicons/2.0.0/css/ionicons.min.css"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hallelujah! We integrated AdminLTE template to rails application.&lt;/p&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%2Fl7nsesgz8zf5iqjtm11h.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%2Fl7nsesgz8zf5iqjtm11h.png" width="760" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary and the best advice ever
&lt;/h1&gt;

&lt;p&gt;This tutorial will help you to install any bootstrap template. I took AdminLTE template integration as an example. To add bootstrap to rails you should set the following steps:&lt;br&gt;
1) install a package with some package manager,&lt;br&gt;
2) install and include dependencies,&lt;br&gt;
3) include template assets.&lt;/p&gt;

&lt;p&gt;And finally, the main advice from me is to &lt;strong&gt;read the documentation carefully&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It remains for me to wish you success in your work!&lt;/p&gt;




&lt;p&gt;&lt;a href="https://datarockets.com/blog/integration-rails-with-adminlte-template/" rel="noopener noreferrer"&gt;Easy integration Rails with AdminLTE template&lt;/a&gt; blog post was written by the datarockets' lead developer &lt;strong&gt;Roman Dubrovsky&lt;/strong&gt; for datarockets' blog. &lt;/p&gt;

</description>
      <category>rails</category>
      <category>npm</category>
    </item>
    <item>
      <title>Getting started with Kotlin for Android development</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Mon, 17 Aug 2020 18:49:10 +0000</pubDate>
      <link>https://forem.com/datarockets/getting-started-with-kotlin-for-android-development-16n7</link>
      <guid>https://forem.com/datarockets/getting-started-with-kotlin-for-android-development-16n7</guid>
      <description>&lt;p&gt;&lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin programming language&lt;/a&gt; now on everyone’s lips. Some people seriously considered it as a full-fledged replacement of Java in Android development. It is a modern, statically-typed language aimed at trying to make the code simpler and clearer for everyone and bring long-awaited Java features to Android developers. Let’s look at the history of that language, sort out the pros and cons of the language, as well as a look at an example and how you can start using Kotlin for Android development.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Kotlin was created and by whom
&lt;/h1&gt;

&lt;p&gt;Creating of language began in 2010 at &lt;a href="https://www.jetbrains.com/" rel="noopener noreferrer"&gt;JetBrains&lt;/a&gt; by two talented programmers – Andrew Breslav and Dmitry Zhemerov. These guys dreamed about removing those restrictions which are imposed on developers in Java 6: no streams, no lambda functions, no try-with-resources and etc. Kotlin creators wanted to invent null-safety language that could be more flexible and friendlier than Java. They provided a solution of so-called ‘one billion problem’: null by default. Many of these features have appeared only in the latest versions of Java but were implemented by Kotlin creators.&lt;/p&gt;

&lt;h1&gt;
  
  
  A slight dive into Kotlin syntax
&lt;/h1&gt;

&lt;p&gt;Starting to develop an Android application on Kotlin is not very difficult. Let’s see how the declaration of variables looks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var explicitName : String = "Kotlin" // Here we declare the type

var implicitName = "Kotlin" // In that case we declare a variable implicitly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin also allows you to declare immutable objects with keyword ‘val’.&lt;/p&gt;

&lt;p&gt;It’s time to tell you how null-safety in Kotlin works. In Java, when we need to check variable for null, we usually write block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (name != null) {
   name.length
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Kotlin, we can do the same thing in one line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name?.length
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s define the variable this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val name : String = null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler will generate an error – there should be at least some value. Since Kotlin considers itself as &lt;strong&gt;null-safety language&lt;/strong&gt;, that makes a bet on prevention of such situations during compilation.&lt;/p&gt;

&lt;p&gt;If you’re a fan of hardcore, it’s possible to compile the code, but I would not recommend to do it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val name: String!! = null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Collections
&lt;/h1&gt;

&lt;p&gt;If you had an experience with developing on Java, there is nothing special in Kotlin. I would say that Kotlin simplified everything for us again. Instead of &lt;code&gt;LinkedLists&lt;/code&gt; and &lt;code&gt;ArrayLists&lt;/code&gt;, we have &lt;code&gt;Lists&lt;/code&gt;, &lt;code&gt;Maps&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Kotlin allows us to define immutable lists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val list: List&amp;lt;String&amp;gt; = listOf("Kotlin", "is", "awesome")
list.add("though") // No such method, guys!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you decided to use a mutable list, you can use generic &lt;code&gt;MutableList&amp;lt;T&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val mutableList: MutableList&amp;lt;String&amp;gt; = mutableListOf("Kotlin", "is","awesome")
mutableList.add("though")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Methods
&lt;/h1&gt;

&lt;p&gt;Let’s write a simple method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun summarize(a: Int, b: Int) : Int {
return a + b
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first argument is the name of the parameter and then type. After the colon, we specify the return type, if required. Do not forget that Kotlin is very, very friendly, so with this elementary function, we can write it in one line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun summarize(a: Int, b: Int) : Int = a + b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin also provides an ability to use default parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun summarize(a: Int, b: Int = 20) : Int {
return a + b
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And yeah, you can write &lt;a href="https://kotlinlang.org/docs/reference/lambdas.html" rel="noopener noreferrer"&gt;lambda-expressions&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Classes
&lt;/h1&gt;

&lt;p&gt;Classes and methods in Kotlin are final by default. We can construct classes in two ways: with primary and secondary constructors. The primary class constructor is a part of a header. Also, it doesn’t have any code to execute. If we need to do some operations, we can use &lt;code&gt;init&lt;/code&gt; block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Cat(val name: String)  {
init {
println("We've just initialized Cat with ${name}")
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secondary constructor works, like in Java, without any difference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Dog: Animal {
constructor(name: String) {
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the &lt;code&gt;super&lt;/code&gt; method works like inheritance and it’s absolutely incredible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Cat : Animal {
constructor(name: String) : super(name) {
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Data-classes
&lt;/h1&gt;

&lt;p&gt;I’m sure, during development, you’re using &lt;strong&gt;POJO-objects&lt;/strong&gt; that don’t contain any specific logic. Kotlin creators decided to make developers satisfied and now you can submit your model as a data-class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data class Person(
val firstName: String,
val lastName: String
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all. All the necessary getters and setters are there by default.&lt;/p&gt;

&lt;p&gt;If you want to use data class, just make an instance by this construction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val person = Person("Paul", "Johnson")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also make changes based on an initialized instance of data class using the &lt;code&gt;copy&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val newPerson = person.copy(first_name="Carl")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Extension functions
&lt;/h1&gt;

&lt;p&gt;Extension functions is an incredible replacement of many Utils classes which may have been in the separate package. Are you familiar with monkey-patching in Ruby? In Kotlin, that feature is called &lt;strong&gt;extension function&lt;/strong&gt; and it provides an ability to shorten your code the easiest way. Let’s see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun Context.showMeToast(text: String) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have just replaced this ugly boilerplate construction with an elegant and short method.&lt;/p&gt;

&lt;h1&gt;
  
  
  Enough of these tutorial-like snippets! Let’s get to the real code!
&lt;/h1&gt;

&lt;p&gt;In March, within a few weeks, I wrote &lt;a href="https://github.com/datarockets/munchkin-counter-android" rel="noopener noreferrer"&gt;Munchkin Level Counter&lt;/a&gt; for use in the world-famous game. This app became rather &lt;a href="https://datarockets.com/case-studies/mlc/" rel="noopener noreferrer"&gt;popular on Google Play&lt;/a&gt;. I decided to build an application with the use of pattern proposed by Android-developer and Kotlin-lover, &lt;a href="https://antonioleiva.com/" rel="noopener noreferrer"&gt;Antonio Leiva&lt;/a&gt;, who demonstrated how to build an application in the MVP architecture. You will find a lot of useful things in his &lt;a href="https://github.com/antoniolg" rel="noopener noreferrer"&gt;repositories&lt;/a&gt;.&lt;br&gt;
It is even more reminiscent of VIPER popular architecture for developing iOS, which, in our version, deleted the letter R (Router).&lt;/p&gt;

&lt;p&gt;We are constantly improving our application to provide the best user experience. Added dependency injection to Dagger and transferred all the code on Kotlin. We plan to use &lt;strong&gt;RxJava&lt;/strong&gt; to eliminate the heaps of the implementation of interfaces that do not make the code elegant nor beautiful for the perception of any developer.&lt;/p&gt;

&lt;p&gt;Let’s see how &lt;code&gt;DashboardPresenter class&lt;/code&gt; looks before converting to Kotlin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DashboardPresenterImpl implements DashboardPresenter, DashboardInteractor.OnLoadPlayerListener {

   private DashboardView dashboardView;
   private DashboardInteractor interactor;

   public DashboardPresenterImpl(DashboardView dashboardView, DashboardInteractor interactor) {
       this.dashboardView = dashboardView;
       this.interactor = interactor;
   }

   @Override
   public void updatePlayerListItem(Player player, int position) {
       if (dashboardView != null) {
           interactor.updatePlayer(player, position, this);
       }
   }

   @Override
   public void onResume() {
       if (dashboardView != null) {
           interactor.loadPlayersList(this);
       }
   }

   @Override
   public void onFinished(ArrayList&amp;lt;Player&amp;gt; players) {
       if (dashboardView != null) {
           dashboardView.setItems(players);
       }
   }

   @Override
   public void onPlayerUpdated(Player player, int position) {
       if (dashboardView != null) {
           dashboardView.updatePlayerData(player, position);
       }
   }

   @Override
   public void onDestroy() {
       if (dashboardView != null) {
           dashboardView = null;
       }
   }

   @Override
   public void setGameFinished() {
       if (dashboardView != null) {
           interactor.setGameFinished();
       }
   }

   @Override
   public void insertStep(Player player) {
       if (dashboardView != null) {
           interactor.insertStep(player);
       }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that whenever we send the data through the presenter in the interactor, it works with business logic. If the user closes the application, and &lt;code&gt;Activity&lt;/code&gt; is destroyed, we can be sure that the callback interactor will not appeal to &lt;code&gt;DashboardView&lt;/code&gt; interface which will appeal to the reel to send data to the user’s screen (&lt;strong&gt;View&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;We have re-written this class in Kotlin. It can be achieved with a plug-in for Android Studio, made by JetBrains, and will automatically convert the code from Java to Kotlin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class DashboardPresenterImpl : DashboardPresenter, DashboardInteractor.OnLoadPlayerListener {

   private var interactor: DashboardInteractor
   private var dashboardView: DashboardView?

   constructor(dashboardView: DashboardView, interactor: DashboardInteractor) {
       this.dashboardView = dashboardView
       this.interactor = interactor
   }

   override fun updatePlayerListItem(player: Player, position: Int) {
       interactor.updatePlayer(player, position, this)
   }

   override fun onResume() {
       interactor.loadPlayersList(this)
   }

   override fun onFinished(players: ArrayList&amp;lt;Player&amp;gt;) {
       dashboardView?.setItems(players)
   }

   override fun onPlayerUpdated(player: Player, position: Int) {
       dashboardView?.updatePlayerData(player, position)
   }

   override fun onDestroy() {
       dashboardView = null
   }

   override fun setGameFinished() {
       interactor.setGameFinished()
   }

   override fun insertStep(player: Player) {
       interactor.insertStep(player)
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We were able to reduce the code by approximately 20 lines. We excluded checks at Null in three lines, which occupied an important place. When we turn to the interactor, we do not need to know about the status of the twist, so from this part of the code, it can be eliminated. It is much more important to know the state of the twist when we send a callback from interactor back to the presenter. We need to know the state of the twist and interface call methods that are implemented in the Activity code. As a result, the code looks cleaner, clearer and still performs its tasks.&lt;/p&gt;

&lt;p&gt;Let’s look at how we can &lt;strong&gt;improve the code in the Activity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We have an activity where we load game results in three fragments that display charts and a list of players with sorting by maximum points.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class GameResultActivity extends AppCompatActivity implements GameResultView {

   public static final String TAG = LogUtil.makeLogTag(GameResultActivity.class);

   private GameResultPresenter presenter;
   private Toolbar toolbar;
   private ViewPager vpCharts;
   private TabLayout tlChartsTitle;
   private ChartsPagerAdapter vpChartsAdapter;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       presenter = new GameResultPresenterImpl(this, this);
       setContentView(R.layout.activity_game_result);
       toolbar = (Toolbar) findViewById(R.id.toolbar);
       setSupportActionBar(toolbar);
       getSupportActionBar().setHomeButtonEnabled(true);
       getSupportActionBar().setDisplayHomeAsUpEnabled(true);
       presenter.onCreate();
   }

   @Override
   public void loadChartFragments() {
       vpCharts = (ViewPager) findViewById(R.id.vp_charts);
       vpChartsAdapter = new ChartsPagerAdapter(getSupportFragmentManager(), this);
       vpCharts.setAdapter(vpChartsAdapter);
       vpCharts.setOffscreenPageLimit(3);
       tlChartsTitle = (TabLayout) findViewById(R.id.tl_charts_title);
       tlChartsTitle.setupWithViewPager(vpCharts);
   }

   @Override
   protected void onResume() {
       super.onResume();
   }

   @Override
   public void onBackPressed() {
       super.onBackPressed();
       presenter.onBackPressed();
       Intent intent = new Intent(this, PlayersListActivity.class);
       startActivity(intent);
       finish();
   }

   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
       switch (item.getItemId()) {
           case android.R.id.home:
               onBackPressed();
               return true;
           default:
               break;
       }
       return false;
   }

   @Override
   protected void onStop() {
       super.onStop();
       presenter.onStop();
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see how an &lt;strong&gt;Activity&lt;/strong&gt; can look in Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class GameResultActivity : AppCompatActivity(), GameResultView {

   companion object {
       val TAG = LogUtil.makeLogTag(GameResultActivity::class.java)
   }

   private val toolbar by lazy { findViewById(R.id.toolbar) as Toolbar? }
   private val vpCharts by lazy { findViewById(R.id.vp_charts) as ViewPager? }
   private val tlChartsTitle by lazy { findViewById(R.id.tl_charts_title) as TabLayout? }
   private val vpChartsAdapter: ChartsPagerAdapter = ChartsPagerAdapter(supportFragmentManager, this)

   private val presenter: GameResultPresenter = GameResultPresenterImpl(this, this)

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_game_result)
       setSupportActionBar(toolbar)
       supportActionBar?.setHomeButtonEnabled(true)
       supportActionBar?.setDisplayHomeAsUpEnabled(true)
       presenter.onCreate()
   }

   override fun loadChartFragments() {
       vpCharts?.adapter = vpChartsAdapter
       vpCharts?.offscreenPageLimit = 3
       tlChartsTitle?.setupWithViewPager(vpCharts)
   }

   override fun onBackPressed() {
       super.onBackPressed()
       presenter.onBackPressed()
       val intent = Intent(this, PlayersListActivity::class.java)
       startActivity(intent)
       finish()
   }

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
       when (item.itemId) {
           android.R.id.home -&amp;gt; {
               onBackPressed()
               return true
           }
       }
       return false
   }

   override fun onStop() {
       super.onStop()
       presenter.onStop()
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s look what we have changed.&lt;/p&gt;

&lt;p&gt;First, we have transferred the entire boilerplate-code &lt;code&gt;findViewById View&lt;/code&gt; element code of the overridden method onCreate in properties, where we presented our view-components as “lazy” field. What does this mean? It means initialization happens as soon as we turn to this field in the &lt;code&gt;onCreate&lt;/code&gt;. Second, we have transferred initialization of presenter and adapter for &lt;code&gt;ViewPager&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  But how we can make it much better?
&lt;/h1&gt;

&lt;p&gt;We can simply use &lt;strong&gt;Butterknife&lt;/strong&gt;. There are no big changes in comparison with standard Android development with Java.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private val toolbar by bindView(R.id.toolbar)
private val vpCharts by bindView(R.id.vp_charts)
private val tlChartsTitle by bindView(R.id.tl_charts_title)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks better! Let’s see what Kotlin offers us to work with creating layouts.&lt;/p&gt;

&lt;h1&gt;
  
  
  Anko
&lt;/h1&gt;

&lt;p&gt;Typically, Android developers have to write their views in the form of the XML markup. The parsing of XML-markup spent processor resources which caused the applications to load each activity a little longer. Usage of &lt;strong&gt;Anko DSL&lt;/strong&gt; with Kotlin gives an enormous advantage. We can simply turn XML markup in domain-specific language provided by Anko.&lt;/p&gt;

&lt;h1&gt;
  
  
  Kotlin in action
&lt;/h1&gt;

&lt;p&gt;Kotlin already being used in production. In May, I was able to listen to the presentation of two developers from the Belarusian startup, &lt;a href="https://sudonull.com/post/232843-Juno-startup-with-a-development-office-in-Minsk-sells-for-250-million" rel="noopener noreferrer"&gt;Juno&lt;/a&gt;. They built its application in a new language. What interesting things did uncover? What is their stack? &lt;/p&gt;

&lt;p&gt;First, their application is made in the &lt;strong&gt;MVVM-architecture&lt;/strong&gt;. Second, they use &lt;strong&gt;Dagger2, RxKotlin, Retrofit and Gson&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The developers claim that they don’t completely use for-loops because of RxKotlin. Spek helps them to unit test their code.&lt;/p&gt;

&lt;h1&gt;
  
  
  What’s next?
&lt;/h1&gt;

&lt;p&gt;The developers of Kotlin are constantly improving their language to provide the best experience to developers. For now, we can say that the goals which have been set at the beginning of the development of Kotlin have been achieved. Kotlin makes you write a better, cleaner and safer code, provides long-awaited Java features, and lets you use Java-code along with Kotlin.&lt;/p&gt;

&lt;p&gt;These are the pros, but we have cons too: compile time is a little bit longer than in Java and some libraries are not compatible with Kotlin. But it’s not a serious issue because the most popular libraries are used by developers from all over the world. So, it is a great choice to start using Kotlin for Android development now.&lt;/p&gt;

&lt;p&gt;The article about &lt;a href="https://datarockets.com/blog/start-using-kotlin-for-android-development/" rel="noopener noreferrer"&gt;Kotlin for mobile app development&lt;/a&gt; was originally written by former datarockets' mobile developer &lt;strong&gt;Dmitry Chyrta&lt;/strong&gt; for datarockets' blog&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
      <category>java</category>
    </item>
    <item>
      <title>Object-Oriented Views in Rails</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Mon, 17 Aug 2020 18:27:38 +0000</pubDate>
      <link>https://forem.com/datarockets/object-oriented-views-in-rails-133n</link>
      <guid>https://forem.com/datarockets/object-oriented-views-in-rails-133n</guid>
      <description>&lt;p&gt;Views can be organized in Rails applications with many different user roles. This is the story of one refactoring.&lt;/p&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%2F98r5imchd5c65aczqzot.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%2F98r5imchd5c65aczqzot.png" width="760" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Story
&lt;/h1&gt;

&lt;p&gt;We were building a CRM app responsible for collecting orders from e-commerce sites across the internet. The system had 5 different user roles, including admins, shipping managers, and call operators.&lt;/p&gt;

&lt;p&gt;Each order could be marked as one of 8 statuses. When an order came to our system, its status was “new.” The order was “confirmed” when the call operator contacted the customer and was “shipped” when the shipping manager sent the items to the customer.&lt;/p&gt;

&lt;p&gt;A lot of data was attached to each order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Order &amp;lt; ActiveRecord::Base
  has_one :customer_information
  has_one :clarification
  has_one :cart
  has_one :shipping
  # and more
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It had 8 separate components with information from the customer or added by users. With 5 user roles, 8 order statuses, and 8 order components, we had to display orders to each user role differently. Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.order
  .order__header
    .order_id = order.id
    - if current_user.admin?
      .order__state = render('orders/editable_state_field')
    - elsif current_user.call_operator?
      .order__state = order.state
      .order__created-at = order.created_at
      .order__confirmed-at = order.confirmed_at
    - elsif current_user.shipping_manager?
      .order__state = order.state
      .order__shipped-at = order.shipped_at
  .order__body
    / }:]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specific roles were allowed to see specific order components. The shipping manager, for example, shouldn’t see the call log from the call operator. The call operator should see the call log, but only an administrator had the ability (and a button in the UI) to listen to each call.&lt;/p&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%2Fhscm28spy34l231b8lxz.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%2Fhscm28spy34l231b8lxz.png" width="760" height="435"&gt;&lt;/a&gt;&lt;br&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%2Farrm95m19zczurnaxblu.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%2Farrm95m19zczurnaxblu.png" width="760" height="393"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  First solution
&lt;/h1&gt;

&lt;p&gt;Our first solution was to create a separate namespaced controller for each role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Admin::OrdersController &amp;lt; ApplicationController
  include Orders::CommonActions
  include Orders::EditActions
end

class CallOperator::OrdersController &amp;lt; ApplicationController
  include Orders::CommonActions
end

class ShippingManager::OrdersController &amp;lt; ApplicationController
  include Orders::CommonActions
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we could write separate templates for each role:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app/views/admin/orders/index.html.slim&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;app/views/call_operator/orders/index.html.slim&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;We duplicated a lot of the common template code, but we could code unique parts without including tons of “if” statements. Duplications are better than untraceable conditions, but they are still not perfect.&lt;/p&gt;

&lt;p&gt;We were constantly looking for possible solutions.&lt;/p&gt;
&lt;h1&gt;
  
  
  Rails don’t help much here
&lt;/h1&gt;

&lt;p&gt;There are not many tools to work with templates in Rails. We can use helpers to remove complex logic from our templates. Partials help us reduce duplication.&lt;/p&gt;

&lt;p&gt;Helpers are hard to use since they are all in the global namespace. So you may end up with name collisions. We only have 27 helper methods in the project:&lt;/p&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%2Fg581i38gijigowmz2025.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%2Fg581i38gijigowmz2025.png" width="770" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Partials are very useful, but they didn’t help in our case. Even with partials, we had to write a lot of conditions.&lt;/p&gt;

&lt;p&gt;There are even more options to deal with view complexity, including decorators, view model, and more.&lt;/p&gt;

&lt;p&gt;Using decorated models in templates is almost always a bad idea. Developers often add HTML generation code to decorator methods, but it doesn’t make the code clearer. Sometimes it’s hard to choose where to put a particular method: in the decorator or in the model. There are no clear boundaries.&lt;/p&gt;

&lt;p&gt;The view model pattern looks really good, but we didn’t have a chance to try it with real code. We’re not sure it could help us avoid conditionals in the views.&lt;/p&gt;
&lt;h1&gt;
  
  
  View ≠ Template
&lt;/h1&gt;

&lt;p&gt;One day we discovered &lt;a href="https://trailblazer.to/2.0/gems/cells/" rel="noopener noreferrer"&gt;cells&lt;/a&gt;: a library for Rails views. This brings a new approach to writing views. What Rails offers us as views and what we put in the app/views folder aren’t really views but templates. Views are not equal to templates. Cells give us a way to write real views.&lt;/p&gt;

&lt;p&gt;Let’s define a view as an object with the public method “show,” which returns a string — html — result of “rendering” this view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Order::Cell &amp;lt; Cell::Concept
  def show
    render("show.slim")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;#render&lt;/code&gt; method is provided by the cells library. It renders a slim file located in the &lt;code&gt;“views”&lt;/code&gt; folder, which is funny because it should really be called &lt;code&gt;“templates”&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app
`--concepts
   `--order
      |--views
      |  `--show.slim
      `--cell.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can initialize the view with the objects you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Order:Cell &amp;lt; Cell::Concept
  attr_reader :order

  def initialize(order)
    @order = order
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In templates, we can call methods of our view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time datetime=#{date}
  = formatted_date

class Order::Cell &amp;lt; Cell::Concept
  private

  def date
    order.created_at
  end

  def formatted_date
    date.strftime('%F, %H:%M')
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the most important part. Since “views” is just a Ruby object, we know how to deal with it. We have a lot of experience and a powerful arsenal of patterns and OOP best practices.&lt;/p&gt;

&lt;p&gt;One of the most powerful of these patterns is inheritance. Since “views” is an OOP class, we can override some methods or HTML templates for child views.&lt;/p&gt;

&lt;h1&gt;
  
  
  How views help
&lt;/h1&gt;

&lt;p&gt;Let’s use an example from our project. We had to show each user different things for each order status. So we moved this template into “views” and split it into smaller templates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--order
  |--views
  |  |--partials
  |  |  `--status_history.slim
  |  |  `--calls_history.slim
  |  |  `--cart.slim
  |  |  `--contact_information.slim
  |  |  `--shipping.slim
  |  `--show.slim
  `--cell.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ show.slim

= render(‘partials/status_history.slim’)
= render(‘partials/calls_history.slim’)
= render(‘partials/contact_information.slim’)
= render(‘partials/cart.slim’)
= render(‘partials/shipping.slim’)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine that the admin can see the full history of status changes but the call operator can only see a few changes. For example, the call operator doesn’t care when the order moved from “shipped” to “delivered”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ status_history.slim

- transactions.each do |transaction|
  p #{transaction.from} → #{transaction.to} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We created a separate view for the call operator inherited it from the order view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--call_operator
  `--order
     `--cell.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CallOperator::Order::Cell &amp;lt; Order::Cell
  def transactions
    order.transactions.select do |transaction|
      # ...
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we did not rewrite the templates; we inherited them from the parent view.&lt;/p&gt;

&lt;p&gt;Since we can inherit templates, we can also redefine them, which is a very convenient feature. For example, the call operator can change the shipping address for an order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ order/views/partials/shipping.slim

p = shipping_address.address_line_1

/ call_operator/order/views/partials/shipping.slim

= form_for shipping_address do |f|
  = f.input :address_line_1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Let’s make it together
&lt;/h1&gt;

&lt;p&gt;To render the correct view, we can write a simple factory method &lt;code&gt;.build&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Order::Cell &amp;lt; Cell::Concept
  def self.build(order, current_user)
    selected_view_for(order, current_user).new(order)
  end

  def self.selected_view_for(order, current_user)
    if current_user.call_operator?
      {
        “new” =&amp;gt; CallOperator::Order::Cell,
        “shipping” =&amp;gt; CallOperator::ShippingOrder::Cell
      }[order.state]
    elsif current_user.admin?
      {
        “new” =&amp;gt; Admin::Order::Cell,
        “shipping” =&amp;gt; Admin::ShippingOrder::Cell
      }[order.state]
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So in our Rails templates, we can write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ app/views/order/show.slim

= Oder::Cell.build(order, current_user).show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Cells
&lt;/h1&gt;

&lt;p&gt;To introduce the concept of views and describe how they are different from templates, we didn’t use all the available APIs in the cells library. You can read more about cells on the &lt;a href="https://trailblazer.to/2.0/gems/cells/" rel="noopener noreferrer"&gt;official site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The cells library allows us to encapsulate parts of the UI into views. You can work with views as simple Ruby classes, which gives you more than a template rendering. Views enable OOP: you can make them polymorphic and use well-known OOP patterns.&lt;/p&gt;

&lt;p&gt;Cells help you build views. Some base views may also be reusable and transferable between projects, which is a different topic.&lt;/p&gt;

&lt;h1&gt;
  
  
  Other solutions
&lt;/h1&gt;

&lt;p&gt;There are some other similar solutions that can help us write real views, but unfortunately, we haven’t investigated them yet since they are pretty new and we didn’t know about them two years ago. They’re worth looking at, though:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. [Hanami views](https://github.com/hanami/view)
2. [Dry views](https://github.com/dry-rb/dry-view)
3. [React components](https://reactjs.org/docs/components-and-props.html)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;How do you deal with views complexity?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datarockets.com/blog/object-oriented-views-in-rails/" rel="noopener noreferrer"&gt;Object-Oriented Views in Rails&lt;/a&gt; was originally written by the CTO of datarockets Dmitry Zhlobo and lead developer Roman Dubrovsky for datarockets' blog.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
    </item>
    <item>
      <title>8 rules to stay strong remote team</title>
      <dc:creator>Yuliya Haranok</dc:creator>
      <pubDate>Wed, 12 Aug 2020 17:09:31 +0000</pubDate>
      <link>https://forem.com/datarockets/8-rules-to-stay-strong-remote-team-17e2</link>
      <guid>https://forem.com/datarockets/8-rules-to-stay-strong-remote-team-17e2</guid>
      <description>&lt;p&gt;Despite the fact that our &lt;a href="https://datarockets.com/capabilities/" rel="noopener noreferrer"&gt;web and mobile development team&lt;/a&gt; works remotely from 9 countries in 5 different time zones and up to 7 hours difference, we still don’t have any problems in team collaboration and efficiency. In fact, we always receive wonderful feedback about our work style and processes. Since 2014, we have been experimenting with different processes, tools, rules, traditions, and styles for continuous improvements. It has resulted in a system which we want to share with our readers. Next, we shared 8 remote work rules that datarockets team follows.&lt;/p&gt;

&lt;h1&gt;
  
  
  Proactive communication
&lt;/h1&gt;

&lt;p&gt;Proactive communication brings a lot of value to the team. We don’t need to waste our time synchronizing with each other. Every teammate knows exactly what others are working on. We achieve it by &lt;strong&gt;sharing intermediate results in chats and comments under tasks&lt;/strong&gt;. Apart from this, we also share our thoughts and decisions we make. This helps us stay on one page with our teammates and clients, who also work in different time zones and can easily review our updates at their most convenience.&lt;/p&gt;

&lt;p&gt;Additionally, when talking about the problems out loud (in our case – in the chat), someone who has experienced a similar situation can be aware of your struggles and offer help to solve it faster. At the same time, you don’t disturb anybody from their work. People can read your note when they are available without getting distracted. We believe this is the main advantage of working remotely.&lt;/p&gt;

&lt;h1&gt;
  
  
  Public chats
&lt;/h1&gt;

&lt;p&gt;Creating an environment that promotes natural information flow through communication can be challenging. Due to the nature of remote work, physical interaction is not possible. &lt;/p&gt;

&lt;p&gt;As such, &lt;strong&gt;we achieve that by using public channels on Slack, instead of private or direct messages&lt;/strong&gt;. We never discuss work-related questions in direct messages and don’t hide anything. We add clients to our public chats and consider them as part of our team. No matter what we want to post, from an important update to a casual new meme, it should always be in the public chats, so everyone knows what’s going on with the projects and can also enjoy the funny pics.&lt;/p&gt;

&lt;p&gt;In order to track the usage of private and public channels, we use Slack’s basic analytics.&lt;/p&gt;

&lt;h1&gt;
  
  
  Post call summary
&lt;/h1&gt;

&lt;p&gt;A lot of people blame remote work for not being able to interact with their teammates which causes the loss of information. In reality, you may even lose more information at the office where verbal conversations are never documented and can’t be reproduced. &lt;/p&gt;

&lt;p&gt;If it’s necessary to have a verbal discussion, then &lt;strong&gt;a summary of the conversation is required to be updated in the chat&lt;/strong&gt;. Usually, we have video calls for planning meetings, retrospective meetings, weekly standups, or pair programming sessions. Every time we discuss something, we immediately share the highlights or essential insights with the whole team.&lt;/p&gt;

&lt;h1&gt;
  
  
  Weekly project updates
&lt;/h1&gt;

&lt;p&gt;We have an established tradition to &lt;strong&gt;post weekly project updates&lt;/strong&gt; at the beginning of a working week on Slack in the #general channel. Such updates allow team members to know more about the projects our company works on, our recent achievements, and indicate if someone needs help.&lt;/p&gt;

&lt;p&gt;We usually use bots to make up these updates. For instance, when a person starts their working week on Monday, they share updates with the bot. When all project members share their updates, the bot publishes them to the public channel. &lt;/p&gt;

&lt;h1&gt;
  
  
  Non-work stuff channels
&lt;/h1&gt;

&lt;p&gt;When working remotely, people often miss simple communications. They can’t have small talk while drinking coffee or discuss the movie they have watched on the weekend. To overcome this obstacle, we have intentionally designed spaces for casual conversations in our Slack, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;animal_therapy — we share photos of our cute pets,&lt;/li&gt;
&lt;li&gt;cooking — photos of the food we cook. Sometimes we guess what others are cooking from the photo of just the ingredients 🙂&lt;/li&gt;
&lt;li&gt;ihateremotework — support each other during the pandemic, while we can’t work from the coffeeshops, co-working spaces or other public places,&lt;/li&gt;
&lt;li&gt;media — share music we love,&lt;/li&gt;
&lt;li&gt;playground — play computer games together.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these non-work stuff channels have helped us strengthen the culture within our remote team. We believe it is crucial enough and recommend having them to make the remote work more engaging and enjoyable. &lt;/p&gt;

&lt;h1&gt;
  
  
  Company weekly check-in
&lt;/h1&gt;

&lt;p&gt;Once a week, we have an informal call on Zoom – we name it check-in. Check-in is a &lt;strong&gt;1-hour meeting within the teammates&lt;/strong&gt; where we discuss personal updates and talk about non-work stuff like books, films, kids, hobbies, cooking, etc. It has helped us get to know each other better and turned our work team into a close-knit family. Indeed, even the members’ pets join our call. They grab our attention and create a lot of funny situations during the check-ins.&lt;/p&gt;

&lt;h1&gt;
  
  
  “Good morning” rule
&lt;/h1&gt;

&lt;p&gt;As we work in different time zones, it’s hard to tell when others are available. Our solution is to &lt;strong&gt;send a greeting message on Slack whenever we start a workday&lt;/strong&gt;. We call it the “Hello” rule. It helps the rest of the team and our clients understand when we start and finish our day. Sometimes, it can get pretty creative. For example, instead of only saying ‘hi/hello’, we share the weather from the places we are located in 🙂&lt;/p&gt;

&lt;p&gt;A "good night" message could be a good add-on to let the team know when your day has ended. Moreover, if you receive notifications after you officially finished working, you won’t be frustrated and may feel more comfortable not answering them until tomorrow 🙂 &lt;/p&gt;

&lt;h1&gt;
  
  
  Metrics evaluation
&lt;/h1&gt;

&lt;p&gt;At datarockets, we &lt;a href="https://datarockets.com/blog/team-performance-metrics/" rel="noopener noreferrer"&gt;evaluate team performance and personal metrics&lt;/a&gt;. These metrics work as a reflection tool and help us monitor the company “health”. In the beginning, it was implemented to care about our team members by asking how they felt and providing specific personalized feedback to help increase individual growth. Eventually, it has empowered a much stronger relationship within the team and become one of the keys to datarockets’ today success.&lt;/p&gt;

&lt;p&gt;Every week, we go through these metrics and reflect on how the last week has passed, evaluate our satisfaction and check important metrics such as “proactive communication”, “sharing knowledge”, “professional growth”, “goals completion”, etc.&lt;/p&gt;

&lt;p&gt;These metrics help our managers provide valuable feedback, reveal issues, and react fast. For the team, it’s a safe place to share their concerns and acknowledge their weaknesses, which results in personal growth. &lt;/p&gt;

&lt;h1&gt;
  
  
  Remote work is awesome
&lt;/h1&gt;

&lt;p&gt;Remote work brings a lot of advantages and satisfaction as long as the processes are well defined. The rules we have described above work perfectly for our team size and &lt;a href="https://datarockets.com/blog/transparent-development-process/" rel="noopener noreferrer"&gt;transparent development values&lt;/a&gt;. However, there are other ways of how remote work processes can be implemented. We suggest you experiment with different solutions and tools, discuss it with your team, and allow them to participate in setting up the process since they will be required to follow it after all.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://datarockets.com/blog/8-rules-of-strong-remote-team/" rel="noopener noreferrer"&gt;remote work rules&lt;/a&gt; post was originally published in the datarockets blog.&lt;/p&gt;

</description>
      <category>remote</category>
      <category>startup</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
