<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Dídac Rios</title>
    <description>The latest articles on Forem by Dídac Rios (@didacrios).</description>
    <link>https://forem.com/didacrios</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%2F558791%2F199d1af0-a89e-4295-a994-48ff566e084e.jpeg</url>
      <title>Forem: Dídac Rios</title>
      <link>https://forem.com/didacrios</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/didacrios"/>
    <language>en</language>
    <item>
      <title>Understanding the Domain and Building the Team: The Foundations of Change (II)</title>
      <dc:creator>Dídac Rios</dc:creator>
      <pubDate>Sun, 19 Jan 2025 09:43:56 +0000</pubDate>
      <link>https://forem.com/didacrios/understanding-the-domain-and-building-the-team-the-foundations-of-change-ii-4442</link>
      <guid>https://forem.com/didacrios/understanding-the-domain-and-building-the-team-the-foundations-of-change-ii-4442</guid>
      <description>&lt;p&gt;When starting a complex project like the one we are tackling, it's essential to gather as much context as possible while also approaching the domain knowledge from scratch and exploring it with the help of domain experts. This activity not only helps the technical team align with business goals but also creates a global map that lays the foundation for making better decisions throughout the product lifecycle.&lt;/p&gt;

&lt;p&gt;To understand how the existing application worked, identify the various processes it executed, and determine how they were represented in the code, while establishing a common language with the previous team and current application users, we conducted initial sessions that were not very fruitful. At one point, we even considered whether we could move forward without these sessions and figure things out on our own, despite the potential for disruption.&lt;/p&gt;

&lt;h2&gt;
  
  
  EventStorming
&lt;/h2&gt;

&lt;p&gt;From the beginning of the project, as the tech lead, given the complexity of the project and the need for the team to take real ownership of the product, I pushed to adopt a domain-driven approach to both the project and the team.&lt;/p&gt;

&lt;p&gt;This approach allowed us to place the domain at the center of the narrative, aligning the entire team around a common language (&lt;em&gt;ubiquitous language&lt;/em&gt;), which facilitated communication and enabled us to map the application's current state.&lt;/p&gt;

&lt;p&gt;With this goal in mind, we formed the initial team and began preparing &lt;a href="https://www.eventstorming.com/" rel="noopener noreferrer"&gt;EventStorming&lt;/a&gt; sessions. This visual methodology helped us decompose the system’s key processes and identify relevant domain events and entities.&lt;/p&gt;

&lt;p&gt;To facilitate the sessions, we used a &lt;a href="https://miro.com/miroverse/event-storming/" rel="noopener noreferrer"&gt;Miro template&lt;/a&gt; that provided some guidance and a legend with key references to focus such sessions effectively. If you plan to conduct such a session, it’s helpful for participants to have a basic understanding of the concepts they’ll be working with, either through some pre-work or an explanation at the start of the session.&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%2F0xyl8n12zvjevg3m1x3d.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%2F0xyl8n12zvjevg3m1x3d.png" alt="EventStorming legend" width="711" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To maximize the effectiveness of these sessions, we developed a structured process divided into several phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Exploring Domain Events&lt;/strong&gt; (Big picture)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify the system's key events.&lt;/li&gt;
&lt;li&gt;Order them chronologically.&lt;/li&gt;
&lt;li&gt;Detect gaps and dependencies.&lt;/li&gt;
&lt;li&gt;Validate the sequence with domain experts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Refinement and Analysis&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add explanatory notes.&lt;/li&gt;
&lt;li&gt;Document doubts and questions.&lt;/li&gt;
&lt;li&gt;Delve deeper into each event.&lt;/li&gt;
&lt;li&gt;Highlight critical decision points.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Domain Modeling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify aggregates and their boundaries.&lt;/li&gt;
&lt;li&gt;Define actors and their roles.&lt;/li&gt;
&lt;li&gt;Establish commands that trigger processes.&lt;/li&gt;
&lt;li&gt;Document policies and business rules.&lt;/li&gt;
&lt;li&gt;Identify internal and external triggers for each event.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Documentation and Validation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organize and clean the collected information.&lt;/li&gt;
&lt;li&gt;Establish clear relationships between elements.&lt;/li&gt;
&lt;li&gt;Validate the model with all stakeholders.&lt;/li&gt;
&lt;li&gt;Create reference documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;EventStorming not only helped us understand the domain but also served as the starting point for applying &lt;em&gt;Domain-Driven Design (DDD)&lt;/em&gt; principles both strategic and tactical.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strategic Domain-Driven Design
&lt;/h3&gt;

&lt;p&gt;One of the most important aspects during the initial project phase was deciding how to structure the domain at a strategic level. The system's complexity, combined with the need to align technical and business goals, led us to adopt principles of Domain-Driven Design (DDD).&lt;/p&gt;

&lt;p&gt;During this process, one of the most useful tools was &lt;em&gt;Context Mapping&lt;/em&gt;. Although we were working with a monolith still awaiting refactoring, we took the time to identify various &lt;em&gt;Bounded Contexts&lt;/em&gt; within the domain. Practically speaking, this meant that while we had described and defined multiple conceptual contexts, technically, we operated within a single &lt;em&gt;Bounded Context&lt;/em&gt; with a shared kernel. This monolithic reality didn't prevent us from benefiting from this analysis.&lt;/p&gt;

&lt;p&gt;Although we didn't delve deeply into &lt;em&gt;Context Mapping&lt;/em&gt;, using these techniques at this stage was critical to ensuring the project had a clear path toward a domain-oriented architecture. This approach not only facilitated technical development but also fostered better collaboration between technical and business teams.&lt;/p&gt;

&lt;h4&gt;
  
  
  Defining Boundaries (&lt;em&gt;Bounded Contexts&lt;/em&gt;)
&lt;/h4&gt;

&lt;p&gt;Identifying the &lt;em&gt;Bounded Contexts&lt;/em&gt; helped us better understand how different parts of the system related to each other and to external systems. This exercise not only helped us manage complexity more efficiently but also established a clear foundation for the project's evolutionary steps. As the system transitions to a more modular architecture, these initial decisions will guide us in breaking down the monolith into more manageable components aligned with the defined contexts.&lt;/p&gt;

&lt;p&gt;It also helped us prioritize development efforts and identify parts of the system that could be simplified, decoupled, or eliminated. Technically, we focused on implementing &lt;em&gt;Anti-Corruption Layers&lt;/em&gt; (ACL) to interact with external systems without compromising our system's integrity.&lt;/p&gt;

&lt;p&gt;In our case, we initially identified five major contexts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Order Assignment&lt;/li&gt;
&lt;li&gt;Label Generation&lt;/li&gt;
&lt;li&gt;Order Preparation&lt;/li&gt;
&lt;li&gt;E-commerce Integration&lt;/li&gt;
&lt;li&gt;Bulk Order Preparation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These decisions not only established the foundation for a sustainable architecture but also ensured that development processes were more focused and aligned with business needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/dufky4znh/image/upload/v1736502607/event-storming2_nlyn9s.png" rel="noopener noreferrer"&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%2Fonpx4vzdbhtsccs8d9y5.png" alt="Bounded Contexts, OMS" width="200" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Ubiquitous Language
&lt;/h4&gt;

