<?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: Víctor Falcón</title>
    <description>The latest articles on Forem by Víctor Falcón (@victoor).</description>
    <link>https://forem.com/victoor</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%2F1298%2F238766.jpeg</url>
      <title>Forem: Víctor Falcón</title>
      <link>https://forem.com/victoor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/victoor"/>
    <language>en</language>
    <item>
      <title>Building a Privacy-First Finance App with Laravel 12 and React 19</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Sat, 14 Feb 2026 15:53:17 +0000</pubDate>
      <link>https://forem.com/victoor/building-a-privacy-first-finance-app-with-laravel-12-and-react-19-2j3d</link>
      <guid>https://forem.com/victoor/building-a-privacy-first-finance-app-with-laravel-12-and-react-19-2j3d</guid>
      <description>&lt;p&gt;Every personal finance app wants your bank credentials. I built one that doesn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;I've been tracking my finances digitally for years. Every app I tried followed the same pattern: "Connect your bank account to get started." This means handing your credentials to a third-party aggregator like Plaid, which in turn means your complete transaction history flowing through systems you don't control.&lt;/p&gt;

&lt;p&gt;After seeing multiple fintech data breaches make the news, I decided to take a different approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Approach
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Whisper Money&lt;/strong&gt; is a personal finance app that never connects to your bank. Instead, you export a CSV or XLS from your bank (which every bank supports) and import it. A year of transactions loads in about 10 seconds.&lt;/p&gt;

&lt;p&gt;The trade-off is clear: no real-time sync, but complete privacy. For me, importing once a week takes less than a minute and is worth the peace of mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Stack
&lt;/h3&gt;

&lt;p&gt;I built this with the latest Laravel ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Laravel 12&lt;/strong&gt; (PHP 8.4) - The backend handles accounts, transactions, budgets, categorization, and user management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React 19&lt;/strong&gt; - The frontend with full TypeScript strict mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inertia.js v2&lt;/strong&gt; - Bridges Laravel and React without building a separate API. Deferred props, prefetching, and the new Form component are used throughout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS v4&lt;/strong&gt; - CSS-first configuration with the &lt;code&gt;@theme&lt;/code&gt; directive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Laravel Wayfinder&lt;/strong&gt; - Generates type-safe TypeScript functions from Laravel routes. No more hardcoded URL strings in the frontend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pest v4&lt;/strong&gt; - Test suite with factories and feature tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture Decisions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why Inertia instead of a separate API?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a product like this, Inertia is perfect. You get the SPA experience (client-side routing, smooth transitions, reactive forms) without maintaining a separate API layer. The backend renders props, the frontend renders components. Authentication, authorization, and validation all happen server-side through standard Laravel patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why no bank integration?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Beyond privacy, this is also an architectural simplification. Bank API integrations are complex: they require handling multiple aggregators, dealing with connection failures, managing OAuth flows, and storing sensitive credentials. By removing this entirely, the codebase stays focused on what matters: helping users understand their spending.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dual distribution: OSS + SaaS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same codebase powers both the self-hosted version and the hosted SaaS. Laravel Pennant feature flags control what's available in each context (e.g., Stripe subscriptions are only enabled for the SaaS version). This keeps everything in one codebase without maintenance overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Automation Rules with JSON Logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Users can create rules to auto-categorize transactions without writing code. Under the hood, this uses JSON Logic - a portable, serializable way to represent conditional logic. Example rule: "if the transaction description contains 'Netflix', set category to 'Subscriptions' and add label 'recurring'."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smart Budgets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Budgets support different periods (daily, weekly, monthly, yearly) and rollover types. If you underspend in one period, the remainder can roll into the next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Hosting Made Easy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The project includes a production Docker image, a Docker Compose file, and a Coolify one-click deploy template. Getting it running on your own server takes minutes, not hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try It
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Demo&lt;/strong&gt; (no registration): &lt;a href="https://whisper.money/login?demo=1" rel="noopener noreferrer"&gt;https://whisper.money/login?demo=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/whisper-money/whisper-money" rel="noopener noreferrer"&gt;https://github.com/whisper-money/whisper-money&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted version&lt;/strong&gt;: &lt;a href="https://whisper.money" rel="noopener noreferrer"&gt;https://whisper.money&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is open source under CC BY-NC 4.0. Contributions welcome.&lt;/p&gt;




&lt;p&gt;What's your take on the "no bank integration" trade-off? Would you give up real-time sync for complete privacy over your financial data?&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>react</category>
      <category>opensource</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Supercharge Your AI Skills: 5 Open Source Repositories You Can't Afford to Miss</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Thu, 21 Nov 2024 09:13:09 +0000</pubDate>
      <link>https://forem.com/victoor/supercharge-your-ai-skills-5-open-source-repositories-you-cant-afford-to-miss-24b8</link>
      <guid>https://forem.com/victoor/supercharge-your-ai-skills-5-open-source-repositories-you-cant-afford-to-miss-24b8</guid>
      <description>&lt;p&gt;In the rapidly evolving landscape of artificial intelligence, open source projects are at the forefront of innovation, providing developers and enthusiasts with the tools they need to create groundbreaking solutions. &lt;/p&gt;

&lt;p&gt;As someone passionate about sharing the latest advancements in AI, &lt;strong&gt;I’ve been curating and sharing 2-3 open source projects daily on my Twitter/X account &lt;a href="https://x.com/victoor" rel="noopener noreferrer"&gt;@victoor&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This article &lt;strong&gt;highlights five of the best open source AI repositories I’ve come across&lt;/strong&gt;, each offering unique features and capabilities that can enhance your projects and inspire your creativity. &lt;/p&gt;

&lt;p&gt;Whether you’re a seasoned developer or just starting your journey in AI, these repositories are invaluable resources that can help you unlock new possibilities. &lt;/p&gt;

&lt;p&gt;Let’s dive in and explore these game-changing tools!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://github.com/Pythagora-io/gpt-pilot" rel="noopener noreferrer"&gt;GPT Pilot&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Pythagora-io/gpt-pilot" 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%2Fkplg5rkq9j7gjst3kn6s.png" alt="Image description" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first real AI developer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It aims to research how much LLMs can be utilized to generate fully working, production-ready apps while the developer oversees the implementation.&lt;/p&gt;

&lt;p&gt;The main idea is that AI can write most of the code for an app (maybe 95%), but for the rest, 5%, a developer is and will be needed until we get full AGI.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://github.com/All-Hands-AI/OpenHands" rel="noopener noreferrer"&gt;OpenHands (formerly OpenDevin)&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/All-Hands-AI/OpenHands" 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%2Fhj0jo2gg3n13yjxecbj5.png" alt="Image description" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenHands, &lt;strong&gt;previously known as OpenDevin&lt;/strong&gt;, is an innovative platform designed to revolutionize the software development process through the power of artificial intelligence.&lt;/p&gt;

&lt;p&gt;By leveraging advanced AI technologies, OpenHands provides developers with intelligent agents that can perform a wide array of tasks typically handled by human programmers. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From modifying code and executing commands to browsing the web and calling APIs&lt;/strong&gt;, these agents are equipped to enhance productivity and streamline workflows. &lt;/p&gt;

