<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rogério Rodrigues de Alcântara</title>
    <description>The latest articles on DEV Community by Rogério Rodrigues de Alcântara (@roalcantara).</description>
    <link>https://dev.to/roalcantara</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%2F230035%2F3adb32d6-f824-4224-95de-1b0beb1d9572.jpg</url>
      <title>DEV Community: Rogério Rodrigues de Alcântara</title>
      <link>https://dev.to/roalcantara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roalcantara"/>
    <language>en</language>
    <item>
      <title>FCIS — Functional Core, Imperative Shell</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Wed, 11 Mar 2026 00:04:17 +0000</pubDate>
      <link>https://dev.to/roalcantara/fcis-functional-core-imperative-shell-4haf</link>
      <guid>https://dev.to/roalcantara/fcis-functional-core-imperative-shell-4haf</guid>
      <description>&lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&lt;br&gt;
This is a few notes regarding what (I think/hope) I have learned this week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PLEASE:&lt;/strong&gt; Use it with a grain of salt! &lt;strong&gt;YOU HAVE BEEN WARNED!&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;PS:&lt;/strong&gt; Any corrections, clarifications, or suggestions would be greatly appreciated! &lt;strong&gt;NO, SERIOUSLY!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;OVERVIEW&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%2Fhd56fibxkeq2j4xcunlx.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%2Fhd56fibxkeq2j4xcunlx.png" alt="Functional Core Imperative Shell" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 A pattern that splits your codebase into two hard zones:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ZONE&lt;/strong&gt; &lt;code&gt;src/core/&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PURE&lt;/strong&gt; functions only&lt;/li&gt;
&lt;li&gt;No I/O. &lt;/li&gt;
&lt;li&gt;No side effects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ZONE&lt;/strong&gt; &lt;code&gt;src/shell/&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NON-PURE&lt;/strong&gt; functions only&lt;/li&gt;
&lt;li&gt;All &lt;code&gt;I/O&lt;/code&gt; lives here.&lt;/li&gt;
&lt;li&gt;Causes side effects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&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%2Fxlvfwos17cqx1hu9cvn1.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%2Fxlvfwos17cqx1hu9cvn1.png" alt="The shell pattern" width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Why Bother?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Testability without ceremony:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Core tests need zero setup - no mocks, no DB, no async. Plain object literals in, assertions out. If a test needs beforeEach or await, the function is in the wrong layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deterministic replay:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pure functions mean you can log inputs at the shell boundary and reproduce any production bug exactly - no database state, no timing, no environment to reconstruct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No framework lock-in at the core:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;src/core/ has zero runtime dependencies. Switching from Express to Hono, Drizzle to Prisma, or Node to Bun touches only the shell. Business logic is untouched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallel development:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once core types and signatures are defined, shell and business logic can be built simultaneously. The contract is just data in, data out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free documentation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pure function signatures are the spec. canTransitionTo(current: TaskStatus, next: TaskStatus): boolean tells you everything - no layer-tracing required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safer code review:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any PR touching only src/core/ cannot introduce a regression caused by I/O, timing, or external state. That's a meaningful trust boundary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incremental adoption:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No minimum viable structure. Extract one pure function from a messy handler and grow from there. Unlike DDD or clean architecture, it scales down.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Compares
&lt;/h2&gt;




&lt;h3&gt;
  
  
  vs. Clean Architecture / Hexagonal Architecture (Ports &amp;amp; Adapters)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://amazon.com/Clean-Architecture-Craft-Software-Structure/dp/0134494164" rel="noopener noreferrer"&gt;Clean Architecture&lt;/a&gt;&lt;/strong&gt; (Robert Martin) and &lt;strong&gt;&lt;a href="https://amazon.com/Hexagonal-Architecture-Software-Pragmatic-Programmers/dp/1941222325" rel="noopener noreferrer"&gt;Hexagonal Architecture&lt;/a&gt;&lt;/strong&gt; (Alistair Cockburn) solve the same dependency problem - keep business logic independent of infrastructure - but through abstraction layers: interfaces, ports, adapters, and dependency injection containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FCIS&lt;/strong&gt; gets there through data flow instead. No interfaces. No adapter classes. No DI framework. The core is isolated not by indirection, but because it literally only speaks in plain data types and pure functions.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean / Hexagonal vs. FCIS
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Isolation mechanism
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean / Hexagonal:&lt;/strong&gt; Interfaces + DI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FCIS:&lt;/strong&gt; Pure functions + data&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Boilerplate
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean / Hexagonal:&lt;/strong&gt; High&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FCIS:&lt;/strong&gt; Minimal&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean / Hexagonal:&lt;/strong&gt; Good (with mocks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FCIS: Better&lt;/strong&gt; (no mocks needed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learning curve
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean / Hexagonal:&lt;/strong&gt; Steep&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FCIS:&lt;/strong&gt; Low&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best fit
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean / Hexagonal:&lt;/strong&gt; Large teams, complex domains&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FCIS:&lt;/strong&gt; Small-to-medium codebases&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SUGGESTION
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Clean Architecture:&lt;/strong&gt; is powerful&lt;br&gt;
&lt;strong&gt;FCIS&lt;/strong&gt; is cheaper&lt;/p&gt;

&lt;p&gt;Pick the one that matches your actual complexity. :)&lt;/p&gt;


&lt;h3&gt;
  
  
  vs. Domain-Driven Design (DDD)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215" rel="noopener noreferrer"&gt;DDD&lt;/a&gt;&lt;/strong&gt; (Eric Evans, Domain-Driven Design, 2003) is a design philosophy - ubiquitous language, bounded contexts, aggregates, domain events. FCIS is an architectural pattern. They aren't competitors.&lt;/p&gt;
&lt;h4&gt;
  
  
  The key differences
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;DDD encourages rich domain models&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;— objects that encapsulate both data and behaviour &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(Aggregates, Entities, Value Objects with methods).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;FCIS enforces the opposite:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data and behaviour are always separate. &lt;/li&gt;
&lt;li&gt;A Task in FCIS is a plain type; &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;canTransitionTo&lt;/code&gt; is a standalone function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can apply &lt;strong&gt;DDD&lt;/strong&gt; thinking (bounded contexts, ubiquitous language) to an &lt;strong&gt;FCIS&lt;/strong&gt; codebase. But you cannot use rich OOP domain objects in &lt;code&gt;src/core/&lt;/code&gt; without violating the purity constraint.&lt;/p&gt;


&lt;h3&gt;
  
  
  vs. Layered / N-Tier Architecture
&lt;/h3&gt;

&lt;p&gt;The classic &lt;code&gt;Service → Repository → Database&lt;/code&gt; stack organises code by technical role.&lt;/p&gt;

&lt;p&gt;Business logic typically lives in a Service class that also coordinates I/O — calling repositories, dispatching events, logging. &lt;/p&gt;

&lt;p&gt;The layers are present, but the boundary between logic and I/O is blurry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FCIS&lt;/strong&gt; makes that boundary a hard rule. The equivalent of a Service is split in two: pure logic goes to &lt;code&gt;src/core/&lt;/code&gt;, orchestration goes to &lt;code&gt;src/shell/&lt;/code&gt;. There's no &lt;code&gt;"service that also does I/O"&lt;/code&gt; — that's the entire violation FCIS exists to prevent.&lt;/p&gt;
&lt;h3&gt;
  
  
  vs. Functional Programming &lt;code&gt;(pure FP)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Languages like Haskell enforce purity at the type system level - impure code must be declared as such (e.g. &lt;code&gt;IO&lt;/code&gt; monad). FCIS is a convention-based approximation of that discipline in TypeScript. There's no compiler enforcement of the core/shell boundary - it relies on discipline and linting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tradeoff is pragmatism:&lt;/strong&gt; you get most of the reasoning and testability benefits of pure FP without leaving the TypeScript ecosystem or retraining your team.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gary Bernhardt's &lt;a href="https://destroyallsoftware.com/talks/boundaries" rel="noopener noreferrer"&gt;Boundaries talk (2012)&lt;/a&gt;&lt;/strong&gt; is the canonical introduction to this idea. His framing: push values to the edges, keep the centre pure.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  MAIN CONCEPTS
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Core &lt;code&gt;(src/core/)&lt;/code&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ALLOWED:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;domain types&lt;/li&gt;
&lt;li&gt;validation&lt;/li&gt;
&lt;li&gt;business rules&lt;/li&gt;
&lt;li&gt;data transformations&lt;/li&gt;
&lt;li&gt;pure formatters&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;FORBIDDEN:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;async/await&lt;/li&gt;
&lt;li&gt;fetch&lt;/li&gt;
&lt;li&gt;fs.*&lt;/li&gt;
&lt;li&gt;console.log&lt;/li&gt;
&lt;li&gt;process.env&lt;/li&gt;
&lt;li&gt;new Date()&lt;/li&gt;
&lt;li&gt; DB calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;EXAMPLES:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Pure validation - returns Result, never throws&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cannot be empty&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Pure business rule - receives `now` as param, never calls new Date() internally&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isOverdue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dueAt&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dueAt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Pure workflow - all data arrives as params, returns computed result&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateTaskInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;




&lt;h3&gt;
  
  
  The Shell &lt;code&gt;(src/shell/)&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Every handler follows the same 5 steps - no exceptions:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;PARSE  → extract input from args/env/stdin&lt;/li&gt;
&lt;li&gt;FETCH  → read required data from DB/filesystem&lt;/li&gt;
&lt;li&gt;CALL   → pass data to core, inspect Result&lt;/li&gt;
&lt;li&gt;ACT    → persist what core returned&lt;/li&gt;
&lt;li&gt;OUTPUT → print to stdout/stderr&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 If you're making a business decision in step 4,&lt;br&gt;
move it to step 3.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Thin handler - all decisions happen in core&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskDoneCommand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. PARSE&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;printError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ID required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. FETCH&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;findTaskById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;printError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. CALL CORE&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;transitionTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;toStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;printError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 4. ACT&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updatedTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// 5. OUTPUT&lt;/span&gt;
  &lt;span class="nf"&gt;printSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task marked as done.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ERROR HANDLING
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Use Result - never throw for expected failures.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AppError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ok&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected failures are values. Thrown exceptions are for truly unexpected crashes only.&lt;/p&gt;

&lt;h3&gt;
  
  
  TESTING
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 No setup. No mocks. No async.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ No setup. No mocks. No async.&lt;/span&gt;
&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rejects empty title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blocks invalid transitions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;canTransitionTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returns a new task without mutating the original&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeTask&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Original&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;applyTaskUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Updated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2024-06-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Updated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Original&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Bu, when NOT TO USE IT?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;NOTE&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the business logic is the I/O - e.g. a file watcher, a sync tool. The core/shell distinction collapses when there's nothing to separate.&lt;/li&gt;
&lt;li&gt;When the team is deeply invested in OOP/DDD and the retraining cost outweighs the benefit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Pre-Commit Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] No async/await in src/core/&lt;/li&gt;
&lt;li&gt;[ ] No imports from src/shell/ in src/core/&lt;/li&gt;
&lt;li&gt;[ ] No console.log, process.env, fs.*, fetch in src/core/&lt;/li&gt;
&lt;li&gt;[ ] new Date() only in shell, passed as param into core&lt;/li&gt;
&lt;li&gt;[ ] All expected failures return Result, nothing throws&lt;/li&gt;
&lt;li&gt;[ ] Shell handlers follow parse → fetch → call → act → output&lt;/li&gt;
&lt;li&gt;[ ] Core tests: no mocks, no DB, no async&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  REFERENCES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://destroyallsoftware.com/talks/boundaries" rel="noopener noreferrer"&gt;Boundaries&lt;/a&gt; - the canonical source for FCIS thinking&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/Clean-Architecture-Craft-Software-Structure/dp/0134494164" rel="noopener noreferrer"&gt;Clean Architecture&lt;/a&gt; - dependency rule, layers, and ports&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/Hexagonal-Architecture-Software-Pragmatic-Programmers/dp/1941222325" rel="noopener noreferrer"&gt;Hexagonal Architecture&lt;/a&gt; - ports &amp;amp; adapters original essay&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215" rel="noopener noreferrer"&gt;Domain-Driven Design&lt;/a&gt; - aggregates, bounded contexts, ubiquitous language&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/Simplify-Succeed-Replacing-Layered-Architectures/dp/1801075540" rel="noopener noreferrer"&gt;Simplify &amp;amp; Succeed: Replacing Layered Architectures with an Imperative Shell and Functional Core&lt;/a&gt; - practical TypeScript walkthrough&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/Railway-Oriented-Programming-Thinking-Software/dp/1680502530" rel="noopener noreferrer"&gt;Railway Oriented Programming&lt;/a&gt; - the Result pattern in depth&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>fsic</category>
      <category>functionalreactiveprogramming</category>
    </item>
    <item>
      <title>Adding Zsh Completion for `gh copilot`</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Thu, 03 Oct 2024 23:07:58 +0000</pubDate>
      <link>https://dev.to/roalcantara/adding-zsh-completion-for-gh-copilot-12n9</link>
      <guid>https://dev.to/roalcantara/adding-zsh-completion-for-gh-copilot-12n9</guid>
      <description>&lt;p&gt;You are not alone if you are using the &lt;code&gt;gh copilot&lt;/code&gt; CLI and have noticed the lack of Zsh completions.&lt;/p&gt;