&lt;p&gt;Another key aspect was establishing a solid ubiquitous language. The advantages of defining this language far outweigh the extra translation effort or the risk of misinterpreting concepts. Domain Experts and developers must actively collaborate to create this common language, which goes beyond a simple glossary of terms. It's a living, dynamic resource that connects the technical team with domain experts.&lt;/p&gt;

&lt;p&gt;Implementing this ubiquitous anguage improved communication, reduced misunderstandings, and ensured the code faithfully represented the domain. Software development isn't just a technical activity; it's based on communication and collaboration. Thanks to the ubiquitous language, all team members work in alignment, resulting in more efficient technical solutions that better meet business needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tactical Domain-Driven Design
&lt;/h3&gt;

&lt;p&gt;Once we established the strategic framework, we moved on to implementing tactical DDD principles in the system. This allowed us to structure the code to reflect the domain's reality and ensure long-term sustainability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Entities and Value Objects
&lt;/h4&gt;

&lt;p&gt;Entities and Value Objects are two fundamental concepts in Domain-Driven Design (DDD). Understanding their differences and roles within the domain is crucial.&lt;/p&gt;

&lt;h4&gt;
  
  
  Entities
&lt;/h4&gt;

&lt;p&gt;Entities are domain elements with a unique identity that persists over time, even if their attributes change. This unique identity distinguishes them from other elements of the same type. Additionally, entities usually have a defined lifecycle within the system. Examples of entities we identified in the project include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Order: Represents a purchase order with a unique identity and an associated state.&lt;/li&gt;
&lt;li&gt;Product: Catalog item with attributes like SKU code, price, and description.&lt;/li&gt;
&lt;li&gt;Carrier: Company responsible for delivering orders with specific service options.&lt;/li&gt;
&lt;li&gt;Shop: Identifies the e-commerce or platform where the order originated.&lt;/li&gt;
&lt;li&gt;Customer: The person or entity placing the order and receiving the product.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Value Objects
&lt;/h4&gt;

&lt;p&gt;Value Objects, on the other hand, are domain elements without their own identity. Their value defines them, and two Value Objects with the same attributes are considered equivalent. This makes them immutable and ideal for encapsulating key concepts that may appear across various parts of the domain. Examples of Value Objects in the project include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ProductReference: Unique code identifying a product.&lt;/li&gt;
&lt;li&gt;ProductEan13: EAN-13 barcode associated with a product.&lt;/li&gt;
&lt;li&gt;OrderReference: Unique identifier for an order.&lt;/li&gt;
&lt;li&gt;Price: With currency and precise value.&lt;/li&gt;
&lt;li&gt;Weight: With standardized measurement units.&lt;/li&gt;
&lt;li&gt;ShippingNumber: Identification number for tracking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach helps create more understandable and modular code, as each system element has a clear and well-defined responsibility.&lt;/p&gt;

&lt;p&gt;Example of a Value Object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductEan13&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/^\d{13}$/'&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="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Invalid product Ean13'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&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;h4&gt;
  
  
  Services
&lt;/h4&gt;

&lt;p&gt;In a complex application like ours, the concept of Services plays a central role in maintaining clean and modular code. Services are categorized into different layers and types based on their purpose and the patterns they implement. Let's explore how we organize and implement services effectively.&lt;/p&gt;

&lt;h5&gt;
  
  
  Domain Services
&lt;/h5&gt;

&lt;p&gt;Domain Services encapsulate business logic that doesn't fit directly into any specific entity or value. These services operate strictly within domain rules and don't depend on infrastructure components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheapestCarrierGetter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;DeliveryOptionCarrierCollection&lt;/span&gt; &lt;span class="nv"&gt;$deliveryOptionCarriers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;Weight&lt;/span&gt;                          &lt;span class="nv"&gt;$orderWeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;Country&lt;/span&gt;                         &lt;span class="nv"&gt;$country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;PostalCode&lt;/span&gt;                      &lt;span class="nv"&gt;$postalCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt;                            &lt;span class="nv"&gt;$isCashOnDelivery&lt;/span&gt; &lt;span class="o"&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="kt"&gt;Carrier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Lògica per obtenir el transportista més econòmic&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;h2&gt;
  
  
  Application Services
&lt;/h2&gt;

&lt;p&gt;Application Services encapsulate and coordinate logic that combines domain operations with external interactions to implement specific business or application scenarios. These services centralize and simplify the implementation of complex operations, ensuring a clear separation between the domain and infrastructure. The most well-known examples are use cases, but in our case, we will also have &lt;em&gt;Command Handlers&lt;/em&gt; and &lt;em&gt;Event Handlers&lt;/em&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%2Fu44ahgpfgl6dv14u8nlj.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%2Fu44ahgpfgl6dv14u8nlj.png" alt="Application Services Types" width="680" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use Cases represent specific actions or processes that the application needs to perform to meet business requirements. They encapsulate the necessary logic to execute complex operations, including interactions with domain services and infrastructure, keeping the domain clean and focused. We could say that their responsibility should be only to orchestrate between these two layers, leaving the responsibility to the domain, as Vaughn Vernon says, &lt;em&gt;"Keep Application Services thin, using them only to coordinate tasks on the model."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Command Handlers&lt;/em&gt; are the entry point for modifications to the domain. Upon receiving a &lt;em&gt;Command&lt;/em&gt;, they validate the request, delegate the business logic to the corresponding aggregates, and finally, publish an event that reflects the change produced in the system.&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;em&gt;Event Handlers&lt;/em&gt; act as &lt;em&gt;listeners&lt;/em&gt; to changes in the system. They listen to events and execute specific actions in response, such as sending notifications, updating other aggregates, or integrating with external systems. This decoupled reaction allows for the construction of more flexible and scalable systems. I will expand on the details and concepts in future entries when we talk about the evolution of the application as an event-driven architecture (EDA) and queuing systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotifyShopOnOrderShipped&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;EventHandlerInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;OrderRepositoryInterface&lt;/span&gt;    &lt;span class="nv"&gt;$orderRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;ExternalOrderUpdaterFactory&lt;/span&gt; &lt;span class="nv"&gt;$externalOrderUpdaterFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;LoggerInterface&lt;/span&gt;             &lt;span class="nv"&gt;$logger&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;OrderShippedDomainEvent&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Lògica per notificar la botiga quan una comanda ha estat enviada&lt;/span&gt;
        &lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;orderRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getOrderId&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="nv"&gt;$order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Comanda no trobada"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'orderId'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getOrderId&lt;/span&gt;&lt;span class="p"&gt;()]);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$updater&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;externalOrderUpdaterFactory&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$updater&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;updateStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'shipped'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Notificació d'enviament completada"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'orderId'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&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;h2&gt;
  
  
  Infrastructure Services
&lt;/h2&gt;

&lt;p&gt;Infrastructure Services implement operations that rely on external components such as databases, file systems, or third-party services. They often act as adapters to ensure that the domain remains agnostic to the specific implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MonologLogger&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;LoggerInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Logger&lt;/span&gt; &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="p"&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;h2&gt;
  
  
  Service Classification
