<?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: Tevin Dean</title>
    <description>The latest articles on DEV Community by Tevin Dean (@deant_).</description>
    <link>https://dev.to/deant_</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%2F1984095%2F7818afec-d74b-4d03-9a86-f4c8876cf4ce.png</url>
      <title>DEV Community: Tevin Dean</title>
      <link>https://dev.to/deant_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deant_"/>
    <language>en</language>
    <item>
      <title>Devlogs: October 2024</title>
      <dc:creator>Tevin Dean</dc:creator>
      <pubDate>Wed, 06 Nov 2024 06:21:14 +0000</pubDate>
      <link>https://dev.to/deant_/devlogs-october-2024-1cfa</link>
      <guid>https://dev.to/deant_/devlogs-october-2024-1cfa</guid>
      <description>&lt;p&gt;In the late of September 2024, I stumbled upon a TikTok video about an Indonesian developer creating a WhatsApp bot for his girlfriend. The bot itself is used when the said developer is away for work and can't reply to his girlfriend. (Shame on me because I'm maidenless.)&lt;/p&gt;

&lt;p&gt;I think that the TikTok creator who made the bot is also selling the bot as a service. I also believe that the creator was skilled enough to create such a bot.&lt;/p&gt;

&lt;p&gt;Then I, as a developer, wanted to challenge myself to create the same similar bot. Although much simpler by connecting the WhatsApp Chat API with OPENAI.&lt;/p&gt;

&lt;h2&gt;
  
  
  THE UNCHARTED WATERS
&lt;/h2&gt;

&lt;p&gt;The first problem that I encounter during this project is the &lt;u&gt;Concept of Chat Messages&lt;/u&gt;. I also think that the WhatsApp API is paid for use, even in the developer mode. But I'll breakdown my problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Concept of Chat Messages API (Message, Callbacks, and Events)&lt;/li&gt;
&lt;li&gt;ChatGPT vs. Ollama&lt;/li&gt;
&lt;li&gt;Is the WhatsApp API really paid for use?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are the three main issues that I encounter. Number 1 is regarding the technicality. Points 2 and 3 are basically about my monetary resources that I don't have available at the moment. (Yes, I'm broke and unemployed. LOL)&lt;/p&gt;

&lt;h2&gt;
  
  
  DEFINING PROBLEMS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;u&gt;Concept of Chat Messages&lt;/u&gt;
&lt;/h3&gt;

&lt;p&gt;So, I happen to create notification messages from webhooks. I know how to use them. But it wasn't in Whatsapp; rather, it was in Slack. Getting familiar with how the Slack works, partially. I tried to understand how it works first before I go to the main dish. (The WhatsApp API)&lt;/p&gt;

&lt;p&gt;There's three things that I needed to know.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Callbacks&lt;br&gt;
The callbacks are not so difficult; I know how it worked in the past. I did work with the FLIP Callback API for payment gateways about 2 years prior. Jog a little bit of my memories when trying to integrate into the Slack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Events&lt;br&gt;
So, after I establish the callback, there's another thing called events. I don't really know how events are working, and it turns out that I needed to subscribe to events in order to send the related events that trigerred in the Slack APP to my callback API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Message&lt;br&gt;
The callbacks have been set, and the events are configured to be sent into my backend. It's now time for the BOT to reply to the message. A simple if-else statement for the sake of the test is delivered.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;u&gt;ChatGPT vs Ollama&lt;/u&gt;
&lt;/h3&gt;

&lt;p&gt;I think that chatGPT is paid for use, so I tried Ollama for this little project of mine. I learned how to use it, and to my surprise, it was so easy to use. I pull the DeepSeek Coder model and use the Ollama API service to create a prompt and get the generated response.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;u&gt;SLACK BOT + DEEPSEEK&lt;/u&gt;
&lt;/h3&gt;

&lt;p&gt;My prototype of the bot is ready, but it wasn't in WhatsApp. It was still in Slack. 2 weeks just to wrangle the concept of messaging services was so worth it. It was a very exciting week that I had.&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%2F89wmgdmhlhy5p7jvhtj8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89wmgdmhlhy5p7jvhtj8.jpeg" alt="Slack Deepseek Bot" width="731" height="1600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  WHATSAPP BOT
&lt;/h2&gt;

&lt;p&gt;Remember the 3rd problem about the WhatsApp being paid to use? turns out that the developer and testing environment is &lt;u&gt;&lt;strong&gt;NOT&lt;/strong&gt;&lt;/u&gt; paid to use. But after looking through the WhatsApp documentation and Indian Tech Videos (yes, we all did look at the Indian IT Tutorials), it wasn't really much of a different from Slack.&lt;/p&gt;