&lt;p&gt;With OpenHands, developers can focus on higher-level problem-solving while the AI takes care of repetitive and time-consuming tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;a href="https://github.com/m-bain/whisperX" rel="noopener noreferrer"&gt;WhisperX&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/m-bain/whisperX" 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%2Fdyf9peq1s78hwi9754sm.png" alt="Image description" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WhisperX is an advanced automatic speech recognition (ASR) repository that significantly enhances the capabilities of existing models, particularly OpenAI's Whisper. &lt;/p&gt;

&lt;p&gt;Designed for &lt;strong&gt;efficiency and accuracy&lt;/strong&gt;, WhisperX provides fast transcription at an impressive rate of 70 times real-time using the large-v2 model. &lt;/p&gt;

&lt;p&gt;This is made possible through its &lt;strong&gt;innovative batched inference approach&lt;/strong&gt;, which allows for rapid processing while maintaining the quality of transcriptions. &lt;/p&gt;

&lt;p&gt;With features like &lt;strong&gt;word-level timestamps and speaker diarization&lt;/strong&gt;, WhisperX is an essential tool for developers and researchers seeking to implement high-performance speech recognition in their applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. &lt;a href="https://github.com/Nutlope/llama-ocr" rel="noopener noreferrer"&gt;Llama OCR&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Nutlope/llama-ocr" 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%2Fbnrzk03150cwimyvr8sw.png" alt="Image description" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Llama OCR is a powerful npm library designed to provide &lt;strong&gt;free optical character recognition (OCR) capabilities using the advanced Llama 3.2&lt;/strong&gt; Vision model from Together AI.&lt;/p&gt;

&lt;p&gt;This library simplifies the process of extracting text from images, making it an invaluable tool for developers looking to &lt;strong&gt;integrate OCR functionality into their applications without incurring high costs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With easy installation via npm and straightforward usage, Llama OCR allows users to convert images, such as receipts or documents, into editable markdown format with minimal effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. &lt;a href="https://github.com/richards199999/Thinking-Claude" rel="noopener noreferrer"&gt;Thinking Claude&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/richards199999/Thinking-Claude" 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%2Fmoqt5zkzj7m3vaxwhy8d.png" alt="Image description" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thinking Claude is an innovative project &lt;strong&gt;designed to enhance the response quality of the Claude AI model&lt;/strong&gt; by encouraging a more comprehensive and systematic thinking process before generating replies. &lt;/p&gt;

&lt;p&gt;While not focused on achieving benchmarks or solving complex mathematical problems, &lt;strong&gt;Thinking Claude aims to explore the depths of Claude's reasoning capabilities&lt;/strong&gt;, making interactions not only more insightful but also engaging.&lt;/p&gt;

&lt;p&gt;Users will find that Claude's inner monologue—its thought process—adds a layer of depth to conversations, transforming mundane interactions into fascinating dialogues.&lt;/p&gt;




&lt;p&gt;In conclusion, the world of open source AI repositories is brimming with innovative tools that empower developers and enhance productivity.&lt;/p&gt;

&lt;p&gt;From OpenHands and WhisperX to Llama OCR and Thinking Claude, each of these projects showcases the incredible potential of AI to transform how we approach software development, speech recognition, document processing, and intelligent interactions. &lt;/p&gt;

&lt;p&gt;I encourage you to explore these repositories and consider how they can elevate your own projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For daily insights and updates on the latest open source AI projects, be sure to follow me on Twitter/X at &lt;a href="https://x.com/victoor" rel="noopener noreferrer"&gt;@victoor&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Join the conversation and stay informed about the exciting developments in the AI landscape!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to mitigate a DDoS attack on a small server</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Thu, 21 Nov 2024 08:06:00 +0000</pubDate>
      <link>https://forem.com/victoor/how-to-mitigate-a-ddos-attack-on-a-small-server-1a74</link>
      <guid>https://forem.com/victoor/how-to-mitigate-a-ddos-attack-on-a-small-server-1a74</guid>
      <description>&lt;p&gt;&lt;a href="https://metricswave.com?ref=developerjoy" rel="noopener noreferrer"&gt;MetricsWave&lt;/a&gt; was the target of a DDoS attack.  &lt;/p&gt;

&lt;p&gt;It receives about 750k requests per hour for 8 hours.  &lt;/p&gt;

&lt;p&gt;I don't know what the goal was; I guess it's what happens when you share your projects publicly, but now the service is faster and more stable than ever!&lt;/p&gt;

&lt;p&gt;Let me tell your how I did it.&lt;/p&gt;

&lt;h2&gt;
  
  
  DDoS Attack Numbers
&lt;/h2&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%2F8dwpbnss54ynby02438y.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%2F8dwpbnss54ynby02438y.png" alt="Server CPU usage during the attack" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't have the exact numbers, because the server was not ready before this, but it seems that from 8 am to 18 pm the web was receiving about 750k request per hour from a single IP.&lt;/p&gt;

&lt;p&gt;That's about 7.5 M request in 10 hours.&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%2F0a1u60rsvrxun57l3y0q.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%2F0a1u60rsvrxun57l3y0q.png" alt="Request per minute since we got metrics" width="617" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know it's not too much for a big server, but take into account that MetricsWave still run in a relative small server with a simple config.&lt;/p&gt;

&lt;p&gt;The good news is &lt;strong&gt;the app keep alive during the hole day&lt;/strong&gt; and we were able to manage all the traffic, registering all the events and visits from our users pages.&lt;/p&gt;

&lt;p&gt;Slow loading was experienced for a few hours, but the service was up at all times.&lt;/p&gt;

&lt;p&gt;A part from that, we did some improvements and now the site is faster than ever.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we blocked the IP
&lt;/h2&gt;

&lt;p&gt;At the beginning we try to add a block on our side by the type of request and the IP, but it was not enough.&lt;/p&gt;

&lt;p&gt;The damage one our server was mitigated but we still need to process each request and do some checks before rejecting it.&lt;/p&gt;

&lt;p&gt;The final solution was to install Cloudflare in front of our server.&lt;/p&gt;

&lt;p&gt;With this, I'm able to reject all the malicious requests before they even reach our server, so we can keep the CPU usage and memory healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improvements We Did
&lt;/h2&gt;

&lt;p&gt;Also, it was a good opportunity to make some improvements&lt;/p&gt;

&lt;p&gt;With this huge amount of traffic, I was able to &lt;strong&gt;identify some slow queries and repeated processes that we can avoid&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We improved our dashboard queries and cached some of the ones that do not change much, and we can even invalidate the cache when they do.&lt;/p&gt;

&lt;p&gt;Now the dashboard load time is reduced by almost a 50%.&lt;/p&gt;

&lt;p&gt;Also, with Cloudflare, now we can cache some static pages like the landing page, or some resources like the &lt;code&gt;visits.js&lt;/code&gt; script among others.&lt;/p&gt;




&lt;p&gt;I still haven't been able to figure out what the objective of this attack is.&lt;/p&gt;

&lt;p&gt;I don't understand what anyone wants to achieve by doing something like this, but oh well.&lt;/p&gt;

&lt;p&gt;I guess that's what happens when you share your projects in public.&lt;/p&gt;

</description>
      <category>ddos</category>
      <category>security</category>
    </item>
    <item>
      <title>5 Tools to Increase Your SaaS MRR</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Tue, 19 Nov 2024 12:45:00 +0000</pubDate>
      <link>https://forem.com/victoor/5-tools-to-increase-your-saas-mrr-4f42</link>
      <guid>https://forem.com/victoor/5-tools-to-increase-your-saas-mrr-4f42</guid>
      <description>&lt;p&gt;In the competitive landscape of Software as a Service (SaaS), &lt;strong&gt;maximizing Monthly Recurring Revenue (MRR) is crucial&lt;/strong&gt; for growth and sustainability. &lt;/p&gt;