&lt;/h2&gt;

&lt;p&gt;As we've seen, services help us decouple and decompose our application's logic into more granular and independent units. Here's a classification of common services we've identified in our project, grouped by their primary function and associated with known design patterns. This classification provides a more structured view of our architecture and facilitates decision-making when designing new features.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transformers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Convert data between different formats or representations.&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Adapter&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Convert external API responses into domain models.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Builders&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Construct complex objects step by step.&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Builder&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Create an &lt;code&gt;Order&lt;/code&gt; object.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Factories&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create domain objects ensuring they comply with rules and restrictions.&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Factory&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Create instances of &lt;code&gt;Product&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Presenters&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Format data for the user interface or API responses.&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Decorator&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Enrich data to display to the user.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notifiers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Send notifications (email, SMS, etc.).&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Observer&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Notify the user of important changes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validators&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ensure that objects comply with business rules.&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Strategy&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Validate user requests or forms.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Clients&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Interact with external applications or services.&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Proxy&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Consume external APIs to obtain information.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;All these domain concepts are just a small sample of everything we managed to model. Obviously, we didn't do it all at once and we didn't get everything right the first time: there are many parts that still needed to be restructured, concepts that we didn't fully clarify and repositories that we knew didn't make sense, but that we had to maintain for functionalities, but that we had to end up eliminating.&lt;/p&gt;

&lt;p&gt;But with this initial work done, it allowed the entire team to participate in this process and have a commitment to everything we were building.&lt;/p&gt;

&lt;p&gt;To delve deeper into these DDD concepts and how to apply them, I recommend reading the following books:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Domain-Driven Design: Tackling Complexity in the Heart of Software" by Eric Evans: The foundational work on DDD that introduces and explains in depth the concepts of entities and value objects.&lt;/li&gt;
&lt;li&gt;"Implementing Domain-Driven Design" by Vaughn Vernon: A practical book that offers concrete examples of how to implement DDD in real-world projects.&lt;/li&gt;
&lt;li&gt;"Domain-Driven Design in PHP" by Carlos Buenosvinos, Christian Soronellas &amp;amp; Keyvan Akbary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building the Team
&lt;/h2&gt;

&lt;p&gt;The process of adopting DDD went hand-in-hand with the team's formation and evolution. This is where I want to talk about Tuckman's stages model (1965): Forming, Storming, Norming, Performing, as I believe the team's evolution followed this sequence and it helped us, on the one hand, to align our technical practices and on the other to develop a culture of collaboration and trust within the team. As Tuckman (1965) describes, understanding and embracing these stages is key to building high-performing teams. The original reference can be found in his work: Tuckman, B. W. (1965). Developmental sequence in small groups. Psychological Bulletin, 63(6), 384–399.&lt;/p&gt;

&lt;p&gt;According to this model, teams go through four distinct phases to reach maximum performance. During the initial phase (&lt;em&gt;Forming&lt;/em&gt;), team members introduce themselves and define general objectives. In the &lt;em&gt;Storming&lt;/em&gt; phase, conflicts emerge as roles begin to be established. Over time, in the &lt;em&gt;Norming&lt;/em&gt; phase, teams achieve a cohesive work dynamic, culminating in &lt;em&gt;Performing&lt;/em&gt;, where they work efficiently towards common goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Forming
&lt;/h3&gt;

&lt;p&gt;The team was initially formed with two developers who began reviewing the project and documenting its operation, while other members closed their respective projects to join. For my part, I joined as a tech lead and began reviewing the new documentation that had been generated and establishing the technical and organizational foundations of the project and the team in terms of processes, standards, and tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storming
&lt;/h3&gt;

&lt;p&gt;We couldn't say there were major disagreements within the team, but we did see the need to "regulate" certain aspects in order to be more aligned. This need became more apparent when we added two more people to the team and the roadmap began to take shape. This led us to consider how we wanted to work, communicate, and above all, how to make all these decisions and knowledge visible in a project that was constantly evolving.&lt;/p&gt;

&lt;p&gt;So we quickly moved on to the &lt;em&gt;Norming&lt;/em&gt; phase to establish the foundations of how we wanted to work and how we wanted to organize ourselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Norming
&lt;/h3&gt;

&lt;p&gt;During this period, we agreed on several aspects to facilitate teamwork:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Team Agreements:&lt;/strong&gt; Rules for teamwork and communication such as defining ceremonies, meeting schedules, communication channels, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coding Standards:&lt;/strong&gt; Guidelines for writing clean and maintainable code following the foundations of DDD, Hexagonal Architecture, and SOLID principles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development Process:&lt;/strong&gt; Definition of the tools, processes, and practices to follow to maintain an efficient workflow, with the aim of improving code quality and team productivity, fostering a culture of collaboration and learning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WIP (Work In Progress) Limits:&lt;/strong&gt; To ensure a sustainable workflow. It has a separate chapter to reinforce its importance, as part of the Lean methodology that we approached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployments:&lt;/strong&gt; Rules for controlled and reliable deployments, including time limits and rollback procedures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical Debt:&lt;/strong&gt; Definition and management of accumulated technical debt as well as providing a framework to identify and prioritize it if necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ADRs:&lt;/strong&gt; Registration and justification of architectural decisions to ensure consistency and traceability of decisions made.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performing
&lt;/h3&gt;

&lt;p&gt;With all the work done in the previous stages, we had created a framework that allowed us to focus on product development efficiently and without worry, beyond the need to prioritize those initiatives that provided the most value in the context of each moment. This allowed the team to focus on implementing business functionalities while improving code quality, training, and keeping documentation alive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;All this effort would be meaningless if it were not made visible in some way. We documented it so that it was accessible at any time and easy to update. We used GitLab to manage the project code, so we activated the &lt;a href="https://docs.gitlab.com/ee/user/project/pages/" rel="noopener noreferrer"&gt;GitLab Pages&lt;/a&gt; functionality and after a little research we used Jekyll with the &lt;a href="https://just-the-docs.com/" rel="noopener noreferrer"&gt;Just the Docs&lt;/a&gt; theme.&lt;/p&gt;

&lt;p&gt;To organize the information, we based ourselves on the &lt;a href="https://diataxis.fr/" rel="noopener noreferrer"&gt;Diátaxis&lt;/a&gt; model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tutorials:&lt;/strong&gt; Guides for application functionalities, mainly aimed at the end user (example: Transporter Configuration).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guides:&lt;/strong&gt; Practical instructions and solutions to specific problems, for both end users and developers (example: How to install the application).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explanations:&lt;/strong&gt; In-depth knowledge of team processes and standards (example: Team agreements and coding standards).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;References:&lt;/strong&gt; Detailed information for developers (example: ADRs, application architecture).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A next step we didn't fully implement was automating technical documentation using &lt;a href="https://www.eventcatalog.dev/" rel="noopener noreferrer"&gt;Event Catalog&lt;/a&gt; and &lt;a href="https://www.asyncapi.com/" rel="noopener noreferrer"&gt;AsyncAPI&lt;/a&gt;. This would have allowed us to generate documentation directly from our codebase, ensuring that it was always up-to-date.&lt;/p&gt;