&lt;p&gt;The steps are pretty simple. Aside from creating the META Developer and business account, with the whole team roles, and other &lt;em&gt;mambo-jambo&lt;/em&gt;. It was fairly easy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a Meta Business App &lt;/li&gt;
&lt;li&gt;Create a bot and assign it to the Meta Business App.&lt;/li&gt;
&lt;li&gt;Create a system user within the business app that is authorized in the bot.&lt;/li&gt;
&lt;li&gt;Create an API key for the system user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, all steps above were a bit confusing and took me 4 days with the additional procrastination that I did. 😏😏&lt;/p&gt;

&lt;p&gt;And then the same step as the Slack API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the Callback API&lt;/li&gt;
&lt;li&gt;Set the Events&lt;/li&gt;
&lt;li&gt;Test the Bot Reply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Its just the matter of connecting the Ollama with the Whatsapp API. Then VOILA!&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%2Fxfp0f0x97yz3btt72bds.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxfp0f0x97yz3btt72bds.jpeg" alt="Whatsapp Deepseek" width="740" height="1600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is far from good; it's just a simple project for me to not get bored. But hell yeah, bruv. This is very exciting. I think I'll make some little project and document it on the monthly or weekly devlogs until I get a job. Cheers guys! 😆😆&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devjournal</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why I No Longer Prefer Monolithic MVC</title>
      <dc:creator>Tevin Dean</dc:creator>
      <pubDate>Sat, 21 Sep 2024 05:02:41 +0000</pubDate>
      <link>https://dev.to/deant_/why-i-no-longer-prefer-monolithic-mvc-mkd</link>
      <guid>https://dev.to/deant_/why-i-no-longer-prefer-monolithic-mvc-mkd</guid>
      <description>&lt;p&gt;Looking back when I was in college, I used to make apps. Small-scale monolithic projects, hosted on local machines so they can be accessed by my peers. CRUD apps, or probably little calculator stuff, or an app that can post an article. Whether it was on Java or PHP Laravel at that time.&lt;/p&gt;

&lt;p&gt;Every project that I used back then always started with an MVC (Model-View-Controller) Design Patterns in mind. Let’s overview what MVC is for a moment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model: This is what we know as the ORM (Object Relational Models). The models basically map the database tables into a class object.&lt;/li&gt;
&lt;li&gt;View: The user interface is how the user would interact. (In the backend, we can assume this as URL endpoints of an API; it can also be client requests.)&lt;/li&gt;
&lt;li&gt;Controllers: The classes that handle the processing of data, whether it was objects, arrays, variables, etc. The controllers become the central of logic blocks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I join the tech industry, my first company is in the financial sector. I learn about many things, including microservices. As a startup, this company wants to move its monolithic application into a microservice architecture. My biggest challenge is that we didn’t have much time to research on how to do such a feat.&lt;/p&gt;

&lt;p&gt;I was a junior back then, and I barely know about microservices. The managers told me to create various microservices using Laravel Lumen frameworks. It was a mess to decouple the logic within controllers. I create 7 microservices and a “makeshift” API gateway in the span of 8 months. I cannot validate my work to be the “gold” standard of microservices. Post-covid events, the company goes bankrupt and laid off all of their employees.&lt;/p&gt;

&lt;p&gt;During my unemployment era, I learned about the DDD (Domain Driven Design) which eventually led me to make another little API project to experiment with Modulit, also known as the Modular Monolith. This makes me know that the MVC is not just the only way to create a software architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  Death by Line of Code
&lt;/h2&gt;

&lt;p&gt;I’ve seen many projects that implement MVC models without implementing any abstraction or composition. There’s no dependency injection, no logic, or business layer segregation. Most inexperienced developers like me back then would throw everything into the controllers. In the controller classes, many of us would easily make poorly written code. Which are very difficult to read and to understand.&lt;/p&gt;

&lt;p&gt;The if-else, the switch-cases, the magic numbers, and all that SQL Queries happen in the same controllers. Should we follow the Robert C. Martin Clean Code? Where does he do many layers of abstractions? I don’t think we need to. Create readable code by segregating logic and business layers, or maybe 1 or 2 layers of abstraction or inheritance are more than enough.&lt;/p&gt;

&lt;p&gt;Imagine if the IDE shows 12000 lines of code within a single controller. It would probably be really hard to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modules and Domains
&lt;/h2&gt;