&lt;p&gt;To address this issue, I (err.. GPT, actually) created a completion script to enhance the command-line experience. &lt;/p&gt;

&lt;p&gt;Below is a quick guide on setting it up, including a tip on enabling autocompletion for aliases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a few aliases &lt;em&gt;(optional)&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Somewhere on your &lt;code&gt;~/.zshrc&lt;/code&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# GitHub Copilot&lt;/span&gt;
&lt;span class="c"&gt;# Use Copilot with the GitHub CLI to get suggestions and explanations for the command line&lt;/span&gt;
&lt;span class="c"&gt;# https://docs.github.com/en/copilot/using-github-copilot/using-github-copilot-in-the-command-line&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; &lt;span class="nv"&gt;$+&lt;/span&gt;commands[gh] &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
  &lt;span class="c"&gt;# GitHub Copilot&lt;/span&gt;
  &lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;ghcp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'gh copilot'&lt;/span&gt;

  &lt;span class="c"&gt;# Explain a command&lt;/span&gt;
  &lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;cpe&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ghcp explain'&lt;/span&gt;

  &lt;span class="c"&gt;# Suggest a command&lt;/span&gt;
  &lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;cps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ghcp suggest'&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After reloading the shell, you should be able to run &lt;code&gt;ghcp --help&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ghcp &lt;span class="nt"&gt;--help&lt;/span&gt;
Your AI &lt;span class="nb"&gt;command &lt;/span&gt;line copilot.

Usage:
  copilot &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

Examples:

&lt;span class="nv"&gt;$ &lt;/span&gt;gh copilot suggest &lt;span class="s2"&gt;"Install git"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;gh copilot explain &lt;span class="s2"&gt;"traceroute github.com"&lt;/span&gt;


Available Commands:
  &lt;span class="nb"&gt;alias       &lt;/span&gt;Generate shell-specific aliases &lt;span class="k"&gt;for &lt;/span&gt;convenience
  config      Configure options
  explain     Explain a &lt;span class="nb"&gt;command
  &lt;/span&gt;suggest     Suggest a &lt;span class="nb"&gt;command

&lt;/span&gt;Flags:
  &lt;span class="nt"&gt;-h&lt;/span&gt;, &lt;span class="nt"&gt;--help&lt;/span&gt;              &lt;span class="nb"&gt;help &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;copilot
      &lt;span class="nt"&gt;--hostname&lt;/span&gt; string   The GitHub host to use &lt;span class="k"&gt;for &lt;/span&gt;authentication
  &lt;span class="nt"&gt;-v&lt;/span&gt;, &lt;span class="nt"&gt;--version&lt;/span&gt;           version &lt;span class="k"&gt;for &lt;/span&gt;copilot

Use &lt;span class="s2"&gt;"copilot [command] --help"&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;more information about a command.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, when running &lt;code&gt;ghcp &amp;lt;TAB&amp;gt;&lt;/code&gt;, nothing happens...&lt;/p&gt;

&lt;p&gt;Yet!&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the Completion Script
&lt;/h3&gt;

&lt;p&gt;First, create a new file for the completion script and name it &lt;code&gt;_ghcp&lt;/code&gt;. Place the following content inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#compdef ghcp&lt;/span&gt;

&lt;span class="nb"&gt;local &lt;/span&gt;context state line
&lt;span class="nb"&gt;typeset&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; opt_args

_arguments &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'-h[help]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'--help[help]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'--hostname=[The GitHub host to use for authentication]:hostname:'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'-v[version for copilot]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'--version[version for copilot]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'1:command:-&amp;gt;command'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'*::args:-&amp;gt;args'&lt;/span&gt;

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$state&lt;/span&gt; &lt;span class="k"&gt;in
  &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; commands
    &lt;span class="nv"&gt;commands&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
      &lt;span class="s1"&gt;'alias:Generate shell-specific aliases for convenience'&lt;/span&gt;
      &lt;span class="s1"&gt;'config:Configure options'&lt;/span&gt;
      &lt;span class="s1"&gt;'explain:Explain a command'&lt;/span&gt;
      &lt;span class="s1"&gt;'suggest:Suggest a command'&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
    _describe &lt;span class="nt"&gt;-t&lt;/span&gt; commands &lt;span class="s1"&gt;'copilot command'&lt;/span&gt; commands
    &lt;span class="p"&gt;;;&lt;/span&gt;
  args&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$words&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;2] &lt;span class="k"&gt;in
      &lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;# No additional arguments for 'alias'&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
      config&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;# No additional arguments for 'config'&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
      explain&lt;span class="p"&gt;)&lt;/span&gt;
        _message &lt;span class="s1"&gt;'Provide the command you want to explain'&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
      suggest&lt;span class="p"&gt;)&lt;/span&gt;
        _message &lt;span class="s1"&gt;'Provide a description of what you want to do'&lt;/span&gt;
        &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;esac&lt;/span&gt;
    &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;

&lt;span class="c"&gt;# Associate the completion script with the alias&lt;/span&gt;
compdef _ghcp ghcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install the Completion Script
&lt;/h3&gt;

&lt;p&gt;Next, you must place the &lt;code&gt;_ghcp&lt;/code&gt; file in a directory that's part of your $fpath. Here's how you can do it:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create a Completions Directory
&lt;/h3&gt;

&lt;p&gt;If you don't already have a custom directory for Zsh completions, create one:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ mkdir -p ~/.zsh/completions&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Move the Script
&lt;/h4&gt;

&lt;p&gt;Move or copy the &lt;code&gt;_ghcp&lt;/code&gt; file into this directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ mv _ghcp ~/.zsh/completions/&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Update Your $fpath
&lt;/h4&gt;

&lt;p&gt;Add the completions directory to your $fpath by appending this line to your &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ fpath=(~/.zsh/completions $fpath)&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Ensure the Script Is Executable
&lt;/h4&gt;

&lt;p&gt;Make the completion script executable:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ chmod +x ~/.zsh/completions/_ghcp&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Enable Alias Completion
&lt;/h4&gt;

&lt;p&gt;If you use aliases for &lt;code&gt;gh copilot&lt;/code&gt; (like &lt;code&gt;ghcp&lt;/code&gt;), Zsh must be configured to handle completions for aliases. Add the following line to your &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ setopt complete_aliases&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, you can explicitly associate the completion script with your alias by adding:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ compdef _ghcp ghcp&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Reload Zsh Configuration
&lt;/h4&gt;

&lt;p&gt;Apply the changes by sourcing your &lt;code&gt;.zshrc&lt;/code&gt; or restarting your terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ source ~/.zshrc&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Is that so?
&lt;/h3&gt;

&lt;p&gt;Well, let's try typing &lt;code&gt;ghcp &amp;lt;TAB&amp;gt;&lt;/code&gt; and.. &lt;em&gt;voila!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You should see the available subcommands and options auto-complete for you.&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;Having shell completions can significantly speed up your workflow by reducing the need to remember every command and option.&lt;/p&gt;

&lt;p&gt;Enabling alias completion ensures that your custom shortcuts benefit from the same convenience.&lt;/p&gt;

&lt;p&gt;That's all, folks!&lt;/p&gt;