</description>
      <category>php</category>
      <category>symfony</category>
      <category>ddd</category>
      <category>legacy</category>
    </item>
    <item>
      <title>From Legacy Software to Strategic Opportunity: The Starting Point (I)</title>
      <dc:creator>Dídac Rios</dc:creator>
      <pubDate>Mon, 13 Jan 2025 16:02:21 +0000</pubDate>
      <link>https://forem.com/didacrios/de-software-legacy-a-oportunitat-estrategica-el-punt-de-partida-i-178n</link>
      <guid>https://forem.com/didacrios/de-software-legacy-a-oportunitat-estrategica-el-punt-de-partida-i-178n</guid>
      <description>&lt;p&gt;When we talk about legacy software, we often think of outdated or poorly designed applications. However, the reality is that "legacy" can refer to any application that, while functioning correctly, presents significant challenges for evolution and maintenance. This is the story of how we approached the internalization of a logistics order management system (OMS), with the added challenge of integration with a new e-commerce platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Initial Context
&lt;/h2&gt;

&lt;p&gt;In 2018, the application was developed with the aim of optimizing the order preparation process for a growing e-commerce business and ensuring efficient integration with various logistics operators. Built with PHP (Symfony), MySQL, Socket.io, and jQuery, the application handled everything from packaging to shipping, including shipment tracking, carrier connections, label generation, and performance metrics for order preparation.&lt;/p&gt;

&lt;p&gt;For years, this tool fulfilled its purpose. However, over time and with business evolution, significant limitations began to surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accumulated Technical Debt
&lt;/h2&gt;

&lt;p&gt;The technical debt situation was particularly concerning, as it affected multiple layers of the project. On the technological infrastructure level, the application ran on outdated versions of both the framework and the base language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Symfony version (4.0) was not LTS (Long-Term Support) and had stopped receiving security updates as of January 2019.&lt;/li&gt;
&lt;li&gt;PHP 7.1 had also reached its end-of-support cycle, leaving the system without critical security updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond outdated versions, the project showed significant deficiencies in fundamental aspects of software development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Non-existent or inadequate testing&lt;/strong&gt;: The lack of automated tests (unit, integration, and end-to-end) not only made early error detection difficult but also turned any modification into a potential risk for system stability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of code standards&lt;/strong&gt;: The codebase did not follow documented patterns or standards, and those applied were not aligned with industry best practices. This complicated both maintenance and the on-boarding of new developers to the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Insufficient documentation&lt;/strong&gt;: Existing documentation was scarce and often incomplete. This impacted not only technical development but also the understanding of business processes implemented in the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Poor version control&lt;/strong&gt;: The Git history was poorly descriptive, with non-granular commits and messages that followed no conventions or provided context about the changes made. This made it hard to understand the code's evolution and the decisions made over time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This accumulation of technical debt not only posed a risk to the system's stability and security but also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slowed the development pace for new features.&lt;/li&gt;
&lt;li&gt;Increased the risk of introducing errors.&lt;/li&gt;
&lt;li&gt;Hindered the on-boarding of new team members.&lt;/li&gt;
&lt;li&gt;Increased maintenance costs.&lt;/li&gt;
&lt;li&gt;Complicated problem diagnosis and resolution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Structural Limitations
&lt;/h2&gt;

&lt;p&gt;The initial architecture presented coupling issues that severely affected its flexibility and scalability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Total dependency on the main e-commerce platform&lt;/em&gt;: The application could not operate autonomously, as all logistics operations depended directly on the data and processes of the e-commerce platform. This meant that any change to the main platform could break the system's functionality.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Shared database causing performance issues&lt;/em&gt;: Both the logistics application and the e-commerce platform used the same database, leading to performance problems, especially during peak loads for either application. Additionally, this setup complicated permission management, as any database access could compromise critical data from other systems.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Inability to operate independently:&lt;/em&gt; The application was designed to work exclusively with the e-commerce platform. This not only limited its portability but also complicated testing in isolated environments or migration to other platforms. Its dependencies were not properly encapsulated, making any attempt to isolate it require massive and costly system-wide changes, with main classes failing to adhere to the Single Responsibility Principle.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Difficulty implementing new features:&lt;/em&gt; The lack of adherence to principles like Open/Closed (OCP) and Liskov Substitution (LSP) made system evolution extremely challenging. New features required modifying existing code, increasing the risk of introducing regressions. Moreover, direct module dependencies made it nearly impossible to follow the Dependency Inversion Principle (DIP).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These structural limitations not only reduced the system's maintainability and scalability but also increased the risks associated with any modification or evolution, placing the application in a technically fragile and strategically vulnerable state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Management and Strategic Alignment
&lt;/h2&gt;

&lt;p&gt;One of the most significant challenges was not only technical but also strategic. External development, while functionally correct, presented important limitations in the organizational domain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Disconnection from overall strategy&lt;/em&gt;: Development was carried out in isolation, without a complete view of the company internal goals and processes. As a result, functionalities that were technically correct did not always align with the business actual needs.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Lack of strategic prioritization&lt;/em&gt;: New features were implemented without a clear vision, valuation and prioritization process. There was no questioning of whether a feature was truly necessary, the best way to implement it, or whether there were more efficient alternatives.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Reactive vs. proactive development&lt;/em&gt;: Development followed a largely reactive pattern, addressing immediate needs without considering the long-term impact or potential synergies with other company processes.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Absence of validation processes&lt;/em&gt;: The lack of a structured review and validation process resulted in functionalities that, while operational, were not always the best solution for end users or the company's overall objectives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This situation was unsustainable in the long term, as it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Produced a product increasingly misaligned with real needs.&lt;/li&gt;
&lt;li&gt;Complicated integration with other systems and company processes.&lt;/li&gt;
&lt;li&gt;Hindered strategic decision-making about the product.&lt;/li&gt;
&lt;li&gt;Limited the team's capacity for innovation and continuous improvement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Basal Cost Impact
&lt;/h2&gt;

&lt;p&gt;An often-overlooked but particularly relevant aspect of this project was the basal cost, a key concept in software development that refers to the minimum cost required to keep a system operational, even without adding new features or improvements.&lt;/p&gt;

&lt;p&gt;In our case, the basal cost included all expenses related to maintaining outdated versions of the framework and language, addressing urgent issues stemming from accumulated technical debt, managing dependencies with other systems, adapting to a tightly coupled architecture, and lacking domain knowledge. These factors consumed a significant portion of available resources, directly impacting the team's ability to invest in innovation and continuous improvement.&lt;/p&gt;

&lt;p&gt;While the basal cost was not the sole reason behind the decision to internalize development, it played a crucial role in the initial diagnosis of the project. Ignoring basal costs when evaluating the sustainability of a system can lead to overlooked risks, but in this case, it was clear evidence that the current strategy was unsustainable in the long term. As we will explore in subsequent articles, any attempt to maintain the existing structure would have led to exponential increases in the basal cost over time.&lt;/p&gt;

&lt;p&gt;For a more detailed explanation of the basal cost concept and its implications, I recommend consulting &lt;a href="https://www.eferro.net/2024/07/el-coste-basal-del-software.html" rel="noopener noreferrer"&gt;Eduardo Ferro's original article&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Turning Point: A New Challenge and Strategic Decision
&lt;/h2&gt;