&lt;p&gt;Leveraging the right tools can streamline processes, enhance customer engagement, and ultimately drive revenue. &lt;/p&gt;

&lt;p&gt;Here are &lt;strong&gt;five essential tools that can help you increase your SaaS MRR&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Semrush
&lt;/h2&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%2Fxj3cbed7j81as300hue5.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%2Fxj3cbed7j81as300hue5.png" alt="Image description" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.semrush.com/dashboard/" rel="noopener noreferrer"&gt;Semrush&lt;/a&gt; is a leading SEO optimization tool renowned for delivering data-driven results.&lt;/p&gt;

&lt;p&gt;It enables &lt;strong&gt;SaaS marketers to monitor and analyze keywords, both for their own websites and their competitors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With comprehensive reporting on keyword rankings and critical issues that need addressing, Semrush equips teams with the insights needed to enhance their online visibility.&lt;/p&gt;

&lt;p&gt;Additionally, its resourceful toolkits are designed for social media and content management, making it an all-in-one solution for improving organic traffic and, subsequently, MRR.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. MetricsWave
&lt;/h2&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%2F0tz1hlzvpafuz6b3093l.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%2F0tz1hlzvpafuz6b3093l.png" alt="Image description" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://metricswave.com?ref=devto" rel="noopener noreferrer"&gt;MetricsWave&lt;/a&gt; is designed to offer &lt;strong&gt;valuable insights into user behavior and engagement metrics&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By analyzing data trends, MetricsWave can help SaaS businesses identify opportunities for growth and optimize their marketing strategies.&lt;/p&gt;

&lt;p&gt;You can track sign-ups, complex forms, simple buttons, create funnels, and see what the user is actually doing in your app. You can even track sales and subscriptions to see the income in one single place.&lt;/p&gt;

&lt;p&gt;Utilizing such analytics tools can lead to better decision-making, improved customer targeting, and ultimately, an increase in MRR.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Typefully
&lt;/h2&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%2Flseb130z6x3kqa6t5v2h.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%2Flseb130z6x3kqa6t5v2h.png" alt="Image description" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typefully.com/" rel="noopener noreferrer"&gt;Typefully&lt;/a&gt; is a powerful tool that streamlines social media management, allowing SaaS businesses to schedule posts on platforms like X (formerly Twitter), Threads, and LinkedIn.&lt;/p&gt;

&lt;p&gt;Typefully &lt;strong&gt;simplifies this process by enabling users to plan and automate their social media content&lt;/strong&gt;, ensuring that their messaging reaches the right audience at optimal times. &lt;/p&gt;

&lt;p&gt;This capability is essential for SaaS companies looking to &lt;strong&gt;promote their products effectively and attract new users&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Promoting your tool on social media not only helps in acquiring new customers but also strengthens relationships with existing users.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Formbricks
&lt;/h2&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%2Fg5hbzbox5rvgab2r0tvf.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%2Fg5hbzbox5rvgab2r0tvf.png" alt="Image description" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/formbricks/formbricks" rel="noopener noreferrer"&gt;Formbricks&lt;/a&gt; offers a free and open-source surveying platform that &lt;strong&gt;allows SaaS companies to gather feedback at every point in the user journey&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With beautiful in-app, website, link, and email surveys, Formbricks enables businesses to understand their customers better.&lt;/p&gt;

&lt;p&gt;This feedback is crucial for improving user experience and product offerings, which can lead to increased customer satisfaction and loyalty—key factors in enhancing MRR.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. HubSpot Marketing Hub
&lt;/h2&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%2Fz7z2uk94rrgsevukauve.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%2Fz7z2uk94rrgsevukauve.png" alt="Image description" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Managing multiple marketing streams can be overwhelming, but &lt;a href="https://www.hubspot.com/products/marketing" rel="noopener noreferrer"&gt;HubSpot’s Marketing Hub&lt;/a&gt; simplifies the process by integrating various functions into one powerful tool.&lt;/p&gt;

&lt;p&gt;This marketing automation platform &lt;strong&gt;facilitates email marketing, landing page creation, social media marketing, content management, reporting, and analytics&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By enabling personalized marketing campaigns, HubSpot helps SaaS businesses save time and increase efficiency, ultimately leading to higher customer acquisition and retention rates, which are vital for boosting MRR.&lt;/p&gt;




&lt;p&gt;By integrating these tools into your SaaS business strategy, you can enhance your marketing efforts, improve customer engagement, and drive significant growth in your Monthly Recurring Revenue.&lt;/p&gt;

&lt;p&gt;Each tool offers unique features that cater to different aspects of your business, making them essential components of a successful SaaS operation.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>tooling</category>
      <category>marketing</category>
    </item>
    <item>
      <title>How to organize your Laravel 11 Project in 2024</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Mon, 09 Sep 2024 07:00:00 +0000</pubDate>
      <link>https://forem.com/victoor/how-to-organize-your-laravel-11-project-in-2024-325a</link>
      <guid>https://forem.com/victoor/how-to-organize-your-laravel-11-project-in-2024-325a</guid>
      <description>&lt;p&gt;Because of my work at &lt;a href="//developerjoy.co"&gt;developerjoy.co&lt;/a&gt;, I have created over 10 Laravel projects from scratch in the last year, and worked on more than 25 and I have seem one common thing in all of them.&lt;/p&gt;

&lt;p&gt;The Laravel default directory structure only works when your project it's really small.&lt;/p&gt;