</description>
      <category>zsh</category>
      <category>githubcopilot</category>
      <category>cli</category>
      <category>gh</category>
    </item>
    <item>
      <title>Convert insert mutation to upsert</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Wed, 18 Sep 2024 12:52:46 +0000</pubDate>
      <link>https://dev.to/roalcantara/convert-insert-mutation-to-upsert-2n3n</link>
      <guid>https://dev.to/roalcantara/convert-insert-mutation-to-upsert-2n3n</guid>
      <description>&lt;p&gt;Upsert operations are crucial for maintaining data consistency.&lt;/p&gt;

&lt;p&gt;In this quick post, we’ll walk through implementing an &lt;a href="https://hasura.io/docs/latest" rel="noopener noreferrer"&gt;Upsert&lt;/a&gt; operation in &lt;a href="https://hasura.io/docs/latest" rel="noopener noreferrer"&gt;Hasura&lt;/a&gt; using &lt;a href="https://postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; and GraphQL.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Given some tables, i.e.:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- a companies table&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;companies&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- a customers table&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;company_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;acquirer&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- a unique constraint for some fields to be used by the mutation's on_conflict clause&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;customers_customer_id_company_id_acquirer_key&lt;/span&gt; 
    &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;company_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acquirer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- an index on the unique constraint for better performance&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_customers_customer_id_company_id_acquirer&lt;/span&gt; 
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;company_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acquirer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- a foreign key constraint for company_id&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_customers_company&lt;/span&gt;
    &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;company_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;companies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;And the following executed seed&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- a few existing companies&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;companies&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'a75645ac-b99e-477f-b4a9-b59380b48693'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Acme Corporation'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'b75645ac-b99e-477f-b4a9-b59380b48693'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Globex Corporation'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'c75645ac-b99e-477f-b4a9-b59380b48693'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Soylent Corp'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'d75645ac-b99e-477f-b4a9-b59380b48693'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Initech'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'e75645ac-b99e-477f-b4a9-b59380b48693'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Umbrella Corporation'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Upsert Customer GraphQL Mutation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The following mutation either inserts a new customer or updates the token field of an existing customer if a conflict occurs.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="c"&gt;# upsert mutation using on_conflict to handle duplicates&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UpsertCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$customer_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$company_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$acquirer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;insert_customers_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;company_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$company_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;acquirer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$acquirer&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;on_conflict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;constraint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;customers_customer_id_company_id_acquirer_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;update_columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;company_id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;acquirer&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Insert a New Customer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the unique constraint fields do not exist, the mutation inserts a new customer.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- **Query Variables**
&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;    ```json
    {
      "customer_id": "CUST123",
      "company_id": "a75645ac-b99e-477f-b4a9-b59380b48693",
      "acquirer": "ACQUIRER789",
      "token": "TOKEN456"
    }
    ```
&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;- **Response**
&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;    ```json
    {
      "data": {
        "customers": [
          {
            "id": "fd285dfc-b818-4db0-bd15-80cb015983d7",
            "token": "TOKEN456",
            "company_id": "a75645ac-b99e-477f-b4a9-b59380b48693",
            "created_at": "2024-09-17T19:37:44.350509+00:00",
            "acquirer": "ACQUIRER789",
            "updated_at": "2024-09-17T19:40:01.456019+00:00"
          }
        ]
      }
    }
    ```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update an Existing Customer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whereas the unique constraint fields already exist, the mutation updates the token field.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- **Query Variables**
&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;    ```json
    {
      "customer_id": "CUST123",
      "company_id": "a75645ac-b99e-477f-b4a9-b59380b48693",
      "acquirer": "ACQUIRER789",
      "token": "TOKEN4567"
    }
    ```
&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;- **Response**
&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;    ```json
    {
      "data": {
        "customers": [
          {
            "id": "fd285dfc-b818-4db0-bd15-80cb015983d7",
            "token": "TOKEN4567",
            "company_id": "a75645ac-b99e-477f-b4a9-b59380b48693",
            "created_at": "2024-09-17T19:37:44.350509+00:00",
            "acquirer": "ACQUIRER789",
            "updated_at": "2024-09-17T19:42:01.456019+00:00"
          }
        ]
      }
    }
    ```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;By following these steps, we can easily implement &lt;a href="https://postgresql.org/docs/current/sql-insert.html#SQL-ON-CONFLICT" rel="noopener noreferrer"&gt;upsert&lt;/a&gt; operations in &lt;a href="https://hasura.io/docs/latest" rel="noopener noreferrer"&gt;Hasura&lt;/a&gt;, allowing for efficient data management and updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hasura.io/docs/latest" rel="noopener noreferrer"&gt;Hasura Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://postgresql.org" rel="noopener noreferrer"&gt;Postgres&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://postgresql.org/docs/current/sql-insert.html#SQL-ON-CONFLICT" rel="noopener noreferrer"&gt;Postgres Upsert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hasura.io/docs/latest/graphql/core/mutations/upsert/" rel="noopener noreferrer"&gt;Hasura GraphQL Upsert Mutations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hasura</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Simplifying Your Git Workflow with Aliases</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Thu, 08 Feb 2024 03:18:11 +0000</pubDate>
      <link>https://dev.to/roalcantara/simplifying-your-git-workflow-with-aliases-1nbi</link>
      <guid>https://dev.to/roalcantara/simplifying-your-git-workflow-with-aliases-1nbi</guid>
      <description>&lt;h1&gt;
  
  
  Simplifying Your Git Workflow with Aliases
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction to Git Aliases
&lt;/h2&gt;

&lt;p&gt;Git &lt;a href="https://git-scm.com/docs/git-config#Documentation/git-config.txt-alias" rel="noopener noreferrer"&gt;aliases&lt;/a&gt; are a powerful feature that allows you to create custom shortcut commands for longer Git command sequences. They can significantly simplify and speed up your Git workflow by reducing repetitive typing and complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Configure Git Aliases
&lt;/h2&gt;

&lt;p&gt;Configuring a Git alias is straightforward. You can define aliases in the &lt;code&gt;.gitconfig&lt;/code&gt; file located in your home directory, or you can set them directly via the command line using the &lt;code&gt;git config&lt;/code&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting an Alias via &lt;code&gt;.gitconfig&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To set an alias in &lt;code&gt;.gitconfig&lt;/code&gt;, you need to edit the file and add your alias under the &lt;code&gt;[alias]&lt;/code&gt; section. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[alias]&lt;/span&gt;
  &lt;span class="py"&gt;co&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
  &lt;span class="py"&gt;br&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;branch&lt;/span&gt;
  &lt;span class="py"&gt;ci&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Setting an Alias via Command Line
&lt;/h3&gt;

&lt;p&gt;Alternatively, you can set an alias directly from the command line:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.co checkout
git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.br branch
git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.ci commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will update your .gitconfig file with the new aliases.&lt;/p&gt;
&lt;h2&gt;
  
  
  Examples of Git Aliases
&lt;/h2&gt;

&lt;p&gt;Let's explore some practical examples of Git aliases from the attached file, showcasing how they can simplify your daily Git usage:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Quick Commit: Instead of typing &lt;code&gt;git commit -m "Your message"&lt;/code&gt;, use:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;cm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;commit -m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git cm &lt;span class="s2"&gt;"Your initial commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Interactive Rebase: Replace the lengthy &lt;code&gt;git rebase -i HEAD~3&lt;/code&gt; with:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;ri&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;rebase -i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git ri HEAD~3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Staging All Changes: Use a simple &lt;code&gt;git aa&lt;/code&gt; instead of &lt;code&gt;git add --all&lt;/code&gt;:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;aa&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;add --all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  4. Viewing Logs: Instead of &lt;code&gt;git log --oneline --graph --all&lt;/code&gt;, configure:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;lg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;log --oneline --graph --all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git lg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  5. Deleting Branches: Replace git branch -d with:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;bd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;branch -d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git bd feature-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Useful Git Aliases
&lt;/h2&gt;

&lt;p&gt;To further streamline your Git experience, I've compiled an extensive list of Git aliases that cover a wide range of functionalities, from basic commit operations to advanced log filtering. This comprehensive list is designed to cater to both novice and seasoned Git users.&lt;/p&gt;


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



&lt;h3&gt;
  
  
  How to Use the Gist
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Explore the Gist&lt;/strong&gt;: Browse through the list of aliases in the Gist. Each alias is accompanied by a brief description, making it easier to understand its purpose and usage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Incorporate Into Your Workflow&lt;/strong&gt;: Select the aliases that resonate with your daily Git tasks. You can add these aliases to your &lt;code&gt;.gitconfig&lt;/code&gt; file or set them up using the &lt;code&gt;git config&lt;/code&gt; command, as explained earlier in this post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customization&lt;/strong&gt;: Feel free to modify or expand upon these aliases to better fit your personal workflow. Git aliases are highly flexible and can be tailored to meet your specific needs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Sharing and Collaboration
&lt;/h3&gt;

&lt;p&gt;If you have suggestions or additional aliases that could benefit others, consider contributing to the Gist. Collaboration and knowledge sharing are key to enhancing our collective Git experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;With this extensive list of Git aliases and the foundational knowledge from this post, you're well-equipped to make your Git usage more efficient and enjoyable. Embrace the power of Git aliases and watch your productivity soar!&lt;/p&gt;

&lt;p&gt;Remember, the key to effective use of Git aliases lies in identifying the Git commands you use most frequently and simplifying them to suit your workflow.&lt;/p&gt;

</description>
      <category>git</category>
      <category>dotfiles</category>
    </item>
    <item>
      <title>Tidy Up Your VSCode Explorer with File Nesting</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Thu, 18 Jan 2024 03:45:25 +0000</pubDate>
      <link>https://dev.to/roalcantara/tidy-up-your-vscode-explorer-with-file-nesting-2d0h</link>
      <guid>https://dev.to/roalcantara/tidy-up-your-vscode-explorer-with-file-nesting-2d0h</guid>
      <description>&lt;p&gt;Just a quick note of a nifty VSCode feature to streamline the project's explorer view by nesting related files under a single parent file. This is done through the &lt;code&gt;explorer.fileNesting.patterns&lt;/code&gt; setting. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Frxvtu538icqjhqtscbk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Frxvtu538icqjhqtscbk6.png" alt="explorer.fileNesting.patterns in action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s a visual aid that keeps your workspace uncluttered.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Configure File Nesting
&lt;/h2&gt;