&lt;p&gt;Have you ever seen that within a project, there’s no difference between the &lt;code&gt;PaymentController&lt;/code&gt; and the &lt;code&gt;InvoiceController&lt;/code&gt; or any other controllers? It's all in the same &lt;code&gt;/controller&lt;/code&gt; folder. Then there’s another business requirement that demands you to create an invoice for shipment and logistics. Then you would start writing &lt;code&gt;InvoiceShipmentController&lt;/code&gt; or &lt;code&gt;InvoiceLogisticController&lt;/code&gt;&lt;/p&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%2Fxdpbq8a61feqzcye8chi.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%2Fxdpbq8a61feqzcye8chi.png" alt="Image description" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The structure above will create a total mess because there’s no context of the controllers that belongs to which features or business decision.&lt;/p&gt;

&lt;p&gt;Let's say we try to structure this to create context:&lt;br&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%2Fktqz7lm7o2auar6yy6om.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%2Fktqz7lm7o2auar6yy6om.png" alt="Image description" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see within the Modules folder that each module/domain will have its own models and controllers. You can also add another folder, such as Views, Requests, Validations, or Routes, inside of each module folder.&lt;/p&gt;
&lt;h2&gt;
  
  
  Don’t Repeat Yourself Principle
&lt;/h2&gt;

&lt;p&gt;For inexperienced programmer, Controller became the processing points of an application. There’s no other sub-classes that handles the process. Some processes are sometimes requires the same code to be implemented. And the easiest shortcut that many of us lazy developer tend to take is to copy-paste the code from an existing controllers to the other controller. &lt;/p&gt;

&lt;p&gt;Imagine if &lt;code&gt;InvoiceShipmentController&lt;/code&gt; and &lt;code&gt;InvoiceLogisticController&lt;/code&gt; had to insert SQL query to the same Invoice Table in the Database. Let’s just say the difference between them is only in the category column which are ENUMS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Category 1 is for Shipment&lt;/li&gt;
&lt;li&gt;Category 2 is for Logistic&lt;/li&gt;
&lt;li&gt;Category 3 is for Other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also wants to make possible changes if there’s another category that might be included in the future.&lt;/p&gt;

&lt;p&gt;We can copy paste the code and probably just change the &lt;code&gt;category=1&lt;/code&gt; or &lt;code&gt;category=2&lt;/code&gt; in the insert database models. But instead, try to incorporates sub-processes in other class and then call its method. for example like this:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceShipmentController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;InvoiceController&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="c1"&gt;//call the action&lt;/span&gt;
            &lt;span class="nv"&gt;$action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InvoiceShipmentAction&lt;/span&gt;
            &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$action&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceShipmentAction&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Instantiate InvoiceAction within the constructor&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="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;shipmentAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InvoiceAction&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;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="c1"&gt;// call SetShipmentCategory&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;shipmentAction&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;SetShipmentCategory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'category'&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceAction&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Main Logic &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;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="c1"&gt;//call SetShipmentCategory&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="nf"&gt;SetShipmentCategory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'category'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="cm"&gt;/* Invoice LOGIC*/&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// THIS WILL ACT AS SUB-PROCESS&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;SetShipmentCategory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;InvoiceModel&lt;/span&gt; &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$category&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="nv"&gt;$category&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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="nv"&gt;$category&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&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="s2"&gt;"Invalid Category!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Update the category&lt;/span&gt;
            &lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$category&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$model&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;p&gt;We can do this in many different ways. We can try to use inheritance in &lt;code&gt;InvoiceShipmentAction&lt;/code&gt;, dependency injection in the class constructor, or just like what I did in the code, manually calling&lt;code&gt;new InvoiceAction()&lt;/code&gt; in constructor. We can reuse the &lt;code&gt;SetShipmentCategory()&lt;/code&gt;  in a lot of different ways. We can chop things up to break the code into smaller parts, rather than jam-packed the whole thing inside of the controller.&lt;/p&gt;

&lt;p&gt;We can also just declare the category for each individual module, whether it was intended for &lt;code&gt;ShipmentInvoice&lt;/code&gt;,  &lt;code&gt;LogisticInvoice&lt;/code&gt;, or &lt;code&gt;OtherInvoice&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Prepared for Microservices
&lt;/h2&gt;

&lt;p&gt;We don’t always need to build our architecture in microservices; it would be very time-consuming if you wanted to create your little calculator app in a microservice.&lt;/p&gt;

&lt;p&gt;Probably right now, your company doesn’t want to adopt microservices because the number of clients is still small and the number of business processes is not even that big. You might even never need to migrate into microservices at all.&lt;/p&gt;