&lt;p&gt;As the project grows, &lt;strong&gt;the default directory structure becomes a problem because it does not scale properly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After a few use cases, models, policies, and so on, you will end with something similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
├── Actions
│   ├── Actionable.php
│   ├── Graph
│   │   └── ...
│   ├── MonthlyResume
│   │   └── GenerateMonthlyResumeAssets.php
│   ├── User
│   │   └── UpdateUser.php
│   └── VoidActionable.php
├── Console
│   ├── Commands
│   │   ├── CalculateUserCryptoPortfolioBalanceCommand.php
│   │   ├── CategorizeTransactionsIaCommand.php
│   │   ├── GenerateMonthlyReportAssetsCommand.php
│   │   ├── IdeHelperAllCommand.php
│   │   ├── PruneNotificationsCommand.php
│   │   ├── SendMonthlyReportNotificationCommand.php
│   │   ├── SendNewUpdateChangeLogNotificationCommand.php
│   │   └── TrainCategorizationIaCommand.php
│   └── Kernel.php
├── Contracts
│   └── Pipe.php
├── Events
│   ├── SharingConfigurationSaved.php
│   ├── SupportMessageCreated.php
│   └── VisitIncreased.php
├── Exceptions
│   ├── GetBankAccountTransactionError.php
│   ├── Handler.php
│   └── RenderableApiError.php
├── Http
│   ├── Controllers
│   │   ├── Banks
│   │   ├── Controller.php
│   │   ├── CryptoCurrency
│   │   ├── Notification
│   │   ├── SupportMessage
│   │   └── User
│   │       ├── DeleteUserController.php
│   │       ├── GetUserController.php
│   │       └── PutUserController.php
│   ├── Kernel.php
│   ├── Middleware
│   │   ├── Authenticate.php
│   │   ├── DefaultLocale.php
│   │   ├── TrustProxies.php
│   │   ├── ValidateSignature.php
│   │   └── VerifyCsrfToken.php
│   ├── Requests
│   │   ├── PostSupportMessageRequest.php
│   │   └── PutUserRequest.php
│   └── Resources
├── Jobs
│   ├── CalculateUserCryptoPortfolioBalanceJob.php
│   ├── GenerateMonthlyResumeAssetsJob.php
│   ├── GetBankAccountDetails.php
│   └── GetCoinGeckoValuesJob.php
├── Listeners
│   ├── SendAdminNotificationOnSupportMessageCreated.php
│   ├── SendEmailToUserOnVisitIncremented.php
│   └── SendMailOnSupportMessageCreated.phpphp
├── Mail
│   ├── SupportMessage
│   └── Visits
├── Models
│   ├── Bank.php
│   ├── SharingConfiguration.php
│   ├── SupportMessage.php
│   ├── User.php
│   └── UserCryptoPortfolioBalance.php
├── Notifications
│   ├── Notifiable.php
│   ├── ThrottledNotification.php
│   ├── UncategorizedTransactionNotification.php
│   └── UpdateChangeLogNotification.php
├── Policies
│   └── CryptoCurrencyOrderPolicy.php
├── Providers
│   ├── AppServiceProvider.php
│   ├── EventServiceProvider.php
│   ├── HorizonServiceProvider.php
│   └── RouteServiceProvider.php
├── Services
│   └── CategorizationAi.php
└── Support
    ├── OrderType.php
    ├── SafeNumberFromStringParser.php
    ├── ShortNumberFormatter.php
    ├── StockAssets
    └── helpers.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I removed a lot of files and directories from tree, but you can imagine that it's impossible to see all the code related to users.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, it's really difficult to know what's happening there. You are working in a users controller, for example, and you don't have all the relevant classes close to it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can't see, at a glance, all the relevant classes and models for your current use case.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A better directory structure in our Laravel project
&lt;/h2&gt;

&lt;p&gt;The main key, to properly scale your app, is to being able to see al the related code to the current use case you're working on at a glance.&lt;/p&gt;

&lt;p&gt;For example, if you're working on the user registration use case, you should have the user model, user policies, registration request, the registered event, and more, close to you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── Leads
├── Teams
└── Users
    ├── Actions
    │   ├── CreateUser
    │   │   ├── CreateUser.php
    │   │   └── CreateUserAction.php
    │   ├── LoginUserAction.php
    │   ├── LogoutUserAction.php
    │   └── RefreshAuthenticationTokenAction.php
    ├── Authenticatable.php
    ├── Authentication.php
    ├── Events
    │   └── UserRegistered.php
    ├── Http
    │   ├── Controllers
    │   │   └── Api
    │   │       ├── PostAuthenticationLoginApiController.php
    │   │       ├── PostAuthenticationLogoutApiController.php
    │   │       ├── PostAuthenticationRefreshApiController.php
    │   │       └── PostAuthenticationRegisterApiController.php
    │   ├── Requests
    │   │   ├── PostAuthenticationLoginRequest.php
    │   │   └── PostUserRequest.php
    │   └── routes
    │       └── api.php
    ├── Infrastructure
    │   └── UserEventServiceProvider.php
    ├── InvalidCredentials.php
    ├── Listeners
    │   └── SendWelcomeEmailOnUserRegistered.php
    ├── Mail
    │   └── WelcomeMail.php
    └── User.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But know, you're wondering, how can I achieve this architecture easily on Laravel.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement a domain directory architecture on Laravel
&lt;/h2&gt;

&lt;p&gt;The start point is &lt;code&gt;composer.json&lt;/code&gt; file. We are going to create a new folder &lt;code&gt;./src&lt;/code&gt; to store all our new code.&lt;/p&gt;

&lt;p&gt;Adding the directory to the &lt;code&gt;psr-4&lt;/code&gt; key in the &lt;code&gt;composer.json&lt;/code&gt; we are going to autoimport all our files easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"autoload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="nl"&gt;"psr-4"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"App\\"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"app/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"DeveloperJoy\\"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;

     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just with this, you can put all your models, controllers, requests, policies, and more, in a custom domain folder under &lt;code&gt;src/User&lt;/code&gt;, for example.&lt;/p&gt;

&lt;p&gt;There are only a few things missing: routes, and providers, so let's go one by one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Move routes to a custom folder
&lt;/h3&gt;

&lt;p&gt;For routes we have multiple options, for me, the most simpler and easier is to import them in the &lt;code&gt;web.php&lt;/code&gt; or in the &lt;code&gt;api.php&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;I usually write a helper file inside routes folder that looks 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="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;domain_web_routes&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;$domain&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="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"/../src/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/Http/routes/web.php"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;domain_api_routes&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;$domain&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="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"/../src/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/Http/routes/api.php"&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;and imported in my composer.json file just adding it to the files array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"autoload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"routes/helpers.php"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A them, in my default &lt;code&gt;web.php&lt;/code&gt; or &lt;code&gt;api.php&lt;/code&gt; I just import each new domain folder when it has any route.&lt;/p&gt;

&lt;p&gt;This is, for example, my &lt;code&gt;web.php&lt;/code&gt; file:&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="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;inertia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Welcome'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;domain_web_routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Leads'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;src/Leads/Http/routes&lt;/code&gt; y have a &lt;code&gt;web.php&lt;/code&gt; file with all my routes related to leads.&lt;/p&gt;

&lt;p&gt;Is really that simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Move service providers, to a custom domain folder
&lt;/h3&gt;

&lt;p&gt;With providers is actually pretty easy.&lt;/p&gt;

&lt;p&gt;We have a file under &lt;code&gt;bootstrap/app.php&lt;/code&gt; that has an array of all our providers.&lt;/p&gt;

&lt;p&gt;You just have to add new providers to it, and it will be processed automatically on load time.&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="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basePath&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;__DIR__&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withProviders&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;

        &lt;span class="nc"&gt;DeveloperJoy\Users\Infrastructure\UserEventServiceProvider&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>Three Keys to Create a maintainable Laravel Application</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Mon, 25 Sep 2023 12:35:05 +0000</pubDate>
      <link>https://forem.com/victoor/three-keys-to-create-a-maintainable-laravel-application-2e2n</link>
      <guid>https://forem.com/victoor/three-keys-to-create-a-maintainable-laravel-application-2e2n</guid>
      <description>&lt;p&gt;Laravel is a framework that gives you a lot of freedom. It allows you to structure your application code as you wish.&lt;/p&gt;

&lt;p&gt;You can decide to put all the code in the controller, you can create use cases, DDD, or use jobs to host all your logic.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://developerjoy.co?utm_source=devto&amp;amp;utm_medium=poat&amp;amp;utm_campaign=laravel&amp;amp;utm_id=693262&amp;amp;utm_term=laravel"&gt;developerjoy.co&lt;/a&gt; I have been able to work on dozens of different projects and I have seen first-hand what makes a Laravel application easy to maintain as it grows.&lt;/p&gt;

&lt;p&gt;For me, if I had to keep only three keys, they would be the following:&lt;/p&gt;

&lt;h4&gt;
  
  
  Table Of Contents
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Use Events and Listeners&lt;/li&gt;
&lt;li&gt;Tests everything, it's super important&lt;/li&gt;
&lt;li&gt;Embrace DDD and create Modules&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Use Events and Listeners &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It is very common, in all applications, to have to do something extra after a simple use case.&lt;/p&gt;