&lt;p&gt;To configure file nesting, access your settings JSON file and add or modify the &lt;code&gt;explorer.fileNesting.patterns&lt;/code&gt;. Here's an example that nests common &lt;em&gt;project files&lt;/em&gt; under &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"explorer.fileNesting.enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"explorer.fileNesting.expand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"explorer.fileNesting.patterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"package.json"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".babelrc, .browserslistrc, .dockerignore, .editorconfig, .env, .eslintignore, .eslintrc.&lt;em&gt;, .gitignore, .graphqlrc.&lt;/em&gt;, .nvmrc, .prettierignore, .prettierrc.*, README.md, babel.config.json, cypress.json, jest.config.ts, jest.preset.js, nx.json, package.json, tsconfig.base.json, tsconfig.json, workspace.json, yarn.lock, vercel.json, netlify.toml, pnpm-lock.yaml"&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Benefits of File Nesting&lt;br&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cleaner Workspace:&lt;/strong&gt; Reduces clutter by showing only relevant files at a glance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Focus:&lt;/strong&gt; Helps you focus on the files you are actively working on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Organization:&lt;/strong&gt; Groups logically related files together.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember, you can always adapt the nesting patterns to fit your project's structure and your personal preferences.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_64#_explorer-file-nesting" rel="noopener noreferrer"&gt;VSCode Docs - Explorer file nesting&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>settings</category>
    </item>
    <item>
      <title>Some suggestions on GitHub's Pull Request Settings to Think About</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Mon, 25 Sep 2023 14:26:23 +0000</pubDate>
      <link>https://dev.to/roalcantara/some-pull-request-settings-on-github-to-think-about-lk8</link>
      <guid>https://dev.to/roalcantara/some-pull-request-settings-on-github-to-think-about-lk8</guid>
      <description>&lt;p&gt;GitHub offers different ways to merge pull requests into your repository. &lt;/p&gt;

&lt;p&gt;Depending on your project’s needs and preferences, you can choose which merge methods to enable or disable in your repository settings. Here are some suggestions of pull request settings on GitHub to consider/think about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Allow Merge Commits:”&lt;/strong&gt; ❌&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This means that you cannot use the merge commit method to merge pull requests. &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-merging-for-pull-requests" rel="noopener noreferrer"&gt;The merge commit method creates a new commit that combines the commits from the base branch and the head branch.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;“Allow Squash Merging”&lt;/strong&gt; ❌&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This means that you cannot use the squash merge method to merge pull requests. &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-squashing-for-pull-requests" rel="noopener noreferrer"&gt;The squash merge method combines all the commits from the head branch into a single commit and adds it to the base branch.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;“Allow Rebase Merging”&lt;/strong&gt; ✅&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This means that you can use the rebase merge method to merge pull requests. &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-rebasing-for-pull-requests" rel="noopener noreferrer"&gt;The rebase merge method applies the commits from the head branch individually on top of the base branch.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;“Always suggest updating pull request branches”&lt;/strong&gt; ✅&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This means that GitHub will suggest that you update the head branch of your pull request if there are new commits on the base branch. &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-suggestions-to-update-pull-request-branches" rel="noopener noreferrer"&gt;This can help avoid merge conflicts and keep the commit history clean.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;“Automatically delete head branches”&lt;/strong&gt; ✅&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This means that GitHub will automatically delete the head branch of your pull request after it is merged. &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-the-automatic-deletion-of-branches" rel="noopener noreferrer"&gt;This can help keep your repository organized and avoid unnecessary branches.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These are some of the pull request settings on GitHub that you can consider or think about for your project. &lt;/p&gt;

&lt;p&gt;By choosing the right merge methods and options, you can ensure that your pull requests are merged smoothly and efficiently, while maintaining a clear and consistent commit history.&lt;/p&gt;

&lt;p&gt;You can also customize your pull request settings further by using branch protection rules, required reviews, status checks, and &lt;a href="https://docs.github.com/en/github/collaborating-with-pull-requests" rel="noopener noreferrer"&gt;more&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>pullrequests</category>
    </item>
    <item>
      <title>The one on Firebase 🔥</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Thu, 21 Sep 2023 17:33:17 +0000</pubDate>
      <link>https://dev.to/roalcantara/the-one-on-firebase-17b2</link>
      <guid>https://dev.to/roalcantara/the-one-on-firebase-17b2</guid>
      <description>&lt;p&gt;A curated list of &lt;strong&gt;awesome&lt;/strong&gt; resources on Firebase!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build extraordinary apps with Firebase&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All the tools you need to build a successful app: reach new users, keep them engaged, scale up an infrastructure to meet that demand, in addition to earning money.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/O17OWyx08Cg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Test different variants with ease&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Improve your app experience by creating variants of your app and testing them with real users, then use the results to make improvements that drive the metrics you care about, like user engagement and revenue.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/OxMQORNh2E4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Realtime crash reporting&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lightweight, realtime crash reporter that helps you track, prioritize, and fix stability issues that erode your app quality, intelligently grouping crashes and highlighting the circumstances that lead up to them.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/k_mdNRZzd30"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Create personalized experiences&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Change the look-and-feel of your app, gradually roll out features, run A/B tests, and deliver customized content to certain users, all from the cloud without needing to publish a new version of your app.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_CXXVFPO6f0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Engage active users with contextual messages&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Send targeted, personalized, and contextual messages that nudge them through app funnels toward the ultimate in-app action, like subscribing, watching a video, completing a level, or buying an item, triggered based on user behavior.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/5MRKpvKV2pg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Re-engage users with personalized messages&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Manage and send notifications to your users easily, measuring the effectiveness of your messages, with no additional coding required.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/rTB7fTqMlS0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Bring the power of machine learning&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A set of tools and services for bringing powerful machine learning features to your app.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/p5-BDRCAkMI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Distribute pre-release builds to trusted testers&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Manage all of your pre-release testing on Android and iOS in one place.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/SiPOaV-5j9o"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Prepackaged solutions with extended functionalities&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Written, tested, and debugged by the Firebase team.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/9YOWO2zQkmY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📉 Predictions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Predict user behavior with machine learning&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Increase user retention, reduce churn, and improve in-app purchase revenue with predictive analytics and targeting.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ORrvrVEHJz4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Getting Started with Predictions&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anticipate your users’ actions through machine-learned models of their behavior: which of your users are likely to churn, which are likely to make in-app purchases, and etc.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/244DL0YXdhU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📈 Analytics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Behavioral analytics and marketing analytics&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Provide all the data in one easy place. It's free and unlimited analytics that combines both behavioral analytics -- who your users are and what they do in your app -- with marketing analytics -- which lets you see which campaigns brought users to your app in the first place.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/8iZpH7O6zXo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Track events with Google Analytics for Firebase&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Events are user interactions that you want to measure. Events can be automatically collected or manually defined by you, used to create audiences and analyze user behavior.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/cn1Vx9pX-yQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Conversions: events that matter the most&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Conversions shows how many conversion events and purchases, along with how much revenue and life-time value were driven by each aspect of your marketing (e.g., campaign, ad network, creative)&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/tTMGCQn5rxk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Walkthrough the Google Analytics for Firebase dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Get to know all of your reports and settings.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/QDOZbhXWfQI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Use audiences and user properties to analyze users&lt;/strong&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/50zTCzySXEg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature flagging to test new features&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Change the behavior and appearance of your app without requiring users to download an app update. Test different features and then analyze the results.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/23T9SGLcDsM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Tracking events&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ever wondered which users are interacting with your app, what part of your app they are spending the most time on, and where they are encountering issues?&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/kpkW78OSbiw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Tracking marketing campaigns&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Know which marketing efforts get the most new users and which marketing efforts keep them coming back.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/lvADEr1CfEs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;How to monitor errors and performance in Cloud Functions with Open Telemetry&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Leverage the Google Cloud Platform to adopt a modern observability stack like &lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt; to effectively monitor Cloud Functions.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/61WC7urgvQ4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;[PLAYLIST: Google Analytics for Firebase]&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Google Analytics for Firebase is a free app measurement solution that provides insight on app usage and user engagement, helps to understand clearly how users behave, which enables informed decisions regarding app marketing and performance optimizations.&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.youtube.com/playlist?list=PLl-K7zZEsYLkV1DCmC8Vj9Wl9hjVI2AJm&amp;amp;amp%3Bsi=j4fiLTnOxL_7MqnH" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--cPx4Ii41--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.ytimg.com/vi/8iZpH7O6zXo/hqdefault.jpg%3Fsqp%3D-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE%3D%26rs%3DAOn4CLDa8Hmxqv9bdy0krtBOvkAoXpFDyw%26days_since_epoch%3D19976" height="270" class="m-0" width="480"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.youtube.com/playlist?list=PLl-K7zZEsYLkV1DCmC8Vj9Wl9hjVI2AJm&amp;amp;amp%3Bsi=j4fiLTnOxL_7MqnH" rel="noopener noreferrer" class="c-link"&gt;
          Google Analytics for Firebase - YouTube
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Google Analytics for Firebase is a free app measurement solution that provides insight on app usage and user engagement. Documentation here: https://goo.gl/7...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--IjILtKgL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.youtube.com/s/desktop/536ed9a8/img/favicon.ico" width="16" height="16"&gt;
        youtube.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🔌 Extensions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Firebase Extensions Hub&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find extensions to build an app quickly and easily&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://extensions.dev" rel="noopener noreferrer"&gt;
      extensions.dev
    &lt;/a&gt;
&lt;/div&gt;