&lt;p&gt;In any refactoring project, multiple strategies can be adopted, and it is common to face the dichotomy of: the &lt;a href="https://martinfowler.com/bliki/StranglerFigApplication.html" rel="noopener noreferrer"&gt;strangler fig&lt;/a&gt; strategy or starting anew with a "&lt;a href="https://scalablehuman.com/2023/10/14/why-a-big-bang-rewrite-of-a-system-is-a-bad-idea-in-software-development/" rel="noopener noreferrer"&gt;big bang rewrite&lt;/a&gt;."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1ttcgpvdzx596ofg9b1.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%2Fp1ttcgpvdzx596ofg9b1.png" alt="Red pill blue pill meme, the question says Choose Refactor Strategy and options between Strangler Fig and Big Bang Rewrite" width="488" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Initially, the technical decision was to work within the same legacy project, applying the &lt;strong&gt;Strangler Fig&lt;/strong&gt; strategy, an approach that involves developing a new module or system that progressively replaces parts of the old system. This strategy allowed us to make parallel changes, reducing risks and maintaining current functionality while building a more solid foundation for future features.&lt;/p&gt;

&lt;p&gt;However, from a business perspective, this option was considered too risky for the current system, which was already operational and meeting its functions. The decision was made to avoid modifying the existing project and instead focus on developing an independent application that met the new requirements.&lt;/p&gt;

&lt;p&gt;This change of direction led us to fork the existing codebase, a decision that, while technically feasible, came with certain challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Codebase duplication: Two separate codebases now needed to be maintained.&lt;/li&gt;
&lt;li&gt;Separate databases: Data structures had to be duplicated and adapted for each system.&lt;/li&gt;
&lt;li&gt;Replicated infrastructure: Independent servers had to be deployed, ensuring adequate observability for each system.&lt;/li&gt;
&lt;li&gt;Increased cognitive load for the team: All these duplication required additional effort to maintain consistency between the two systems, increasing the team's complexity and error risk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach allowed us to move towards an independent solution, ensuring the existing system's stability while developing a project aligned with the new strategic objectives. However, it was crucial to analyze the pros and cons in detail to tackle this challenge with confidence and planning. Additionally, a business-level commitment was made to avoid expanding functionalities and maintain strict control over the project backlog until the migration to the new e-commerce system was complete.&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%2Fhtymh22ns5q4tzj2kdhg.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%2Fhtymh22ns5q4tzj2kdhg.png" alt="New architecture diagram" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Working in a non-productive environment, reducing production risks&lt;/td&gt;
&lt;td&gt;Temporarily maintaining multiple projects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Freedom to implement new technologies and patterns from scratch&lt;/td&gt;
&lt;td&gt;Temporary duplication of maintenance efforts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No concern for technical limitations or dependencies of the old system&lt;/td&gt;
&lt;td&gt;Duplicating functionalities may slow development due to synchronization needs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ability to focus exclusively on necessary functionalities&lt;/td&gt;
&lt;td&gt;Risk to deadlines from managing two codebases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Opportunity to implement best practices from the beginning&lt;/td&gt;
&lt;td&gt;Complexity in project management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greater ease of incorporating testing from the start&lt;/td&gt;
&lt;td&gt;Need to maintain compatibility with historical data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexibility to adapt to new business requirements&lt;/td&gt;
&lt;td&gt;Higher initial cost in time and resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Better alignment with the company's overall strategy&lt;/td&gt;
&lt;td&gt;Possible temporary loss of non-essential functionalities&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusions and Next Steps
&lt;/h2&gt;

&lt;p&gt;The decision to internalize and rewrite legacy software is never easy, especially when the software fulfills its function. The saying &lt;em&gt;"if it ain't broke, don't fix it"&lt;/em&gt; will always be present. However, sometimes it is necessary to take one step back in order to take two steps forward.&lt;/p&gt;

&lt;p&gt;The next steps in this process involve a gradual migration strategy that focuses on the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prioritize features based on their business impact and technical cost.&lt;/li&gt;
&lt;li&gt;Adopt automated testing and CI/CD practices to ensure the stability of new developments.&lt;/li&gt;
&lt;li&gt;Improve team training and communication to ensure alignment between business and development.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The ultimate goal is to deliver a product that not only meets the company's operational needs but also ensures its future growth. As with any process of change, this will not happen overnight, but the team is committed to moving forward one step at a time.&lt;/p&gt;

</description>
      <category>eventdriven</category>
      <category>refactoring</category>
      <category>eventstorming</category>
      <category>php</category>
    </item>
    <item>
      <title>Plantilla d'iniciatives pel desenvolupament de software</title>
      <dc:creator>Dídac Rios</dc:creator>
      <pubDate>Mon, 30 Dec 2024 17:58:43 +0000</pubDate>
      <link>https://forem.com/didacrios/plantilla-diniciatives-pel-desenvolupament-164e</link>
      <guid>https://forem.com/didacrios/plantilla-diniciatives-pel-desenvolupament-164e</guid>
      <description>&lt;p&gt;En els meus últims projectes amb responsabilitats compartides de Product Owner i Team Lead en la que tenia més control sobre el backlog del producte, vaig veure la necessitat de crear una plantilla per treballar les nostres iniciatives. Aquest sistema no només ens ajuda a prioritzar el treball enfront d'altres tasques, sinó que també garanteix que tots els implicats comparteixin un mateix context abans de començar. Aquesta metodologia reforça la transparència i l’alineament dins de l’equip i facilita l’avaluació de les decisions durant el desenvolupament.&lt;/p&gt;

&lt;h2&gt;
  
  
  Què és una iniciativa?
&lt;/h2&gt;

&lt;p&gt;Podem debatre molt sobre organització i jerarquia de les tasques en un &lt;em&gt;backlog&lt;/em&gt;, cada equip i empresa son completament diferents. Des del meu punt de vista, una iniciativa és una agrupació de desenvolupaments necessaris per solucionar un problema o implementar una funcionalitat o requeriment. Cada iniciativa pot dividir-se en:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Èpiques: Conceptes generals que funcionen com a etiquetes.&lt;/li&gt;
&lt;li&gt;Històries d’usuari: Unitats més concretes de treball.&lt;/li&gt;
&lt;li&gt;Tasques: Accions específíques derivades de les històries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnaviywy5nyendcdsnuku.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%2Fnaviywy5nyendcdsnuku.png" alt="Backlog items" width="649" height="747"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Com es treballa una iniciativa?
&lt;/h2&gt;

&lt;p&gt;Idealment, l'equip es centra en una única iniciativa a treballar, la que té la prioritat més alta i està lo suficientment refinada per poder començar el seu desenvolupament. I que vol dir &lt;strong&gt;suficientment refinada&lt;/strong&gt; us preguntareu? Aquí és on entra la plantilla, la plantilla ens donarà uns mínims, però al igual que una història d'usuari, no ens donarà la solució, sinó que serà el tret de sortida per trobar la millor solució.&lt;/p&gt;

&lt;h2&gt;
  
  
  Com és la plantilla?
