Ognjen Regoje • ognjen.ioJekyll2024-01-28T18:25:13+08:00https://ognjen.io/Ognjen Regojehttps://ognjen.io/me@ognjen.iohttps://ognjen.io/tracking-cursor-in-selenium2024-01-27T00:00:00+08:002024-01-27T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>From the links in the sources, the following code snippet can be used to track the cursor:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><style></span>
<span class="nc">.dot</span> <span class="p">{</span>
<span class="nl">background</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span>
<span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span>
<span class="nl">width</span><span class="p">:</span> <span class="m">2px</span><span class="p">;</span>
<span class="nl">height</span><span class="p">:</span> <span class="m">2px</span><span class="p">;</span>
<span class="nl">z-index</span><span class="p">:</span> <span class="m">10000</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt"></style></span>
</code></pre></div></div>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">use strict</span><span class="dl">"</span><span class="p">;</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">onmousemove</span> <span class="o">=</span> <span class="nx">handleMouseMove</span><span class="p">;</span>
<span class="kd">function</span> <span class="nf">handleMouseMove</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">dot</span><span class="p">,</span> <span class="nx">eventDoc</span><span class="p">,</span> <span class="nx">doc</span><span class="p">,</span> <span class="nx">body</span><span class="p">,</span> <span class="nx">pageX</span><span class="p">,</span> <span class="nx">pageY</span><span class="p">;</span>
<span class="nx">event</span> <span class="o">=</span> <span class="nx">event</span> <span class="o">||</span> <span class="nb">window</span><span class="p">.</span><span class="nx">event</span><span class="p">;</span> <span class="c1">// IE-ism</span>
<span class="c1">// If pageX/Y aren't available and clientX/Y</span>
<span class="c1">// are, calculate pageX/Y - logic taken from jQuery</span>
<span class="c1">// Calculate pageX/Y if missing and clientX/Y available</span>
<span class="k">if </span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">pageX</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">&&</span> <span class="nx">event</span><span class="p">.</span><span class="nx">clientX</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">eventDoc</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">target</span> <span class="o">&&</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">ownerDocument</span><span class="p">)</span> <span class="o">||</span> <span class="nb">document</span><span class="p">;</span>
<span class="nx">doc</span> <span class="o">=</span> <span class="nx">eventDoc</span><span class="p">.</span><span class="nx">documentElement</span><span class="p">;</span>
<span class="nx">body</span> <span class="o">=</span> <span class="nx">eventDoc</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">pageX</span> <span class="o">=</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">clientX</span> <span class="o">+</span>
<span class="p">((</span><span class="nx">doc</span> <span class="o">&&</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">scrollLeft</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="nx">body</span> <span class="o">&&</span> <span class="nx">body</span><span class="p">.</span><span class="nx">scrollLeft</span><span class="p">)</span> <span class="o">||</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-</span>
<span class="p">((</span><span class="nx">doc</span> <span class="o">&&</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">clientLeft</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="nx">body</span> <span class="o">&&</span> <span class="nx">body</span><span class="p">.</span><span class="nx">clientLeft</span><span class="p">)</span> <span class="o">||</span> <span class="mi">0</span><span class="p">);</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">pageY</span> <span class="o">=</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">clientY</span> <span class="o">+</span>
<span class="p">((</span><span class="nx">doc</span> <span class="o">&&</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">scrollTop</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="nx">body</span> <span class="o">&&</span> <span class="nx">body</span><span class="p">.</span><span class="nx">scrollTop</span><span class="p">)</span> <span class="o">||</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-</span>
<span class="p">((</span><span class="nx">doc</span> <span class="o">&&</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">clientTop</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="nx">body</span> <span class="o">&&</span> <span class="nx">body</span><span class="p">.</span><span class="nx">clientTop</span><span class="p">)</span> <span class="o">||</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// Add a dot to follow the cursor</span>
<span class="nx">dot</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">"</span><span class="s2">div</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">dot</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">dot</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">dot</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">pageX</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">px</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">dot</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">top</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">pageY</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">px</span><span class="dl">"</span><span class="p">;</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">dot</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">})();</span>
</code></pre></div></div>
<p>You can then wrap that into a helper that you can call in your test. You can just <code class="language-plaintext highlighter-rouge">page.execute_script(helper_js)</code> and you can inject the CSS similarly.</p>
<p>Then <code class="language-plaintext highlighter-rouge">binding.pry</code> after that’s done and move the cursor around to get the correct offsets.</p>
<p>Note that if you add this javascript snippet <em>hover</em> will no longer trigger on your elements because a new <code class="language-plaintext highlighter-rouge">dot</code> element will always be under the cursor.</p>
<p><a href="https://ognjen.io/tracking-cursor-in-selenium/">Tracking the cursor in Selenium driven Chrome</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 27, 2024.</p>https://ognjen.io/do-forgettable-work2024-01-27T00:00:00+08:002024-01-27T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p><a href="https://taylor.town/do-unforgettable-work">There was a great post about doing unforgettable work.</a> Absolutely. Go above and beyond. <a href="/do-whats-right">Do what’s right.</a></p>
<p>But also, do forgettable work. Work that you won’t remember the following week.</p>
<p>Do a lot of it.</p>
<p>In fact, do at least 30 minutes of utterly forgettable work on something you’re trying to improve every day.</p>
<p>Very soon it’ll stop being forgettable.</p>
<p><a href="https://ognjen.io/do-forgettable-work/">Do forgettable work</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 27, 2024.</p>https://ognjen.io/system-design-interviews-are-about-design2024-01-20T00:00:00+08:002024-01-20T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Over the past year or so I’ve done about two dozen systems design interviews (as an interviewer) and have two somewhat subtle observations that would help some candidates.</p>
<h2 id="1-the-word-system-has-two-meanings">1. The word <em>system</em> has two meanings</h2>
<p>The definition most engineers reach for immediately is the one relating to computers.</p>
<p><strong>But the organization itself is a system, in a generic meaning of the word.</strong></p>
<p>It’s important to consider the organization for two reasons:</p>
<h3 id="1-its-structure-informs-the-computer-systems">1. Its structure informs the computer systems</h3>
<p>Boundaries between domains are often strong indicators that boundaries between computer systems should also exist. <a href="https://en.wikipedia.org/wiki/Conway%27s_law">Conway’s law</a> and all that.</p>
<h3 id="2-tech-exists-in-service-of-the-business">2. Tech exists in service of the business</h3>
<p>Putting systems in the context of the orga demonstrates the understanding that business requirements take precedence over technical convenience.</p>
<p>These two considerations get considerably more important with seniority.</p>
<p>While junior developers often don’t consider the organization, their area of influence is local so it’s not too relevant to their everyday work.</p>
<p>On the other hand, staff+ engineers who are supposed to influence entire domains or even the whole organization must understand this.</p>
<h2 id="2-the-interview-is-about-design">2. The interview is about design</h2>
<p>Several candidates shy away from <em>designing</em> a system using tech they theoretically know about but wouldn’t be able to <em>implement</em> themselves.</p>
<p>It mostly happens to senior engineers who are in a transitionary phase to staff where they have a wide overview of tech and understand much of the implications to the organization. They have an overview of a lot of tech and can discuss tradeoffs. But, they do not have hands-on experience in all of them.</p>
<p>Secondly, candidates often don’t appreciate that design is iterative. As the interview progresses the experienced engineer re-evaluates assumptions, re-checks constraints and iterates. Components are changed, replaced or removed entirely. The less experienced candidates typically just add components.</p>
<p>And finally, design is about trade-offs. What are you willing to sacrifice and, most importantly, why? As you’re making trade-offs it’s the process you go through to make the call that’s being evaluated.</p>
<p><a href="https://ognjen.io/system-design-interviews-are-about-design/">As silly as it sounds, system design interviews are about systems and design</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 20, 2024.</p>https://ognjen.io/ddd-from-ecommerce2024-01-19T00:00:00+08:002024-01-19T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>In a recent conversation with some colleagues, we were talking about how startups make the trade-off between design, domain-driven specifically, in favor of speed. They intentionally take on debt, technical and otherwise, to move faster.</p>
<p>I wasn’t in favour of employing DDD in a startup because it’s expensive and slow for a small system. There comes a time when the startup code needs to transition into enterprise DDD-style code, but I think it can be made if and when necessary.</p>
<p>After the conversation, I thought about the shortcuts I took building <a href="/projects/supplybunny">Supplybunny</a> but noticed a few things that I did that were DDD-like.</p>
<p>E-commerce as a domain seems to encourage the same practices that DDD advocates for.</p>
<h2 id="ubiquitous-language">Ubiquitous language</h2>
<p>When we started Supplybunny I knew little about the food and beverage industry. That’s what prompted me to <a href="https://themarketplace.guide/learn-the-correct-jargon-and-be-consistent">learn the jargon</a>.</p>
<p>Besides, the different <em>actors</em> used different language. For instance, a supplier would call a product an “SKU”, while a buyer would call it an “ingredient”. A supplier would care about an order and a logistics partner would care about a delivery or shipment.</p>
<p>The difference in language made it plenty clear that there were different contexts at play even if I wasn’t intentionally trying to separate them.</p>
<h2 id="bounded-contexts">Bounded contexts</h2>
<p>In e-commerce bounded contexts are clearer than in most other domains.</p>
<p>There is a public search for which you don’t need to log in.</p>
<p>The way a supplier and a buyer interact with orders and the information they need to see is different.</p>
<p>On the admin side, <a href="https://themarketplace.guide/each-job-should-have-a-custom-dashboard">different departments need to see different things</a>: logistics don’t care about customer support information, and vice versa.</p>
<h2 id="aggregates">Aggregates</h2>
<p>A big part of e-commerce is dealing with the financial aspect of it. A key part of that is that the order information must be isolated and not change as a result of changes elsewhere.</p>
<p>For instance, the product name in an order item, the supplier address in the invoice, and the delivery charge.</p>
<p>Not only that, but several fields have multiple values. Take, for instance, the delivery charge: one amount is shown to the buyer, one to the supplier, one to the admin, and one might be sent to an external provider.</p>
<p>And not just that, but each of these must be independently traceable - that is, you must be able to generate an account statement for each of those actors.</p>
<p>This naturally encourages duplication and isolation of data.</p>
<p>Two patterns I used to manage that were the <a href="https://ognjen.io/functional-model-pattern/">functional model</a> and the <a href="https://ognjen.io/actor-model-pattern/">actor model</a>.</p>
<p>All these requirements naturally lead to clearer boundaries between contexts.</p>
<p><a href="https://ognjen.io/ddd-from-ecommerce/">Lessons in DDD from building an e-commerce platform</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 19, 2024.</p>https://ognjen.io/using-robots-txt-to-discover-hidden-content2024-01-13T00:00:00+08:002024-01-13T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>I sometimes check the <code class="language-plaintext highlighter-rouge">robots.txt</code> of sites to see what they might not want to be indexed.</p>
<p>It’s interesting because some sites use it as access control, which, of course, is silly. Just because robots won’t index it doesn’t mean people won’t find it. Plus, by specifying it in robots, you’re making it easier for humans to discover.</p>
<p>Pr0-tip: instead of adding content to <code class="language-plaintext highlighter-rouge">robots.txt</code> to prevent indexing, use <code class="language-plaintext highlighter-rouge">noindex</code> in the <code class="language-plaintext highlighter-rouge">meta</code> tag.</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><meta</span> <span class="na">name=</span><span class="s">"robots"</span> <span class="na">content=</span><span class="s">"noindex"</span> <span class="nt">/></span>
</code></pre></div></div>
<p><a href="https://ognjen.io/using-robots-txt-to-discover-hidden-content/">Using robots.txt to discover hidden content</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 13, 2024.</p>https://ognjen.io/do-whats-right2024-01-13T00:00:00+08:002024-01-13T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Doing what’s right is so interesting.</p>
<h3 id="its-so-difficult">It’s so difficult</h3>
<p>It’s difficult to be completely honest with yourself when you know what’s right but you don’t want to do it.</p>
<p>It’s often physically more difficult: you’ll have to spend more effort, more time, more money.</p>
<h3 id="but-its-so-easy">But it’s so easy</h3>
<p>Even doing the much more difficult thing is made much easier when you know that it’s right.</p>
<h3 id="its-so-rewarding">It’s so rewarding</h3>
<p>You feel good about yourself. You feel good about the world. You feel good about the future.</p>
<h3 id="its-stays-right">It’s stays right</h3>
<p>You don’t second-guess yourself.</p>
<h2 id="but-at-work-its-a-superpower">But at work, it’s a superpower</h2>
<p>Besides the ethical or moral implications, doing the right thing is a superpower at work.</p>
<p>People often don’t do the right thing because it’s not their job. Or because it’s not their fault. Or because no one asked them to.</p>
<p>They don’t do the right thing even though they know it’s the right thing.</p>
<p>But if you see that something is the right thing to do, and you do it despite it not being your job, your fault or having been asked, you’ll be a superhero.</p>
<p><a href="https://ognjen.io/do-whats-right/">Do what's right</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 13, 2024.</p>https://ognjen.io/when-am-i-allowed-to-quit2024-01-06T00:00:00+08:002024-01-06T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>There’s a type of startup that stays alive but doesn’t achieve meaningful growth. One that keeps raising bridge rounds but whose valuation stagnates.</p>
<p>Anecdotally, their founders belong to two groups:</p>
<ol>
<li>They’re still convinced that the business will work and are unflappable in their resolve.</li>
<li>They’ve fallen prey to the sunk cost fallacy and are looking for a way to stop but might be afraid to quit</li>
</ol>
<p>For the second group, a key question is:</p>
<blockquote>
<p>When am I “allowed” to quit and not be labelled a quitter?</p>
</blockquote>
<p>In other words, how much time should they have spent on the business before it counts as a legitimate attempt and that failure is not just them quitting when things got difficult?</p>
<p>I can think of two milestones at which you should re-evaluate whether you need to continue.</p>
<p><small>(Please note these are suggestions for when you might need to re-evaluate, <strong>not</strong> indications that you’ve failed. Plenty of counter-examples exist, but if you find yourself at one of these points, in my opinion, it’s perfectly reasonable to decide that you don’t want to continue.)</small></p>
<h2 id="1-two-years-and-no-seed">1. Two years and no seed</h2>
<p>If you’ve spent two years building the product and haven’t been able to switch to full-time and/or haven’t been able to close seed funding, to me at least, that’s a very strong indicator that you should re-evaluate.</p>
<p>There are two qualifiers here, however.</p>
<p>Firstly, it should be most (all?) of your free time not a couple of hours every other week.</p>
<p>If you’re not willing to spend that kind of time think about <a href="https://themarketplace.guide/is-it-a-hobby">whether it’s a business or a hobby</a>, and then treat it as such.</p>
<p>Second, you need to have pitched dozens of times before you can conclude that you won’t raise seed - several dozen if you’re an engineer with no sales or public speaking background. Even then, you should consider if you just suck at pitching and if you need to bring in a business co-founder.</p>
<p>A bit later, if you’ve had to close multiple seed or multiple bridge rounds, it might also be worth reconsidering.</p>
<h2 id="2-4-years-to-1-million-arr">2. 4 years to 1 million ARR</h2>
<p>Further down the line, if you’ve been working on the product for 4 years, preferably full-time and with external funding and you did not achieve 1M ARR yet, it’s time to re-think.</p>
<p>I think that’s a good point at which to close up shop. You will have learnt a great deal about an industry and running a company and have had enough time that you didn’t leave a lot unexplored.</p>
<p>If you’re looking to build a unicorn, and not a lifestyle business, 4 years is enough time to get a feeling for whether you’ll succeed or not.</p>
<p>The timeline in this scenario would roughly be:</p>
<ol>
<li>A year of building the product</li>
<li>Raise seed</li>
<li>A year to year-and-a-half of confirming PMF</li>
<li>Raise series A</li>
<li>Two years to get 1 million ARR</li>
</ol>
<p>I think this is enough time to spend a year building the product and figuring things out.</p>
<p>This time will be especially useful for first-time founders who might not be competent at sales yet.</p>
<p>It’s enough time to transition away from a job, perhaps starting with the weekends, then switching to 40%/50%/60% time at work and eventually becoming full-time.</p>
<p>It is enough time to be able to iterate over a couple of potential value propositions and market segments.</p>
<p>It’s a clear milestone that indicates a certain level of success that isn’t ridiculous but might be out of reach without VC money.</p>
<p>And then either the next stage begins or the journey is over.</p>
<p>PS. I’d not even put companies that you “co-founded” that lived for less than a year on your resume.</p>
<p>e. <a href="https://news.ycombinator.com/item?id=38990508">Some interesting comments on Hacker News.</a></p>
<p><a href="https://ognjen.io/when-am-i-allowed-to-quit/">When am I "allowed" to quit and not be labeled a quitter?</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 06, 2024.</p>https://ognjen.io/green-flags-for-founders-to-invest-in2024-01-03T00:00:00+08:002024-01-03T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Here are a few things I’ve seen founders do that made me confident in their ability and dedication.</p>
<h2 id="elevator-pitch-in-linkedin-tagline">Elevator pitch in LinkedIn tagline</h2>
<p>A founder who is all in is constantly selling. That means their tagline will:</p>
<p>a) be for their company, not for them</p>
<p>b) be the sales pitch, not a vague aspirational vision</p>
<h2 id="value-proposition-keeps-getting-more-specific">Value proposition keeps getting more specific</h2>
<p>If every time you talk to a founder and their value proposition is more and more specific to me indicates that they’re learning more and more about their USP, about their target customer, about the market.</p>
<p>The opposite of this is a company that pivots every six months.</p>
<h2 id="no-short-stints-in-the-cv">No short stints in the CV</h2>
<p>Building a startup is decidedly a marathon. <a href="/when-can-you-give-up">I think it takes about 4 years to make real progress in a startup.</a></p>
<p>Folks who jump positions every year are chasing a career and are unlikely to want to slog through for such a long time. Not that there’s anything wrong with that, it’s just not the right profile.</p>
<h2 id="worked-at-companies-of-different-sizes">Worked at companies of different sizes</h2>
<p>A founder who’s seen multiple stages of a startup is more likely to be successful.</p>
<p>While they might not have been in the top leadership positions they would have seen the challenges the organization faces, especially during the transitions.</p>
<h2 id="worked-in-different-industries-or-not">Worked in different industries, or not</h2>
<p>There is a difference between the technical and the business founders.</p>
<p>The startups I’ve seen where the business founder was part of the industry for a while worked well. But I’ve also seen them get so focused on how things are that they can’t see how things <em>should</em> be.</p>
<p>For technical founders, on the other hand, I think it’s a clear advantage to have been in different industries and seen different approaches.</p>
<h2 id="switched-to-full-time-as-soon-as-possible">Switched to full-time as soon as possible</h2>
<p>It might be obvious but the sooner the founder goes full time the more skin in the game, but also belief in the business, they have. They’re that much more committed to it.</p>
<p>The opposite of this is founders who are simultaneously CEOs of multiple companies. I don’t think that can ever work – least of all for startups.</p>
<h2 id="dont-succumb-to-the-hype">Don’t succumb to the hype</h2>
<p>The founders who aren’t always talking about how they’re going to incorporate the latest hype in their product seemed to get more accomplished.</p>
<h2 id="founded-or-was-an-early-employee-of-a-startup-that-raised-a-round-or-two">Founded, or was an early employee, of a startup that raised a round or two</h2>
<p>I think this is probably the biggest indicator. Having done the early stages, seed and maybe series A, eliminates A LOT of uncertainty.</p>
<p>At least the company won’t fail because the founders aren’t competent at running a business, since they’ve done it before.</p>
<p>I’d even be biased toward someone who did a startup over someone who’s been employed at a name-brand unicorn simply because the skill set is not at all equivalent.</p>
<p><a href="https://ognjen.io/green-flags-for-founders-to-invest-in/">Green flags for investable founders</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 03, 2024.</p>https://ognjen.io/experiment-i-will-not-spend-longer-than-one-hour2024-01-01T00:00:00+08:002024-01-01T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Over the past year, the backlog of things I wanted to write had piled up. But my free time had dwindled.</p>
<p>So, in the interest of <a href="https://www.scotthyoung.com/blog/2019/01/23/how-to-be-prolific/">being prolific</a> and producing content that I can iterate and learn from, at the start of the year I decided that this year I would not spend more than two hours on any particular blog post.</p>
<p>It didn’t work out as I imagined, since I didn’t have time to write at all, but I did try to make the posts smaller and focused on only one idea and only the words strictly needed to get it across.</p>
<p>Instead, the approach that seems to work better now is to make three passes for each post.</p>
<p>First, to get most of the content written.
Second, to edit the content, improve the structure and remove anything that doesn’t support the main idea.
Third, and final, to proof-read and improve readability.</p>
<p>We’ll see how that goes.</p>
<p><a href="https://ognjen.io/experiment-i-will-not-spend-longer-than-one-hour/">What if I spent exactly two hours on each post</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 01, 2024.</p>https://ognjen.io/a-review-of-the-blog-in-20232024-01-01T00:00:00+08:002024-01-01T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>2023 was a busy year so I did not spend a lot of time blogging, unfortunately.</p>
<p>It was only in December that I had meaningful time for writing.</p>
<p>In the <a href="/a-review-of-the-blog-in-2022">2022 review</a> I set a few targets for the blog in 2023:</p>
<h2 id="targets-for-2023">Targets for 2023</h2>
<ul>
<li>❎ Publish at least 40 posts
<ul>
<li>14</li>
</ul>
</li>
<li>✅ Reach at least 150k readers
<ul>
<li>With a couple of viral posts this is very easily achievable. I’m at 180k even though I only had a few posts. I will include a target for the number of posts as well.</li>
</ul>
</li>
<li>
<p>❎ Get at least 10 posts professionally? publicized</p>
<ul>
<li>
<p>I was thinking of hiring someone to help me distribute the content, but</p>
<p>a) I didn’t produce much of it and</p>
<p>b) I didn’t hire anyone.</p>
</li>
</ul>
</li>
<li>❎ Build an audience (recurring readers, Twitter, newsletter?)
<ul>
<li>Did not do this at all.</li>
</ul>
</li>
<li>❎ Publish something on at least two other sites
<ul>
<li>Did not do this. And I think I will not focus on this going forward.</li>
</ul>
</li>
</ul>
<h2 id="quantity">Quantity</h2>
<p>I published 14 posts, totaling approximately 9700 words. The average blog post length is 695 words.</p>
<p><a href="/working-on-legacy-features">Working on legacy code</a> is the longest post at ~729 words, followed by <a href="/lie-still-in-bed">Lie still in bed</a> with 679.</p>
<p>The sample size isn’t sufficient to comment on whether the average length is adequate.</p>
<h2 id="popularity">Popularity</h2>
<p><a href="/lie-still-in-bed">Lie still in bed</a> was the most popular substantial article. That’s encouraging because it’s not about tech, it’s just generic advice.</p>
<p><a href="/mit-no-ai">MIT No AI</a> was fairly popular but got flagged on HackerNews which killed it. It was also very quick to write.</p>
<p>Interestingly <a href="/reddits-disrespectful-design">Reddit’s disrespectful design</a> and <a href="/big-tech-should-help-tackle-misinformation-on-smaller-platforms">Big tech should help tackle misinformation on smaller platforms</a> made a comeback. I don’t have detailed tracking anymore, it’s all based on server logs, so I can’t dig deeper into where the traffic is coming from.</p>
<p><a href="/jekyll-editing-rendered-posts-using-chrome-filesystem-api">Editing the source markdown of a generated static site in the browser</a> had some traffic as well which is interesting. It’s probably the most interesting post I wrote in a long while.</p>
<p>Feedly reports 18 followers. Up three.</p>
<h2 id="what-ive-learnt">What I’ve learnt</h2>
<p>I think I got better at writing more clearly.</p>
<p>I’m more comfortable, at least at the moment, with publishing posts and not worrying too much about whether they’re perfect. I think that’s at least partly because I wrote so many posts in December.</p>
<p>I made one pass with the rough draft. Then another pass that finalized the content. Then a final one where I didn’t change the content but just proofread and ensured clarity. Then I published the post.</p>
<p>I took to heart the 2022 objective to frame posts positively more positively and have done that for several of them.</p>
<h2 id="targets-for-2024">Targets for 2024</h2>
<ul>
<li>Publish at least 40 posts</li>
<li>Reach at least 200k readers</li>
<li>Have at least 6 posts on the front page of something</li>
<li>Make at least $50 from writing.
<ul>
<li>I’m not sure if this is a good objective but maybe it might motivate me to think of monetization alternatives.</li>
</ul>
</li>
</ul>
<p><a href="https://ognjen.io/a-review-of-the-blog-in-2023/">A review of the blog in 2023</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on January 01, 2024.</p>https://ognjen.io/the-boy-who-cried-risk2023-10-21T00:00:00+08:002023-10-21T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>On a recent project, I worked with a principal engineer. He’s a very prolific contributor and involved in several projects. Most of his contributions are related to risk management.</p>
<p>That made me think about the other senior-most engineers and what they work on, leading me to conclude that <em>the amount of time you spend managing risk is directly proportional to seniority</em>. And at the top, it’s nearly all a CTO does.</p>
<p>And, of course, the higher you go, the more existential the risks become.</p>
<p>A senior engineer might evaluate the risk of using a new library – a principal engineer might think about what happens if new legislation passes.</p>
<p>It made me reflect on how involved I should be in identifying potential risks in my domain and how to do that effectively.</p>
<h2 id="time-spent-managing-risk">Time spent managing risk</h2>
<p>There isn’t a fixed amount of time you should spend on identifying and mitigating risk.</p>
<p>Instead, it’s about continuously analyzing the things you’re working on and trying to understand where there might be bottlenecks, dead-ends, or other issues.</p>
<p>Rather than sitting down and going through a finished design and pointing out where there might be issues down the line, do it every step of the way.</p>
<h2 id="at-what-level">At what level?</h2>
<p>It’s difficult to tell how senior you need to be before you should consciously start evaluating risk.</p>
<p>It seems to happen progressively throughout the career. As you become more senior, you start to think about the bigger picture and the impact of your work and part of that is what might go wrong down the line.</p>
<p>At some point, you will not be able to progress further without being able to gauge risk accurately.</p>
<p>Besides, you also need a level of credibility before you can mobilize people to help you mitigate risk. It’s much easier for a principal engineer to get a week of dev time, than for a senior engineer.</p>
<h2 id="risk-is-invisible">Risk is invisible</h2>
<p>Accurately gauging risk is invisible work. If you identify, estimate and tackle it in time, nothing happens. The company gets through it, and feels no adverse effects.</p>
<p>If you aren’t very senior, that might be a net negative to your political capital. And, if you do it more than once, you might become <em>the boy who cried risk</em>.</p>
<p>But, at the senior-most level, it’s a huge part of your job. Underestimating risk means you’ve made a significant error in judgment. Overestimating risk means you’ve wasted time and money. Your effectiveness is measured by how well you can do this.</p>
<h2 id="gauging-risk">Gauging risk</h2>
<p>In general, risk is classified as <code class="language-plaintext highlighter-rouge">likelihood × severity</code>.</p>
<p>Severity is relatively easy to estimate – it’s a bit more tangible. If a library breaks we’ll have to spend <code class="language-plaintext highlighter-rouge">x</code> hours replacing it.</p>
<p>But how do you accurately estimate likelihood?</p>
<p>One piece of advice I’ve got is to ask several others and then aggregate.</p>
<p>That would work, especially when coupled with frequently re-visiting the estimates, which is a good idea anyway.</p>
<p>Then, you also know whether the likelihood might be increasing or decreasing – a good indicator of whether you should be spending more or less time on it.</p>
<p>Another thing to do is to estimate the likelihood on different time-horizons. Some things might not be a problem now, but they might be in the future.</p>
<p>Similarly, you can ask: “How far in the future before the likelihood of this happening is 100%?”</p>
<h2 id="conclusion">Conclusion</h2>
<p>I don’t have a conclusion. I’m still working on understanding this aspect of the job. I haven’t really found any <em>authoritative</em> sources on this topic that go beyond the <code class="language-plaintext highlighter-rouge">likelihood × severity</code> formula.</p>
<p>Feel free to send me any resources or advice you might have.</p>
<p><a href="https://ognjen.io/the-boy-who-cried-risk/">The boy who cried risk</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on October 21, 2023.</p>https://ognjen.io/return-to-office-to-gratify-ceo2023-10-16T00:00:00+08:002023-10-16T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Many CEOs and companies are pushing for a return to the office. They can’t all be crazy – they must have some justification.</p>
<p>Remote work increases individual productivity, so what are they trading off against then?</p>
<p>One argument is <em>serendipity</em> and those spontaneous moments of collective <em>ideation</em>. I doubt it. That’s not something that a CEO would be able to feel.</p>
<p>I think it’s about responsiveness and the instant gratification it brings.</p>
<p>When everyone is in the office, the CEO can get a response to any question in a few minutes.</p>
<p>A CEO can feel that. They can stroll to their VP’s office, and interrupt their phone call to ask a question. They get an immediate answer. If the VP doesn’t know, they can saunter over to the director’s office and ask them. In either case, the CEO’s gratification is instant.</p>
<p>If people are remote, however, there’s no sauntering to be done.</p>
<p>Does that translate to a better-functioning and more productive company where alignment on key decisions is quicker? I doubt it - but since the CEO feels good, they probably think it does.</p>
<p><a href="https://ognjen.io/return-to-office-to-gratify-ceo/">CEOs are mandating return to office because they need instant gratification</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on October 16, 2023.</p>https://ognjen.io/not-wanting-to-work-remotely-is-a-competitive-advantage2023-10-15T00:00:00+08:002023-10-15T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>As much as <a href="https://world.hey.com/dhh/working-remotely-is-a-competitive-hiring-advantage-again-c182250eV">working remotely is a competitive hiring advantage again</a>, not wanting to work remotely is now an advantage for getting hired.</p>
<p>A lot of companies are mandating returns to the office. Many more are scrapping fully remote positions, with some even rescinding fully-remote offers.</p>
<p>So, for better or worse, not wanting to work remotely is now a competitive advantage. If that’s not one of your requirements you’re likely to pick up more offers.</p>
<p><a href="https://ognjen.io/not-wanting-to-work-remotely-is-a-competitive-advantage/">Not wanting to work remotely is now a competitive advantage</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on October 15, 2023.</p>https://ognjen.io/bsl-is-not-good2023-09-02T00:00:00+08:002023-09-02T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Another day, another project adopted BSL.</p>
<p>Another day, another round of outrage from people harping on the difference between Open Source and open source.</p>
<p>Another day, another inferior fork of a product due to a technicality that has nothing to do with the product itself and that will not impact the vast majority of users.</p>
<p>Another day, another business built on a platform they don’t control with no contingencies should that platform become unavailable.</p>
<p>Is it outrage purely on principle?</p>
<p>Is it really useful to fork a project and have it perpetually limp behind the original but with the <em>one true licence</em>?</p>
<p>Is it genuine surprise that re-packaging a product that belongs to someone else might not be viable long-term and needs contingency planning?</p>
<p>I don’t know.</p>
<p>I do know, however, that BSL is not good. It’s great.</p>
<p>It’s helping keep open source projects alive <em>and</em> providing a way for its creators to move from being just “indie open source devs” to successful business owners.</p>
<p>New open source software is probably being made right now, specifically because if it becomes popular the creator knows they might make a business out of it.</p>
<p><strong>BSL makes open source a viable career path.</strong></p>
<p>What’s not to like? What’s there to be outraged about?</p>
<p><a href="https://ognjen.io/bsl-is-not-good/">BSL is not good, it's great</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on September 02, 2023.</p>https://ognjen.io/don-t-write2023-09-01T00:00:00+08:002023-09-01T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Content farms and AI are doing a great job at producing content that is good enough for most people.</p>
<p>We don’t need more good quality, niche, carefully crafted content.</p>
<p>So, if you are thinking about starting a blog, a Substack, a Twitter account or something similar, please know that there’s no need for you to write, and no one wants to hear what you have to say.</p>
<h2 id="well-unless">Well, unless…</h2>
<h3 id="you-want-to-help-others-with-a-similar-problem">You want to help others with a similar problem</h3>
<p>If you went through an issue and you think others might benefit from your experience, OK, then it might be a good idea to write about it.</p>
<h3 id="you-want-others-to-learn-from-your-experience">You want others to learn from your experience</h3>
<p>Fine, if you went through a unique experience and you learned something from it, then it might be a good idea to write about it.</p>
<h3 id="you-want-to-make-information-more-easily-accessible">You want to make information more easily accessible</h3>
<p>OK, I agree, sometimes content is there but in a form that’s difficult to discover.</p>
<h3 id="you-want-to-encourage-others">You want to encourage others</h3>
<p>So, you went through a challenging experience but you managed to overcome it. You want to share your story to encourage others to do the same. OK, that might be a good reason to write.</p>
<h3 id="you-want-to-share-something-youre-proud-of">You want to share something you’re proud of</h3>
<p>I guess if you want to keep a record of your accomplishments and share them with others, that’s fine.</p>
<h3 id="you-want-to-get-it-off-your-chest">You want to get it off your chest</h3>
<p>Did you have an idea that keeps coming back? Do you have a story that you keep telling yourself? Do you have a feeling that you can’t shake off? Very well, write it down.</p>
<h3 id="you-want-to-learn-something">You want to learn something</h3>
<p>So, OK, I admit that writing about a topic might help you learn it better. Fine, keep notes and publish them when you’re done, that might be interesting.</p>
<h3 id="you-want-to-learn-to-communicate-better">You want to learn to communicate better</h3>
<p>I guess practising writing is a good way to learn to communicate more clearly.</p>
<h3 id="you-have-some-niche-knowledge">You have some niche knowledge</h3>
<p>So, <em>maybe</em> you know something very specific that’s not widely known. Fine, write it down, I’ll read it.</p>
<h2 id="but-otherwise-dont-write">But, otherwise, don’t write…</h2>
<p><a href="https://ognjen.io/don-t-write/">Don't write</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on September 01, 2023.</p>https://ognjen.io/lie-still-in-bed2023-08-27T00:00:00+08:002023-08-27T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>I found it very difficult to switch to a regular sleep, and wake, schedule after university.</p>
<p>I even started using <a href="https://kukuklok.com/">one of the loudest and most annoying alarm clocks I could find</a>. (That sound still gives my university housemate flashbacks.)</p>
<p>In my search for ways to fix my sleep schedule, I came across a seemingly simple piece of advice:</p>
<blockquote>
<p>Lie still in bed.</p>
</blockquote>
<p>If I remember correctly, that article, like many others, suggested sleeping at the target time every day. To do that, it said, you should lie still in bed with your eyes closed.</p>
<p>It explained that most people fail not because they go to bed late, but because they play on their phones, watch TV or read a book. So, they go to bed earlier but still go to <em>sleep</em> late.</p>
<p>The logic made sense and I tried it. Of course, it didn’t work the first night. But it did in a couple of weeks.</p>
<p>Eventually, I was able to take that to an extreme and became a morning person.</p>
<p>Over the following ~10 years, I’ve successfully applied a generalized version of this advice to several other things.</p>
<p>And over that time I’ve realized three things about practice.</p>
<h2 id="1-you-can-practice-anything">1. You can practice anything</h2>
<p>Just like you can practice going to sleep at a reasonable hour, so can you practice keeping your bed made, liking a particular food, or doing collage.</p>
<p>Most people I talked to about this disagree. But I think they underestimate themselves. And for whatever reason, they don’t prioritize practice highly enough at that time.</p>
<p><em>Perhaps</em> there are exceptions, but I doubt it. I certainly haven’t come across any.</p>
<h2 id="2-use-your-willpower-to-lie-still">2. Use your willpower to lie still</h2>
<p>You have limited willpower so use it for the hardest parts.</p>
<p>And try to make the hardest part as small as possible by simplifying it and eliminating as many variables as possible.</p>
<p>If you want to establish a regular sleep pattern, going to bed is often the easy part. But putting your phone away and closing Netflix might be tough. That’s where willpower comes in.</p>
<p>Focus on the simplest possible unit of work – lying still – and apply it there.</p>
<p>It becomes easier if you eliminate as many variables as possible. For example, go to sleep and wake up at the same time even on the weekends.</p>
<p>Another example might be trying to exercise regularly. You don’t need willpower to do the exercise but to change and get out of your house. And if you exercise at the same time and for the same duration every day, you need even less of it.</p>
<h2 id="3-your-progress-will-be-in-much-smaller-steps-than-you-think">3. Your progress will be in <strong>much</strong> smaller steps than you think</h2>
<p>Most of us expect results to start showing very quickly. If I go to bed early <em>once</em>, I must be able to go to bed early every day from then on.</p>
<p>I want to exercise, so I must be able to run 5k in a week.</p>
<p>And when we can’t do this, we feel discouraged.</p>
<p>Consistency and recognizing <em>small</em>, barely noticeable, improvements is how you get better at something.</p>
<p>To fix your sleep, you must lie still in bed. On the first night, you’ll grab your phone after 2 minutes. But on the second after 4. And while you will not have fixed your sleep schedule in those two nights, you will have made exactly 6 minutes of progress. But progress nonetheless.</p>
<p>That it took almost no willpower to change today, even if you didn’t hit your targets at the gym, is progress.</p>
<p>Recognizing progress in the face of setbacks is also crucial. Your motivation will wax and wane, and you might not be able to practice every day. It’s only natural. But recognize that even though you failed to practice today, you’ve still made progress overall.</p>
<p>You’ve had an hour more sleep this week, and you’ve exercised more this month than the entire last year.</p>
<h2 id="lie-still-in-bed">Lie still in bed</h2>
<p>So, if you <strong>have never been able to do something</strong>, it’s simple. Just:</p>
<blockquote>
<p>Lie still in bed</p>
</blockquote>
<p><a href="https://ognjen.io/lie-still-in-bed/">Lie still in bed</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on August 27, 2023.</p>https://ognjen.io/chat-gpt-google-news2023-08-27T00:00:00+08:002023-08-27T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>ChatGPT ingesting content produced by others and reproducing it, wholly, or in-part as a result of the model, is almost exactly the same like Google ingesting news and presenting it on the search results page.</p>
<p>Actually, it’s worse, because it gives absolutely no attribution to the original author. Google News at least included a link to the source.</p>
<p><a href="https://ognjen.io/chat-gpt-google-news/">ChatGPT == Google News?</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on August 27, 2023.</p>https://ognjen.io/good-uses-of-tdd2023-08-13T00:00:00+08:002023-08-13T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>While I’m not a fan of using TDD all the time, here are a few situations where it’s effective.</p>
<h2 id="bugfix">Bugfix</h2>
<p>Starting a bugfix by writing the broken test case is often very practical, especially with issues that show up somewhere in the front end, but the fix is somewhere deep in the logic.</p>
<h2 id="unfamiliar-source-or-feature">Unfamiliar source or feature</h2>
<p>If your feature breaks another team’s scope, it’s often very difficult to trace from scratch. Instead, writing a failing test case in one of their existing suites is much more efficient.</p>
<h2 id="feature-setup-takes-too-long">Feature setup takes too long</h2>
<p>When a bug is buried deep within feature switches and multiple settings, it’s much easier to set everything up in a test case, rather than manually.</p>
<h2 id="build-takes-too-long">Build takes too long</h2>
<p>If you’re in an unfortunate position where the build takes too long, making it very inefficient to make a change and then wait for the build to test it, doing that through unit tests is almost always <em>much</em> faster.</p>
<h2 id="reproduction-takes-too-long">Reproduction takes too long</h2>
<p>If reproducing a bug or feature takes multiple steps, writing a test case is once again the way to go.</p>
<h2 id="legacy-code">Legacy code</h2>
<p>And finally, TDD is very helpful when <a href="/working-on-legacy-features">working on legacy features</a>.</p>
<p><a href="https://ognjen.io/good-uses-of-tdd/">Situations in which TDD is the way to go</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on August 13, 2023.</p>https://ognjen.io/working-on-legacy-features2023-08-12T00:00:00+08:002023-08-12T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<h2 id="take-your-time">Take your time</h2>
<p>If you rush, you might miss some implications of your changes and cause more work in the long run. So, do it right the first time.</p>
<p>Secondly, since you’ll be in the code anyway, take some time to ensure that it will survive unchanged for another stretch of time.</p>
<h3 id="estimate-appropriately">Estimate appropriately</h3>
<p>It’s difficult to estimate how long a change to code you’re unfamiliar with might take. For legacy code, even more so. Make it clear, however, that this is a learning and improvement expedition, not just a ✅ ticket.</p>
<h2 id="ensure-and-improve-test-coverage">Ensure and improve test coverage</h2>
<p>Knowing that <strong>sufficient and necessary</strong> coverage exists to give you the confidence to make your changes is a hard pre-requisite.</p>
<h3 id="investigate-the-existing-tests">Investigate the existing tests</h3>
<p>First, find all existing tests to determine whether there is sufficient coverage. If you use a tool like <a href="https://coveralls.io/">Coveralls</a> or one that selects a subset of tests to run for a PR, you can query it to get a list of tests that cover the feature.</p>
<p>You can also change the feature to throw an error and re-run the test suite to see which tests will fail.</p>
<p>This step will also help you understand the code and its dependencies.</p>
<h3 id="improve-coverage">Improve coverage</h3>
<p>Next, improve coverage until you’re confident that any breaking change will be caught. Keep in mind that tests must be <strong>sufficient and necessary</strong>.</p>
<p>In my experience, not only will you need to add test cases but you might need to refactor the existing test suites.</p>
<p>As code evolves, new test cases are just added to the bottom of the test.</p>
<p>The test file then consists of one-half of nicely structured test cases, possibly broken down by function or branch.</p>
<p>And of one-half of test cases in chronological order.</p>
<h3 id="ensure-the-correct-mix-of-test-types">Ensure the correct mix of test types</h3>
<p>As you’re improving coverage, you should also pay attention to the proportion of the different test types.</p>
<p>Changes in related code often mean that tests are changed or removed. Over time, the proportion of unit/integration/end-to-end tests is likely to go out of balance.</p>
<p>Updates to the testing guidelines might also call for changes in test proportions.</p>
<p>❗ At this point, you should have well-tested, but still <em>legacy</em> code.</p>
<h2 id="refactor-the-legacy-code">Refactor the legacy code</h2>
<p>Since you now have a nicely tested piece of code it should be easy to employ the Scout rule and leave the place better than you found it.</p>
<h3 id="ensure-that-the-legacy-code-complies-with-current-guidelines">Ensure that the legacy code complies with current guidelines</h3>
<p>Legacy code that is changed only rarely will not get upgraded to the latest company guidelines.</p>
<p>For instance, if your organization adopted TypeScript, legacy JavaScript files might not have been upgraded yet.</p>
<p>You have the chance to do that now.</p>
<h3 id="check-dependencies">Check dependencies</h3>
<p>Deprecated libraries or helpers are often maintained only for legacy code that is rarely changed and no one fully owns.</p>
<p>Evaluate what it uses under the hood and see if you can clean up and/or upgrade.</p>
<h3 id="verify-any-assumptions-that-the-code-might-be-making">Verify any assumptions that the code might be making</h3>
<p>Legacy code might be operating under assumptions that are no longer true.</p>
<p>I’ve seen legacy code that relies on a long-deprecated feature that still worked only because of a side effect.</p>
<p>An extreme case I’ve come across is a silo of self-supporting legacy code that could be removed entirely.</p>
<p>❗ At this point you should have well-tested code, that can no longer be considered legacy.</p>
<h2 id="make-your-change">Make your change</h2>
<p>Now that the code is well covered, you understand it much better, and it follows the latest guidelines and architecture, you’re good to make your change.</p>
<h3 id="comment-liberally">Comment liberally</h3>
<p>I’d also suggest that as you work you’re <em>very</em> liberal with your comments. Note down any assumptions the code makes and any edge cases you may have discovered. Also, explain the change you’re making and why and include a link to your ticket.</p>
<p>That will help the person who comes after you. And who knows when that will be?</p>
<h2 id="try-to-get-reviews-from-outside-the-team">(Try to) Get reviews from outside the team</h2>
<h3 id="look-for-previous-contributors">Look for previous contributors</h3>
<p>Look at the git blame of the related files and ping a couple of people who worked on it most recently for reviews.</p>
<h3 id="look-for-affected-teams">Look for affected teams</h3>
<p>It is a good idea to ping any downstream teams for a review. They might not know how the code works, but they might know its implications.</p>
<p><a href="https://ognjen.io/working-on-legacy-features/">Working on legacy code</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on August 12, 2023.</p>https://ognjen.io/paying-for-content-after-you-ve-consumed-it2023-08-03T00:00:00+08:002023-08-03T00:00:00+08:00Ognjen Regojehttps://ognjen.iome@ognjen.io<p>Platforms like Patreon created a new paradigm. By billing periodically they created predictability for content creators allowing them to switch to full-time.</p>
<p>But, might it be better for content creators, and consumers, if they were paid a flexible amount after the content was consumed?</p>
<p><em>Note that this concept is based entirely on my anecdotal experience, not on any data.</em></p>
<h2 id="the-problem-with-periodic-billing">The problem with periodic billing</h2>
<p>Periodic billing is a great way to get a predictable income. But there are two problems.</p>
<p>First, it’s a <strong>barrier to entry</strong> for new customers. Content creators get around this by doing a split release where their subscribers get access to content first, and it’s released to the public a week later. It’s also clunky to convert a free to a paying customer which is why the free audience must be frequently reminded the the Patreon exists.</p>
<p>Second, since there is a time constraint to get the content out, it creates pressure on the content creator to publish <em>something</em> in order to fulfill the terms of the subscription.</p>
<p>This might, at times, result in them publishing something that is not up to their standards. Or, at the very least, not as good as it could be.</p>
<h2 id="so-what-if-we-paid-after-we-consumed-the-content">So, what if we paid after we consumed the content?</h2>
<p>The way I see it, there are two components to this distribution system:</p>
<ul>
<li>
<p><strong>Allowing access to content without payment but automatically charging time after</strong></p>
<p>This effectively gives the customer a trial period to see if they like the content creator. They’d still need to enter their billing information but they’d not be charged yet.</p>
<p>Customers, of course, get a warning email before they’re charged reminding them of their purchase. This is also where part two comes into play.</p>
</li>
<li>
<p><strong>Allowing some degree of flexibility in the amount charged</strong></p>
<p>The content creator might want to set a floor price, but the customer should be able to pay more if they want to. I do see there being a benefit of allowing the customer to select to not pay at all thus removing “risk” entirely.</p>
</li>
</ul>
<h3 id="some-examples">Some examples</h3>
<ul>
<li>Concert tickets might be charged the day after the show</li>
<li>Albums might be charged a week after you’ve first downloaded it</li>
<li>Movies perhaps two days later</li>
<li>Comics maybe an hour later</li>
</ul>
<h2 id="the-benefits">The benefits</h2>
<p>This system would create two positive effects:</p>
<ol>
<li>It removes the subscription as the barrier to entry making it much cheaper to try out new content creators.</li>
<li>It would create a direct positive feedback loop incentivizing better, rather than regular, content.</li>
</ol>
<p>In turn, this also be much more effective at capitalizing on a piece of content that went viral – since there’s no risk to exploring the rest of the content creators’ portfolio, there would be a larger pool of potential customers to convert.</p>
<p>And everyone should be better off.</p>
<p><a href="https://ognjen.io/paying-for-content-after-you-ve-consumed-it/">Paying for content after you've consumed it</a> was originally published by Ognjen Regoje at <a href="https://ognjen.io">Ognjen Regoje • ognjen.io</a> on August 03, 2023.</p>