&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Quickstart&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Get started with the amazing Firebase Extensions&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/agity_5plBU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;[Firebase Summit "21] Build your retail app step-by-step&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build a web-based coffee retail app with fully functional e-commerce features using Firebase products including Firestore, Authentication, and Extensions.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/nhCbAezbiQ8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Connect millions of developers to your product by building a Firebase Extension&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sign up, build, and publish your own extension on extensions.dev for Firebase and Google Cloud developers. This could be either a utility package, an API integration, database functionality, or something else.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PLOw63DvZdc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📰 Updates
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The biggest news from Firebase Demo Day 2023&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Top six biggest announcements that include (but not limited to) Duet AI in Firebase, AI-powered automated app testing, Firebase Flutter SDK support for Windows development, Firebase Hosting’s integration with Project IDX, and more.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/zFHp6uj3aJ0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Firebase Demo Day 2023&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Short demos that showcase what’s new, what’s possible, and how you can solve your biggest app development challenges with Firebase.&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.youtube.com/playlist?list=PLl-K7zZEsYLkUthzGfGv7f1rbcgLK_Nq8&amp;amp;amp%3Bsi=o8iHCywfm-f8AB8u" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--kvb1rms9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.ytimg.com/vi/zFHp6uj3aJ0/hqdefault.jpg%3Fsqp%3D-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE%3D%26rs%3DAOn4CLAx_3M5A4TUlNX5bjiJG-bk0pv47Q%26days_since_epoch%3D19976" height="270" class="m-0" width="480"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.youtube.com/playlist?list=PLl-K7zZEsYLkUthzGfGv7f1rbcgLK_Nq8&amp;amp;amp%3Bsi=o8iHCywfm-f8AB8u" rel="noopener noreferrer" class="c-link"&gt;
          Firebase Demo Day - YouTube
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Join us on November 8, 2023 for a new virtual experience where we’ll unveil short demos that showcase what’s new, what’s possible, and how you can solve your...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--IjILtKgL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.youtube.com/s/desktop/536ed9a8/img/favicon.ico" width="16" height="16"&gt;
        youtube.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Firebase Summit ‘22 Keynote&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Latest product updates, shows demos of how it works smoothly with the ecosystem of developer tools to accelerate app development.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/D4e_TTY2dfI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Catch up on @ Google I/O ‘23&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;From new AI Extensions to real-time updates for Remote Config, learn how to make full stack development seamless and simpler.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/rGqj6U7SawA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What’s new in Cloud Firestore at Google I/O ‘23&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The latest query features, Eventarc integration that supports triggering in new compute destinations, and Terraform provisioning.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/rW9MkxD5318"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awesome</category>
      <category>cheatsheet</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Git-Flow vs GitHub flow</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Mon, 18 Sep 2023 15:41:27 +0000</pubDate>
      <link>https://dev.to/roalcantara/github-flow-32h3</link>
      <guid>https://dev.to/roalcantara/github-flow-32h3</guid>
      <description>&lt;h2&gt;
  
  
  A Practical Comparison
&lt;/h2&gt;

&lt;p&gt;When choosing a Git branching model, consider these widely adopted approaches:&lt;/p&gt;




&lt;h3&gt;
  
  
  The &lt;strong&gt;GitFlow &lt;a href="https://gitkraken.com/learn/git/git-flow" rel="noopener noreferrer"&gt;✵&lt;/a&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Suited for structured release cycles&lt;/li&gt;
&lt;li&gt;Helps manage complex projects with long-lived branches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmzqhu0f2kr9ss9jvqz78.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmzqhu0f2kr9ss9jvqz78.png" alt="GitFlow" width="800" height="1060"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;strong&gt;GitHub flow &lt;a href="https://docs.github.com/en/get-started/quickstart/github-flow" rel="noopener noreferrer"&gt;✵&lt;/a&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ideal for continuous deployment and rapid iteration&lt;/li&gt;
&lt;li&gt;Streamlined for frequent releases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vnx8scvs2qal44qb8o5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vnx8scvs2qal44qb8o5.png" alt="GitHubFlow" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A quick comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Git-Flow&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;GitHub flow&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Designed for structured, long-term development cycles&lt;/td&gt;
&lt;td&gt;Optimized for Continuous Integration and delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Main focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Structured release cycles&lt;/td&gt;
&lt;td&gt;Continuous deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Main branches&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;master&lt;/code&gt;, &lt;code&gt;develop&lt;/code&gt;, &lt;code&gt;feature&lt;/code&gt;, &lt;code&gt;release&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;main&lt;/code&gt;, short-lived feature branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Higher; suited for larger projects&lt;/td&gt;
&lt;td&gt;Lower; suited for fast-moving projects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release strategy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-stage releases (dev, QA, prod)&lt;/td&gt;
&lt;td&gt;Direct to production after merging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large apps with formal releases&lt;/td&gt;
&lt;td&gt;Web apps, startups, frequent releases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Challenges&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can slow down development due to its complexity and multiple branches&lt;/td&gt;
&lt;td&gt;Can be too simplistic for large projects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large-scale projects such as operating systems or ERP systems&lt;/td&gt;
&lt;td&gt;SaaS platforms, mobile apps with frequent updates, or web services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  DECISION TREE
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr12i0xntz6sh11xvod2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr12i0xntz6sh11xvod2.png" alt="Decision Tree" width="800" height="740"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  SUMMARY
&lt;/h2&gt;

&lt;p&gt;Both &lt;strong&gt;&lt;a href="https://gitkraken.com/learn/git/git-flow" rel="noopener noreferrer"&gt;Git-Flow&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://docs.github.com/en/get-started/quickstart/github-flow" rel="noopener noreferrer"&gt;GitHub flow&lt;/a&gt;&lt;/strong&gt; serve distinct purposes.&lt;/p&gt;

&lt;p&gt;For agility, &lt;a href="https://docs.github.com/en/get-started/quickstart/github-flow" rel="noopener noreferrer"&gt;GitHub flow&lt;/a&gt; streamlines development and deployment, fostering faster iteration and innovation.&lt;/p&gt;

&lt;p&gt;While &lt;strong&gt;&lt;a href="https://gitkraken.com/learn/git/git-flow" rel="noopener noreferrer"&gt;Git-Flow&lt;/a&gt;&lt;/strong&gt; is structured for enterprise applications, &lt;strong&gt;GitHub flow&lt;/strong&gt; shines for speed and simplicity.&lt;/p&gt;

&lt;p&gt;With fewer branches and a direct-to-production process, &lt;a href="https://git-scm.com/book/en/v2" rel="noopener noreferrer"&gt;GitHub flow&lt;/a&gt; enables teams to focus on delivering value quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  REFERENCES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/book/en/v2" rel="noopener noreferrer"&gt;Pro Git book&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/get-started/quickstart/github-flow" rel="noopener noreferrer"&gt;Git Flow vs GitHub flow | Alex Hyett&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/juLIxo42A_s" rel="noopener noreferrer"&gt;The GitHub flow - GitHub Universe 2016&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/fsvlzHF6NNg" rel="noopener noreferrer"&gt;Fine Tuning Your GitHub flow: A Deeper Dive Into GitHub Workflows - GitHub Universe 2017&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://alexhyett.com/git-flow-github-flow" rel="noopener noreferrer"&gt;Git Flow vs GitHub flow | Alex Hyett&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  DISCLAIMER
&lt;/h2&gt;

&lt;p&gt;This content is my own exploration of Git workflows and is open to feedback and new insights.&lt;/p&gt;

</description>
      <category>awesome</category>
      <category>cheatsheet</category>
      <category>gitflow</category>
      <category>githubflow</category>
    </item>
    <item>
      <title>:wq cheats/code-review</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Wed, 13 Sep 2023 19:36:36 +0000</pubDate>
      <link>https://dev.to/roalcantara/wq-cheatscode-review-1hfb</link>
      <guid>https://dev.to/roalcantara/wq-cheatscode-review-1hfb</guid>
      <description>&lt;h2&gt;
  
  
  The One About Code Reviews
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;TL;RD&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Some best practices for getting great Code Reviews&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keeping the Pull Request small and focused on a single feature or bug fix&lt;/li&gt;
&lt;li&gt;Providing clear and concise descriptions of the changes made&lt;/li&gt;
&lt;li&gt;Including relevant documentation and tests&lt;/li&gt;
&lt;li&gt;Addressing any known issues or potential concerns in the description&lt;/li&gt;
&lt;li&gt;Requesting specific feedback or areas of review from the reviewers&lt;/li&gt;
&lt;li&gt;Being responsive and open to feedback during the review process&lt;/li&gt;
&lt;li&gt;Making changes and updates based on the feedback received&lt;/li&gt;
&lt;li&gt;Keeping the Pull Request up-to-date with the latest changes in the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Some best practices for giving great Code Reviews&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting clear expectations for the review process&lt;/li&gt;
&lt;li&gt;Focusing on the code, not the person who wrote it&lt;/li&gt;
&lt;li&gt;Providing specific, actionable feedback&lt;/li&gt;
&lt;li&gt;Being respectful and constructive in your comments&lt;/li&gt;
&lt;li&gt;Prioritizing high-impact issues over minor ones&lt;/li&gt;
&lt;li&gt;Following up on the review to ensure that feedback is addressed&lt;/li&gt;
&lt;li&gt;Encouraging collaboration and discussion among team members.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Some common mistakes to avoid&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making the review personal or attacking the author&lt;/li&gt;
&lt;li&gt;Focusing on minor issues at the expense of larger ones&lt;/li&gt;
&lt;li&gt;Being too nitpicky or pedantic&lt;/li&gt;
&lt;li&gt;Not providing enough context or explanation for your feedback&lt;/li&gt;
&lt;li&gt;Not following up on the review to ensure that feedback is addressed&lt;/li&gt;
&lt;li&gt;Not being open to feedback yourself&lt;/li&gt;
&lt;li&gt;Not considering the bigger picture or the project's goals.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  My Favorite Resources on Code Reviews
&lt;/h3&gt;

&lt;p&gt;Curated list of tools, articles, books, and any other resource related to code review&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Pull Requests, Code Review, and the GitHub Flow&lt;/strong&gt; • &lt;a href="https://youtu.be/vCwuZfK0VG4" rel="noopener noreferrer"&gt;GitHub Universe 2015&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Discusses the benefits of using the GitHub Flow for development. GitHub Flow helps to promote collaboration, code review, and continuous delivery.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What are pull requests?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Pull requests are a way to propose changes to a codebase and get them reviewed by other developers.&lt;br&gt;
They are a key part of the GitHub Flow, a development workflow that emphasizes collaboration and code review.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Why are pull requests important?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Pull requests help to ensure that code is of high quality and that it meets the team's standards. &lt;br&gt;
They also help to promote collaboration and knowledge sharing among developers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How to create a good pull request&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write a clear and concise description of your changes.&lt;/li&gt;
&lt;li&gt;Make sure your changes are small and focused.&lt;/li&gt;
&lt;li&gt;Test your changes thoroughly before submitting your pull request.&lt;/li&gt;
&lt;li&gt;Be responsive to feedback from reviewers.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;How to review a pull request&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take the time to read and understand the changes.&lt;/li&gt;
&lt;li&gt;Test the changes yourself.&lt;/li&gt;
&lt;li&gt;Provide constructive feedback to the developer.&lt;/li&gt;
&lt;li&gt;Be respectful of the developer's time.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Here are some additional key takeaways from the talk:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull requests should be used for all changes to the codebase, no matter how small.&lt;/li&gt;
&lt;li&gt;Code reviews should be focused on the overall quality of the code, not just on finding bugs.&lt;/li&gt;
&lt;li&gt;It is important to be respectful of the developer's time when providing feedback on a pull request.&lt;/li&gt;
&lt;li&gt;The GitHub Flow is a great development workflow for teams of all sizes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Code Review is an Architectural Necessity&lt;/strong&gt; • &lt;a href="https://youtu.be/pJFM321_lAs" rel="noopener noreferrer"&gt;GitHub Universe 2016&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Emphasizes the importance of making code review a regular part of the development process. Code review should be seen as an investment in the quality and maintainability of the software system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code review is an architectural necessity because it helps to ensure that code is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Correct:&lt;/strong&gt; Code review helps to catch bugs and errors in code before it is deployed to production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent:&lt;/strong&gt; Code review helps to ensure that code is written in a consistent style and that it follows the team's coding standards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainable:&lt;/strong&gt; Code review helps to ensure that code is easy to read and understand, making it easier to maintain in the future.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure:&lt;/strong&gt; Code review can help to identify and fix security vulnerabilities in code.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Code review can also help to improve the overall architecture of a software system by:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identifying and refactoring potential architectural flaws:&lt;/strong&gt; Code review can help to identify areas of the code that are poorly designed or that could be improved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ensuring that the code is aligned with the overall architectural vision for the system:&lt;/strong&gt; Code review can help to ensure that the code is being written in a way that is consistent with the team's overall architectural vision for the system.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Tips for effective code review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set clear expectations for code reviews:&lt;/strong&gt; The team should have a clear understanding of what is expected of code reviews, such as what types of issues should be raised and how the reviews should be conducted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a code review tool:&lt;/strong&gt; A code review tool can help to streamline the code review process and make it more efficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be constructive in your feedback:&lt;/strong&gt; Code reviewers should focus on providing constructive feedback that will help the developer improve their code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be respectful of the developer's time:&lt;/strong&gt; Code reviews should be conducted in a timely manner, and reviewers should be respectful of the developer's time.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Implementing a Strong Code-Review Culture&lt;/strong&gt; • &lt;a href="https://youtu.be/PJjmw9TRB7s" rel="noopener noreferrer"&gt;RailsConf 2015&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code reviews are not about catching bugs. &lt;br&gt;
Modern code reviews are about socialization, learning, and teaching.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The primary purpose of code review:&lt;/strong&gt; Improve the overall code health of the system being worked on, not to catch bugs or enforce style guides.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reviewers should favor approving a change, even if the change isn’t perfect:&lt;/strong&gt; Once it is in a state where it definitely improves the overall code health of the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reviewers should balance out:&lt;/strong&gt; The need to make forward progress compared to the importance of the changes they are suggesting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reviewers should also mentor developers:&lt;/strong&gt; By teaching them something new about a language, a framework, or general software design principles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reviewers should not require the author to polish every tiny piece of a change before granting approval:&lt;/strong&gt; But they should feel free to leave comments expressing that something could be better, prefixed with something like &lt;code&gt;"Nit: "&lt;/code&gt; to let the author know that it’s just a point of polish that they could choose to ignore.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reviewing code and writing easily-reviewed features are skills:&lt;/strong&gt; That will make developers better and more productive teammates.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Goldilocks And The Three Code Reviews&lt;/strong&gt; • &lt;a href="https://youtu.be/d2CMwgm2pXk" rel="noopener noreferrer"&gt;JSConf Budapest 2017&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Encourages developers to be supportive of each other and to learn from each other's code&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The three types of code reviews
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Too short:&lt;/strong&gt; This type of review is too focused on finding bugs, and it doesn't give enough feedback on the overall quality of the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Too long:&lt;/strong&gt; This type of review is too nitpicky, and it can discourage developers from submitting their code for review.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Just right:&lt;/strong&gt; This type of review is focused on finding bugs and improving the overall quality of the code, but it is also respectful of the developer's time and effort.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to write a good code review
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Focus on the overall quality of the code, not just on finding bugs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be constructive and specific in your feedback.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be respectful of the developer's time and effort.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to get the most out of code reviews
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Be open to feedback and suggestions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be willing to make changes to your code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask questions if you don't understand something.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;The Science of Code Reviews&lt;/strong&gt; • &lt;a href="https://youtu.be/pL_fJ2fQSZw" rel="noopener noreferrer"&gt;DPC2018&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code reviews should be seen as an opportunity to learn and grow, not as a way to criticize or blame developers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code reviews are an important part of the software development process:&lt;/strong&gt; They help to improve the quality of the code by identifying and fixing bugs, improving the overall design of the code, and ensuring that the code follows the team's coding standards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;However, code reviews can be time-consuming and inefficient:&lt;/strong&gt; It can be difficult to know which parts of the code to focus on, and it can be challenging to provide constructive feedback.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Research on code reviews has shown that there are a number of factors that can affect the effectiveness of code reviews. These factors include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The size and complexity of the code being reviewed.&lt;/li&gt;
&lt;li&gt;The experience and expertise of the reviewers.&lt;/li&gt;
&lt;li&gt;The process used for the code review.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Based on this research, Kuipers recommends a number of best practices for code reviews
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Focus on the most important parts of the code:&lt;/strong&gt; Not all code is created equal. Some parts of the code are more important than others, and they should be the focus of the code review.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use a code review tool:&lt;/strong&gt; A code review tool can help to automate tasks such as identifying potential bugs and code violations. This can save time and effort, and it can help to improve the quality of the code review.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Provide constructive feedback:&lt;/strong&gt; The goal of a code review is to improve the code, not to criticize the developer. Feedback should be specific and actionable, and it should be delivered in a respectful and constructive manner.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Code Reviews: Honesty, Kindness, Inspiration: Pick Three by Jacob Stoebel&lt;/strong&gt; • &lt;a href="https://youtu.be/hP_2XKYia9I" rel="noopener noreferrer"&gt;RubyConf 2017&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Introduces the &lt;strong&gt;Liz Lerman Critical Response&lt;/strong&gt; process for code reviews. Encouraging to try out this process and see how it can improve their code reviews and their team culture&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code reviews can be both honest and nice:&lt;/strong&gt; While code reviews should be both honest and kind, they should be focused on inspiring creators to go back to their work, excited to make it better. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Liz Lerman Critical Response process consists of:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;#1. statement of meaning&lt;/li&gt;
&lt;li&gt;#2. artist questions&lt;/li&gt;
&lt;li&gt;#3. neutral questions&lt;/li&gt;
&lt;li&gt;#4. permissioned opinions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Amazing Code Reviews: Creating a Superhero Collective&lt;/strong&gt; • &lt;a href="https://youtu.be/ly86Wq_E18o" rel="noopener noreferrer"&gt;GOTO 2019&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Many code reviews are superficial, unclear, or unhelpful, which can lead to frustration, wasted time, and missed opportunities&lt;br&gt;
Code reviews are an important step for improving the code health, quality, and knowledge of the system being worked on&lt;br&gt;
How to create a culture of amazing code reviews in software development teams&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Key principles and practices of Shopify's code review process
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Focus on the &lt;strong&gt;intent&lt;/strong&gt; of the change, not the &lt;strong&gt;implementation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Provide &lt;strong&gt;actionable feedback&lt;/strong&gt; that helps the author improve their code and learn something new&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;positive language&lt;/strong&gt; and &lt;strong&gt;empathy&lt;/strong&gt; to communicate their feedback in a respectful and constructive way&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust&lt;/strong&gt; the author to make the final decision on their change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Celebrate&lt;/strong&gt; the author's work and achievements&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Benefits and challenges of this code review process, such as:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Increases the &lt;strong&gt;collaboration&lt;/strong&gt;, &lt;strong&gt;learning&lt;/strong&gt;, and &lt;strong&gt;motivation&lt;/strong&gt; of the team&lt;/li&gt;
&lt;li&gt;Improves the &lt;strong&gt;consistency&lt;/strong&gt;, &lt;strong&gt;readability&lt;/strong&gt;, and &lt;strong&gt;maintainability&lt;/strong&gt; of the code base&lt;/li&gt;
&lt;li&gt;Requires more &lt;strong&gt;time&lt;/strong&gt;, &lt;strong&gt;effort&lt;/strong&gt;, and &lt;strong&gt;skill&lt;/strong&gt; from both reviewers and authors&lt;/li&gt;
&lt;li&gt;Depends on the &lt;strong&gt;context&lt;/strong&gt;, &lt;strong&gt;culture&lt;/strong&gt;, and &lt;strong&gt;preferences&lt;/strong&gt; of the team&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Creating Simple and Effective Guidelines for Code Reviews&lt;/strong&gt; • &lt;a href="https://newrelic.com/blog/best-practices/code-review-guidelines" rel="noopener noreferrer"&gt;@newrelic&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simple and effective code review guidelines that will help them to improve the quality of their code&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clear, concise, and easy to understand&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;They should be written in a way that is accessible to both experienced and inexperienced developers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tailored to the specific needs of the team and the project&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The guidelines should take into account the type of code being reviewed, the experience level of the reviewers, and the goals of the code review.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Focused on the quality of the code, not on the individual developer&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The guidelines should be used to identify and fix bugs, improve the overall design of the code, and ensure that the code follows the team's coding standards.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Updated regularly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To reflect the team's changing needs and practices&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recommendations for code review guidelines
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Identifying and fixing bugs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for common bugs such as missing semicolons, unending loops, and missing error handling.&lt;/li&gt;
&lt;li&gt;Be aware of the team's coding standards and ensure that the code follows them.&lt;/li&gt;
&lt;li&gt;Test the code yourself to see if it works as expected.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Improving the overall design of the code&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for areas where the code can be simplified or refactored.&lt;/li&gt;
&lt;li&gt;Suggest ways to make the code more readable and maintainable.&lt;/li&gt;
&lt;li&gt;Consider the overall architecture of the system and ensure that the code fits well within it.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Ensuring that the code follows the team's coding standards&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for areas where the code does not follow the team's coding standards.&lt;/li&gt;
&lt;li&gt;Suggest ways to make the code more consistent with the team's standards.&lt;/li&gt;
&lt;li&gt;Be aware of any new coding standards that have been adopted by the team.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Code Review As A Gateway&lt;/strong&gt; • &lt;a href="https://blog.jetbrains.com/upsource/2017/01/18/code-review-as-a-gateway" rel="noopener noreferrer"&gt;@jetbrains&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Overall, code review as a gateway is a valuable process that can help to improve the quality of code, reduce the risk of regressions, and improve collaboration between developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code review as a gateway is a process where a code review is required before any code is merged into the main branch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This process can help to ensure that the code is of high quality and that it meets the team's standards.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  There are a number of benefits to using code review as a gateway
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Improved code quality&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Code reviews can help to identify and fix bugs in the code, improve the overall design of the code, and ensure that the code follows the team's coding standards.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reduced risk of regressions&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Code reviews can help to prevent regressions by ensuring that new code does not break existing functionality.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Improved collaboration&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Code reviews can help to improve collaboration between developers by providing a forum for developers to discuss their code and learn from each other.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  There are a few things to keep in mind when implementing code review as a gateway:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setting clear expectations&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;It is important to set clear expectations for code reviews, such as what types of issues should be raised and how the reviews should be conducted.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Providing training&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;It is important to provide training to developers on how to conduct effective code reviews.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Using a code review tool&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;A code review tool can help to automate tasks such as identifying potential bugs and code violations. This can save time and effort, and it can help to improve the quality of the code review.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Being flexible&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;It is important to be flexible when implementing code review as a gateway. There may be cases where it makes sense to bypass the code review process, such as for small changes or for changes that are made by experienced developers.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;How to Do Code Reviews Like a Human (Part One)&lt;/strong&gt; • &lt;a href="https://mtlynch.io/human-code-reviews-1" rel="noopener noreferrer"&gt;@mtlynch.io&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Emphasizes the importance of having a &lt;code&gt;"blameless culture"&lt;/code&gt; when it comes to code review. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Focus on finding and fixing bugs, not on blaming the developer who wrote the code.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Code review is a process in which one or more developers review the code of another developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code review can help to improve the quality of the code by identifying and fixing bugs, improving the overall design of the code, and ensuring that the code follows the team's coding standards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To be effective, code reviews should be conducted in a collaborative and respectful manner.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Here are some tips for doing code reviews like a human:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set clear expectations for the code review&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This includes things like what types of issues should be raised and how the reviews should be conducted.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be prepared for the code review&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This means taking the time to read and understand the code before the review begins.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be specific and constructive in your feedback&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Focus on providing feedback that will help the developer improve their code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be respectful of the developer's time&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Code reviews should be conducted in a timely manner, and reviewers should be respectful of the developer's time.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;How to Do Code Reviews Like a Human (Part Two)&lt;/strong&gt; • &lt;a href="https://mtlynch.io/human-code-reviews-2" rel="noopener noreferrer"&gt;@mtlynch.io&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Emphasizes the importance of creating a positive and supportive culture for code reviews. Code reviews should be seen as an opportunity to learn and grow, not as a way to criticize or blame developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How to handle disagreements in code reviews
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be respectful and open-minded&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even if you disagree with a developer's code, it's important to be respectful of their work and to be open to their perspective.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Try to understand the developer's motivation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why did they write the code in the way that they did? Once you understand their motivation, you can better understand their reasoning and you may be able to find a compromise.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be willing to compromise&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's important to be willing to compromise in code reviews. Not every change that you suggest will be accepted, and that's okay.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't be afraid to escalate the issue&lt;/strong&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can't come to an agreement with a developer, you may need to escalate the issue to a more senior developer or to a manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to give effective feedback in code reviews
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be specific and actionable&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Don't just say &lt;code&gt;"This code is bad."&lt;/code&gt; Explain why you think the code is bad and suggest a specific way to fix it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be positive and constructive&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Focus on providing feedback that will help the developer improve their code. Avoid being negative or critical.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be concise and to the point&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Don't overwhelm the developer with a lot of feedback. Focus on the most important issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be open to feedback yourself&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;It's important to be open to feedback from other developers, even if you don't agree with it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to get the most out of code reviews
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be open to feedback&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Be willing to listen to feedback from other developers and to make changes to your code based on their feedback.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be prepared for the code review&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Take the time to read and understand the code before the review begins.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be responsive to feedback&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;If a developer raises an issue with your code, try to address it promptly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ask questions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you don't understand something in the code, ask questions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;How to Give and Get Better Code Reviews&lt;/strong&gt; • &lt;a href="https://medium.com/hackernoon/how-to-give-and-get-better-code-reviews-e011c3cda55e" rel="noopener noreferrer"&gt;@medium&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Emphasizes the importance of creating a culture of &lt;code&gt;"trust"&lt;/code&gt; and &lt;code&gt;"respect"&lt;/code&gt; in order to foster effective code reviews. &lt;br&gt;
Encourages developers to be supportive of each other and to learn from each other's code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How to give better code reviews:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try to understand the context and the proposed solution.&lt;/li&gt;
&lt;li&gt;Be specific and actionable in your feedback.&lt;/li&gt;
&lt;li&gt;Focus on the overall quality of the code, not just on finding bugs.&lt;/li&gt;
&lt;li&gt;Be respectful of the developer's time and effort.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;How to get the most out of code reviews:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be open to feedback and suggestions.&lt;/li&gt;
&lt;li&gt;Be willing to make changes to your code.&lt;/li&gt;
&lt;li&gt;Ask questions if you don't understand something.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Additional tips:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set clear expectations for code reviews.&lt;/li&gt;
&lt;li&gt;Use a code review tool.&lt;/li&gt;
&lt;li&gt;Be constructive in your feedback.&lt;/li&gt;
&lt;li&gt;Be respectful of the developer's time.&lt;/li&gt;
&lt;li&gt;Make code review a regular part of the development process.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  REFERENCES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://leanpub.com/whattolookforinacodereview" rel="noopener noreferrer"&gt;What to Look for in a Code Review: A Guide for the Reviewer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://project-awesome.org/joho/awesome-code-review" rel="noopener noreferrer"&gt;A curated list of tools, articles, books, and any other resource related to code review&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/vCwuZfK0VG4" rel="noopener noreferrer"&gt;Pull Requests, Code Review, and the GitHub Flow - GitHub Universe 2015&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/pJFM321_lAs" rel="noopener noreferrer"&gt;Code Review is an Architectural Necessity - GitHub Universe 2016&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/PJjmw9TRB7s" rel="noopener noreferrer"&gt;RailsConf 2015 - Implementing a Strong Code-Review Culture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/d2CMwgm2pXk" rel="noopener noreferrer"&gt;Vaidehi Joshi: Goldilocks And The Three Code Reviews | JSConf Budapest 2017&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/pL_fJ2fQSZw" rel="noopener noreferrer"&gt;DPC2018: The Science of Code Reviews - Rick Kuipers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/hP_2XKYia9I" rel="noopener noreferrer"&gt;RubyConf 2017: Code Reviews: Honesty, Kindness, Inspiration: Pick Three by Jacob Stoebel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://newrelic.com/blog/best-practices/code-review-guidelines" rel="noopener noreferrer"&gt;Creating Simple and Effective Guidelines for Code Reviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jetbrains.com/upsource/2017/01/18/code-review-as-a-gateway" rel="noopener noreferrer"&gt;Code Review As A Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mtlynch.io/human-code-reviews-1" rel="noopener noreferrer"&gt;How to Do Code Reviews Like a Human (Part One)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mtlynch.io/human-code-reviews-2" rel="noopener noreferrer"&gt;How to Do Code Reviews Like a Human (Part Two)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/hackernoon/how-to-give-and-get-better-code-reviews-e011c3cda55e" rel="noopener noreferrer"&gt;How to Give and Get Better Code Reviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/ly86Wq_E18o" rel="noopener noreferrer"&gt;Amazing Code Reviews: Creating a Superhero Collective&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/roalcantara/sane-code.reviews" rel="noopener noreferrer"&gt;Sane Code Reviews: A guide to improve the Git(Hub) flow and commits messages • @roalcantara&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>awesome</category>
      <category>cheatsheets</category>
      <category>bestpractices</category>
      <category>codereview</category>
    </item>
    <item>
      <title>:wq cheats/git-commits</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Wed, 13 Sep 2023 19:30:15 +0000</pubDate>
      <link>https://dev.to/roalcantara/wq-cheatsgit-1lkj</link>
      <guid>https://dev.to/roalcantara/wq-cheatsgit-1lkj</guid>
      <description>&lt;h2&gt;
  
  
  Git Commits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cbea.ms/git-commit" rel="noopener noreferrer"&gt;How to Write a Git Commit Message&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thoughtbot.com/blog/5-useful-tips-for-a-better-commit-message" rel="noopener noreferrer"&gt;5 Useful Tips For A Better Commit Message&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://conventionalcommits.org/en/v1.0.0" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.aleksandrhovhannisyan.com/blog/atomic-git-commits" rel="noopener noreferrer"&gt;Atomic Git Commits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7 rules of a great Git commit message&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;#1 Keep in mind: This has all been said before.&lt;/li&gt;
&lt;li&gt;#2 Separate subject from body with a blank line&lt;/li&gt;
&lt;li&gt;#3 Limit the subject line to 50 characters&lt;/li&gt;
&lt;li&gt;#4 Capitalise the subject line&lt;/li&gt;
&lt;li&gt;#5 Do not end the subject line with a period&lt;/li&gt;
&lt;li&gt;#6 Use the imperative mood in the subject line&lt;/li&gt;
&lt;li&gt;#7 Wrap the body at 72 characters&lt;/li&gt;
&lt;li&gt;#8 Use the body to explain what and why vs. how&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Commit message structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;type&amp;gt;[optional scope]: &amp;lt;Description&amp;gt;

[optional body]

[optional footer(s)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Examples
&lt;/h4&gt;

&lt;p&gt;Commit with description and breaking change footer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat: Allow provided config object to extend other configs

BREAKING CHANGE: `extends` key in the config file is now used for extending other config files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit with ! to draw attention to breaking change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat!: Send an email to the customer when the product is shipped
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit with scope and ! to draw attention to breaking change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(api)!: Send email to the customer when product is shipped
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit with both! And BREAKING CHANGE footer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chore!: Drop support for Node 6

BREAKING CHANGE: use JavaScript features not available in Node 6.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit with nobody&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs(CHANGELOG): Correct spelling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit with scope&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(lang): Add Polish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit with a multi-paragraph body and multiple footers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix(requests): Prevent racing

Introduce a request ID and a reference to the latest request.

Also:
- Dismiss incoming responses other than from the latest request.
- Remove timeouts, which were used to mitigate the racing issue but are obsolete now.

Refs: #123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/medialesson/setting-up-github-copilot-for-better-commit-messages-in-vs-code-82d73fb6b016" rel="noopener noreferrer"&gt;Use GitHub Copilot for Better Commit Messages in VSCode&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Add to &lt;code&gt;settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// https://medium.com/medialesson/setting-up-github-copilot-for-better-commit-messages-in-vs-code-82d73fb6b016&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"github.copilot.chat.commitMessageGeneration.instructions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use conventional commit format: &amp;lt;type&amp;gt;[(scope)]: &amp;lt;Subject&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;[optional body]&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;[optional footer(s)]"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use types: feat, fix, docs, style, ref, test, revert, chore, ci, build, perf, git"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Include scope when relevant (e.g.: 'api', 'ui', 'auth', 'admin/users')"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Separate subject from body with a blank line"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The subject should use the imperative mood, be capitalised, short, clear, concise, descriptive, meaningful, and communicate the context surrounding a change"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Limit the subject line to 50 characters"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Do not end the subject line with a period"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The body should explain what and why vs. how"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wrap the body at 72 characters"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Reference issue numbers with # prefix"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use the footer to reference breaking changes with 'BREAKING CHANGE: &amp;lt;description&amp;gt;'"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use the footer to reference issues with 'Closes #&amp;lt;issue-number&amp;gt;'"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use the footer to reference links that may exceed 72 characters with 'More: https://very.long.link/lorem-ipsum-excepteur-anim-dolore-et-laborum-officia-nostrud-nisi-tempor-in.-Sint-laboris-ex-ea-ex/'"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Follow the constraints defined in the gitlint configuration, in order of precedence: ./.gitlint, ~/.config/gitlint/gitlint.cfg"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Tooling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jorisroovers.com/gitlint/latest" rel="noopener noreferrer"&gt;Gitlint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pre-commit.com" rel="noopener noreferrer"&gt;Pre-commit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://semantic-release.gitbook.io/semantic-release" rel="noopener noreferrer"&gt;Semantic Release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/compilerla/conventional-pre-commit" rel="noopener noreferrer"&gt;conventional-pre-commit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Nutlope/aicommits" rel="noopener noreferrer"&gt;aicommits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/coder/aicommit" rel="noopener noreferrer"&gt;aicommit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/di-sukharev/opencommit" rel="noopener noreferrer"&gt;opencommit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/book/en/v2" rel="noopener noreferrer"&gt;Pro Git book&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.rocketseat.com.br/como-fazer-um-commit-conventional-commits" rel="noopener noreferrer"&gt;Como fazer um commit semântico&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jorisroovers.com/gitlint/latest" rel="noopener noreferrer"&gt;Conventional Commits: Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtube.com/watch?v=gQVUCTVt39o" rel="noopener noreferrer"&gt;Git e Github na prática: Guia do iniciante&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://roalcantara.medium.com/a-guide-to-improve-the-git-hub-flow-and-commits-messages-b495461e1115" rel="noopener noreferrer"&gt;A guide to improve the Git(Hub) flow and commits messages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.alexhyett.com/git-flow-github-flow" rel="noopener noreferrer"&gt;Git Flow vs GitHub Flow | Alex Hyett&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/18188492/what-are-the-pros-and-cons-of-git-flow-vs-github-flow" rel="noopener noreferrer"&gt;What are the pros and cons of git-flow vs github-flow?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@vava_silva/choosing-the-right-git-workflow-for-your-project-gitflow-github-flow-and-gitlab-flow-6a12cb438ccb" rel="noopener noreferrer"&gt;Choosing the Right Git Workflow for Your Project: GitFlow, GitHub Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freshconsulting.com/insights/blog/git-development-workflows-git-flow-vs-github-flow" rel="noopener noreferrer"&gt;Workflows Comparison: Git Flow Vs GitHub Flow - Fresh Consulting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reviewpad.com/blog/github-flow-trunk-based-development-and-code-reviews" rel="noopener noreferrer"&gt;Git(Hub) Flow, Trunk Based Development, and Code reviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/medialesson/setting-up-github-copilot-for-better-commit-messages-in-vs-code-82d73fb6b016" rel="noopener noreferrer"&gt;Setting up GitHub Copilot for Better Commit Messages in VS Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>awesome</category>
      <category>cheatsheet</category>
      <category>bestpractices</category>
      <category>git</category>
    </item>
    <item>
      <title>:wq cheats/solid</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Wed, 13 Sep 2023 19:12:14 +0000</pubDate>
      <link>https://dev.to/roalcantara/wq-cheatssolid-5gk1</link>
      <guid>https://dev.to/roalcantara/wq-cheatssolid-5gk1</guid>
      <description>&lt;h2&gt;
  
  
  SOLID
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Design principles encourage us to create more maintainable, understandable, and flexible software. &lt;/p&gt;

&lt;p&gt;Consequently, as our applications grow in size, we can reduce their complexity and save ourselves a lot of headaches further down the road!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Single-responsibility
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;There should never be more than one reason for a class to change or every class should have only one responsibility&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is, a class should only have one responsibility. Furthermore, it should only have one reason to change. &lt;/p&gt;

&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;A class with one responsibility will have far fewer test cases&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lower coupling&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Less functionality in a single class will have fewer dependencies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Organization&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Smaller, well-organized classes are easier to search than monolithic ones.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Open–closed
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Software entities should be open for extension, but closed for modification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In doing so, we stop ourselves from modifying existing code and causing potential new bugs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Benefits:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Error Prevention&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Minimize the possibilities of error by not modifying existing classes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Functionality Extension&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Easily add new functionalities by adding new classes wherein no current functionality depends on the new classes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Responsibility Segregation&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Promote the Single Responsibility Principle&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Class Testing&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Unit test each class&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Liskov substitution
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is, if class A is a subtype of class B, we should be able to replace B with A without disrupting the behavior of our program.&lt;/p&gt;

&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code reusability&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Allows creating a set of related classes that can be used interchangeably without modifying the code. This makes it easier to reuse code and can save us time when we’re developing new features.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Easier maintenance&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Avoids introducing conditional logic or type checking to handle different subclasses. This makes the code more readable and easier to maintain. It also reduces the risk of introducing bugs or breaking changes when we add or modify subclasses.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reduced coupling&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Reduces the dependency between classes and make them more loosely coupled. This means that changes in one class will not affect other classes that depend on it. This also makes the code more flexible and adaptable to changing requirements&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Interface segregation
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Many client-specific interfaces are better than one general-purpose interface&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is, larger interfaces should be split into smaller ones. By doing so, we can ensure that implementing classes only need to be concerned about the methods that are of interest to them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency inversion
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Depend upon abstractions, not concretions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This way, instead of high-level modules depending on low-level modules, both will depend on abstractions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decoupling&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The code becomes more modular and less tightly coupled. This makes it easier to maintain, extend, and test the code. It also reduces the impact of changes in one module on other modules&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reusability:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The code becomes more reusable and adaptable. High-level modules can use different low-level modules that implement the same abstraction without modifying the code. This allows for swapping implementations, mocking dependencies, and supporting different scenarios&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inversion of control&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The flow of the application is inverted from low-level modules to high-level modules. High-level modules define the abstractions and own the interfaces, while low-level modules provide the implementations and depend on the interfaces. This gives more power and flexibility to the high-level modules&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.techonline.com/tech-papers/design-principles-and-design-patterns" rel="noopener noreferrer"&gt;Design Principles and Design Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/applying-solid-principles-typescript" rel="noopener noreferrer"&gt;Applying SOLID principles in TypeScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://baeldung.com/solid-principles" rel="noopener noreferrer"&gt;A Solid Guide to SOLID Principles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reflectoring.io/interface-segregation-principle/" rel="noopener noreferrer"&gt;Interface Segregation Principle: Everything You Need to Know&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reflectoring.io/single-responsibility-principle/" rel="noopener noreferrer"&gt;Single Responsibility Principle Unpacked&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>awesome</category>
      <category>cheatsheet</category>
      <category>coding</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>:wq cheat/12factor</title>
      <dc:creator>Rogério Rodrigues de Alcântara</dc:creator>
      <pubDate>Wed, 13 Sep 2023 17:33:29 +0000</pubDate>
      <link>https://dev.to/roalcantara/wq-cheat12factor-2n8h</link>
      <guid>https://dev.to/roalcantara/wq-cheat12factor-2n8h</guid>
      <description>&lt;h2&gt;
  
  
  &lt;a href="https://12factor.net" rel="noopener noreferrer"&gt;The Twelve-Factor App&lt;/a&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"A methodology for building modern, scalable, maintainable software-as-a-service apps."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Codebase&lt;/strong&gt; &lt;br&gt;
One codebase tracked in revision control, many deploys&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependencies&lt;/strong&gt; &lt;br&gt;
Explicitly declare and isolate dependencies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Config&lt;/strong&gt; &lt;br&gt;
Store config in the environment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backing services&lt;/strong&gt; &lt;br&gt;
Treat backing services as attached resources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build, release, run&lt;/strong&gt;&lt;br&gt;
Strictly separate build and run stages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Processes&lt;/strong&gt; &lt;br&gt;
Execute the app as one or more stateless processes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Port binding&lt;/strong&gt;&lt;br&gt;
Export services via port binding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Concurrency&lt;/strong&gt;&lt;br&gt;
Scale out via the process model&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Disposability&lt;/strong&gt;&lt;br&gt;
Maximize robustness with fast startup and graceful shutdown&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dev/prod parity&lt;/strong&gt;&lt;br&gt;
Keep development, staging, and production as similar as possible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logs&lt;/strong&gt;&lt;br&gt;
Treat logs as event streams&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Admin Processes&lt;/strong&gt;&lt;br&gt;
Run admin/management tasks as one-off processes&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://12factor.net" rel="noopener noreferrer"&gt;The Twelve-Factor App: A methodology for building modern, scalable, maintainable software-as-a-service apps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>awesome</category>
      <category>cheatsheet</category>
      <category>commons</category>
    </item>
  </channel>
</rss>