&lt;/h2&gt;

&lt;p&gt;La plantilla conté diferents apartats que permeten capturar tota la informació necessària. Vegem els més importants:&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 Títol de la iniciativa
&lt;/h3&gt;

&lt;p&gt;Un títol breu i descriptiu que resumeixi el propòsit de la iniciativa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taula resum
&lt;/h3&gt;

&lt;p&gt;Inclou informació clau com:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;🧑‍🏫 Product&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Name of the product owner/ project manager in charge of the initiative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;👩‍💼 Stakeholders&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Name of the stakeholders involved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;👥 Teams Involved&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Name of the teams&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Criteris de priorització
&lt;/h3&gt;

&lt;p&gt;Aquí es pot afegir el criteri de priorització que cada equip consideri, en el nostre cas hem passat per varis criteris, des del &lt;a href="https://www.productplan.com/glossary/rice-scoring-model/" rel="noopener noreferrer"&gt;RICE&lt;/a&gt; a una &lt;a href="https://blackswanfarming.com/qualitative-cost-delay/" rel="noopener noreferrer"&gt;versió simplificada de la matriu Value/Urgency&lt;/a&gt; per quantificar el màxim possible el cost del endarreriment. Us deixo un article del &lt;a href="https://www.linkedin.com/in/marcrodriguezpique" rel="noopener noreferrer"&gt;Marc Rodríguez&lt;/a&gt; (former Digital Project Manager @ Freshly Cosmetics) on explica com treballavem a &lt;a href="https://producthackers.com/es/blog/metodologia-trabajo-startup" rel="noopener noreferrer"&gt;nivell de productes per priotitzar objectius&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Priorization criteria&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;🎯 RICE Score&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;💎 Value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Meh / Bonus / Killer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;⏰ Urgency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ASAP / Soon / Whenever&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  📚 Context
&lt;/h3&gt;

&lt;p&gt;L'equip o persona de producte s'ha d'encarregar de donar el màxim de context possible de la iniciativa, deixant clar l'&lt;strong&gt;oportunitat&lt;/strong&gt; que implica aquesta iniciativa, quin &lt;strong&gt;impacte&lt;/strong&gt; ens aporta i el &lt;strong&gt;criteri&lt;/strong&gt; pel qual sabrem que aquesta iniciativa l'hem complementat.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧐 Problemes a resoldre
&lt;/h3&gt;

&lt;p&gt;A omplir per l'equip o persona de producte que ha proposat la iniciativa. Una taula que connecta la iniciativa amb els objectius globals de l'empresa:&lt;/p&gt;

&lt;h3&gt;
  
  
  📐 Framing
&lt;/h3&gt;

&lt;p&gt;Aquesta taula s'ha d'omplir per part de l'equip o persona de producte amb l'ajuda d'un referent tècnic de l'equip, aquí es tracta també d'identificar a quins punts claus dels objectius globals de l'empresa impacta. Pot ser una &lt;strong&gt;⭐ North Star&lt;/strong&gt; o pot ser un OKR, etc, el que s'intenta aquí es identificar si anem alineats o no.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;⭐ North Star&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;filled by PM/PO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;🚀 Direct Impact&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;filled by PM/PO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;🌱 Indirect Impact&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;filled by PM/PO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;💻 Development effort&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low, Middle, High (filled by team lead or team)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;📈 KPIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;filled by PM/PO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Fins aquest punt de la plantilla, tot el que s'ha demanat no requereix cap tipus de desenvolupament, però es molt rellevant per entendre el que es vol fer i dona la informació suficient per poder-la prioritzar o descartar-la. Si la passem a prioritzar i volem començar-ne el desenvolupament, el que farem, ja per part de l'equip de desenvolupament, es omplir un últim apartat que anirà seguit d'una &lt;em&gt;kick-off&lt;/em&gt; per presentar el document i anar tots alineats.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔭 Descoberta
&lt;/h3&gt;

&lt;p&gt;En aquest apartat s'hauran d'omplir els següents punts:&lt;/p&gt;

&lt;h4&gt;
  
  
  🛠️ Solució
&lt;/h4&gt;

&lt;p&gt;En aquest punt es tracta d'exposar una proposta de solució, tot i que és a nivell teòric també pot anar acompanyat d'una prova de concepte (POC)&lt;/p&gt;

&lt;h4&gt;
  
  
  🐉 Riscs
&lt;/h4&gt;

&lt;p&gt;Llistats d'impdiments i riscs que poden afectar el desenvolupament o al producte pel fet d'optar per aquesta solució&lt;/p&gt;

&lt;h4&gt;
  
  
  🔖 Enllaços i altres documents
&lt;/h4&gt;

&lt;p&gt;Llistat d'altra informació rellevant o enllaços d'interes que poden ser útils. (Diagrames, issue tracker, project managment tool ...)&lt;/p&gt;

&lt;p&gt;A continuació us deixò la plantilla complerta en format Markdown&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# 💡 Initiative Title&lt;/span&gt;

| &lt;span class="gs"&gt;**Summary**&lt;/span&gt; |  |
| ----------- | --- |
| &lt;span class="gs"&gt;**🧑‍🏫 Product**&lt;/span&gt; |  Name of the product owner/ project manager in charge of the initiative |
| &lt;span class="gs"&gt;**👩‍💼 Stakeholders**&lt;/span&gt; | Name of the stake holders involved  |
| &lt;span class="gs"&gt;**👥 Teams Involved**&lt;/span&gt; | Name of the teams |

| &lt;span class="gs"&gt;**Priorization criteria**&lt;/span&gt; |     |
| ----------------- | --- |
| &lt;span class="gs"&gt;**🎯 RICE Score**&lt;/span&gt; | Points |
| &lt;span class="gs"&gt;**💎 Value**&lt;/span&gt; | Meh &lt;span class="se"&gt;\|&lt;/span&gt; Bonus &lt;span class="se"&gt;\|&lt;/span&gt; Killer |
| &lt;span class="gs"&gt;**⏰ Urgency**&lt;/span&gt; | ASAP &lt;span class="se"&gt;\|&lt;/span&gt; Soon &lt;span class="se"&gt;\|&lt;/span&gt; Whenever |

&lt;span class="gu"&gt;## 📚 Context&lt;/span&gt;

The context should be filled by the PM, PO or the person who is proposing the initiative. It should contain the following information:
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Opportunity**&lt;/span&gt;: What is the opportunity that we are trying to take advantage of?
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Impact**&lt;/span&gt;: What is the impact that we are trying to achieve?
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Success Criteria**&lt;/span&gt;: What are the criteria that we will use to measure the success of the initiative?

&lt;span class="gu"&gt;## 🧐 Problems to solve&lt;/span&gt;

The problems to solve should be filled by the PM, PO or the person who is proposing the initiative.

&lt;span class="gu"&gt;### 📐 Framing&lt;/span&gt;