&lt;p&gt;But for companies and enterprises, scalability is going to be an issue. Something that we need to prepare before the problem arises. If we planned our projects to have their own modules, we might have an easier grasp to translate the monolithic apps into microservices, or even if we didn’t use microservices, we might have better maintainability over the context over each module that we had created.&lt;/p&gt;

</description>
      <category>development</category>
      <category>architecture</category>
      <category>devjournal</category>
      <category>learning</category>
    </item>
    <item>
      <title>Dungeon Master’s Guide to Project Management</title>
      <dc:creator>Tevin Dean</dc:creator>
      <pubDate>Sat, 07 Sep 2024 16:37:32 +0000</pubDate>
      <link>https://dev.to/deant_/dungeon-masters-guide-to-project-management-de4</link>
      <guid>https://dev.to/deant_/dungeon-masters-guide-to-project-management-de4</guid>
      <description>&lt;p&gt;The Red Dragon approaches from the distance, its wings brought terror and death. An impending doom is coming towards the city. The bell rang and the kingdom shook ablaze. A group of brave adventurers are ready at the gates, waiting silently to face off this monstrous beast.&lt;/p&gt;

&lt;p&gt;The Red Dragon is a massive creature. Its body weigh around 100 story points. Its wings made out of uncertainty of business decisions. Its breath weapon is an acidic taste of coffee in the late night overtime. Its speaks with Draconian magic, commanding people to obey him and serve him forcefully like a corporate slave.&lt;/p&gt;

&lt;p&gt;The adventurer that stood at the gates, never slain a beast this big. They probably nervous and scared at the same time, as if the spell of Imposter Syndrome washes over them. Before the battle begins, we gonna take a look at this brave adventurers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tim, a young Frontend Ranger. His quiver is full with the Tailwind Arrows. His bow is made out of Javascript wood, its probably not the best but it will serve its purpose.&lt;/li&gt;
&lt;li&gt;Greg, The warrior who clad himself in the full body armor who called himself the “Iron Golang” is arisen by the horn of war; the sound of API CALLS.&lt;/li&gt;
&lt;li&gt;Sue, a Mastermind Rogue who strategize how they will approach the monster. The layout of the terrain and building is being drawn into series of Patterns and Architectural Design.&lt;/li&gt;
&lt;li&gt;Steve, in hooded robes leaning on a crooked stick. Nobody knows him, but rumors said he is The Devops Warlock. He understand the Ebb-and-Flow of complicated Sigil of AWS. He secretly draws power from a Fiendish Machine God called Linux. Furthermore, he is existed in this world before we all even exist, he is the one who maintains the SQL Databases to not meddle with the mortal world.&lt;/li&gt;
&lt;li&gt;The last member is Bob. Bob is a Technical Writer Bard. He is apparently useless in this fight. His spell is charisma-based. It won’t work against the dragon, but Bob is a good bullshitter. He can write API Documentation and Technical Manual just like a poetic edda. Bob is just fine, he can join the team.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The battle starts at dawn, The group plans ahead by scouting the designated System Architecture. Validating if they can pull and ambush on this dragon. The Warrior began to appear first, sounding the API Calls to lure the dragon. Its chased him down. Tim notch his arrow and releases a barrage of attacks in quick succession. The arrows barely scratch its thick scales. The warrior turns around preparing his sword, but the dragon flaps its wings and produce a massive wind that shoots Greg into the Deadline Wall.&lt;/p&gt;

&lt;p&gt;They are running out of time, Sue sees her party unable to do anything. She decided to leap from the shadow and started to climb the dragon’s back. The red dragon thrashed around looking for someone to blame, but sue still maintains her grip. Until she eventually thrown up to the air and being swallowed by the dragon. On the inside, Sue manages to damage the dragon internal organs. &lt;/p&gt;

&lt;p&gt;Make it reeling around in pain, but sue knew this is not the part of her job description. But sacrifices needed to be made. In the final push, Steve open a portal to the Outerplanes of AWS. Ship it away sealed within the prison of containerized image of a red dragon. &lt;/p&gt;

&lt;p&gt;Bob, however he’s busy stealing drinks from the nearby tavern. He said that booze can help him to find a great story to tell to the kingdom authority, or simply the management. They lost Sue that day, she was swallowed by the red dragon and never be seen again after the incident.&lt;/p&gt;

&lt;p&gt;The Question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Who unleashed The Red Dragon in the first place?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“It was you, the Project Manager. The Dungeon Master.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;I will get a bit serious here, the project manager is almost like a Dungeon Master. The job is to weave stories and telling tales. That’s why its called “STORY POINTS” for a reason. The technical team doesn’t know what coming to them. The element of surprise and unpreparedness of the team can overwhelm even in the greatest of individuals.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚔️ The Party of Adventurers
&lt;/h2&gt;