&lt;p&gt;For example, send an email, after creating a user.&lt;/p&gt;

&lt;p&gt;This type of case tends to dirty our use cases and forces us to add more and more logic. In addition, we make the use case slower and slower, and the user has to wait longer.&lt;/p&gt;

&lt;p&gt;Why does the user have to wait, when they register, for us to send an email?, for example. Has no sense.&lt;/p&gt;

&lt;p&gt;To avoid this and keep our use cases clean, &lt;strong&gt;you should use events and listeners&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;UserCreated&lt;/code&gt; event and a &lt;code&gt;SendWelcomeMailOnUserCreated&lt;/code&gt; listener.&lt;/p&gt;

&lt;p&gt;Every time you need to do something else in a use case, you will simply have to create the listener. Your use case will be able to continue working as is, without any changes.&lt;/p&gt;




&lt;h3&gt;
  
  
  Tests everything, it's super important &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I know, making tests is boring and a waste of time. Really?&lt;/p&gt;

&lt;p&gt;Apart from making sure that the basic use cases still work, it will also help you keep your code clean. You do not believe me?&lt;/p&gt;

&lt;p&gt;If you test your use cases you will be able to refactor the code when and how you want without breaking anything. This is something of a superpower.&lt;/p&gt;

&lt;p&gt;Do you want to simplify your use case and start launching events? Do you want to move your site code? No problem. First write a test and then you can play what you want with the assurance that you are not breaking anything.&lt;/p&gt;

&lt;p&gt;Plus, testing in Laravel is easy.&lt;/p&gt;

&lt;p&gt;Most of the time, testing an endpoint is just a couple of lines. It's easy to make and quick to execute.&lt;/p&gt;

&lt;p&gt;Really, there is no turning back. When you prove the value that the tests give you, you will not stop writing them.&lt;/p&gt;




&lt;h3&gt;
  
  
  Embrace DDD and create Modules &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When an application with Laravel grows we find many models, controllers, events, listeners and jobs together in the same folder.&lt;/p&gt;

&lt;p&gt;This makes it impossible to have a context of what is happening with our model.&lt;/p&gt;

&lt;p&gt;Imagine that you are working with the user, and you need to update a use case, the registration case, for example.&lt;/p&gt;

&lt;p&gt;By having everything together it is impossible, at a single glance, to see everything that affects our user model, in which controllers it is being used and what events it launches.&lt;/p&gt;

&lt;p&gt;Using DDD, you will separate your code into modules and be able to see at a glance what you are working on.&lt;/p&gt;

&lt;p&gt;Personally I like to create a &lt;code&gt;src&lt;/code&gt; folder and there create a Module for each model or entity.&lt;/p&gt;

&lt;p&gt;In the end it would be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/src
   /Users
      User.php
      /Listeners
      /Controllers
      /Events
      /Providers
      ...
   /Posts
      Post.php
      ...
   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Believe me, in the end, as your application grows, you will appreciate it.     &lt;/p&gt;

</description>
      <category>laravel</category>
    </item>
    <item>
      <title>Why Choose MetricsWave as Your Google Analytics Alternative</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Thu, 27 Jul 2023 17:49:06 +0000</pubDate>
      <link>https://forem.com/victoor/why-choose-metricswave-as-your-google-analytics-alternative-5agg</link>
      <guid>https://forem.com/victoor/why-choose-metricswave-as-your-google-analytics-alternative-5agg</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://metricswave.com?utm_source=devto&amp;amp;utm_medium=poat&amp;amp;utm_campaign=devtoai&amp;amp;utm_id=devtoai"&gt;MetricsWave&lt;/a&gt; is a powerful and user-friendly Google Analytics alternative that offers a comprehensive set of features and tools to track and analyze website performance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With MetricsWave, you can easily monitor key metrics, such as website traffic, page views, bounce rate, conversion rate, and more. The platform provides detailed reports and visualizations, allowing you to gain valuable insights into your website's performance and make data-driven decisions. &lt;/p&gt;

&lt;p&gt;In addition, MetricsWave offers advanced features like event tracking, goal tracking, and e-commerce tracking, enabling you to optimize your website and improve its overall effectiveness. &lt;/p&gt;

&lt;p&gt;Whether you are a small business owner, a marketer, or a website administrator, MetricsWave provides the tools you need to understand your audience, measure your success, and drive growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why choose MetricsWave as your Google Analytics alternative?
&lt;/h2&gt;

&lt;p&gt;MetricsWave is the perfect alternative to Google Analytics for several reasons. &lt;/p&gt;

&lt;p&gt;Firstly, it offers a user-friendly interface that is easy to navigate and understand, making it accessible to users of all skill levels. &lt;/p&gt;

&lt;p&gt;Additionally, MetricsWave provides comprehensive analytics and reporting features, allowing users to gain valuable insights into their website's performance. Furthermore, MetricsWave prioritizes data privacy and security, ensuring that users' information is protected at all times. &lt;/p&gt;

&lt;p&gt;Lastly, MetricsWave offers competitive pricing plans, making it a cost-effective choice for businesses of all sizes. With all these advantages, it's clear why MetricsWave is the top choice for those seeking an alternative to Google Analytics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of using MetricsWave
&lt;/h2&gt;

&lt;p&gt;MetricsWave offers a wide range of benefits that make it a compelling choice as a Google Analytics alternative. One of the key advantages is its user-friendly interface, which makes it easy for users to navigate and understand their website data. &lt;/p&gt;

&lt;p&gt;Additionally, MetricsWave provides in-depth analytics and reporting features that allow businesses to gain valuable insights into their website performance. Another benefit is the ability to track and analyze multiple websites and domains from a single dashboard, saving time and effort. &lt;/p&gt;

&lt;p&gt;Furthermore, MetricsWave offers advanced filtering and segmentation options, enabling businesses to dive deep into their data and uncover meaningful patterns and trends. With its robust features and intuitive interface, MetricsWave is a reliable and efficient alternative to Google Analytics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Real-time data tracking
&lt;/h3&gt;

&lt;p&gt;Real-time data tracking is one of the key features that sets metricswave.com apart as a Google Analytics alternative. With metricswave.com, you can get up-to-the-minute insights into your website's performance, allowing you to make data-driven decisions in real time. Whether you're monitoring the success of a marketing campaign or tracking user behavior on your site, metricswave.com provides accurate and timely data that helps you stay ahead of the competition. Say goodbye to waiting for data updates and hello to instant insights with metricswave.com.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced analytics
&lt;/h3&gt;

&lt;p&gt;Advanced analytics provide deep insights into your website's performance and user behavior. With metricswave.com as your Google Analytics alternative, you can unlock a whole new level of data analysis. Our advanced analytics tools offer comprehensive reports and visualizations, allowing you to track key metrics, understand user journeys, and identify areas for improvement. Whether you're a small business owner or a marketing professional, our platform empowers you to make data-driven decisions and optimize your online presence. Say goodbye to the limitations of traditional analytics and embrace the power of metricswave.com for advanced analytics like never before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customizable dashboards
&lt;/h3&gt;