|  | |
| ----------- | --- |
| &lt;span class="gs"&gt;**⭐ North Star**&lt;/span&gt; | filled by PM/PO  |
| &lt;span class="gs"&gt;**🚀 Direct Impact**&lt;/span&gt; | filled by PM/PO  |
| &lt;span class="gs"&gt;**🌱 Indirect Impact**&lt;/span&gt; | filled by PM/PO  |
| &lt;span class="gs"&gt;**💻 Development effort**&lt;/span&gt; | Low, Middle, High (filled by team lead or team) |
| &lt;span class="gs"&gt;**📈 KPIs**&lt;/span&gt; | filled by PM/PO  |

&lt;span class="gu"&gt;## 🔭 Discovery&lt;/span&gt;

&lt;span class="gu"&gt;### 🛠️ Solution&lt;/span&gt;

To be filled by the whole team or the team lead during the Kickoff

&lt;span class="gu"&gt;### 🐉 Risks&lt;/span&gt;

To be filled by the whole team or team lead during the Kickoff

&lt;span class="gu"&gt;### 🔖 Important links and documents&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;project managment&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;#&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;drive folder&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;#&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enllaços relacionats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://producthackers.com/es/blog/metodologia-trabajo-startup" rel="noopener noreferrer"&gt;La metodología de desarrollo de Producto que utiliza Freshly Cosmetics para crecer a toda velocidad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>product</category>
      <category>agile</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Lean Software Development: Muda (I)</title>
      <dc:creator>Dídac Rios</dc:creator>
      <pubDate>Wed, 25 Oct 2023 21:29:47 +0000</pubDate>
      <link>https://forem.com/didacrios/lean-software-development-muda-i-1i2i</link>
      <guid>https://forem.com/didacrios/lean-software-development-muda-i-1i2i</guid>
      <description>&lt;p&gt;Aquest estiu he revisat el llibre &lt;a href="https://www.goodreads.com/book/show/194338.Lean_Software_Development"&gt;&lt;em&gt;Lean Software Development: An Agile Toolkit&lt;/em&gt;&lt;/a&gt; de Mary &amp;amp; Tom Poppendieck i aprofitaré per fer una serie d'articles resum dels punts que crec més interessants del llibre.&lt;/p&gt;