&lt;p&gt;I like the idea of Dungeons and Dragons group. Its small, concise, reliable, and fairly easy to maintain. set your team around 3-8 people max. Its always the rule of thumb for me. The bigger the people, the bigger the cost to miscommunicate and harder to schedule an appointment or meetings.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧙‍♂️ The Roles
&lt;/h2&gt;

&lt;p&gt;Each player character will be given out roles. Whether it was damage dealing, magic, ranged attacks, etc. Some character is good at certain tasks, other can also be an all rounder that good at many things but probably not an expert. Same like in project management, knowing which individual is fit for carried out certain task. give them the worthy opponent which suitable for their playstyle.&lt;/p&gt;

&lt;p&gt;for example, you need to know that the frontend is suitable to fight in styling CSS and create a responsive web pages. Otherwise the backend is suitable to fight in REST API and Microservices. But some people can also do both, but check their job description. Even if they can, doesn’t mean that they want to do it. Maybe the someone like Sue can handle Frontend and Backend really well, but that’s not her job, and maybe that’s take a toll on her and eventually quits from the team.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧌 Scaling Up The Enemy Encounter
&lt;/h2&gt;

&lt;p&gt;Maybe a Red Dragon is a bit much for level 3 character right? or we can set the encounter into smaller parts. First the goblins, then the ogres, scales up into the dragons. We can chop things around and sees how the team manage it. You should also needed to keep close eye on the team. Ask around what make the task so difficult, what can be evaluated on each sprints. What works with them and what didn’t work with them. Remember, the team is in the same boat for you. You are not with the company nor with the management, but you are here to tell a story.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏹 Magic Items, Loot, and Treasure Chests
&lt;/h2&gt;

&lt;p&gt;Let’s say that the team had multiple encounters before facing the dragons, you can see how the goblins might have treasure chests filled with magic items. It’s a common thing in D&amp;amp;D that players would get magic items, loot and treasure chests after completing an encounter.&lt;/p&gt;

&lt;p&gt;Imagine that the magic items, loot, and treasure chests is a part of project milestone. For each small encounter that they tackle, it may help them to make the final boss to be much more easier. You also need to keep in mind that this small encounters is also a way to understand the viewpoints of the bigger problems before actually executing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔮 The Game Rules
&lt;/h2&gt;

&lt;p&gt;Probably many people will not agree in this. But in order to create a neatly woven story, you needed to understands the rules. Technical stuff, like concepts of API. What is a Framework, Databases, and different environments is basically easy to learn. You don’t need to master it, or became an expert, being able to know the concept is enough. Learn with your team about these things, ask them around how they created an OAUTH token just for your curiosity. Take a little bit of walk with your system architect and discuss how MVC works while enjoying a cup of coffee.&lt;/p&gt;

&lt;h2&gt;
  
  
  👩‍🚀 The Responsible Dungeon Master
&lt;/h2&gt;

&lt;p&gt;Being a Dungeon Master is not an easy task, for those of you who create a D&amp;amp;D campaign might know this. Its sometimes comes with sacrifices; such as the time to ensure the miniatures is available, the story is easy to understand by the rest of the player, and so on. The Project manager will also have the similar fate. The management will push you around, telling the deadlines is near, but you also cannot blame the devs (unless if they are an as***le).&lt;/p&gt;

&lt;p&gt;In D&amp;amp;D, plot can also suddenly changes. It’s mostly to many things. Lets pretend that the number business decisions is a number of dice rolls. Sometimes it is a successful or failed roll. Either way it can shifts in sudden changes. But you can never do anything about it. Accept that the management will always put the pressure on you because of you are the Project Manager.&lt;/p&gt;

&lt;p&gt;The way you handle management expectation is also the challenge of project management. In the world full of KPI’s we often forget that it is also our job to communicate to the company management what is happening inside of the Team and what to expected from them.&lt;/p&gt;

&lt;p&gt;P.S. &lt;/p&gt;

&lt;p&gt;Yes, this is my late night thoughts. I don’t even proofread it very much. There’s gonna be grammatical errors.  But, I decided not to care. This probably looks like I’m consuming a ton amount of mushrooms while writing this article. Also check out &lt;a href="https://www.youtube.com/watch?v=kcSWsvvJ0fQ" rel="noopener noreferrer"&gt;Matt Brunt talking about D&amp;amp;D and project management&lt;/a&gt;, its such a great talk.&lt;/p&gt;

</description>
      <category>management</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