&lt;p&gt;Customizable dashboards are one of the key features that set metricswave.com apart as a top Google Analytics alternative. With metricswave.com, users have the ability to create personalized dashboards tailored to their specific needs and preferences. This allows users to easily track and analyze the data that is most important to them, providing valuable insights into their website's performance. Whether it's monitoring website traffic, conversion rates, or user engagement, metricswave.com's customizable dashboards offer a comprehensive view of key metrics in a visually appealing and user-friendly format. By giving users the flexibility to customize their dashboards, metricswave.com empowers businesses to make data-driven decisions and optimize their online presence.&lt;/p&gt;

&lt;p&gt;Ease of Use&lt;br&gt;
Simple setup process&lt;br&gt;
The simple setup process of metricswave.com makes it the perfect Google Analytics alternative. With just a few easy steps, you can start tracking your website's performance and gaining valuable insights. There's no need for complicated configurations or technical expertise. Whether you're a beginner or an experienced user, metricswave.com provides a user-friendly interface that simplifies the setup process. Say goodbye to the hassle of dealing with complex tracking codes and say hello to a seamless and straightforward setup experience with metricswave.com.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intuitive user interface
&lt;/h3&gt;

&lt;p&gt;The intuitive user interface of metricswave.com sets it apart as a top choice for a Google Analytics alternative. With its clean and user-friendly design, navigating through the platform is a breeze. Whether you are a beginner or an experienced user, you will find it easy to understand and use the various features and tools provided. The intuitive layout ensures that you can quickly access the information you need, analyze data efficiently, and make informed decisions to optimize your website performance. Say goodbye to complex and overwhelming interfaces, and say hello to a seamless and enjoyable user experience with metricswave.com.&lt;/p&gt;

&lt;h3&gt;
  
  
  Easy-to-understand reports
&lt;/h3&gt;

&lt;p&gt;MetricsWave.com is the perfect Google Analytics alternative because of its easy-to-understand reports. With MetricsWave, you don't have to be a data expert to make sense of your website's performance. The reports are designed to be intuitive and user-friendly, providing you with clear insights into your website's traffic, conversions, and user behavior. Whether you're a beginner or an experienced marketer, MetricsWave's easy-to-understand reports will help you make data-driven decisions and optimize your website for success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Privacy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Secure data storage
&lt;/h3&gt;

&lt;p&gt;Secure data storage is a critical aspect when choosing a Google Analytics alternative, and metricswave.com excels in this regard. With state-of-the-art security measures and robust data encryption protocols, metricswave.com ensures that your valuable data is stored securely and protected from unauthorized access. &lt;/p&gt;

&lt;p&gt;Whether you are a small business or a large enterprise, you can trust metricswave.com to keep your data safe and confidential. By choosing metricswave.com as your Google Analytics alternative, you can have peace of mind knowing that your data is in good hands.&lt;/p&gt;

&lt;h3&gt;
  
  
  GDPR compliance
&lt;/h3&gt;

&lt;p&gt;GDPR compliance is a top priority for businesses operating in the digital age. With the ever-increasing importance of data privacy and protection, it is crucial for companies to choose a Google Analytics alternative that is fully compliant with the General Data Protection Regulation. &lt;/p&gt;

&lt;p&gt;Metricswave.com is proud to offer a solution that meets all the requirements set forth by GDPR. Our platform ensures that user data is collected and processed in a transparent and secure manner, giving businesses peace of mind knowing that they are in full compliance with the regulations. By choosing metricswave.com as your Google Analytics alternative, you can confidently navigate the complex landscape of data privacy and stay ahead of the curve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data anonymization
&lt;/h3&gt;

&lt;p&gt;Data anonymization is a crucial aspect when it comes to online data privacy and security. At metricswave.com, we prioritize the protection of our users' data by implementing advanced anonymization techniques. &lt;/p&gt;

&lt;p&gt;By anonymizing the data, we ensure that personally identifiable information (PII) is removed or encrypted, making it impossible to trace back to individuals. This not only safeguards the privacy of our users but also helps them comply with data protection regulations. With metricswave.com as your Google Analytics alternative, you can trust that your data is handled with the utmost care and security.&lt;/p&gt;




&lt;p&gt;MetricsWave provides a comprehensive knowledge base and &lt;a href="https://metricswave.com/documentation"&gt;documentation&lt;/a&gt; to help users make the most of their platform. &lt;/p&gt;

&lt;p&gt;Whether you're a beginner or an experienced user, you'll find a wealth of resources to guide you through the setup process, understand key features, and troubleshoot any issues that may arise. &lt;/p&gt;

&lt;p&gt;The knowledge base is regularly updated with new articles and tutorials, ensuring that users have access to the latest information and best practices. &lt;/p&gt;

&lt;p&gt;With MetricsWave's robust documentation, you can confidently navigate the platform and maximize its potential for your business.&lt;/p&gt;

&lt;p&gt;Next Steps Now that you have learned about the numerous advantages of MetricsWave as your Google Analytics alternative, it's time to take the next step towards unlocking the full potential of your website's data. &lt;/p&gt;

&lt;p&gt;Sign up for a free trial today and experience the power of MetricsWave firsthand. With its user-friendly interface, comprehensive analytics, and advanced features, MetricsWave will provide you with the insights you need to make informed decisions and drive your business forward. &lt;/p&gt;

&lt;p&gt;Don't miss out on this opportunity to revolutionize your website analytics. &lt;/p&gt;

&lt;p&gt;Visit &lt;a href="https://metricswave.com"&gt;https://metricswave.com&lt;/a&gt; now and start optimizing your online presence like never before.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I made a Raycast extension to manage all your bank accounts easily</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Thu, 27 Oct 2022 06:32:05 +0000</pubDate>
      <link>https://forem.com/victoor/i-made-a-raycast-extension-to-manage-all-your-bank-accounts-easily-81o</link>
      <guid>https://forem.com/victoor/i-made-a-raycast-extension-to-manage-all-your-bank-accounts-easily-81o</guid>
      <description>&lt;p&gt;If you don't know it, &lt;a href="https://www.raycast.com/"&gt;Raycast&lt;/a&gt; it's a super powerful Spotlight replacement for macOS and, it has a store of free extensions where you can find a lot of user-made plugins to add more options and features to it.&lt;/p&gt;

&lt;p&gt;I love this app, and I'm working on &lt;a href="https://get.monse.app"&gt;Monse&lt;/a&gt;, so I decide to make an extension to &lt;a href="https://get.monse.app/page/raycast"&gt;manage all your bank accounts inside Raycast&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create an extension for Raycast
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LoPKlpVa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/laute18la9p76bgvgf7l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LoPKlpVa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/laute18la9p76bgvgf7l.png" alt="How to create an extension for Raycast" width="880" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Raycast extensions are made with JavaScript and React. If you already know it, it will be effortless for you to create and extension, you just need to know a few things about the Raycast API and available options.&lt;/p&gt;

&lt;p&gt;The simpler way to start a new extension is using Raycast and running the "Create Extension" command. This command will ask you some questions about your extension and create a bootstrap folder. You can even choose between a long list of templates to make it even easier.&lt;/p&gt;

&lt;p&gt;After this, you just need to go to your extension folder and run &lt;code&gt;npm install &amp;amp;&amp;amp; npm run dev&lt;/code&gt;. Now you can open Raycast and you will see your extension at the root search.&lt;/p&gt;