&lt;p&gt;En aquesta primera entrega parlarem del malbaratament (&lt;em&gt;desperdici, waste, muda&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;El malbaratament (&lt;em&gt;waste, muda&lt;/em&gt;) és tot allò que al client no li aporta un valor directe. Les pràctiques àgils en el desenvolupament de software busquen eliminar aquest malbaratament, i el primer pas per fer-ho és saber-lo identificar.&lt;/p&gt;

&lt;p&gt;Una de les pràctiques &lt;em&gt;lean&lt;/em&gt; ens diu que per a identificar el malbaratament cal classificar-lo, així que influenciats pels 7 malbarataments del &lt;em&gt;lean manufacturing&lt;/em&gt; es proposa classificar el malbaratament en el desenvolupament de programari en 8 categories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feina feta parcialment (&lt;em&gt;Partially Done Work&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;Fa referencia a desenvolupaments que es queden a mitges i no s'arriben a desplegar en un entorn de producció, aquest tipus de desenvolupaments tendeixen a quedar-se obsolets en poc temps, interferint en el desenvolupament d'altres tasques que s'han de realitzar. El principal problema es que el que s'ha fet no s'arriba desplegar, per tant no hi ha &lt;a href="https://agilemanifesto.org/principles.html"&gt;&lt;em&gt;working software&lt;/em&gt;&lt;/a&gt;, el que ens impossibilita obtenir feedback i saber si realment funciona, si causa algun efecte no previst en el sistema o si realment estem solucionant el problema que voliem solventar.&lt;/p&gt;

&lt;p&gt;S'ha de tenir en compte que en aquests desenvolupaments s'ha fet també una inversió en recursos (planificació, priorització, definició, disseny, codificació…), que encara no ha generat resultats, això implica que es "cancela una gran inversió", convertint-se en un risc si ho extrapolem a nivell financer.&lt;/p&gt;

&lt;p&gt;Així doncs, el fet de reduir la feina feta parcialment redueix riscos i es converteix al mateix temps en una estrategia per a la reducció del malbaratament.&lt;/p&gt;

&lt;h3&gt;
  
  
  Processos extra (&lt;em&gt;Extra Processes&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;T'has preguntat mai si la burocràcia i la paperassa són necessaris? La burocràcia consumeix recursos, és lenta, es perd, queda obsoleta, i molts cops ningú li fa cas.&lt;/p&gt;

&lt;p&gt;En el desenvolupament de programari, també hi ha burocràcia. Molts processos de desenvolupament requereixen d'omplir formularis de sol·licitud, requeriments, tests, actualitzar seguiments, reportar hores, documentar, etc.&lt;/p&gt;

&lt;p&gt;Planteja’t si realment, al client, tots aquest processos importen i l'ajuden a tenir un producte més valuós, i en el cas de que ho sigui, recorda aplicar aquestes 3 regles: Que sigui la minima possible (&lt;em&gt;Keep it short&lt;/em&gt;). que sigui a alt nivell, clara i consisa. (&lt;em&gt;Keep it high level&lt;/em&gt;) i que estigui fora del procés de desenvolupament. (&lt;em&gt;Do it off line&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;En la majoria de desenvolupaments, hi ha requeriments escrits. En aquests casos, el fet que aquests requeriments siguin fàcilment accessibles i evaluats per a la seva comprovació es pot considerar una activitat que aporta valor. Estem parlant de taules i/o plantilles que fan que tant els clients com els desenvolupadors puguin ràpidament entendre i validar. L'utilització de pràctiques com BDD (&lt;em&gt;Behaviour Driven Design&lt;/em&gt;), ATDD (&lt;em&gt;Acceptance Test-Driven Development&lt;/em&gt;), &lt;em&gt;Specification by Example&lt;/em&gt;, reduirien el malbaratament en tant que es consideren pràctiques que aporten valor.&lt;/p&gt;

&lt;p&gt;Una altra forma d'identificar si la burocràcia aporta valor o no és el fet d'identificar si hi ha algú que l'estigui esperant. Hi ha algú que escriu escenaris per a que es puguin interpretar i programar? Doncs probablement aquesta burocràcia aporta valor. Tot i això s'ha de treballar en millorar l'eficiencia en aquest sentit i buscar la millor manera de transmetre la informació, per exemple, no escriure requeriments i utilitzar pràctiques com les citades anteriorment o bé que els detalls d’implementació no fer-los massa aviat i limitar-se a aprofundir-hi en la iteració en la que s'haurien d'implementar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Funcionalitats extra (&lt;em&gt;Extra Features&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;Pot semblar molt bona idea afegir funcionalitats extra, per si de cas es necessiten. Als programadors ens encanta afegir complexitat tècnica i funcionalitats extra. Això que ens pot semblar inofensiu, és un dels més grans malbarataments. Cada línia de codi s'ha de compilar, integrar, testejar, desplegar  i després, s'ha de mantenir. Cada línia de codi incrementa la complexitat i es un punt de fallida (&lt;em&gt;failure point&lt;/em&gt;). Fins i tot hi ha la possibilitat que aquella part de codi quedi obsoleta abans de que s'utilitzi, ja que en realitat mai s'ha arribat a demanar. Quan el codi no es necessita ara, és malbaratament. Que no et tempti la serp.&lt;/p&gt;

&lt;h3&gt;
  
  
  Canvi de tasques (&lt;em&gt;Task Switching&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;Gent treballant en multiples projectes és despedici de per se. Cada cop que un programador canvia de tasca, hi ha un lapse de temps significatiu en el que es despren de les referencies de l'antiga tasca i comença a entrar en la dinàmica de la nova (DeMarco &amp;amp; Lister, 2003). Si algú forma part de varis equips i projectes, les  interrupcions i canvis de tasques es fan exponencials, tot això és malbaratament.&lt;/p&gt;

&lt;p&gt;Així doncs la millor forma de completar 2 projectes que utilitzen els mateixos recursos, és fer-los un després de l'altre. Goldratt (1997) planteja que quan tens 2 projectes d'aproximadament 2 setmanes de duració cadascún, esperes tenir-los enllestits en 4 setmanes. Si els realitzes al mateix temps, al afegir els canvis de context el resultat final és que el tens més aviat en 5 setmanes enlloc de les 4.&lt;/p&gt;

&lt;p&gt;El fet d'afegir un excés de feina en el desenvolupament crea malbaratament, fent que les coses vagin més lentes. Tot va més fluid per una canonada que no està plena (Poppendieck &amp;amp; Poppendieck, 2003).&lt;/p&gt;

&lt;h3&gt;
  
  
  Esperant (&lt;em&gt;Waiting&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;Un dels màxims malbarataments en el desenvolupament de programari es esperar a que les coses passin. Endarrerir l'inici d'un projecte, la conformació de l'equip, la confecció de requeriments, les revisions de codi, les proves, desplegar funcionalitats, tot això és malbaratament. &lt;/p&gt;

&lt;p&gt;Els endarreriments son comuns i poden arribar a forma part de la normalitat i no veure'ls com a malbaratament. Quin és el problema d'esperar? Les esperes fan que el client no rebi valor aviat. Quan el client vol implementar una necessitat o solucionar un problema la velocitat en la que obtindrà la solució anirà estrictament lligada a la velocitat en la que va el nostre proces de desenvolupament.&lt;/p&gt;

&lt;p&gt;En certs entorns, potser aquest no és un dels principals problemes. Però si que ho és si desenvolupes programari per a un domini en constant canvi, en el que s’han de prendre moltes decisions, i aquestes no són àgils. Un dels principis fonamentals de &lt;em&gt;lean&lt;/em&gt; és pospondre les decisions fins a l'ultim moment responsable (&lt;em&gt;the Last Responsible Moment&lt;/em&gt;), de tal manera que puguis decidir més endavant, quan tingui més context. Aquesta és una de les millors formes de manejar la incertesa. Posposar una decisió també és una decisió.&lt;/p&gt;

&lt;p&gt;Es podria pensar que això i procrastinar ve a ser el mateix, però en realitat es una estrategia per evitar riscos. Una mala decisió feta molt al inici d'un projecte el pot comprometre per complet, ja sigui fent que el desenvolupament vagi molt més lent o lligar-se a infrastructures innecesaries, així que les decisions que s'han d'anar prenent han de ser decisions que no et collin massa, i siguin el maxim d'adaptables posibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Moviment (&lt;em&gt;Motion&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;Quan un programador té dubtes, que és el que ha de fer fins aconseguir una resposta? Hi ha gent disponible per solucionar problemes tècnics? I els funcionals? El client o el seu representant (PO, PM) està disponible per contestar-li? Pot el programador interpretar correctament la feina a fer de forma senzilla sense haver d'anar a trobar algun company?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;El text original es refereix més aviat a desplaçaments físics com a malbaratament, ara amb el teletreball i la feina asíncrona això podriem pensar que queda obsolet, però si fem l'adaptació al teletreball, podem canviar el temps del desplaçament físic per la dificultat d'obtenir una resposta adient.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El desenvolupament de programari requereix d'una gran concentració, cada cop que se'ls hi plantegi alguna de les situacions anteriors perdran el focus. Tenir l'equip disponible i treballant conjuntament farà que aquestes situacions acabin esdevenint en grans problemes, evitant així el malbaratament.&lt;/p&gt;

&lt;p&gt;La gent no es la única que es mou, els requeriments, la documentació, el codi, també està en constant moviment durant el cicle de desenvolupament. Traslladar tota aquesta informació és també un malbaratament, tots aquests artefactes no poden contenir la totalitat de la informació, sempre hi ha informació que es retindrà en els seus creadors com a individual o grup. Es per això que també, traslladar aquests recursos entre diferents grups també és malbaratament.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defectes (&lt;em&gt;Defects&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;El principal malbaratament causat pels defectes és l'impacte del defecte sobre el producte i el temps en que passa desapercebut. Un greu defecte que es localitza al cap de 3 minuts no és un gran malbaratament. Però un petit problema que fa setmanes que ningú se n'ha adonat, és un malbaratament molt més gran.&lt;/p&gt;

&lt;p&gt;Així doncs, per tal de reduir l'impacte dels defectes el millor és identificar-los el més aviat possible i per fer-ho cal testar, integrar, i desplegar el més aviat possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Activitats de la gestió (&lt;em&gt;Management Activities&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;Les activitats de gestió no afegixen valor directament a un producte, però tenen un gran impacte en el malbaratament en una organització. Considera per exemple el sistema de gestió de tàsques i projectes. En aquest cas minimitzar el malbaratament implica mantenir al minim la feina feta a mitges, i això prové normalment de com es gestionen els projectes i les seves tasques. Si aquest sistema no va fluït probalement esdevingui en un gran generador de malbaratament i malbaratament de recursos.&lt;/p&gt;

&lt;p&gt;Els sistemes de control i seguiment tampoc aporten valor, i si existeixen acostumen a indicar que hi ha massa feina a fer. En &lt;em&gt;lean manufacturing&lt;/em&gt; quan es parla d'un sistema &lt;em&gt;just-in-time&lt;/em&gt;, es parla d'un sistema en que la feina es realitza de forma eficient i flueix de tal forma que no es necessàri el seu control amb sistemes complicats d'analisis i seguiment.&lt;/p&gt;

&lt;p&gt;Sistemes d'autorització per a la revisió i aprovació de canvis de requisits acostumen a aportar endarreriments enlloc de valor. Aquests sistemes també esdevenent simptoma d'un malbaratament més gran lligat a una definició previa i prematura de llargs requeriments.&lt;/p&gt;

&lt;p&gt;Aprendre a identificar el malbaratament és un procés constant de canviar la manera que tenim de pensar sobre el que realment és i no és necessàri.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bibliografia
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;DeMarco, T., &amp;amp; Lister, T. (2013). Peopleware: productive projects and teams. Addison-Wesley.&lt;/li&gt;
&lt;li&gt;Goldratt, E. M. (1997). Critical chain: A business novel. Routledge.&lt;/li&gt;
&lt;li&gt;Poppendieck, M., &amp;amp; Poppendieck, T. (2003). Lean software development: an agile toolkit. Addison-Wesley.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>lean</category>
      <category>softwaredevelopment</category>
      <category>agile</category>
      <category>waste</category>
    </item>
  </channel>
</rss>