&lt;p&gt;Now it's your time to build your extension using the &lt;a href="https://developers.raycast.com/"&gt;Raycast API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--teXgAu_A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ww7ohgu8vyj51svqzix3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--teXgAu_A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ww7ohgu8vyj51svqzix3.png" alt="Monse extension for Raycast" width="880" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now, this &lt;a href="https://github.com/get-monse/raycast-extension"&gt;Monse extension&lt;/a&gt; it's a simple command where you can see all your expenses and incomes from all your accounts. You can categorize and add notes to them easily without using your mouse.&lt;/p&gt;

&lt;p&gt;It's super simple and convenient to, with just two keystrokes, know the current state and latest transactions of all your bank accounts.&lt;/p&gt;

</description>
      <category>react</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A good alternative to stop using Google Analytics</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Tue, 28 Jun 2022 07:57:13 +0000</pubDate>
      <link>https://forem.com/victoor/a-good-alternative-to-stop-using-google-analytics-3adf</link>
      <guid>https://forem.com/victoor/a-good-alternative-to-stop-using-google-analytics-3adf</guid>
      <description>&lt;p&gt;When I shared my &lt;a href="https://dev.to/victoor/my-solo-developer-stack-to-make-a-saas-5ea3"&gt;solo developer stack to build a SaaS&lt;/a&gt; some people have complained about Google Analytics due to privacy issues, and they are right.&lt;/p&gt;

&lt;p&gt;I want to replace it and stop using it but, &lt;strong&gt;do you know any good free alternative?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>solomaker</category>
    </item>
    <item>
      <title>Large and scalable Laravel application with Domains</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Fri, 29 Apr 2022 12:19:49 +0000</pubDate>
      <link>https://forem.com/victoor/large-and-scalable-laravel-application-with-domains-man</link>
      <guid>https://forem.com/victoor/large-and-scalable-laravel-application-with-domains-man</guid>
      <description>&lt;p&gt;A few months ago, we talk about the &lt;a href="https://dev.to/victoor/repository-pattern-in-laravel-it-s-worth-3mn4"&gt;repository pattern in Laravel&lt;/a&gt; and the reason I don't like it. &lt;/p&gt;

&lt;p&gt;In this post, we are going to talk about how to structure our project if we are working on a large Laravel application.&lt;/p&gt;

&lt;p&gt;I found that the default Laravel structure doesn't work with large projects while I was working in my side project, &lt;a href="https://get.monse.app"&gt;monse&lt;/a&gt;. With every commit I made, I felt that the project it's getting overwhelming, because it was impossible to see all the code related to a desire model at a glance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🎉  By the way, &lt;strong&gt;monse is a simple and automated personal finances&lt;br&gt;
for normal people&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to stop over-expending, retire early and happier, &lt;br&gt;
&lt;a href="https://get.monse.app"&gt;take a look now&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Table of content
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;The problem with the default folder structure&lt;/li&gt;
&lt;li&gt;The solution&lt;/li&gt;
&lt;li&gt;
How to implement this in Laravel

&lt;ol&gt;
&lt;li&gt;Routes&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Commands&lt;/li&gt;
&lt;li&gt;Factories&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The problem with the default folder structure
&lt;/h3&gt;

&lt;p&gt;By default, a Laravel application structure is something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── app
│   ├── Console
│   │   └── Commands
│   ├── Contracts
│   ├── Events
│   ├── Exceptions
│   │   └── Auth
│   ├── Http
│   │   ├── Controllers
│   │   ├── Middleware
│   │   ├── Requests
│   │   └── Resources
│   ├── Jobs
│   ├── Listeners
│   ├── Mail
│   │   ├── Auth
│   │   └── User
│   ├── Models
│   ├── Notifications
│   ├── Policies
│   └── Providers
├── database
│    ├── factories
│    ├── migrations
│    └── seeders
├── config
├── routes
└── resources
    ├── js
    ├── sass
    └── views
        ├── mail
        └── vendor

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

&lt;/div&gt;



&lt;p&gt;There is nothing wrong  with this structure, but when we are working on a big application it's difficult to check, at a glance, all the models, controllers, and services involved in one request, for example.&lt;/p&gt;

&lt;p&gt;Imagine that you have a model called &lt;code&gt;Article&lt;/code&gt; with a &lt;code&gt;PostArticleController&lt;/code&gt;, a &lt;code&gt;GetArticleController&lt;/code&gt; and also some events like &lt;code&gt;ArticleCreated&lt;/code&gt;, &lt;code&gt;ArticleUpdated&lt;/code&gt; and more.  &lt;/p&gt;

&lt;p&gt;You can create a subfolder inside any of this already created folders called Article to split different parts of your application, and you will have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── app
│   ├── Console
│   │   └── Commands
│   ├── Contracts
│   ├── Events
│   │   └── Article 
│   │       ├── ArticleCreated.php 
│   │       ├── ArticleUpdated.php 
│   │       └── ArticleDeleted.php 
│   ├── Exceptions
│   │   ├── Auth
│   │   └── Article 
│   │       └── ArticleWithoutValidDate.php
│   ├── Http
│   │   ├── Controllers
│   │   │   └── Article 
│   │   │       ├── PostArticleController.php 
│   │   │       └── GetArticleController.php 
│   │   ├── Middleware
│   │   ├── Requests
│   │   │   └── Article 
│   │   │       ├── PostArticleRequest.php 
│   │   │       └── GetArticleRequest.php 
│   │   └── Resources
│   │   │   └── Article 
│   │   │       └── ArticleResource.php 
│   ├── Jobs
│   ├── Listeners
│   │   └── Article 
│   │       ├── SendNotificationOnArticleCreated.php 
│   │       └── UpdateDashboardStatsOnArticleDeleted.php 
│   ├── Mail
│   │   ├── Auth
│   │   └── User
│   ├── Models
│   │   └── Article.php 
│   ├── Notifications
│   │   └── Article 
│   │       └── NewArticleNotification.php 
│   ├── Policies
│   └── Providers
├── database
│    ├── factories
│    ├── migrations
│    └── seeders
├── config
├── routes
└── resources
    ├── js
    ├── sass
    └── views
        ├── mail
        └── vendor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the folders are growing a lot, and we still have all our Article code spreader between all the application.&lt;/p&gt;

&lt;p&gt;It's difficult to see, at a glance, all the code related with our domain model Article.&lt;/p&gt;

&lt;p&gt;And this is only the beginning, in a big application we are going to have like 10 or more models with his controllers, events, listeners, and more. This is going to be a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;The idea it's to make domain folders or bounded contexts to store all the code related to one model of our application in one folder only.&lt;/p&gt;

&lt;p&gt;The idea it's to achieve a folder structure like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src
├── BankAccount
│   ├── Actions
│   ├── Http
│   ├── Infrastructure
│   ├── Policies
│   └── BankAccount.php
├── BankConnection
│   ├── Actions
│   ├── Console
│   ├── Events
│   ├── Http
│   ├── Infrastructure
│   ├── Jobs
│   ├── Listeners
│   ├── Mail
│   ├── Notifications
│   ├── Policies
│   └── BankConnection.php
├── StockOrder
│   ├── Actions
│   ├── Http
│   ├── Infrastructure
│   ├── Listeners
│   ├── Policies
│   ├── Support
│   └── StockOrder.php
└── UserStockPortfolio
    ├── Actions
    ├── Console
    ├── Http
    ├── Infrastructure
    ├── Jobs
    └── UserStockPortfolio.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This is the current folder structure of my Laravel project,  &lt;a href="https://get.monse.app"&gt;get.monse.app&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, inside each folder we have the model and different classes related to it. We can see all the actions, HTTP controllers, jobs, listeners, policies, and more.&lt;/p&gt;

&lt;p&gt;This way, when I'm working on &lt;code&gt;StockOrders&lt;/code&gt;, for example, I can see all the code related, and it's easier to add new controllers, routes, and more without affecting all the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement this in Laravel
&lt;/h2&gt;

&lt;p&gt;Implementing this in Laravel it's simple.&lt;/p&gt;

&lt;p&gt;First, you need to create a new &lt;code&gt;src&lt;/code&gt; folder and manually add it to the composer file. I define the namespace as &lt;code&gt;Monse\\&lt;/code&gt;, because it's my project name, but you can use anything else.&lt;br&gt;
&lt;/p&gt;

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

    "psr-4": {
      "App\\": "app/",
      "Monse\\": "src/",
      "Database\\Factories\\": "database/factories/",
      "Database\\Seeders\\": "database/seeders/"
    },

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

&lt;/div&gt;



&lt;p&gt;Now we can add whatever we want to this folder and will be automatically load by composer, but there are some things that we need to take care.&lt;/p&gt;

&lt;p&gt;We want each module to have his own routes, events, commands and all. To do this, we need to create different service providers and add them to our &lt;code&gt;config/app.php&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Routes
&lt;/h3&gt;

&lt;p&gt;For routes we are going to create a new service provider extending from &lt;code&gt;Illuminate\Foundation\Support\Providers\RouteServiceProvider&lt;/code&gt;. In this file we just need to implement the boot method 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="c1"&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;boot&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="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'auth:api'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;GetUserController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="c1"&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="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Events
&lt;/h3&gt;

&lt;p&gt;For events, we can extend from &lt;code&gt;Illuminate\Foundation\Support\Providers\EventServiceProvider&lt;/code&gt; and define the &lt;code&gt;$listen&lt;/code&gt; array. Something 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="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$listen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;UserCreated&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nc"&gt;SendWelcomeMailOnUserCreated&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Commands
&lt;/h3&gt;

&lt;p&gt;For commands, we will create a normal service provider and register them using the &lt;code&gt;register&lt;/code&gt; method:&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="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$commands&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;CreateUserCommand&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;register&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="nf"&gt;commands&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;commands&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Factories
&lt;/h3&gt;

&lt;p&gt;These are a bit tricky, but it's easy.&lt;/p&gt;

&lt;p&gt;We need to put the factory UserFactory, for example, inside the &lt;code&gt;factories/Monse/User&lt;/code&gt; folder (because we define namespace of our folder as Monse in the first step).&lt;/p&gt;

&lt;p&gt;Also, we need to define, inside the factory the model that is owning that factory:&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;modelName&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;Everything else will be working as expected without anything special to do.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What do you think? Do you like this project structure?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>programming</category>
      <category>ddd</category>
      <category>discuss</category>
    </item>
    <item>
      <title>My solo developer stack to make a SaaS</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Wed, 27 Apr 2022 11:39:01 +0000</pubDate>
      <link>https://forem.com/victoor/my-solo-developer-stack-to-make-a-saas-5ea3</link>
      <guid>https://forem.com/victoor/my-solo-developer-stack-to-make-a-saas-5ea3</guid>
      <description>&lt;p&gt;Six month ago, I started working on &lt;a href="https://get.monse.app"&gt;monse.app&lt;/a&gt;, a simple and automated personal finances for normal people.&lt;/p&gt;

&lt;p&gt;I'm a solo maker and I want to build this SaaS faster but also, making a good product that I can scale and work on in the future.&lt;/p&gt;

&lt;p&gt;With that in mind, &lt;a href="https://get.monse.app/page/stack"&gt;this is the stack that I choose&lt;/a&gt;, what do you think?&lt;/p&gt;

</description>
      <category>saas</category>
      <category>maker</category>
      <category>solo</category>
    </item>
    <item>
      <title>How I went from living from day to day to saving and investing my money</title>
      <dc:creator>Víctor Falcón</dc:creator>
      <pubDate>Sun, 20 Mar 2022 16:35:49 +0000</pubDate>
      <link>https://forem.com/victoor/how-i-went-from-living-from-day-to-day-to-saving-and-investing-my-money-3622</link>
      <guid>https://forem.com/victoor/how-i-went-from-living-from-day-to-day-to-saving-and-investing-my-money-3622</guid>
      <description>&lt;p&gt;Three years ago, I started to worry about my money.&lt;/p&gt;

&lt;p&gt;😞 I used to live day to day, I had no savings, I didn't invest.&lt;/p&gt;

&lt;p&gt;✌️ Now I can go 4-5 months without income and nothing would happen.&lt;/p&gt;

&lt;p&gt;I'll tell you how I made the change 👇.&lt;/p&gt;

&lt;p&gt;The first thing I did was to SEE how I spend my money.&lt;/p&gt;

&lt;p&gt;At first, I did it with a crappy excel and entering my two bank accounts in a very manual way and wasting a lot of time.&lt;/p&gt;

&lt;p&gt;Now I do it with &lt;a href="//monse.app"&gt;monse.app&lt;/a&gt;, and I will tell you how.&lt;/p&gt;

&lt;p&gt;After creating the account, the first thing I do is to connect my two banks.&lt;/p&gt;

&lt;p&gt;Automatically, I start to see the transactions on the web and start assigning categories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fa38fvlL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/otlwrly3yph9th03v7bw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fa38fvlL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/otlwrly3yph9th03v7bw.png" alt="Categorize each expense and income" width="880" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, it can be a bit tedious, there are a lot of transactions, but monse learns to assign categories automatically, and then you will only have to do it manually once in a while.&lt;/p&gt;

&lt;p&gt;We do this to get important data about our spending.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤑 How do you spend your money?
&lt;/h2&gt;

&lt;p&gt;There are three fundamental charts that monse gives me.&lt;/p&gt;

&lt;p&gt;1️⃣ Month to month evolution: my wealth, month to month, is increasing or not. Am I closer or further away from FI?&lt;/p&gt;

&lt;p&gt;2️⃣ How much money do I earn, and how much do I spend each month?&lt;/p&gt;

&lt;p&gt;3️⃣ How do I spend money?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZK9DRYbY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pm3qt8nbfky5948cpdj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZK9DRYbY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pm3qt8nbfky5948cpdj0.png" alt="See how do you spend your money" width="880" height="546"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now that we know how we spend our money and how much, let's get down to the basics: paying you first.&lt;/p&gt;

&lt;p&gt;When my paycheck comes in, I have 3 automatic transfers:&lt;/p&gt;

&lt;p&gt;➡️ a savings account.&lt;/p&gt;

&lt;p&gt;➡️ another to an investment fund (in my case, &lt;a href="https://indexacapital.com/t/QUFQZ8"&gt;Indexa Capital&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;➡️ and one to a daily expense account (debit card).&lt;/p&gt;

&lt;p&gt;It is crucial that they are automatic, if you have to do them manually you won't do them.&lt;/p&gt;

&lt;p&gt;They should also be immediately upon receipt of your salary. It is money that you should not count on for other expenses.&lt;/p&gt;

&lt;p&gt;The amount is up to you. How much you can save.&lt;/p&gt;

&lt;p&gt;In my case, I also allocate some of my money to cryptocurrencies, but I'll leave that for later.&lt;/p&gt;

</description>
      <category>motivation</category>
    </item>
  </channel>
</rss>
