<?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: Victor Dorneanu</title>
    <description>The latest articles on DEV Community by Victor Dorneanu (@dorneanu).</description>
    <link>https://dev.to/dorneanu</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%2F284490%2F16b239b7-55d8-4ac8-839d-6afcb2bc3b82.jpeg</url>
      <title>DEV Community: Victor Dorneanu</title>
      <link>https://dev.to/dorneanu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dorneanu"/>
    <language>en</language>
    <item>
      <title>My 2025 review</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Mon, 05 Jan 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/dorneanu/my-2025-review-4hj7</link>
      <guid>https://dev.to/dorneanu/my-2025-review-4hj7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Although it has been a while since my last post here, I don't want to break with the &lt;strong&gt;tradition&lt;/strong&gt; of doing my annual &lt;a href="https://blog.dornea.nu/tags/review/" rel="noopener noreferrer"&gt;review&lt;/a&gt; (make sure to check out the previous years: &lt;a href="https://blog.dornea.nu/2021/12/13/my-2021-review/" rel="noopener noreferrer"&gt;2021&lt;/a&gt;, &lt;a href="https://blog.dornea.nu/2024/01/02/my-2023-review/" rel="noopener noreferrer"&gt;2023&lt;/a&gt;, &lt;a href="https://blog.dornea.nu/2024/12/19/my-2024-review/" rel="noopener noreferrer"&gt;2024&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Coming back to writing again feels like something I should have done months ago, but hey, it's never too late. I used to have this habit of writing, especially in the morning, but this year most of the time I didn't really feel like I wanted to write. I was also increasingly engaged in other hobbies (such as music making - more on that later), so I kind of forgot the positive effects of reflecting on my own thoughts and putting them into words.&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%2Fmekh4yvyjrh4oa5pxze4.jpg" 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%2Fmekh4yvyjrh4oa5pxze4.jpg" alt="2025 Review workspace" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;My workspace while writing the 2025 review: laptop with org-mode and the blog post, bongos from my music journey, cycling helmet representing my new commuting habits, productivity books including 'Slow Productivity', and handwritten planning notebooks - a visual summary of the year's key themes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I sit down here (again in the morning), it feels very hard to remember all the things that happened this year. Whenever this happens, I sometimes wonder if all the AI/GenAI usage has already impacted my brain, making me less capable of remembering things 🫠.&lt;/p&gt;

&lt;p&gt;Professionally, I was constantly switching between &lt;strong&gt;Golang&lt;/strong&gt; (mainly working on &lt;a href="https://github.com/cloudoperators/heureka" rel="noopener noreferrer"&gt;Heureka&lt;/a&gt;) and &lt;strong&gt;Python&lt;/strong&gt; (mostly dealing with &lt;a href="https://docs.openstack.org/barbican/latest/" rel="noopener noreferrer"&gt;OpenStack Barbican&lt;/a&gt;). Beyond that, I had the chance to not only work in a &lt;strong&gt;Kubernetes&lt;/strong&gt; environment but also deploy things on my own, debug, fix issues, and deepen my Kubernetes skills. At some point, I wanted to pursue the &lt;a href="https://training.linuxfoundation.org/certification/certified-kubernetes-security-specialist/" rel="noopener noreferrer"&gt;CKS (Certified Kubernetes Security Specialist)&lt;/a&gt; certification, but due to lack of time, I didn't manage to do so.&lt;/p&gt;

&lt;p&gt;Apart from work I'm pretty grateful for all the things I managed to experience and all the new people I've met. Since January, I'm playing the &lt;strong&gt;Bongos&lt;/strong&gt; regularly together with &lt;a href="https://www.instagram.com/barrio.latino.band" rel="noopener noreferrer"&gt;Barrio Latino&lt;/a&gt; playing Salsa, Cumbia, and Bolero. Not only this: I also managed to get more serious about &lt;strong&gt;House&lt;/strong&gt; music production after purchasing my first groovebox. I also have to think of the great time my family and I had in Peloponnese, Greece. I enjoyed the food, the olive oil, the people and of course the ☀️.&lt;/p&gt;

&lt;p&gt;Now let's first start with the goals I had for this year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals for 2025
&lt;/h2&gt;

&lt;p&gt;Looking back at the goals I set for myself in &lt;a href="https://blog.dornea.nu/2024/12/19/my-2024-review/#goals-for-2025" rel="noopener noreferrer"&gt;2024&lt;/a&gt;, it's time to reflect a little bit on these:&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Goals for 2025
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes exploration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;K8s remains a knowledge gap I'm more than determined to address. I'll again follow a "slow productivity" approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with small-scale experiments using &lt;a href="https://k3s.io/" rel="noopener noreferrer"&gt;k3s&lt;/a&gt;/&lt;a href="https://k3d.io/stable/" rel="noopener noreferrer"&gt;k3d&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Work towards deploying my own little cluster, either on a VPS or locally&lt;/li&gt;
&lt;li&gt;Build practical experience through hands-on projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I still need to finish &lt;a href="https://www.goodreads.com/book/show/34013922-kubernetes-in-action" rel="noopener noreferrer"&gt;Kubernetes in Action&lt;/a&gt; which is really a great book if you want to learn about Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Golang deep dive&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With my recent transition towards more &lt;em&gt;Software Engineering&lt;/em&gt;-focused tasks, I'm planning to strengthen my &lt;strong&gt;Golang&lt;/strong&gt; expertise. There are 2 specific areas I'd like to know more about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Generics&lt;/em&gt;: This remains somewhat of a black box that I need to illuminate more&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Concurrency&lt;/em&gt;: Beyond basic understanding, I want to explore and implement common patterns that can be applied across different problems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security tooling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The GitHub repository security checker is still on my radar. With the rise of LLMs, I believe much of the &lt;em&gt;foundational work&lt;/em&gt; (authentication, API interactions) can be implemented easily. The key focus will be on defining comprehensive &lt;em&gt;security and compliance checks&lt;/em&gt; that provide real value to the users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Music&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My percussion journey continues with a focus on &lt;em&gt;Congas&lt;/em&gt;. I've already invested in some "Compact Congas" (Giovanni Hidalgo model) that fit perfectly in my space. I believe Congas offer more "flexibility" than Bongos for song accompaniment (and solos!), and I'm particularly excited to explore &lt;em&gt;Salsa&lt;/em&gt; music, though I'm keeping my options open for other styles.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;acoustic guitar&lt;/em&gt; hasn't been forgotten - I still pick it up regularly. However, I'm considering taking formal lessons to improve, especially in finger-style playing. But who knows if I'll ever get the chance to do this at all 🤷&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflection on 2025 Goals
&lt;/h3&gt;

&lt;p&gt;To be honest, I must admit that I really made impressive progress only in the &lt;strong&gt;music&lt;/strong&gt; area. But let's start with the technical topics first.&lt;/p&gt;

&lt;h4&gt;
  
  
  Kubernetes
&lt;/h4&gt;

&lt;p&gt;Nowadays, &lt;strong&gt;Kubernetes&lt;/strong&gt; has become the leading orchestration platform. While at &lt;a href="https://blog.dornea.nu/2024/07/11/bye-bye-cashlink/" rel="noopener noreferrer"&gt;Cashlink&lt;/a&gt; I used to set up a completely new environment (using EKS) from scratch (which was rather a simple configuration), at SAP I already found complex clusters that required me to learn new things. I learned a lot by just having a service/application (&lt;a href="https://github.com/cloudoperators/heureka" rel="noopener noreferrer"&gt;Heureka&lt;/a&gt;) and being forced to take care of the full deployment. I definitely learned a lot about Helm charts, and I definitely made my mistakes along the way. Along this journey, I also discovered &lt;a href="https://github.com/abrochard/kubel" rel="noopener noreferrer"&gt;kubel&lt;/a&gt;, which became my main tool for interacting with the various clusters (from Emacs of course). I'm still lacking knowledge in some more advanced topics, which is why I initially planned to at least pursue the CKS. Due to time constraints, I didn't have the time or mental capacity to address this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Golang
&lt;/h4&gt;

&lt;p&gt;I came to SAP partly because I wanted to dive deeper into &lt;strong&gt;Golang&lt;/strong&gt;. Last year (at least for the second half) I went into gopher-mode for quite a long time. During that time, I realized I lacked deep knowledge in &lt;strong&gt;Generics&lt;/strong&gt; and &lt;strong&gt;concurrency&lt;/strong&gt;. Looking back at this year, I think I've learned a lot more about concurrency than Generics. I even started to document some &lt;a href="https://defersec.com/go/concurrency/" rel="noopener noreferrer"&gt;best practices&lt;/a&gt; but at some point I gave it up (mostly because these days, with the use of LLMs, you already have access to lots of information - what's the point of having these kinds of resources available on personal blogs/sites?).&lt;/p&gt;

&lt;p&gt;What made this year particularly interesting was getting to architect and develop a completely new service in the area of &lt;strong&gt;HSM&lt;/strong&gt; (Hardware Security Module) devices. This was fascinating territory - dealing with cryptographic hardware, &lt;strong&gt;PKCS#11&lt;/strong&gt; interfaces, and the inherent complexities of multi-tenancy in security-critical environments. The challenge wasn't just about understanding the &lt;a href="https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/csd01/pkcs11-spec-v3.1-csd01.html" rel="noopener noreferrer"&gt;PKCS#11 standard&lt;/a&gt;, but making the whole system work reliably under concurrent load while maintaining strict security boundaries between tenants.&lt;/p&gt;

&lt;h4&gt;
  
  
  Python &amp;amp; OpenStack
&lt;/h4&gt;

&lt;p&gt;On the Python side, I spent considerable time extending OpenStack Barbican's crypto plugin ecosystem, specifically developing a new plugin that further expands the available PKCS#11 capabilities. It's one thing to read about cryptographic standards, but implementing them in production-grade software really forces you to understand the nuances. You can check out my &lt;a href="https://github.com/sapcc/barbican/pulls?q=is%3Apr+author%3Adorneanu+" rel="noopener noreferrer"&gt;contributions to the SAP Barbican fork&lt;/a&gt; if you're curious about the technical details.&lt;/p&gt;

&lt;p&gt;What struck me most this year was how Python and Go serve such different purposes in our infrastructure. While Go excels at building robust, concurrent services that need to handle high loads and complex orchestration, Python shines in the OpenStack ecosystem where flexibility and rapid iteration matter more than raw performance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Security Tooling
&lt;/h4&gt;

&lt;p&gt;Back in 2024, I mentioned wanting to build a GitHub repository security checker - a tool that would audit repositories for security and compliance issues. This year, I finally started working on this idea, which evolved into &lt;strong&gt;Reposhield&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I kicked off the project in April, and true to my "slow productivity" approach, I spent considerable time on the architectural foundation rather than rushing into feature implementation. The project follows &lt;strong&gt;Hexagonal Architecture&lt;/strong&gt; principles with a clean separation of concerns.&lt;/p&gt;

&lt;p&gt;The current state is what I'd call &lt;em&gt;"architecturally complete but functionally incomplete."&lt;/em&gt; I've established:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Core domain models (Finding, ScanResult, Severity levels)&lt;/li&gt;
&lt;li&gt;A well-defined &lt;code&gt;Scanner&lt;/code&gt; interface for extensibility&lt;/li&gt;
&lt;li&gt;GitHub API abstraction layer with proper rate limiting&lt;/li&gt;
&lt;li&gt;Configuration management through environment variables&lt;/li&gt;
&lt;li&gt;Mock implementations for testing (using &lt;a href="https://github.com/vektra/mockery" rel="noopener noreferrer"&gt;mockery&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;GitHub Action integration structure&lt;/li&gt;
&lt;li&gt;Documentation outlining the complete architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's missing? The actual scanner implementations 🙈. I've designed the system to support multiple scanners (branch protection, secret detection, MFA enforcement, workflow security, etc.), but I haven't implemented them yet.&lt;/p&gt;

&lt;h4&gt;
  
  
  Music
&lt;/h4&gt;

&lt;p&gt;Last year I was very excited about buying my new pair of &lt;strong&gt;Congas&lt;/strong&gt;. Although I was practicing a lot, I soon realized it's not that much fun to play alone (same applies, I guess, for every instrument). Music is meant to bind people, to create some sort of community, to transfer a message. That's why soon (I guess it was January or so) I started looking for bands/musicians on &lt;a href="https://www.berlinmusiker.de/start.html" rel="noopener noreferrer"&gt;berlinmusiker.de&lt;/a&gt;, especially in the area of &lt;strong&gt;Latin music&lt;/strong&gt; (I was mostly interested in &lt;strong&gt;Salsa&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;I was indeed very excited and soon I found myself rehearsing with the rest of the band. Although I thought they were looking for some conguero, I then ended up playing again the &lt;strong&gt;bongos&lt;/strong&gt;. This was/is not per se bad as I re-discovered this instrument and found out new ways to play it. In retrospect, however, I wish I would have played more congas! I haven't used the pair of congas I bought for a while, mostly because I don't have time to &lt;em&gt;practice bongos AND congas&lt;/em&gt;. And if that wasn't enough: Also this year I've found myself making more and more electronic music using my &lt;a href="https://www.roland.com/de/products/mc-101/" rel="noopener noreferrer"&gt;MC-101&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think I'm pretty grateful for finding these lovely people and playing together with them. Meanwhile the overall band size grew to 10-13 people and we already had several concerts this year. Make sure to check out &lt;a href="https://www.instagram.com/barrio.latino.band" rel="noopener noreferrer"&gt;Barrio Latino Band on Instagram&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Looking back at this musical journey, I feel incredibly grateful for being able to play in a band and managing to have concerts with a full ensemble after just a few months of rehearsing together. The experience taught me so much about music arrangement - how different instruments need to complement each other, when to step back and let others shine, and when to drive the rhythm forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Productivity
&lt;/h2&gt;

&lt;p&gt;Compared to my last year's statement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;After years of experimenting with various productivity systems, 2024 was the year where things finally clicked into place. Countless hours of listening to &lt;a href="https://calnewport.com/podcasts/" rel="noopener noreferrer"&gt;Cal Newport's podcast&lt;/a&gt; on &lt;a href="https://www.goodreads.com/book/show/197773418-slow-productivity" rel="noopener noreferrer"&gt;slow productivity&lt;/a&gt; helped me internalize key concepts like &lt;strong&gt;multi-scale planning&lt;/strong&gt;, &lt;strong&gt;time blocking&lt;/strong&gt;, and &lt;strong&gt;deep work&lt;/strong&gt;. This evolution in my approach has fundamentally changed how I structure my days and manage my projects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;... this year I have no revelation to write about. I guess I've incorporated those practices well while keeping the balance between digital and analogue tools. I'm still using paper to actually plan my day:&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%2Fdfubqglkybpdsrlwbhr1.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%2Fdfubqglkybpdsrlwbhr1.jpeg" alt="Daily planning" width="800" height="1066"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Daily planning with time-blocking: Visual representation of scheduled time slots (boxed blocks) for deep work, rest, physical activity, and creative pursuits.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was, of course, tempted to add some AI sauce everywhere in order to &lt;em&gt;optimize all the things&lt;/em&gt;™️, but I'm glad I haven't done so. I'm still using ORG mode files to structure projects and keep track of notes, tasks, meeting notes, etc. I use my (analogue, paper-based) notebook to plan my day and capture spontaneous ideas and meeting notes.&lt;/p&gt;

&lt;p&gt;One thing I stopped doing was meticulously tracking my time in ORG agenda. I found myself feeling blocked every time I wanted to keep track of my activities since it implied creating a new task, refiling it to the right ORG subtree, clocking in, etc. I'm also not keeping track of project tasks in ORG mode anymore, as I'm currently working on three projects max. Most of the time, I use GitHub issues for this purpose.&lt;/p&gt;

&lt;p&gt;Overall, I think the year started with good intentions: I've done my &lt;strong&gt;multi-scale planning&lt;/strong&gt;, I've had my quarters filled in with goals, and of course I'd written down my year's goals. However, I feel I neglected focusing on just a few projects at a time (and also finishing them). Instead, I was more in an &lt;em&gt;on-demand&lt;/em&gt; mode where I couldn't have a clear picture of what I was heading toward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Habits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reading
&lt;/h3&gt;

&lt;p&gt;In terms of tooling, not much has changed since last year. I'm still using Goodreads as a source for book inspiration, and my Pocketbook Inkpad 3 still serves me best. Here is my reading list for 2025:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jäger, Hirten, Kritiker&lt;/li&gt;
&lt;li&gt;Tyranny of the Minority&lt;/li&gt;
&lt;li&gt;Brave New World&lt;/li&gt;
&lt;li&gt;Slow Productivity&lt;/li&gt;
&lt;li&gt;Baustellen der Nation&lt;/li&gt;
&lt;li&gt;Kleine Freiheit Garten&lt;/li&gt;
&lt;li&gt;Brief Answers to the Big Questions&lt;/li&gt;
&lt;li&gt;Nexus&lt;/li&gt;
&lt;li&gt;Becoming Supernatural&lt;/li&gt;
&lt;li&gt;The Anxious Generation&lt;/li&gt;
&lt;li&gt;The Righteous Mind&lt;/li&gt;
&lt;li&gt;The Stoic Mindset: Living the Ten Principles of Stoicism&lt;/li&gt;
&lt;li&gt;The Little Book of Stoicism&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I feel that for this year I've slightly neglected reading and started doing something else as my default activity for the evenings. Whereas the previous years I was trying to read &lt;strong&gt;daily&lt;/strong&gt; now I tend to make music rather than reading something. I think this is OK and I'm also trying to tell myself it's OK for not reading for whole weeks.&lt;/p&gt;

&lt;p&gt;Despite feeling "distracted" by music making, looking at my reading list above, I realize I still managed to read quite a lot this year! Thirteen books covering such diverse topics - from stoicism and philosophy to politics, science, and productivity. I hope to keep this pace and continue deep-diving into new topics that challenge my thinking and expand my worldview.&lt;/p&gt;

&lt;p&gt;💡 I've already shared detailed thoughts on some of these books in my quarterly book summary post: &lt;a href="https://blog.dornea.nu/2025/01/16/book-summaries-october-december-2024/" rel="noopener noreferrer"&gt;October-December 2024&lt;/a&gt;. More book summaries for 2025 will follow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sports
&lt;/h3&gt;

&lt;p&gt;I've started the year with the initial goal of doing sports at least &lt;em&gt;twice a week&lt;/em&gt;. For me, &lt;strong&gt;cycling/commuting&lt;/strong&gt; to work doesn't necessarily count as a sports activity, although it surely has its benefits. I guess for most of the time I didn't have the right discipline (when should I train? during lunch break? on which days?) and &lt;em&gt;routine&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Overall I'm happy I'm back on track, and I can definitely feel the changes already (I can do more pull-ups, my spine has become more straight, I feel more energized). Most importantly, I'm proud that I finally managed to incorporate sports into my day-to-day life and make it an essential part of my routine.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cycling
&lt;/h4&gt;

&lt;p&gt;Since I got a new bike this year, I was more than motivated to cycle not only from home to the office but also to use it for general commuting instead of public transportation. This shift made cycling a natural part of my daily routine rather than just a form of exercise. The convenience and enjoyment of having a reliable bike transformed how I move around the city.&lt;/p&gt;

&lt;h4&gt;
  
  
  Strength Training
&lt;/h4&gt;

&lt;p&gt;For &lt;strong&gt;strength training&lt;/strong&gt; specifically, I aimed to train twice a week with sessions adapted to my location: quick 20-minute workouts when training in the office versus more comprehensive 40-minute sessions when I had access to a proper gym. Looking at my actual Garmin data, this flexible approach helped me maintain consistency throughout the year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Meditation
&lt;/h3&gt;

&lt;p&gt;At the end of last year, I purchased a one-year subscription to the &lt;a href="https://www.wakingup.com/" rel="noopener noreferrer"&gt;Waking Up App&lt;/a&gt;, which was not quite cheap (around $100 for a year). I thought that paying that much money would definitely keep me motivated to meditate regularly. Small spoiler: It actually did, and I really liked the sessions, which all had a different focus.&lt;/p&gt;

&lt;p&gt;I also came across this &lt;a href="https://dynamic.wakingup.com/pack/PK7REQC" rel="noopener noreferrer"&gt;stoic meditation&lt;/a&gt; pack from William B. Irvine, which sparked my interest in more stoic literature. I think this is also the reason I've read so many books on stoicism this year.&lt;/p&gt;

&lt;p&gt;As an "alternative" to meditation, I've started doing regular breathing exercises again (something I'd also completely neglected for a long time). While practicing again, I came across the &lt;a href="https://www.youtube.com/c/breathewithsandy" rel="noopener noreferrer"&gt;Breathe with Sandy sessions&lt;/a&gt;, which turned out to be the most enjoyable and diverse breathing exercises I've ever experienced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software I Use
&lt;/h2&gt;

&lt;p&gt;I'd like to continue with the same scheme I've started last year and describe the tools/services I use on a day-to-day basis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Daily drivers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude&lt;/strong&gt; (Code / Desktop)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, I need to be honest on this: I cannot imagine professional (but also private) life without Claude. It's literally everywhere serving me as a digital assistant. Whether I need to understand a huge code base, analyze multiple PDFs, do a quick web search, write unit tests....Claude has you covered. Ever since I started using &lt;a href="https://github.com/anthropics/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt;, I feel that the whole tooling and workflow has become even more integrated into my personal workflow.&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%2F839o9n7d3ww82y2kzk2b.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%2F839o9n7d3ww82y2kzk2b.png" alt="Claude Code MCP Screenshot Server" width="800" height="624"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Claude Code's MCP screenshot server enables seamless visual debugging workflows for Hugo blog development&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnppk3s2wyasjxcrs3qb9.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%2Fnppk3s2wyasjxcrs3qb9.png" alt="Claude Code Visual Problem Solving" width="800" height="467"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Simply paste a screenshot showing a CSS layout issue, and Claude Code instantly analyzes the problem, understands the context, and provides comprehensive solutions&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Emacs&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No surprises here. It still does its job at almost every task and is the perfect companion to Claude. At some point this year, I again refactored my whole &lt;a href="https://github.com/dorneanu/dotemacs" rel="noopener noreferrer"&gt;dotemacs&lt;/a&gt; to use &lt;a href="https://github.com/jamescherti/minimal-emacs.d" rel="noopener noreferrer"&gt;https://github.com/jamescherti/minimal-emacs.d&lt;/a&gt; as a basis.&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%2Fi8wlqc7kfot3d83x10qm.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%2Fi8wlqc7kfot3d83x10qm.png" alt="Claude Code Emacs Integration" width="800" height="157"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The claude-code.el package brings Claude's capabilities directly into Emacs&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Services
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more than a year, I've been using Claude Pro (whereas sometimes I'm hitting the limit multiple times a day 🙈). I didn't purchase Max 'cause I still think that's a lot of money for a service. Overall, I'm still very satisfied (with both: Claude Desktop and Claude Code, which obviously serve different purposes).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.overdrive.com/" rel="noopener noreferrer"&gt;Overdrive&lt;/a&gt; / &lt;a href="https://libbyapp.com/" rel="noopener noreferrer"&gt;Libbyapp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I still have my account and use it quite regularly.&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%2Facrh27zx3wj2zpmv7kuk.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%2Facrh27zx3wj2zpmv7kuk.png" alt="Libby - Best Books 2024" width="800" height="443"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Libby's curated collection 'Die besten Bücher 2024' showcasing top German books available for digital borrowing&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Goodreads&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out my &lt;a href="https://www.goodreads.com/user/show/121423977-victor-dorneanu" rel="noopener noreferrer"&gt;profile&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fne9649ekst37nc18gg10.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%2Fne9649ekst37nc18gg10.png" alt="Goodreads Profile" width="800" height="565"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;My Goodreads profile showing the 2024 reading challenge progress, favorite books collection, active bookshelves, and recent reading activity&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Blinkist&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use it quite rarely but I still find it useful to get like a sneak peek whats inside a book. It's still a great format to listen to content while commuting for example. Check out &lt;a href="https://www.blinkist.com/" rel="noopener noreferrer"&gt;https://www.blinkist.com/&lt;/a&gt; (they're Berlin based 😎).&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%2Fr0ofrbrvl3q5napbjfxi.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%2Fr0ofrbrvl3q5napbjfxi.png" alt="Blinkist Trending and Categories" width="800" height="466"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Blinkist's trending section showcasing popular books and comprehensive category system&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals for 2026
&lt;/h2&gt;

&lt;p&gt;I don't quite know what will happen in 2026 given the overall geopolitical instability around the world. Also, AI has already had quite a big impact on the industry so it's not really foreseeable what exactly will happen.&lt;/p&gt;

&lt;p&gt;Looking forward to 2026, I think I already have some list of things I'd like to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is definitely one of my weakest points. I definitely need to get more hands-on on more advanced topics. I still haven't finished &lt;a href="https://www.goodreads.com/book/show/34013922-kubernetes-in-action" rel="noopener noreferrer"&gt;Kubernetes in Action&lt;/a&gt; which is definitely a really good and practicable book. I still hope to set some time aside to setup a local cluster and maybe host some services.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Music&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd like to focus even more on &lt;em&gt;live performance&lt;/em&gt;. That's also the reason I've purchased a &lt;a href="https://www.roland.com/global/products/sp-404mk2/" rel="noopener noreferrer"&gt;SP404 MK2&lt;/a&gt; which I guess will be a quite good companion to my MC-101. It's one thing to play a track (with all the layers: drums, bass line, synths, FX etc.) live compared to playing multiple tracks. For the latter, one needs like a structure and good preparation for the live set.&lt;/p&gt;

&lt;p&gt;Of course I will definitely continue to play percussion and try to get better at congas. It has still been my biggest dream to incorporate percussion into a live DJ like performance. Hopefully I can do both at the same time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Books&lt;/strong&gt; / &lt;strong&gt;Topics&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I guess I'll continue my &lt;strong&gt;Stoicism&lt;/strong&gt; journey by going even deeper into the available resources (and/or maybe go to the source and read Marcus Aurelius' Meditations). As this year I had to deal a lot with &lt;strong&gt;software architecture&lt;/strong&gt;, also for the next year I foresee more and more work in this field where services will have to be designed from scratch or refactored.&lt;/p&gt;

&lt;p&gt;Knowing more about &lt;strong&gt;Leadership&lt;/strong&gt; is something I had on my agenda for this year. I definitely want to improve the way I communicate to people (to my colleagues, to my managers, to my family). Staying calm and mindful when all around so many things happen is indeed challenging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking Back, Moving Forward
&lt;/h2&gt;

&lt;p&gt;2025 has been a year of finding balance - between technology and creativity, between digital tools and analog practices, between ambitious goals and realistic progress. While I didn't achieve all my technical objectives, the unexpected depth I found in music and the joy of live performance have added richness to my life that no Kubernetes certification could match.&lt;/p&gt;

&lt;p&gt;The integration of Claude into my workflow has fundamentally changed how I approach both coding and writing, while the return to paper-based planning has grounded me in a more intentional approach to my days. These seemingly contradictory trends - embracing AI while valuing analog tools - actually complement each other beautifully.&lt;/p&gt;

&lt;p&gt;As I look toward 2026, I'm excited about continuing this journey of growth and discovery. Whether it's finally mastering Kubernetes, performing live with electronic music and percussion, or diving deeper into stoic philosophy, the path ahead feels full of possibility.&lt;/p&gt;

&lt;p&gt;Here's to another year of learning, creating, and finding joy in both the planned and the unexpected.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>learning</category>
      <category>devops</category>
      <category>review</category>
    </item>
    <item>
      <title>Add Pagefind Search to Hugo</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Thu, 10 Apr 2025 09:11:24 +0000</pubDate>
      <link>https://dev.to/dorneanu/add-pagefind-search-to-hugo-k34</link>
      <guid>https://dev.to/dorneanu/add-pagefind-search-to-hugo-k34</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Every PKMS/BASB needs a search functionality. Ever since I've created &lt;a href="https://brainfck.org" rel="noopener noreferrer"&gt;brainfck&lt;/a&gt; to host my own collection of thoughts/ideas/resources (aka Zettelkasten) I wanted to be able to actually &lt;strong&gt;search&lt;/strong&gt; within my collection of &lt;a href="https://www.orgroam.com/" rel="noopener noreferrer"&gt;org-roam&lt;/a&gt; based notes. Meanwhile for all my sites I own (&lt;a href="https://blog.dornea.nu" rel="noopener noreferrer"&gt;this&lt;/a&gt; blog, my &lt;a href="https://dornea.nu" rel="noopener noreferrer"&gt;CV/portfolio&lt;/a&gt;, &lt;a href="https://brainfck.org" rel="noopener noreferrer"&gt;brainfck&lt;/a&gt; and &lt;a href="https://defersec.com" rel="noopener noreferrer"&gt;defersec&lt;/a&gt;) I use &lt;a href="https://gohugo.io/" rel="noopener noreferrer"&gt;hugo&lt;/a&gt;. All of them didn't have proper search capabilities. That's why I was looking for a proper way to include search functionalities without any major effort.&lt;/p&gt;

&lt;p&gt;Hugo, indeed, has some &lt;a href="https://gohugo.io/tools/search/" rel="noopener noreferrer"&gt;open-source and commercial search options&lt;/a&gt; you can choose from. I have used this &lt;a href="https://gist.github.com/eddiewebb/735feb48f50f0ddd65ae5606a1cb41ae" rel="noopener noreferrer"&gt;fuse.js integration&lt;/a&gt; in the past but I wasn't happy with it. It didn't index well, I couldn't find all my content. Of course, I was thinking having &lt;a href="https://docsearch.algolia.com/" rel="noopener noreferrer"&gt;Algolia DocSearch&lt;/a&gt; do the magic but one has to apply for it. Also, not all of my sites are about &lt;em&gt;technical documentation&lt;/em&gt;. So I had to find another alternative. Digging deeper I came across &lt;a href="https://pagefind.app/" rel="noopener noreferrer"&gt;Pagefind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a screenshot how it currently looks like:&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%2Fljevv8t6534rq7xn5r4l.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%2Fljevv8t6534rq7xn5r4l.png" alt="Search function on brainfck.org using Pagefind" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pagefind
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pagefind.app/" rel="noopener noreferrer"&gt;Pagefind&lt;/a&gt; is a lightweight, static search solution designed specifically for static sites like those built with Hugo. It works by generating a search index during your site's build process, creating a client-side search experience that doesn't require any server infrastructure.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;indexing&lt;/strong&gt; works by crawling your static HTML files after they're built, extracting content and metadata. Pagefind creates a compressed search index that's both fast and efficient, typically resulting in index sizes of about 1/1000th of your original content size. This means your search functionality remains &lt;em&gt;quick&lt;/em&gt; even on larger sites.&lt;/p&gt;

&lt;p&gt;When examining a typical Pagefind implementation in a Hugo site, the folder structure looks 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;tree public/pagefind
public/pagefind
├── fragment
│   ├── en_02aee83.pf_fragment
...
│   ├── en_2538bf9.pf_fragment
│   ├── en_2550e62.pf_fragment
│   ├── en_2582c6f.pf_fragment
│   ├── en_ffbbc35.pf_index
│   └── en_ffeab69.pf_index
├── pagefind-entry.json
├── pagefind-highlight.js
├── pagefind-modular-ui.css
├── pagefind-modular-ui.js
├── pagefind-ui.css
├── pagefind-ui.js
├── pagefind.en_19e6da436f.pf_meta
├── pagefind.en_1c7f38a66e.pf_meta
├── pagefind.en_1f95755b6e.pf_meta
├── pagefind.en_2a7661ff21.pf_meta
├── pagefind.en_4fdfe13af9.pf_meta
├── pagefind.en_5049ae833f.pf_meta
├── pagefind.en_603dab85b4.pf_meta
├── pagefind.en_6663d2c9c9.pf_meta
├── pagefind.en_7411b4b912.pf_meta
├── pagefind.en_791636c92e.pf_meta
├── pagefind.en_93f1fd4c5c.pf_meta
├── pagefind.en_94bcd0c843.pf_meta
├── pagefind.en_a8061c44f1.pf_meta
├── pagefind.en_a96223e65e.pf_meta
├── pagefind.en_b526d7e391.pf_meta
├── pagefind.en_b6e37679e1.pf_meta
├── pagefind.en_b7a63d2937.pf_meta
├── pagefind.en_c039de83fe.pf_meta
├── pagefind.en_d9c4de17e6.pf_meta
├── pagefind.en_deac3933f1.pf_meta
├── pagefind.en_eb3680ac82.pf_meta
├── pagefind.en_fab96f64ed.pf_meta
├── pagefind.js
├── wasm.en.pagefind
└── wasm.unknown.pagefind

3 directories, 3087 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;You also have some &lt;a href="https://pagefind.app/docs/config-options/" rel="noopener noreferrer"&gt;configuration options&lt;/a&gt;. In my case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Pagefind configuration&lt;/span&gt;

&lt;span class="c1"&gt;# Basic options (using Pagefind 1.0 naming)&lt;/span&gt;
&lt;span class="na"&gt;site&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;
&lt;span class="na"&gt;output_subdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pagefind&lt;/span&gt;

&lt;span class="c1"&gt;# Add date-based metadata for sorting&lt;/span&gt;
&lt;span class="na"&gt;indexing_options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Add date as metadata for all pages&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;metadata_date_field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date&lt;/span&gt;
    &lt;span class="na"&gt;metadata_date_format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iso&lt;/span&gt;

  &lt;span class="c1"&gt;# Global metadata fields for all pages&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;metadata_fields&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Primary metadata sources&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;meta[property='og:title']"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;as&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;content_attr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;optional&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.post-title"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;as&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;optional&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;h1"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;as&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;optional&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;# Date and other metadata&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;meta[property='og:type']"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;as&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;content_attr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;optional&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;meta[name='date']"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;as&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;content_attr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;optional&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;meta[property='article:published_time']"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;as&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;published"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;content_attr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;optional&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;time"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;as&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;content_attr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;datetime"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;optional&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Added languages&lt;/span&gt;
&lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;en&lt;/span&gt;
  &lt;span class="na"&gt;stemming&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;# Search options&lt;/span&gt;
&lt;span class="na"&gt;search_options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ignore_missing_metadata_fields&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;boost_exact_matches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;boost_title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration file sets up Pagefind with optimal settings for a &lt;strong&gt;personal knowledge base&lt;/strong&gt;. The key options include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Basic setup&lt;/em&gt;: Specifies the source directory (public) and where to output the search files (pagefind subdirectory)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Date-based metadata&lt;/em&gt;: Adds date fields for each page, enabling chronological sorting of search results&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Metadata extraction&lt;/em&gt;: Configures multiple fallback methods to extract page titles and dates from different HTML elements and meta tags&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Search optimization&lt;/em&gt;: Boosts exact matches and increases the weight of title matches by 5x, ensuring the most relevant results appear first&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hugo integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Search page
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Search template
&lt;/h3&gt;

&lt;p&gt;The search page implementation works through several key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Loading Pagefind scripts&lt;/em&gt;: The template loads the necessary CSS and JavaScript files that Pagefind generated during the build process.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Search parameter handling&lt;/em&gt;: The implementation supports direct linking to search results using URL parameters. When someone visits &lt;code&gt;/search?q=zettelkasten&lt;/code&gt;, the page automatically populates the search box with "zettelkasten" and triggers the search.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;URL updating&lt;/em&gt;: As the user types in the search box, the URL is dynamically updated with the current query using the browser's History API (pushState). This creates a seamless experience where users can bookmark or share specific search results.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ define "main" }}
&lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"center mv4 content-width ph3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"f3 fw6 heading-color heading-font"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Title }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"lh-copy mt4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Search across all content.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Load Pagefind scripts --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/pagefind/pagefind-ui.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/pagefind/pagefind-ui.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Create the search container with your site's styling --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"search"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-100 mb4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;// Set configuration for pagefind&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pagefindConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;bundlePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/pagefind/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;processTerm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Simple processing to remove undefined text from search results&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;term&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/undefined/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="c1"&gt;// Function to get URL parameters&lt;/span&gt;
      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUrlParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[\[]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[\]]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&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;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;?&amp;amp;]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;=([^&amp;amp;#]*)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;decodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\+&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Initialize the search UI when the DOM is loaded&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the search query from URL parameter 'q' if it exists&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUrlParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;q&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchUI&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;PagefindUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;showSubResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;showImages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Enable sorting by date (newest first) and relevance&lt;/span&gt;
            &lt;span class="na"&gt;options&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="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Date (Newest First)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Relevance&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="c1"&gt;// Use date as the default sorting method&lt;/span&gt;
            &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;translations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search your notes...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;zero_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No results found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;many_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Found {results} results&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;sort_by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sort by:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Set up a listener to watch for changes in the search input&lt;/span&gt;
        &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Find the search input after PagefindUI has initialized&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.pagefind-ui__search-input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.pagefind-ui__form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchInput&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 URL when the search input changes&lt;/span&gt;
            &lt;span class="nx"&gt;searchInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nf"&gt;updateSearchUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="c1"&gt;// Also capture form submission (when user presses Enter)&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchForm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;searchForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Don't prevent default as we want the search to execute&lt;/span&gt;
                &lt;span class="nf"&gt;updateSearchUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="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;// Helper function to update the URL with the search query&lt;/span&gt;
          &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateSearchUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&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;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&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="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;q&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;q&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pushState&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&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="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Short delay to ensure PagefindUI has initialized&lt;/span&gt;

        &lt;span class="c1"&gt;// If there's an initial query, set it and trigger the search&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Use a small timeout to ensure PagefindUI is fully initialized&lt;/span&gt;
          &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;searchUI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;triggerSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialQuery&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;100&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
{{ end }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CSS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Simple pagefind overrides to match site styling */&lt;/span&gt;
&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--pagefind-ui-scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--pagefind-ui-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3e5622&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--pagefind-ui-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--pagefind-ui-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--pagefind-ui-border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ddd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--pagefind-ui-border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Search input styling */&lt;/span&gt;
&lt;span class="nc"&gt;.pagefind-ui__search-input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ddd&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25rem&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* Remove the search icon */&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Adjust clear button position */&lt;/span&gt;
&lt;span class="nc"&gt;.pagefind-ui__search-clear&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Result title styling */&lt;/span&gt;
&lt;span class="nc"&gt;.pagefind-ui__result-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.pagefind-ui__result-link&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3e5622&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Highlight search terms */&lt;/span&gt;
&lt;span class="nc"&gt;.pagefind-ui__result-excerpt&lt;/span&gt; &lt;span class="nt"&gt;mark&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Load more button styling */&lt;/span&gt;
&lt;span class="nc"&gt;.pagefind-ui__button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3e5622&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25rem&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Simple fix for undefined text */&lt;/span&gt;
&lt;span class="nc"&gt;.pagefind-ui__result-excerpt&lt;/span&gt;&lt;span class="nd"&gt;:contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'undefined'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
&lt;span class="nc"&gt;.pagefind-ui__result-title&lt;/span&gt;&lt;span class="nd"&gt;:contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'undefined'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Netlify deployment
&lt;/h2&gt;

&lt;p&gt;Deploying your Pagefind-enabled Hugo site on &lt;a href="https://www.netlify.com/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt; is straightforward with this configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build]&lt;/span&gt;
  &lt;span class="py"&gt;publish&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"public"&lt;/span&gt;
  &lt;span class="py"&gt;command&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hugo &amp;amp;&amp;amp; npx pagefind --site public --output-subdir pagefind"&lt;/span&gt;

&lt;span class="nn"&gt;[build.environment]&lt;/span&gt;
  &lt;span class="py"&gt;HUGO_VERSION&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.145.0"&lt;/span&gt;  &lt;span class="c"&gt;# Replace with your current Hugo version&lt;/span&gt;
  &lt;span class="py"&gt;NODE_VERSION&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"18"&lt;/span&gt;       &lt;span class="c"&gt;# Ensure we have a recent Node version for Pagefind&lt;/span&gt;

&lt;span class="c"&gt;# Cache control for Pagefind files&lt;/span&gt;
&lt;span class="nn"&gt;[[headers]]&lt;/span&gt;
  &lt;span class="py"&gt;for&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/pagefind/*"&lt;/span&gt;
  &lt;span class="nn"&gt;[headers.values]&lt;/span&gt;
    &lt;span class="py"&gt;Cache-Control&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"public, max-age=604800"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration does three critical things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Build command&lt;/em&gt;: It extends the standard Hugo build process by adding Pagefind indexing as a second step. This ensures your search index is generated after Hugo creates all the HTML files.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Environment setup&lt;/em&gt;: It specifies the required Hugo and Node.js versions.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cache configuration&lt;/em&gt;: It adds cache headers for all Pagefind files, setting a one-week cache period. This improves performance for returning visitors, as browsers won't need to download the search index again on every visit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;strong&gt;local development&lt;/strong&gt; this might be also useful:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"brainfck-roam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Your org-roam notes on Hugo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hugo &amp;amp;&amp;amp; npx pagefind --site public --output-subdir pagefind"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hugo server -b http://127.0.0.1:1315/ --disableFastRender --port 1315 --noHTTPCache --logLevel debug --gc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"search-index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx pagefind --site public --output-subdir pagefind"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"full-dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build &amp;amp;&amp;amp; npm run dev"&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;"dependencies"&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;"pagefind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;package.json&lt;/code&gt; file provides several convenient npm scripts that streamline your workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;npm run dev&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Starts a local Hugo server with debug logging and cache disabled.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;npm run search-index&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Runs only the Pagefind indexing on your current build output. This is helpful when you want to rebuild just the search index without regenerating the entire site.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;npm run build&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Performs the complete production build process—generating the Hugo site and then creating the Pagefind search index afterward.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;npm run full-dev&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;A comprehensive development command that builds the complete site with search index and then starts the development server. This is ideal when you need to test search functionality locally.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gohugo.io/tools/search/" rel="noopener noreferrer"&gt;Hugo Search tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pagefind.app/" rel="noopener noreferrer"&gt;Pagefind | Pagefind — Static low-bandwidth search at scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.jverkamp.com/2023/09/25/adding-local-search-to-hugo-with-pagefind/" rel="noopener noreferrer"&gt;Adding local search to Hugo with Pagefind – jverkamp.com&lt;/a&gt; - This is where I got the idea with the q parameter (e.g. &lt;code&gt;/search?q=string&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://michael-le.dev/posts/pagefind-hugo/" rel="noopener noreferrer"&gt;Search with Pagefind - michael-le.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hugo</category>
      <category>webdev</category>
      <category>go</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Book Summaries: January - March 2025</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Wed, 02 Apr 2025 00:00:00 +0000</pubDate>
      <link>https://dev.to/dorneanu/book-summaries-january-march-2025-2ajg</link>
      <guid>https://dev.to/dorneanu/book-summaries-january-march-2025-2ajg</guid>
      <description>&lt;p&gt;Continuing with my tradition of quarterly book summaries, here are my reflections on the books I’ve read between &lt;strong&gt;January&lt;/strong&gt; and &lt;strong&gt;March&lt;/strong&gt; this year.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Tyranny of the Minority
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/122769171-tyranny-of-the-minority" rel="noopener noreferrer"&gt;Tyranny of the Minority by Steven Levitsky &amp;amp; Daniel Ziblatt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the beginning the title seemed very strange to me since my first thought was: “&lt;em&gt;How can a minority overrule the majority?&lt;/em&gt;” As the authors put it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Majorities must also be constrained in a second area: &lt;strong&gt;the rules of democracy itself&lt;/strong&gt;. Elected governments must &lt;strong&gt;not be able to use their temporary majorities to entrench themselves in power&lt;/strong&gt; by changing the rules of the game in ways that weaken their opponents or undermine fair competition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a “&lt;em&gt;liberal&lt;/em&gt;” democracy you need both: protect minority rights but allow the majority to rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And so the form of democracy that emerged in the West between the late eighteenth and the twentieth centuries, which today we call &lt;strong&gt;“liberal” democracy&lt;/strong&gt; , is based on &lt;strong&gt;two pillars: collective self-rule (majority rule) and civil liberties (minority rights)&lt;/strong&gt;. Although liberal democracy cannot exist without free and fair elections, &lt;strong&gt;not everything can or should be up for grabs in elections&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;“&lt;em&gt;Tyranny of the Minority&lt;/em&gt;” is the analysis of the &lt;strong&gt;political system in the USA&lt;/strong&gt; and describes how the minority rule seems to have led to a breaking point in the American democracy. The authors argue that the &lt;strong&gt;US constitution&lt;/strong&gt; (which is one the of the oldest one, and designed in a pre-democratic era) &lt;strong&gt;allows minorities to thwart majorities&lt;/strong&gt; and sometimes even govern them. Institutions that empower these minorities can become instruments of minority rule, which is especially dangerous when these minorities are extremist or antidemocratic.&lt;/p&gt;

&lt;p&gt;Several specific &lt;em&gt;counter-majoritarian&lt;/em&gt; institutions are highlighted as contributing to this problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://en.wikipedia.org/wiki/United_States_Electoral_College" rel="noopener noreferrer"&gt;Electoral College&lt;/a&gt; can distort the popular vote, allowing &lt;strong&gt;a candidate with fewer votes to win the presidency&lt;/strong&gt;. This is exacerbated by the winner-take-all system in most states and a small-state bias that favors Republicans&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/United_States_Senate" rel="noopener noreferrer"&gt;US Senate&lt;/a&gt;&lt;/strong&gt; dramatically &lt;strong&gt;overrepresents citizens of less populated states&lt;/strong&gt; , meaning a Senate majority can represent a small fraction of the U.S. population&lt;/li&gt;
&lt;li&gt;Furthermore, the &lt;a href="https://en.wikipedia.org/wiki/Filibuster" rel="noopener noreferrer"&gt;filibuster&lt;/a&gt; allows a &lt;strong&gt;partisan minority&lt;/strong&gt; in the Senate to permanently &lt;strong&gt;block legislation&lt;/strong&gt; backed by large majorities&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://en.wikipedia.org/wiki/Supreme_Court_of_the_United_States" rel="noopener noreferrer"&gt;Supreme Court&lt;/a&gt;, with lifetime appointments, can be &lt;strong&gt;nominated&lt;/strong&gt; by &lt;strong&gt;presidents who lost the popular vote&lt;/strong&gt; and &lt;strong&gt;confirmed by Senate majorities representing a minority of Americans&lt;/strong&gt;. This can lead to a court that thwarts the will of the majority for generations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The authors suggest the following &lt;strong&gt;democratic reforms&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Uphold the right to vote&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ensure election outcomes reflect majority preferences&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Empower governing majorities&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 Check out my &lt;a href="https://brainfck.org/book/tyranny-of-the-minority" rel="noopener noreferrer"&gt;notes&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Brave New World
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/5129.Brave_New_World?" rel="noopener noreferrer"&gt;Brave New World by Aldous Huxley&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Continuing the “&lt;em&gt;totalitarian path&lt;/em&gt;” I also read “Brave New World” which was written in 1932, before Orwell’s &lt;a href="https://brainfck.org/book/1984" rel="noopener noreferrer"&gt;1984&lt;/a&gt; which was published in 1949. Both are considered two of the most influential &lt;strong&gt;dystopian novels&lt;/strong&gt; of the 20th century, each presenting different aspects of totalitarian features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1984: brutal surveillance that maintains control through &lt;strong&gt;violence, propaganda, and psychological&lt;/strong&gt; manipulation&lt;/li&gt;
&lt;li&gt;Brave New World: portrays a seemingly pleasant society controlled through &lt;strong&gt;pleasure, genetic engineering, and conditioning&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both books give political warnings and complementary concerns about the future of human society and freedom. Reading these two influential 20th-century dystopian novels as complementary warnings provides a more complete picture of the potential threats to human freedom. Orwell feared those who would ban books; Huxley feared there would be no reason to ban books because no one would want to read them. Orwell feared a population controlled by pain; Huxley feared a population controlled by pleasure and distraction.&lt;/p&gt;

&lt;p&gt;I found myself particularly struck by how Huxley anticipated the use of sophisticated biological technology to control populations. His vision of humans engineered from conception to fit predetermined social roles feels disturbingly plausible in an era of advancing genetic technology. The novel’s exploration of how pleasure and constant distraction can serve as effective means of control also resonates with our current attention economy.&lt;/p&gt;

&lt;p&gt;So, read for yourself, I really liked it!&lt;/p&gt;

&lt;p&gt;👉 Check out my &lt;a href="https://brainfck.org/book/brave-new-world" rel="noopener noreferrer"&gt;notes&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Jäger, Hirten, Kritiker
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/39920242-j-ger-hirten-kritiker" rel="noopener noreferrer"&gt;Jäger, Hirten, Kritiker by Richard David Precht&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The author was recommended to me from a friend (this is my first book by Precht), and while I didn’t particularly like his writing style, overall I got interesting new insights from the book. Given that this book was written in 2018 (when AI wasn’t yet available to the masses, and authoritarian regimes hadn’t partnered with technocrats in democratic countries), I was struck to realize that what Precht was foreseeing seems to be becoming reality.&lt;/p&gt;

&lt;p&gt;One of the main ideas is that the &lt;strong&gt;concept of work&lt;/strong&gt; (as we’ve defined it until now) will change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many jobs will disappear because of automation (and of course AI)&lt;/li&gt;
&lt;li&gt;But humans have also become dependent on technology to the point they cannot live without it anymore:&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;People have forgotten how to drive cars, read maps, and navigate the world on their own. They no longer need to remember anything because electronic devices remind us of everything, and they store less and less knowledge about the world because devices take over this function for us. Most people have reverted to toddlers in their knowledge about the world, their dependence on (technical) care, and their lack of courage to leave the house without assistive devices (or soon, a chip in their head). They communicate through stone-age pictograms, and infantilely divide the world into likes and dislikes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People want to be independent, yet we’re increasingly becoming “ &lt;strong&gt;prosumers&lt;/strong&gt; ” ( &lt;strong&gt;producing consumers&lt;/strong&gt; ):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What used to be trained occupations are now handled by robots. And much of what skilled workers once did, customers now do themselves on their flat screens. The development toward the prosumer, the producing consumer, predates digitalization. Remember how supermarkets replaced grocery retailers in Germany since the 1960s. The discounter was not only cheaper because it was larger, but also because customers now served themselves, thereby saving personnel. The same applies to coffee and ticket machines in the eighties and nineties and to the self-assembly skills of IKEA buyers. The principle of the working customer in the digital age is nothing but the consistent continuation of this self-service: booking trips, checking in at the airport, ordering clothes and books, executing transfers, and so on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without noticing it, people blindly trust solutions from Palo Alto meant to make their lives easier, however:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Most people have reverted to toddlers in their knowledge about the world, their dependence on (technical) care, and their lack of courage to leave the house without assistive devices (or soon, a chip in their head). They communicate through stone-age pictograms, and infantilely divide the world into likes and dislikes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Technocrats also want to optimize our lives, but to what degree?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our craftsmanship is dying out, our linguistic expression is being reduced, our memory, outsourced to memory functions, is declining, our imagination consists of prefabricated images, our creativity follows exclusively technical patterns, our curiosity gives way to convenience, our patience to permanent impatience; we can no longer endure the state of non-entertainment. If this is what the superman looks like—who would want to be one?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if computers take over our jobs, what is the solution? The author (among others) suggests &lt;strong&gt;Universal Basic Income&lt;/strong&gt; :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When advocating for the UBI, the unconditional basic income that every citizen should receive regardless of their need, the first reflexive question that comes up is: Who is going to pay for it? The question—so automated that apparently no one asks why it is immediately posed—is strange. Why shouldn’t the UBI be financeable? After all, we live in the richest Germany that has ever existed. And productivity is increasing rapidly through digitalization. Computers and robots don’t cost social security contributions, don’t draw pensions, holiday or maternity pay. They don’t sleep but work effortlessly day and night.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ll definitely check out his &lt;a href="https://www.goodreads.com/author/show/111694.Richard_David_Precht" rel="noopener noreferrer"&gt;other books&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;👉 Check out my &lt;a href="https://brainfck.org/book/j%C3%A4ger-hirten-kritiker" rel="noopener noreferrer"&gt;notes&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Slow Productivity
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/123997223-slow-productivity" rel="noopener noreferrer"&gt;Slow Productivity by Cal Newport&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you read my blog posts regularly and have talked to me in person, you might already know I’m a big fan of &lt;a href="https://calnewport.com/" rel="noopener noreferrer"&gt;Cal Newport&lt;/a&gt;. I also used to listen to &lt;a href="https://www.youtube.com/@CalNewportMedia" rel="noopener noreferrer"&gt;his podcast&lt;/a&gt; regularly, so I got in-touch with the term “&lt;em&gt;slow productivity&lt;/em&gt;” before he even published the book. He has always been a promoter of “doing less (shallow) work and instead doing more deep work.”&lt;/p&gt;

&lt;p&gt;He defines “slow productivity” as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SLOW PRODUCTIVITY A philosophy for organizing knowledge work efforts in a sustainable and meaningful manner, based on the following three principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do fewer things.&lt;/li&gt;
&lt;li&gt;Work at a natural pace.&lt;/li&gt;
&lt;li&gt;Obsess over quality.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;What I’ve found interesting was Newport’s mention of Carl Honoré’s book “&lt;a href="https://www.goodreads.com/book/show/26096.In_Praise_of_Slowness" rel="noopener noreferrer"&gt;In Praise of Slowness&lt;/a&gt;” which seemed to have coined the “ &lt;strong&gt;slow movement&lt;/strong&gt; ”:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As the journalist Carl Honoré documents in his 2004 book, In Praise of Slowness, these second-wave movements include Slow Cities, which also started in Italy (where it’s called Cittaslow), and focuses on making cities more pedestrian-centric, supportive of local business, and, in a general sense, more neighborly. They also include Slow Medicine, which promotes the holistic care of people as opposed to focusing only on disease, and Slow Schooling, which attempts to free elementary school students from the pressures of high-stakes testing and competitive tracking. More recently, the Slow Media movement has emerged to promote more sustainable and higher-quality alternatives to digital clickbait, and the term Slow Cinema is increasingly used to describe realistic, largely nonnarrative movies that reward extended attention with deeper insight into the human condition. “The slow movement was first seen as an idea for a few people who liked to eat and drink well,” explained the mayor of Petrini’s hometown of Bra. “But now it has become a much broader cultural discussion about the benefits of doing things in a more human, less frenetic manner.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the goal of “slow productivity” is to create a more &lt;strong&gt;human and sustainable approach&lt;/strong&gt; to work:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My goal is to offer a more humane and sustainable way to integrate professional efforts into a life well lived. To embrace slow productivity, in other words, is to reorient your work to be a source of meaning instead of overwhelm, while still maintaining the ability to produce valuable output.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to achieve this, the author recommends 3 principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Principle #1: Do fewer things&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The author argues here that factory work is completely different from knowledge work:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a factory, pushing employees to work longer shifts might be directly more profitable. In knowledge work, by contrast, pushing employees into larger workloads can decrease both the quantity and quality of what they produce.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The knowledge sector sets “productivity” = busyness, which is fundamentally misguided.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Principle #2: Work at a natural pace&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Newport gives some background how our working patterns have changed in the past:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This side-by-side comparison underscores the degree to which our experience of work has transformed during the recent past of our species. Our shift from hunting and gathering to agriculture—the Neolithic Revolution—only really picked up speed somewhere around twelve thousand years ago. By the time of the Roman Empire, foraging had almost completely disappeared from the human story. This reorientation toward agriculture threw most of humanity into a state similar to that of the rice-farming Agta, grappling with something new: the continuous monotony of unvarying work, all day long, day after day.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He also mentions we’re constantly grinding without relief:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The second principle of slow productivity argues that these famous scientists were onto something. Our exhausting tendency to grind without relief, hour after hour, day after day, month after month, is more arbitrary than we recognize. It’s true that many of us have bosses or clients making demands, but they don’t always dictate the details of our daily schedules—it’s often our own anxieties that play the role of the fiercest taskmaster. We suffer from overly ambitious timelines and poorly managed workloads due to a fundamental uneasiness with ever stepping back from the numbing exhaustion of jittery busyness.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He also suggests working in cycles (which is a more natural approach):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Work in Cycles The software development company Basecamp is known for experimenting with innovative management practices. This is perhaps not surprising given that its cofounder and current CEO, Jason Fried, once published a book titled It Doesn’t Have to Be Crazy at Work. One of Basecamp’s more striking policies is the consolidation of work into “cycles.” Each such cycle lasts from six to eight weeks. During those weeks, teams focus on clear and urgent goals. Crucially, each cycle is then followed by a two-week “cooldown” period in which employees can recharge while fixing small issues and deciding what to tackle next. “It’s sometimes tempting to simply extend the cycles into the cooldown period to fit in more work,” explains the Basecamp employee handbook. “But the goal is to resist this temptation.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;- Principle #3: Obsess over quality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The author shares examples of how obsessing over quality can provide leverage for greater control over one’s schedule, and how this doesn’t necessarily require becoming a superstar but rather developing rare and valuable skills:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Both Jewel and Paul Jarvis discovered a similar lesson in their careers. The marketplace doesn’t care about your personal interest in slowing down. If you want more control over your schedule, you need something to offer in return. More often than not, your best source of leverage will be your own abilities. What makes Jarvis’s story so heartening is its demonstration that these benefits of “obsessing” over quality don’t necessarily require that you dedicate your entire life to the blinkered pursuit of superstardom. Jarvis didn’t sell fifteen million records; he instead became, over time, good at core skills that were both rare and valuable in the particular field in which he worked. But this was enough, when leveraged properly, to enable significantly more simplicity in his professional life. We’ve become so used to the idea that the only reward for getting better is moving toward higher income and increased responsibilities that we forget that the fruits of pursuing quality can also be harvested in the form of a more sustainable lifestyle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The author provides a strategy for balancing obsession and perfectionism: give yourself enough time to create something great but not unlimited time, and focus on making progress rather than perfection:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your goal is instead reduced to knocking the metaphorical ball back over the net with enough force for the game to proceed. Here we find as good a general strategy for balancing obsession and perfectionism as I’ve seen: Give yourself enough time to produce something great, but not unlimited time. Focus on creating something good enough to catch the attention of those whose taste you care about, but relieve yourself of the need to forge a masterpiece. Progress is what matters. Not perfection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 Check out my &lt;a href="https://brainfck.org/book/slow-productivity" rel="noopener noreferrer"&gt;notes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le Fin
&lt;/h2&gt;

&lt;p&gt;As always: You can find my readings on &lt;a href="https://www.goodreads.com/user/show/121423977-victor-dorneanu" rel="noopener noreferrer"&gt;Goodreads&lt;/a&gt; and my current to-be-read list of books&lt;a href="https://brainfck.org/t/books/TODO" rel="noopener noreferrer"&gt;her&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>books</category>
      <category>reading</category>
    </item>
    <item>
      <title>Book Summaries: October - December 2024</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Thu, 16 Jan 2025 00:00:00 +0000</pubDate>
      <link>https://dev.to/dorneanu/book-summaries-october-december-2024-538e</link>
      <guid>https://dev.to/dorneanu/book-summaries-october-december-2024-538e</guid>
      <description>&lt;p&gt;Continuing with my tradition of quarterly book summaries, here are my reflections on the books I’ve read between &lt;em&gt;October&lt;/em&gt; and &lt;em&gt;December&lt;/em&gt; last year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Biographies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 Elon Musk
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/122765395-elon-musk" rel="noopener noreferrer"&gt;Elon Musk by Walter Isaacson&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I must admit I’m definitely &lt;strong&gt;not&lt;/strong&gt; a fan of Elon Musk and had some curiosity to learn more about the person behind the public façade. I wanted to learn more about all the aspects that shaped him and his mindset. As I learned, his childhood and his relationship to his father have had a profound impact on his thinking and behavioral tendencies.&lt;/p&gt;

&lt;p&gt;Overall, I was fascinated by Musk’s intelectual breadth which spans multiple domains. He decided to major in physics because, like his father, he was drawn to engineering. He also decided to learn about business because he didn’t want to work for others:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I was concerned that if I didn’t study business, I would be forced to work for someone who did,” he says. &lt;strong&gt;“My goal was to engineer products by having a feel for the physics and never have to work for a boss with a business degree.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It was exactly this combination of technical depth and business knowledge that would serve as a fundament for his future ventures. As for his visions he had very concrete expectations:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;He had conceived by then a life vision that he would repeat like a mantra. &lt;strong&gt;“I thought about the things that will truly affect humanity,” he says. “I came up with three: the internet, sustainable energy, and space travel.”&lt;/strong&gt; In the summer of 1995, it became clear to him that the first of these, the internet, was not going to wait for him to finish graduate school. The web had just been opened up for commercial use, and that August the browser startup Netscape went public, soaring within a day to a market value of $2.9 billion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Given our planet’s burning challanges (climate crisis, poverty, low education, war) I still question his Mars colonization plans which are driven by his will to save humanity and our species once there will be no life possible anymore on Mother Earth. The biography not only revelead controversial aspects about his visions but also about his leadership style and work ethics:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Musk responded with a very self-aware email. &lt;strong&gt;“I am by nature obsessive-compulsive,” he wrote Fricker. “What matters to me is winning, and not in a small way.&lt;/strong&gt; God knows why… it’s probably rooted in some very disturbing psychoanalytical black hole or neural short circuit.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While he is undoubtly a visionaire and leaded to the success of multiple multi-billion companies, I still find his management practices problematic: From arbitrary dismissals to creating unsustainable work environments.&lt;/p&gt;

&lt;p&gt;📓 Read my &lt;a href="https://brainfck.org/book/elon-musk/" rel="noopener noreferrer"&gt;notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Politics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 How Democracies Die
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/35356384-how-democracies-die" rel="noopener noreferrer"&gt;How Democracies Die by Steven Levitsky, Daniel Ziblatt&lt;/a&gt; (read in German)&lt;/p&gt;

&lt;p&gt;Unless you have been living under a rock for the last years, you certainly have noticed the rising &lt;em&gt;authoritarian tendencies&lt;/em&gt; worldwide. While this book’s focus is the United States’ constitutional framework, it has provided me with with good analysis of &lt;em&gt;democratic decline&lt;/em&gt; globally and important insights how democratic systems can be systemcally undermined.&lt;/p&gt;

&lt;p&gt;One of the most important revelation to me was the fact that most totalitarian leaders (Hitler, Mussolini, Trump, Erdogan, Orban, Chavez, Fujimori) throuhout history more or less followed the same pattern to gain power. As the authors note (translated from German using LLM):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This story has played out in various forms around the world over the past century. A series of political outsiders, from Adolf Hitler in Germany to Getúlio Vargas in Brazil, Alberto Fujimori in Peru, and Hugo Chávez in Venezuela, all came to power the same way: from within, through elections or alliances with powerful political figures. Each time, elites believed that including the outsider in government would contain them and restore mainstream politicians’ power. This belief proved deceptive. A fatal mixture of ambition, fear, and miscalculation led them to make the same fateful mistake: they knowingly handed over the keys of power to an aspiring autocrat.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What also resonated with me of the crucial role of &lt;em&gt;institutional safeguards&lt;/em&gt; in democratic systems. As the book mentiones also political parties have a responsibility in preserving democracy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While mass response to extremist temptations is important, what matters more is whether political elites, and especially parties, serve as filters. Simply put, parties are the guardians of democracy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Perhaps most disturbing is how autocratic forces often use democratic institutions and rules to gain power while simultaneously undermining democratic values. They often call for “real” or “more” democracy while at the same time working to dismantle it.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Animal Farm
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/170448.Animal_Farm" rel="noopener noreferrer"&gt;Animal Farm by George Orwell&lt;/a&gt; (read in German)&lt;/p&gt;

&lt;p&gt;My first George Orwell reading was &lt;a href="https://brainfck.org/book/1984" rel="noopener noreferrer"&gt;1984&lt;/a&gt; making “Animal Farm” (its chronological predecessor) particularly interesting as it reveals the evolutionof Orwell’s thoughts on &lt;em&gt;authoritarian systems&lt;/em&gt;. Without knowing Orwell’s personal background and political influences that shaped his perspective (on comunism and failed socialist ideals) one cannot truly appreciate his work.&lt;/p&gt;

&lt;p&gt;The book’s central message is perhaps best captured in its famous principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“All animals are equal, but some animals are more equal than others”&lt;/p&gt;

&lt;p&gt;(German: &lt;strong&gt;“ALLE TIERE SIND GLEICH, ABER MANCHE TIERE SIND GLEICHER ALS ANDERE”&lt;/strong&gt; )&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This simple statement encapsulates the entire tragedy of how &lt;em&gt;egalitarian ideals&lt;/em&gt; can be corrupted by those in power (in this case, represented by the &lt;em&gt;pigs&lt;/em&gt; which gradually take over control of the farm). What makes this book particularly relevant today is its brilliant illustration of how &lt;em&gt;manipulation&lt;/em&gt;, &lt;em&gt;fear&lt;/em&gt;, &lt;em&gt;propaganda&lt;/em&gt; and &lt;em&gt;ideology&lt;/em&gt; can facilitate the establishment of &lt;em&gt;authoritarian systems&lt;/em&gt;. Orwell did a good job to show (through farm animals) how revolutionary ideals can be gradually misinterpreted and misused to serve the interests of a new elite. As our world becomes more and more dominated by both autocrats and technocrats, the warnings embedded in the book feel more present than ever.&lt;/p&gt;

&lt;p&gt;📓 Read my &lt;a href="https://brainfck.org/book/farm-der-tiere" rel="noopener noreferrer"&gt;notes&lt;/a&gt; (German)&lt;/p&gt;

&lt;h2&gt;
  
  
  Climate
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 The Ministry of the Future
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/50998056-the-ministry-of-future" rel="noopener noreferrer"&gt;The Ministry of the Future by Kim Stanley Robinson&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve listened to “The Ministry of the Future” through an audiobook which, in retrospect, might not have been the optimal choice for absorbing the depth and complexity of this work. I think I’ll purchase a physical copy or the e-book version of this book as it deserves a more deliberate pace. The audiobook doesn’t really allow you to revisit key passages, make notes and reflect on certain aspects.&lt;/p&gt;

&lt;p&gt;What sets this book apart is its quite realistic approach to climate science fiction. Far from dystopian extremes and far-fetched solutions it offers a quite realistic scenario of how humanity might struggle with the all the challenges of the climate crisis. The main idea of the book, a &lt;em&gt;global governance institution&lt;/em&gt; particularly resonated to me as it demonstrates the need for global actions instead of letting individual nations handle climate actions in isolation. These actions usually have unforeseeable effects on other regions weather conditions which definitely might lead to conflict between countries.&lt;/p&gt;

&lt;p&gt;Apart from that there were two economic concepts that seem crucial solving global problems. First, the role of &lt;em&gt;corporate funding&lt;/em&gt; in environmental projects and secondly the idea of a &lt;em&gt;carbon coin&lt;/em&gt;, a global financial instrument designed to fund climate crisis initiatives. This creates investment opportunities for corporations while maintaining focus on environment goals. And of course, the ROI (return of investment) will be way lower than usual rates.&lt;/p&gt;

&lt;p&gt;As I’ve mentioned already I’m planning to revisit this work in either e-book or physical format. The book has several detail layers that require a more &lt;em&gt;traditional&lt;/em&gt; reading approach allowing me to engage with the complex ideas in a more deeper manner.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 History of Bees
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/34730052-die-geschichte-der-bienen" rel="noopener noreferrer"&gt;The History of Bees by Maja Lunde&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I came to this book through my wife’s recommendation and despite &lt;em&gt;not&lt;/em&gt; being a regular novel reader I became quite interested about the potential consequences of a &lt;em&gt;global bee extinction&lt;/em&gt;. Like “The Ministry of the Future” this work presents a realistic scenario of how environmental crisis could reshape human society, but focusses specially on the critical role of bees in our ecosystem.&lt;/p&gt;

&lt;p&gt;Through the book you’ll get to read stories from different epochs that initially seem distinct but at the end reveal their interconnections. Through these parallel stories, the author illustrates the historial, present and potential future significance of &lt;em&gt;apiculture&lt;/em&gt;(beekeeping).&lt;/p&gt;

&lt;p&gt;If you study bees you’ll get to understand their important for our food systems. Almost without human intervention &lt;em&gt;natural pollination&lt;/em&gt; of trees (through bees) takes place which is crucial for fruit production. This again is vital for continuous &lt;em&gt;harvests&lt;/em&gt; and therefore for &lt;em&gt;food security&lt;/em&gt;. As you delve into the book’s chapters it becomes clear how these small insects play a vital role in maintaining our already fragile &lt;em&gt;ecological balance&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The use of multiple timelines and connected stories effectively highlights the scientific importance of bees (for agriculture) but also the potential costs (for humans) of their potential loss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Food Science
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 Salt Fat Acid Heat
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/30753841-salt-fat-acid-heat" rel="noopener noreferrer"&gt;Salt Fat Acid Heat by Samin Nosrat&lt;/a&gt; (read in German)&lt;/p&gt;

&lt;p&gt;I think that in another life I might have been a cook 🙈 - at least that’s how I explain my passion for cooking and culinary arts. While I explored different techniques from slow cooking to steam preparation, it is Samin Nosrat’s “Salt Fact Acid Heat” that slowly transforms my approach to cooking.&lt;/p&gt;

&lt;p&gt;What’s so cool about this book is the way it deconstructs the &lt;em&gt;fundamental elements&lt;/em&gt; we often take for granted in cooking. Salt, oil, fat are such common ingredients that we don’t really think about their actual purpose in our dishes. Nosrat breaks down (in a semi-scientific approach) the chemical interactions between these elements and various ingredients. This (technical) depth adds a new dimension to understanding how and why certain cooking techniques work the way they do.&lt;/p&gt;

&lt;p&gt;Along the technical explanations Nosrat also shares personal anecdotes and tips making complex cooking techniques accessible and memorable. Personally I struggled for a long time to remember all the ingredients one needs to make a good sauce. The books has a comprehensive section on sauce-making (which oil depending on the what type of food you want to prepare etc.) and definitely helped me created balanced flavours. After all it’s not a rocket science but it feels this way when you don’t know the basics.&lt;/p&gt;

&lt;p&gt;At the end of the book you’ll find a recipe collection which also serves as a pratical demonstration of the principles discussed in the book. These recipes are not only just some steps you should follow, but more like practical lessons in applying (Nosrat’s) science of cooking.&lt;/p&gt;

&lt;p&gt;📓 Read my &lt;a href="https://brainfck.org/book/salz.fett.s%C3%A4ure.hitze" rel="noopener noreferrer"&gt;notes&lt;/a&gt; (German)&lt;/p&gt;

&lt;h2&gt;
  
  
  Business &amp;amp; Productivity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 The Effective Executive
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/48019.The_Effective_Executive" rel="noopener noreferrer"&gt;The Effective Executive by Peter F. Drucker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drucker’s “The Effective Executive” was originally published in 1966 during his tenure as a management professor at the New York University. At least for me this book proved to be a dissapointment: I &lt;em&gt;cannot recommend&lt;/em&gt; reading this book as there are plenty of more valuable works on &lt;a href="https://brainfck.org/tags/management/" rel="noopener noreferrer"&gt;management&lt;/a&gt; and &lt;a href="https://brainfck.org/tags/productivity/" rel="noopener noreferrer"&gt;productivity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The book’s approach sounds kind of odd to me especially after engaging (through books and podcasts) with Cal Newport’s modern frameworks around &lt;a href="https://brainfck.org/t/deep-work" rel="noopener noreferrer"&gt;deep work&lt;/a&gt;, “slow productivity”, &lt;a href="https://dev.to/2024/12/19/my-2024-review/#productivity"&gt;multi-scale planning and time blocking&lt;/a&gt;. Till now these methodologies have been quite effective in my own work. While Drucker is often considered a management thinking pioneer, this particular book (I haven’t read any others yet) offers little practical value for someone working as a &lt;em&gt;knowledge worker&lt;/em&gt;. Perhaps in 1966 and the decades after this book has been revolutionary. However, I’d recommend looking to more current works that better reflect today’s work environment and challenges.&lt;/p&gt;

</description>
      <category>books</category>
      <category>reading</category>
    </item>
    <item>
      <title>My 2024 review</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Thu, 19 Dec 2024 09:00:00 +0000</pubDate>
      <link>https://dev.to/dorneanu/my-2024-review-3d0k</link>
      <guid>https://dev.to/dorneanu/my-2024-review-3d0k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As another year comes to an end, it's time for my annual &lt;a href="https://dev.to/tags/review"&gt;review&lt;/a&gt; (check out &lt;a href="https://dev.to/2021/12/13/my-2021-review/"&gt;2021&lt;/a&gt;, &lt;a href="https://dev.to/2024/01/02/my-2023-review/"&gt;2023&lt;/a&gt;) - a tradition where I reflect on the past twelve months, examining what I've &lt;strong&gt;learned&lt;/strong&gt;, how I've &lt;strong&gt;grown&lt;/strong&gt;, and whether I've managed to stick to my &lt;strong&gt;goals&lt;/strong&gt;. These reviews serve as a personal chronicle but also a way to share experiences that might resonate with others on similar journeys.&lt;/p&gt;

&lt;p&gt;2024 has been a year of significant transitions and new beginnings. Perhaps the most noteworthy change came in my professional life, where I stepped into a more &lt;em&gt;software engineering-focused role&lt;/em&gt;. This transition brought an exciting opportunity to contribute to a large open-source &lt;a href="https://github.com/cloudoperators/heureka" rel="noopener noreferrer"&gt;project&lt;/a&gt; - something that has opened new horizons for learning and collaboration.&lt;/p&gt;

&lt;p&gt;In an effort to share knowledge and best practices, I launched &lt;a href="https://defersec.com" rel="noopener noreferrer"&gt;defersec.com&lt;/a&gt;, a platform dedicated to &lt;strong&gt;DevSecOps&lt;/strong&gt; principles with a particular focus on the &lt;a href="https://brainfck.org/t/golang" rel="noopener noreferrer"&gt;Golang&lt;/a&gt; ecosystem. This project has allowed me to combine my passion for security with practical implementation guidance. Along this journey, I've had the chance to deepen my expertise in infrastructure as code, particularly with &lt;a href="https://brainfck.org/t/terraform" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt;, while also exploring the world of &lt;a href="https://brainfck.org/t/kubernetes" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Beyond the technical realm, this year brought musical adventures I hadn't anticipated. Learning to play the &lt;strong&gt;bongos&lt;/strong&gt; evolved into taking Afro-Cuban Rumba classes for &lt;strong&gt;congas&lt;/strong&gt; - a journey that has added new rhythms and joy to my life.&lt;/p&gt;

&lt;p&gt;Looking back, 2024 has been remarkably fulfilling - a year characterized by growth, learning, and shared experiences with wonderful people. As we dive into the details of this year's journey, I'll explore how various aspects of my life have evolved, from productivity systems to daily habits, and from technical skills to creative pursuits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;p&gt;As another year comes to an end, it's time to look back at the &lt;a href="https://dev.to/2024/01/02/my-2023-review/#goals"&gt;goals I set for 2024&lt;/a&gt; and think about what lies ahead. This reflection helps me understand not just what I've achieved, but also how my interests and priorities have evolved throughout the year.&lt;/p&gt;

&lt;h3&gt;
  
  
  2024 Goals Recap
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Projects
&lt;/h4&gt;

&lt;p&gt;Back in 2023 i wrote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Play with &lt;a href="https://brainfck.org/t/htmx" rel="noopener noreferrer"&gt;HTMX&lt;/a&gt; and &lt;a href="https://brainfck.org/t/golang" rel="noopener noreferrer"&gt;Golang&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd definitely love to do something &lt;em&gt;front-end&lt;/em&gt; related and therefore I'd like to play a little bit with &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;htmx&lt;/a&gt;. But first I need an idea for a small application. This way I plan to code again in Golang (this year I didn't manage to code anything useful).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Security of Github repositories&lt;/p&gt;

&lt;p&gt;While dealing with &lt;em&gt;Github&lt;/em&gt; and the &lt;em&gt;security settings&lt;/em&gt; of &lt;em&gt;repositories&lt;/em&gt;, I wanted to have a small tool at hand which will check for different settings (for each repository in an organization) and report (via Slack, E-Mail) if some settings are not &lt;em&gt;compliant&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finish "Documentation as Code" series&lt;/p&gt;

&lt;p&gt;This year I've started writing about several documentation techniques (as code) in my &lt;a href="https://dev.to/2023/07/18/documentation-as-code-for-cloud/"&gt;Documentation as Code&lt;/a&gt; series. I definitely want to add at least &lt;a href="https://d2lang.com/" rel="noopener noreferrer"&gt;D2Lang&lt;/a&gt; to it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some goals remained aspirational. The tool for auditing GitHub repository security settings is still on the drawing board. I've been thinking whether to develop it as a standalone application or integrate it into existing frameworks like Steampipe.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info Notice:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
👉 Steampipe already has some &lt;a href="https://github.com/turbot/steampipe-plugin-github" rel="noopener noreferrer"&gt;Github integrations&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My "&lt;a href="https://dev.to/2023/07/18/documentation-as-code-for-cloud/"&gt;Documentation as Code&lt;/a&gt;" series took an unexpected turn. While I initially was a &lt;a href="https://brainfck.org/t/plantuml" rel="noopener noreferrer"&gt;Plantuml&lt;/a&gt; advocate, I found myself gravitating more and more towards &lt;a href="https://mermaid.js.org/" rel="noopener noreferrer"&gt;Mermaid charts&lt;/a&gt; (also after having to write some ADRs where, of course, I've added some diagrams). Its seamless integration with GitHub - automatic rendering in Markdown documents 😎 - proved to be a killer feature.&lt;/p&gt;

&lt;h4&gt;
  
  
  Music
&lt;/h4&gt;

&lt;p&gt;Back in 2023 my thoughts were:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Besides playing the &lt;strong&gt;Djembe&lt;/strong&gt; this year I've started learning how to play the &lt;strong&gt;Bongos&lt;/strong&gt;. With the help of ChatGPT I was able to read notes again and therefore play some easy to more advanced rhythms on the Bongos. Next year I'd like to keep practicing and get more insights into Latin rhythms (Salsa, Bachata, Merengue, Mambo, Rumba etc.)&lt;/p&gt;

&lt;p&gt;I have played an &lt;strong&gt;acoustic&lt;/strong&gt; guitar for a while, although not with the same proficiency as I have with hand drums. For motivation, I would like to learn to play the &lt;strong&gt;electric&lt;/strong&gt; guitar and make progress in &lt;strong&gt;live looping&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This year marked a significant milestone in my &lt;em&gt;musical journey&lt;/em&gt;. After starting with &lt;em&gt;Bongos&lt;/em&gt; last year, I dove deeper into &lt;em&gt;Latin percussion&lt;/em&gt; by taking Rumba classes on &lt;em&gt;Congas&lt;/em&gt;. The world of &lt;em&gt;digital music&lt;/em&gt; also opened up to me: I've experimented with &lt;em&gt;live looping&lt;/em&gt; and learned my way around &lt;a href="https://www.reaper.fm/" rel="noopener noreferrer"&gt;Reaper&lt;/a&gt;, a cross-platform &lt;em&gt;DAW&lt;/em&gt; (Digital Audio Workstation). A particular highlight was discovering &lt;a href="https://www.koalasampler.com/" rel="noopener noreferrer"&gt;Koala Sampler&lt;/a&gt;, which completely transformed my approach to &lt;em&gt;live looping&lt;/em&gt; and &lt;em&gt;sampling&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Goals for 2025
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Technical Projects
&lt;/h4&gt;

&lt;p&gt;Looking ahead, I've identified several key areas for &lt;em&gt;technical growth&lt;/em&gt;:&lt;/p&gt;

&lt;h5&gt;
  
  
  Kubernetes exploration
&lt;/h5&gt;

&lt;p&gt;K8s remains a knowledge gap I'm more than determined to address. I'll again follow a "slow productivity" approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with small-scale experiments using &lt;a href="https://k3s.io/" rel="noopener noreferrer"&gt;k3s&lt;/a&gt;/&lt;a href="https://k3d.io/stable/" rel="noopener noreferrer"&gt;k3d&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Work towards deploying my own little cluster, either on a VPS or locally&lt;/li&gt;
&lt;li&gt;Build practical experience through hands-on projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I still need to finish &lt;a href="https://www.goodreads.com/book/show/34013922-kubernetes-in-action" rel="noopener noreferrer"&gt;Kubernetes in Action&lt;/a&gt; which is really a great about if you want to learn about Kubernetes.&lt;/p&gt;

&lt;h5&gt;
  
  
  Golang deep dive
&lt;/h5&gt;

&lt;p&gt;With my recent transition towards more &lt;em&gt;Software Engineering&lt;/em&gt;-focused tasks, I'm planning to strengthen my &lt;a href="https://brainfck.org/t/golang" rel="noopener noreferrer"&gt;Golang&lt;/a&gt; expertise. There are 2 specific areas I'd like to know more about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Generics&lt;/em&gt;: This remains somewhat of a black box that I need to illuminate more&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Concurrency&lt;/em&gt;: Beyond basic understanding, I want to explore and implement common patterns that can be applied across different problems&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Security tooling
&lt;/h5&gt;

&lt;p&gt;The GitHub repository security checker is still on my radar. With the rise of LLMs, I believe much of the &lt;em&gt;foundational work&lt;/em&gt; (authentication, API interactions) can be implemented easily. The key focus will be on defining comprehensive &lt;em&gt;security and compliance checks&lt;/em&gt; that provide real value to the users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Productivity
&lt;/h2&gt;

&lt;p&gt;After years of experimenting with various productivity systems, 2024 was the year where things finally clicked into place. Countless hours of listening to &lt;a href="https://calnewport.com/podcasts/" rel="noopener noreferrer"&gt;Cal Newport's podcast&lt;/a&gt; on &lt;a href="https://www.goodreads.com/book/show/197773418-slow-productivity" rel="noopener noreferrer"&gt;slow productivity&lt;/a&gt; helped me internalize key concepts like &lt;strong&gt;multi-scale planning&lt;/strong&gt;, &lt;strong&gt;time blocking&lt;/strong&gt;, and &lt;a href="https://brainfck.org/t/deep-work" rel="noopener noreferrer"&gt;deep work&lt;/a&gt;. This evolution in my approach has fundamentally changed how I structure my days and manage my projects.&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%2Fdmg80456z5wske04xbsm.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%2Fdmg80456z5wske04xbsm.png" alt="image" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Activity tracking with Garmin&lt;/small&gt;&lt;/center&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%2Fklme5n0z89two0n1jeyh.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%2Fklme5n0z89two0n1jeyh.png" alt="image" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Step tracking throughout the year&lt;/small&gt;&lt;/center&gt;

&lt;h3&gt;
  
  
  Analog Tools Still a Thing
&lt;/h3&gt;

&lt;p&gt;The return to my &lt;em&gt;bullet journal&lt;/em&gt; has been transformative. While digital tools have their place, there's something uniquely effective about &lt;em&gt;pen and paper&lt;/em&gt; for certain tasks. Just the simple physical act of writing helps me process information differently and creates a stronger connection to my plans and ideas.&lt;/p&gt;

&lt;h4&gt;
  
  
  Time Blocking in Practice
&lt;/h4&gt;

&lt;p&gt;One of the most significant changes has been implementing &lt;em&gt;regular time blocking&lt;/em&gt;. This practice has helped me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Visualize&lt;/em&gt; my daily resources more effectively&lt;/li&gt;
&lt;li&gt;Be more realistic about what can be accomplished&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Mentally prepare&lt;/em&gt; for the day ahead before diving into tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The Power of Paper
&lt;/h4&gt;

&lt;p&gt;Despite our digital age, collecting ideas, notes, and TODOs using pen and paper remains unbeatable for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meeting notes can be quickly written down easily and fast&lt;/li&gt;
&lt;li&gt;Spontaneous ideas can be captured immediately&lt;/li&gt;
&lt;li&gt;No need to open a laptop for quick captures&lt;/li&gt;
&lt;li&gt;The tactile experience helps with memory and processing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Digital Organization with ORG Mode
&lt;/h3&gt;

&lt;p&gt;While embracing analog tools, I've also refined my digital organization using &lt;a href="https://orgmode.org/" rel="noopener noreferrer"&gt;ORG mode&lt;/a&gt; in &lt;a href="https://www.gnu.org/software/emacs/" rel="noopener noreferrer"&gt;Emacs&lt;/a&gt;. The system has evolved to become more structured and efficient.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* PROJ Project 1
  * Tasks
    * TODO Do this and that
  * Resources
* PROJ Project 2
  * Tasks
    * TODO Do something else
  * Resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;Code Snippet 1:&lt;/span&gt;&lt;br&gt;
  Project structure in ORG mode&lt;/p&gt;

&lt;p&gt;This structure provides a clear separation between active tasks and reference materials, making it easier to focus on what needs to be done while keeping relevant resources readily accessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Habits
&lt;/h2&gt;

&lt;p&gt;2024 marked a significant shift in how I approach &lt;em&gt;habit tracking&lt;/em&gt; and personal development. While previous years were characterized by meticulous tracking using &lt;a href="https://loophabits.org/" rel="noopener noreferrer"&gt;Loop Habit Tracker&lt;/a&gt;, this year I found myself gravitating towards a more intuitive approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sports
&lt;/h3&gt;

&lt;p&gt;The year started with ambitious goals - I aimed to engage in sports twice weekly and incorporate &lt;strong&gt;20-minute daily exercise&lt;/strong&gt; sessions. Reality, however, had different plans. The transition from a 30-hour to a 40-hour work week significantly impacted my exercise routine.&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%2Fxo4wuqdihytmqqi9gl3s.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%2Fxo4wuqdihytmqqi9gl3s.png" alt="image" width="800" height="966"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Garmin Forerunner 55 - Small and very handy&lt;/small&gt;&lt;/center&gt;

&lt;h3&gt;
  
  
  Reading
&lt;/h3&gt;

&lt;p&gt;My reading habit remains strong, though I've moved away from strict tracking. &lt;a href="https://www.goodreads.com/user/show/121423977-victor-dorneanu" rel="noopener noreferrer"&gt;Goodreads&lt;/a&gt; continues to serve as my primary platform for keeping track of books, while the &lt;a href="https://libbyapp.com/" rel="noopener noreferrer"&gt;Libby App&lt;/a&gt; remains invaluable for accessing e-books and audiobooks.&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%2Fytmor232i0kess5jwx0v.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%2Fytmor232i0kess5jwx0v.png" alt="image" width="756" height="1682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Managing library loans through Libby&lt;/small&gt;&lt;/center&gt;

&lt;h2&gt;
  
  
  Software I Use
&lt;/h2&gt;

&lt;p&gt;Inspired by &lt;a href="https://daryl.wakatara.com/tags/tools/" rel="noopener noreferrer"&gt;Software Tools I use&lt;/a&gt;, I thought I'll also start mentioning my tools I use daily for work and personally. This year I've continued to refine my digital toolkit, focusing on tools that enhance productivity while maintaining simplicity and efficiency in my workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Daily Drivers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gnu.org/software/emacs/" rel="noopener noreferrer"&gt;Emacs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, of course. I've decided to go down the Emacs &lt;em&gt;rabbit-hole&lt;/em&gt; and have thoroughly "Emacsified" my workflows. While I'm fully aware of spending perhaps too much time tweaking my configuration, the result is a &lt;em&gt;system&lt;/em&gt; that perfectly aligns with my needs and working style. A significant milestone this year was transitioning to a &lt;em&gt;fully vanilla setup&lt;/em&gt;, giving me complete control over my configuration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.alfredapp.com/" rel="noopener noreferrer"&gt;Alfred&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being on a Mac, I found myself returning to Alfred. Its snippet management and clipboard functionality have become indispensable parts of my daily workflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://claude.ai/" rel="noopener noreferrer"&gt;Claude AI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude has evolved into my virtual assistant for practically everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coding assistance&lt;/li&gt;
&lt;li&gt;Text summarization&lt;/li&gt;
&lt;li&gt;Recipe collection&lt;/li&gt;
&lt;li&gt;General writing assistance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ivx05w1bi16fwgddahg.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%2F4ivx05w1bi16fwgddahg.png" alt="image" width="800" height="464"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 Organize topic specific conversations into projects&lt;/small&gt;&lt;/center&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%2Fq75z0xc85w61bn5waavy.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%2Fq75z0xc85w61bn5waavy.png" alt="image" width="800" height="464"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 Claude AI artifacts for different projects&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;As a premium user, I work directly with the interface rather than the API. While I occasionally use &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; (integrated into Emacs via &lt;a href="https://github.com/karthink/gptel" rel="noopener noreferrer"&gt;gptel&lt;/a&gt;), Claude remains my primary AI assistant.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://syncthing.net/" rel="noopener noreferrer"&gt;Syncthing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an ORG mode power user, synchronizing my files between devices is crucial. Syncthing elegantly handles this task, enabling seamless sync between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple laptops&lt;/li&gt;
&lt;li&gt;Android smartphone&lt;/li&gt;
&lt;li&gt;Various ORG mode files and notes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's particularly useful for processing smartphone-collected notes and links on my laptop later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sports
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.garmin.com/en-US/p/741137/pn/010-02562-01" rel="noopener noreferrer"&gt;Garmin Forerunner 55&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo4wuqdihytmqqi9gl3s.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%2Fxo4wuqdihytmqqi9gl3s.png" alt="image" width="800" height="966"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 Small and very handy sports watch that perfectly meets my needs&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gymrun.app/" rel="noopener noreferrer"&gt;GymRun&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This app's integration with my Garmin watch has transformed my workout experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create custom routines/workouts&lt;/li&gt;
&lt;li&gt;Start workouts directly from the watch&lt;/li&gt;
&lt;li&gt;Train without smartphone dependency&lt;/li&gt;
&lt;li&gt;Eliminate decision fatigue before workouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhkk6otqk8zhcv9u4xub.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%2Fvhkk6otqk8zhcv9u4xub.png" alt="image" width="800" height="966"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 GymRun app on the Garmin watch&lt;/small&gt;&lt;/center&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%2Fzeovwxtp54ozyk6a60wh.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%2Fzeovwxtp54ozyk6a60wh.png" alt="image" width="756" height="1682"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 GymRun workout overview on Android&lt;/small&gt;&lt;/center&gt;
&lt;h3&gt;
  
  
  Services
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.overdrive.com/" rel="noopener noreferrer"&gt;Overdrive&lt;/a&gt; / &lt;a href="https://libbyapp.com/" rel="noopener noreferrer"&gt;Libbyapp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An invaluable resource that I can't praise enough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration with local library membership&lt;/li&gt;
&lt;li&gt;Access to vast e-book and audiobook collections&lt;/li&gt;
&lt;li&gt;Magazine and newspaper availability&lt;/li&gt;
&lt;li&gt;Waitlist system for popular titles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytmor232i0kess5jwx0v.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%2Fytmor232i0kess5jwx0v.png" alt="image" width="756" height="1682"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 Managing loans through Libby&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.goodreads.com/" rel="noopener noreferrer"&gt;Goodreads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The kind of social media we need more of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Book discovery platform&lt;/li&gt;
&lt;li&gt;Reading progress tracking&lt;/li&gt;
&lt;li&gt;Community reviews and recommendations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Applications
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://f-droid.org/en/" rel="noopener noreferrer"&gt;F-Droid&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An open source app store which contains applications, many of which are not available on the Play Store&lt;/li&gt;
&lt;li&gt;Unlike Google Play Store, F-Droid does not track user activity or collect data&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;a href="https://antennapod.org/" rel="noopener noreferrer"&gt;AntennaPod&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's open source&lt;/li&gt;
&lt;li&gt;This is my main driver for listening to podcasts&lt;/li&gt;
&lt;li&gt;It has a very intuitive UI&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdguux5tfvshiwazlzuby.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%2Fdguux5tfvshiwazlzuby.png" alt="image" width="756" height="1682"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 AntennaPod favorite podcasts&lt;/small&gt;&lt;/center&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%2Fq7udhb89ddnaw20y51fp.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%2Fq7udhb89ddnaw20y51fp.png" alt="image" width="756" height="1682"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 AntennaPod listening statistics&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://f-droid.org/en/packages/InfinityLoop1309.NewPipeEnhanced/" rel="noopener noreferrer"&gt;PipePipe&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Allows you to access Youtube videos&lt;/li&gt;
&lt;li&gt;You can play videos in the background (@Google: When do you finally acknowledge people don't want to see silly ads?)&lt;/li&gt;
&lt;li&gt;But the killer feature is still: &lt;em&gt;download&lt;/em&gt; videos&lt;/li&gt;
&lt;li&gt;I often do this to learn new Conga/Bongos patterns&lt;/li&gt;
&lt;li&gt;It's way easier to learn this way rather than coming back again and again to Youtube&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff31l960w6kc13ug9rgnu.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%2Ff31l960w6kc13ug9rgnu.png" alt="image" width="756" height="1682"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 Video download functionality in PipePipe&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.sdfp-studio.com/" rel="noopener noreferrer"&gt;ABMT Music Trainer&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;This app allows you to play local music/video files and create cue points, loops&lt;/li&gt;
&lt;li&gt;This way you can easily jump to a certain point in the file&lt;/li&gt;
&lt;li&gt;Very useful for jumping to specific portions of a video if you want to learn something&lt;/li&gt;
&lt;li&gt;I use it often to break down specific parts of a percussion pattern and play them individually&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ccanlifycsghzu83lmk.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%2F4ccanlifycsghzu83lmk.png" alt="image" width="756" height="1682"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;center&gt;&lt;small&gt;👉 Creating cue points in ABMT Music Trainer&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Docile-Alligator/Infinity-For-Reddit" rel="noopener noreferrer"&gt;Infinity&lt;/a&gt; (reddit client)

&lt;ul&gt;
&lt;li&gt;If you use reddit a lot this app offers you the most seamless experience&lt;/li&gt;
&lt;li&gt;You can customize your feed with filters, themes and more to tailor your reading experience&lt;/li&gt;
&lt;li&gt;No ads!&lt;/li&gt;
&lt;li&gt;What I like most is the "Hide Read Posts" which allows you to easily check &lt;em&gt;new&lt;/em&gt; posts (no infinite scrolling anymore)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Devices
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.yubico.com/us/product/yubikey-5-nfc/" rel="noopener noreferrer"&gt;Yubikey 5 NFC&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While not software per se, this tool is central to my digital security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primary use as a smartcard for encryption/decryption and signing

&lt;ul&gt;
&lt;li&gt;Encrypt/Decrypt ORG mode files&lt;/li&gt;
&lt;li&gt;Sign git commits&lt;/li&gt;
&lt;li&gt;Store authentication keys (e.g. for SSH)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;GPG agent proxying capability

&lt;ul&gt;
&lt;li&gt;Access to emails on remote machines&lt;/li&gt;
&lt;li&gt;No need to copy GPG keys to remote systems&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Looking Back, Moving Forward
&lt;/h2&gt;

&lt;p&gt;The evolution in my approach to productivity and habits reflects a broader theme this year - finding balance between structure and flexibility. Moving away from rigid tracking towards more intuitive systems hasn't meant losing focus; rather, it has allowed these habits to naturally integrate into daily life.&lt;/p&gt;

&lt;p&gt;My musical journey with &lt;strong&gt;percussion&lt;/strong&gt; has added an entirely new dimension to my life, proving that growth doesn't always have to be technical or career-focused. The rhythm and joy of playing congas and bongos has become a welcome counterpoint to the digital world.&lt;/p&gt;

&lt;p&gt;Looking ahead to 2025, I'm excited about the possibilities that lie ahead - from deepening my &lt;a href="https://brainfck.org/t/kubernetes" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; knowledge to mastering new rhythms on the congas. But perhaps more importantly, I'm grateful for the community of people who have been part of this journey, sharing knowledge, experiences, and moments of joy along the way.&lt;/p&gt;

&lt;p&gt;As always, these reviews serve not just as personal milestones, but as reminders of how we grow through both the &lt;em&gt;challenges we face&lt;/em&gt; and the &lt;em&gt;opportunities we embrace&lt;/em&gt;. Here's to another year of learning, creating, and growing together.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>learning</category>
      <category>devops</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Mastering Golang Debugging in Emacs</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Fri, 29 Nov 2024 10:48:53 +0000</pubDate>
      <link>https://dev.to/dorneanu/mastering-golang-debugging-in-emacs-34p7</link>
      <guid>https://dev.to/dorneanu/mastering-golang-debugging-in-emacs-34p7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Since I've started developing in Golang I didn't really use the &lt;em&gt;debugger&lt;/em&gt;. Instead I was naively adding &lt;code&gt;fmt.Print&lt;/code&gt; statements everywhere to validate my code 🙈. While print statements and logs might be also your first debugging instinct, they often fall short when dealing with large and complex code base, with sophisticated runtime behaviour and (of course!) complex concurrency issues that seem impossible to reproduce.&lt;/p&gt;

&lt;p&gt;After starting working on more complex projects (like this one: &lt;a href="https://github.com/cloudoperators/heureka" rel="noopener noreferrer"&gt;https://github.com/cloudoperators/heureka&lt;/a&gt;) I had to force myself to have a deeper look at &lt;code&gt;delve&lt;/code&gt; (the Golang debugger) and see what Emacs offers for interacting with it. While the Go ecosystem offers excellent debugging tools, integrating them into a comfortable development workflow can be challenging.&lt;/p&gt;

&lt;p&gt;In this post I'll elaborate the powerful combination of &lt;a href="https://brainfck.org/t/Emacs" rel="noopener noreferrer"&gt;Emacs&lt;/a&gt;, &lt;a href="https://github.com/go-delve/delve" rel="noopener noreferrer"&gt;Delve&lt;/a&gt;, and &lt;a href="https://github.com/svaante/dape" rel="noopener noreferrer"&gt;dape&lt;/a&gt;. Together, these tools create a debugging experience that mimics (and often surpasses) traditional IDEs, while preserving the flexibility and extensibility that Emacs is famous for.&lt;/p&gt;

&lt;p&gt;This is what you can expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up and configure &lt;a href="https://github.com/go-delve/delve" rel="noopener noreferrer"&gt;Delve&lt;/a&gt; with &lt;a href="https://github.com/svaante/dape" rel="noopener noreferrer"&gt;dape&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Debug both standard applications and &lt;a href="https://github.com/onsi/ginkgo" rel="noopener noreferrer"&gt;Ginkgo&lt;/a&gt; tests (this is what I'm using at the moment 🤷)&lt;/li&gt;
&lt;li&gt;Optimize your debugging workflow with Emacs specific customizations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up the Development Environment
&lt;/h2&gt;

&lt;p&gt;In this post I assume you already have some Emacs experience and now how to configure packages and write small &lt;code&gt;Elisp&lt;/code&gt; snippets. I personally use &lt;a href="https://github.com/radian-software/straight.el" rel="noopener noreferrer"&gt;straight.el&lt;/a&gt; as a package manager, &lt;a href="https://github.com/jamescherti/minimal-emacs.d" rel="noopener noreferrer"&gt;minimal-emacs.d&lt;/a&gt; as a minimal vanilla Emacs configuration (along with my own &lt;a href="https://github.com/dorneanu/dotfiles/blob/master/minimal-emacs/config.org" rel="noopener noreferrer"&gt;custommizations)&lt;/a&gt;, &lt;a href="https://github.com/svaante/dape" rel="noopener noreferrer"&gt;dape&lt;/a&gt; as the debug adapter client and &lt;a href="https://github.com/joaotavora/eglot" rel="noopener noreferrer"&gt;eglot&lt;/a&gt; as my &lt;em&gt;LSP client&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Required Emacs Packages
&lt;/h3&gt;

&lt;p&gt;For Emacs 29+ users, &lt;code&gt;eglot&lt;/code&gt; is built-in. Check out &lt;a href="https://github.com/golang/tools/blob/master/gopls/doc/emacs.md#configuring-eglot" rel="noopener noreferrer"&gt;configuring eglot for gopls&lt;/a&gt; and some more advanced &lt;a href="https://github.com/golang/tools/blob/master/gopls/doc/settings.md" rel="noopener noreferrer"&gt;gopls settings&lt;/a&gt;. We'll first add &lt;code&gt;dape&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;dape&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:config&lt;/span&gt;
  &lt;span class="c1"&gt;;; Pulse source line (performance hit)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'dape-display-source-hook&lt;/span&gt; &lt;span class="ss"&gt;'pulse-momentary-highlight-one-line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;;; To not display info and/or buffers on startup&lt;/span&gt;
  &lt;span class="c1"&gt;;; (remove-hook 'dape-start-hook 'dape-info)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;remove-hook&lt;/span&gt; &lt;span class="ss"&gt;'dape-start-hook&lt;/span&gt; &lt;span class="ss"&gt;'dape-repl&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;go-mode&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-mode&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:mode&lt;/span&gt; &lt;span class="s"&gt;"\\.go\\'"&lt;/span&gt;
  &lt;span class="ss"&gt;:hook&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;before-save&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;gofmt-before-save&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="ss"&gt;:bind&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:map&lt;/span&gt; &lt;span class="nv"&gt;go-mode-map&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"M-?"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;godoc-at-point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"M-."&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;xref-find-definitions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"M-_"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;xref-find-references&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="c1"&gt;;; ("M-*" . pop-tag-mark) ;; Jump back after godef-jump&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c m r"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-run&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="ss"&gt;:custom&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;gofmt-command&lt;/span&gt; &lt;span class="s"&gt;"goimports"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installing Required Go Tools
&lt;/h3&gt;

&lt;p&gt;Install Delve and gopls, the LSP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Delve&lt;/span&gt;
go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/go-delve/delve/cmd/dlv@latest

&lt;span class="c"&gt;# Install gopls&lt;/span&gt;
go &lt;span class="nb"&gt;install &lt;/span&gt;golang.org/x/tools/gopls@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally I have a bunch of other tools which I use from time to time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/onsi/ginkgo/v2/ginkgo@latest

go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; golang.org/x/tools/cmd/godoc@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; golang.org/x/tools/cmd/goimports@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/stamblerre/gocode@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; golang.org/x/tools/cmd/gorename@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; golang.org/x/tools/cmd/guru@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/cweill/gotests/...@latest

go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/davidrjenni/reftools/cmd/fillstruct@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/fatih/gomodifytags@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/godoctor/godoctor@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/haya14busa/gopkgs/cmd/gopkgs@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/josharian/impl@latest
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/rogpeppe/godef@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you need to configure the corresponding Emacs packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;ginkgo&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="nv"&gt;git&lt;/span&gt; &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="nv"&gt;github&lt;/span&gt; &lt;span class="ss"&gt;:repo&lt;/span&gt; &lt;span class="s"&gt;"garslo/ginkgo-mode"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="ss"&gt;:init&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;ginkgo-use-pwd-as-test-dir&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
        &lt;span class="nv"&gt;ginkgo-use-default-keys&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;gotest&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:after&lt;/span&gt; &lt;span class="nv"&gt;go-mode&lt;/span&gt;
  &lt;span class="ss"&gt;:bind&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:map&lt;/span&gt; &lt;span class="nv"&gt;go-mode-map&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t f"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-test-current-file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t t"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-test-current-test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t j"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-test-current-project&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t b"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-test-current-benchmark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t c"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-test-current-coverage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t x"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-run&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-guru&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:hook&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-guru-hl-identifier-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-projectile&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:after&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;projectile&lt;/span&gt; &lt;span class="nv"&gt;go-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;flycheck-golangci-lint&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:hook&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;flycheck-golangci-lint-setup&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-eldoc&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:hook&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-eldoc-setup&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-tag&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
  &lt;span class="ss"&gt;:bind&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:map&lt;/span&gt; &lt;span class="nv"&gt;go-mode-map&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t a"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-tag-add&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C-c t r"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;go-tag-remove&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="ss"&gt;:init&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;go-tag-args&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="s"&gt;"-transform"&lt;/span&gt; &lt;span class="s"&gt;"camelcase"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-fill-struct&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-impl&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;go-playground&lt;/span&gt;
  &lt;span class="ss"&gt;:straight&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dape Configuration
&lt;/h3&gt;

&lt;p&gt;There is no particular reason why I use &lt;code&gt;dape&lt;/code&gt; instead of &lt;a href="https://github.com/emacs-lsp/dap-mode" rel="noopener noreferrer"&gt;dap&lt;/a&gt;. When I was still using &lt;a href="https://github.com/abougouffa/minemacs" rel="noopener noreferrer"&gt;MinEmacs&lt;/a&gt; it was part of it and I just got used to it. As the &lt;a href="https://github.com/svaante/dape?tab=readme-ov-file#differences-with-dap-mode" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Dape does not support launch.json files, if per project configuration is needed use dir-locals and dape-command.&lt;/li&gt;
&lt;li&gt;Dape enhances ergonomics within the minibuffer by allowing users to modify or add PLIST entries to an existing configuration using options.&lt;/li&gt;
&lt;li&gt;No magic, no special variables like ${workspaceFolder}. Instead, functions and variables are resolved before starting a new session.&lt;/li&gt;
&lt;li&gt;Tries to envision how debug adapter configurations would be implemented in Emacs if vscode never existed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you ever worked with VSCode you already know that it uses a &lt;code&gt;launch.json&lt;/code&gt; to store different debugging profiles:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Launch file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"go"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"auto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${file}"&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;You have different fields/properties which according to &lt;a href="https://github.com/microsoft/vscode-go/blob/master/docs/Debugging-Go-code-using-VS-Code.md" rel="noopener noreferrer"&gt;this page&lt;/a&gt; you can tweak in your debugging configuration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;name&lt;/td&gt;
&lt;td&gt;Name for your configuration that appears in the drop down in the Debug viewlet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;type&lt;/td&gt;
&lt;td&gt;Always set to "go". This is used by VS Code to figure out which extension should be used for debugging your code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;td&gt;Either of &lt;code&gt;launch&lt;/code&gt; or &lt;code&gt;attach&lt;/code&gt;. Use &lt;code&gt;attach&lt;/code&gt; when you want to attach to an already running process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mode&lt;/td&gt;
&lt;td&gt;For launch requests, either of &lt;code&gt;auto&lt;/code&gt;, &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;remote&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;. For attach requests, use either &lt;code&gt;local&lt;/code&gt; or &lt;code&gt;remote&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;program&lt;/td&gt;
&lt;td&gt;Absolute path to the package or file to debug when in &lt;code&gt;debug&lt;/code&gt; &amp;amp; &lt;code&gt;test&lt;/code&gt; mode, or to the pre-built binary file to debug in &lt;code&gt;exec&lt;/code&gt; mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;env&lt;/td&gt;
&lt;td&gt;Environment variables to use when debugging. Example: &lt;code&gt;{ "ENVNAME": "ENVVALUE" }&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;envFile&lt;/td&gt;
&lt;td&gt;Absolute path to a file containing environment variable definitions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;args&lt;/td&gt;
&lt;td&gt;Array of command line arguments that will be passed to the program being debugged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;showLog&lt;/td&gt;
&lt;td&gt;Boolean indicating if logs from delve should be printed in the debug console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;logOutput&lt;/td&gt;
&lt;td&gt;Comma separated list of delve components for debug output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;buildFlags&lt;/td&gt;
&lt;td&gt;Build flags to be passed to the Go compiler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;remotePath&lt;/td&gt;
&lt;td&gt;Absolute path to the file being debugged on the remote machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;processId&lt;/td&gt;
&lt;td&gt;ID of the process that needs debugging (for &lt;code&gt;attach&lt;/code&gt; request with &lt;code&gt;local&lt;/code&gt; mode)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Sample Application
&lt;/h2&gt;

&lt;p&gt;Now let's put our knowledge into practice by debugging a real application implementing a REST API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;Our example is a REST API for task management with the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;taskapi/
├── go.mod
├── go.sum
├── main.go
├── task_store.go
└── task_test.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Core Components
&lt;/h3&gt;

&lt;p&gt;Let's have a look at the &lt;strong&gt;core components&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Task&lt;/code&gt; represents our core domain model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;          &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"title"`&lt;/span&gt;
    &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"description"`&lt;/span&gt;
    &lt;span class="n"&gt;Done&lt;/span&gt;        &lt;span class="kt"&gt;bool&lt;/span&gt;   &lt;span class="s"&gt;`json:"done"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;TaskStore&lt;/code&gt; handles our in-memory data operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TaskStore&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tasks&lt;/span&gt;  &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;
    &lt;span class="n"&gt;nextID&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewTaskStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TaskStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;TaskStore&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;nextID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  REST API
&lt;/h4&gt;

&lt;p&gt;The API exposes following endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /task/create&lt;/code&gt; - Creates a new task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /task/get?id=&amp;lt;id&amp;gt;&lt;/code&gt; - Retrieves a task by ID
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// CreateTask stores a given Task internally&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TaskStore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;CreateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nextID&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nextID&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// GetTask retrieves a Task by ID&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TaskStore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"task with id %d not found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// UpdateTask updates task ID with a new Task object&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TaskStore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;UpdateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"task with id %d not found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Server
&lt;/h4&gt;

&lt;p&gt;Here's the server implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Server implements a web application for managing tasks&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TaskStore&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;handleCreateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodPost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Method not allowed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusMethodNotAllowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;createdTask&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;createdTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;handleGetTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodGet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Method not allowed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusMethodNotAllowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sscanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&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;Let's look at our &lt;code&gt;main&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;NewTaskStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/task/create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleCreateTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/task/get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleGetTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting server on :8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&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;
  
  
  Build application
&lt;/h3&gt;

&lt;p&gt;Let's start the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go build &lt;span class="nt"&gt;-o&lt;/span&gt; taskapi &lt;span class="k"&gt;*&lt;/span&gt;.go
./taskapi
2024/11/14 07:03:48 Starting server on :8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now from a different terminal &lt;strong&gt;create&lt;/strong&gt; a new task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8080/task/create &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"title":"Learn Debugging","description":"Master Emacs debugging with dape","done":false}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&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="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Learn Debugging"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Master Emacs debugging with dape"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"done"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see if we can fetch it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:8080/task/get?id=1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&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="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Learn Debugging"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Master Emacs debugging with dape"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"done"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unit tests
&lt;/h3&gt;

&lt;p&gt;Below are some unit tests (written in &lt;a href="https://pkg.go.dev/github.com/onsi/ginkgo" rel="noopener noreferrer"&gt;Ginkgo&lt;/a&gt;) for the &lt;code&gt;TaskStore&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bytes"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http/httptest"&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"github.com/onsi/ginkgo/v2"&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"github.com/onsi/gomega"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;RegisterFailHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;RunSpecs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Task API Suite"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;store&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TaskStore&lt;/span&gt;
        &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;BeforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NewTaskStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;Describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"POST /task/create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"when creating a new task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;It&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"should create and return a task with an ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;"Test Task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Test Description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HaveOccurred&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

                &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodPost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/task/create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

                &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleCreateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

                &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;
                &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HaveOccurred&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test Task"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;            &lt;span class="n"&gt;It&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"should handle invalid JSON payload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodPost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/task/create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBufferString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invalid json"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

                &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleCreateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&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="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;Describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET /task/get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"when fetching an existing task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;createdTask&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;

            &lt;span class="n"&gt;BeforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;"Test Task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Test Description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;createdTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;

            &lt;span class="n"&gt;It&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"should return the correct task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodGet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/task/get?id=1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

                &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleGetTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

                &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;
                &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HaveOccurred&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;createdTask&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="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"when fetching a non-existent task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;It&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"should return a 404 error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodGet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/task/get?id=999"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

                &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleGetTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&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="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"when using invalid task ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;It&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"should handle non-numeric ID gracefully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodGet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/task/get?id=invalid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

                &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleGetTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="n"&gt;Expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&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="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;In Emacs I would then call &lt;code&gt;ginkgo-run-this-container&lt;/code&gt; as shown in this screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-ginkgo.png"&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%2F8to9ynebg2f280aeqpi5.png" alt="image" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Debugging with Delve and Dape
&lt;/h2&gt;

&lt;p&gt;In order to debug our Task API we have following approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we can &lt;em&gt;launch&lt;/em&gt; the application directly and debug it&lt;/li&gt;
&lt;li&gt;we can &lt;em&gt;attach&lt;/em&gt; to a running process&lt;/li&gt;
&lt;li&gt;we can &lt;em&gt;attach&lt;/em&gt; to a running debugging session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the options for different request types:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;request&lt;/th&gt;
&lt;th&gt;mode&lt;/th&gt;
&lt;th&gt;required&lt;/th&gt;
&lt;th&gt;optional&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;launch&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;debug&lt;/td&gt;
&lt;td&gt;program&lt;/td&gt;
&lt;td&gt;dlvCwd, env, backend, args, cwd, buildFlags, output, noDebug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;test&lt;/td&gt;
&lt;td&gt;program&lt;/td&gt;
&lt;td&gt;dlvCwd, env, backend, args, cwd, buildFlags, output, noDebug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;exec&lt;/td&gt;
&lt;td&gt;program&lt;/td&gt;
&lt;td&gt;dlvCwd, env, backend, args, cwd, noDebug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;core&lt;/td&gt;
&lt;td&gt;program, corefilePath&lt;/td&gt;
&lt;td&gt;dlvCwd, env&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;replay&lt;/td&gt;
&lt;td&gt;traceDirPath&lt;/td&gt;
&lt;td&gt;dlvCwd, env&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;attach&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;local&lt;/td&gt;
&lt;td&gt;processId&lt;/td&gt;
&lt;td&gt;backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;remote&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Profile 1: Launch application
&lt;/h3&gt;

&lt;p&gt;Here's our first debugging profile for &lt;code&gt;.dir-locals.el&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Profile 1: Launch application and start DAP server&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-debug-taskapi&lt;/span&gt;
  &lt;span class="nv"&gt;modes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt; &lt;span class="nv"&gt;go-ts-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;command&lt;/span&gt; &lt;span class="s"&gt;"dlv"&lt;/span&gt;
  &lt;span class="nv"&gt;command-args&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dap"&lt;/span&gt; &lt;span class="s"&gt;"--listen"&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1:55878"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;command-cwd&lt;/span&gt; &lt;span class="nv"&gt;default-directory&lt;/span&gt;
  &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;
  &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;55878&lt;/span&gt;
  &lt;span class="ss"&gt;:request&lt;/span&gt; &lt;span class="s"&gt;"launch"&lt;/span&gt;
  &lt;span class="ss"&gt;:mode&lt;/span&gt; &lt;span class="s"&gt;"debug"&lt;/span&gt;
  &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="s"&gt;"go"&lt;/span&gt;
  &lt;span class="ss"&gt;:showLog&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="ss"&gt;:program&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 You may want to use a different value for &lt;code&gt;command-cwd&lt;/code&gt;. In my case I wanted to start the debugger in a directory which currently is not a project. &lt;code&gt;default-directory&lt;/code&gt; is a variable which holds the working directory for the current buffer you're currently in.&lt;/p&gt;

&lt;p&gt;Start debugging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;dape-info&lt;/code&gt; to show debugging information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-dape-info.png"&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%2F8t3qthvxztnfjgks4pwa.png" alt="image" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create breakpoint using &lt;code&gt;dape-breakpoint-toggle&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-dape-breakpoint.png"&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%2Fhphn01xmxuv6uztlr2dm.png" alt="image" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After starting the debugger with this profile, you should see in the &lt;code&gt;dape-repl&lt;/code&gt; buffer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Available Dape commands: debug, next, &lt;span class="k"&gt;continue&lt;/span&gt;, pause, step, out, up, down, restart, &lt;span class="nb"&gt;kill&lt;/span&gt;, disconnect, quit
Empty input will rerun last command.

DAP server listening at: 127.0.0.1:55878
debugserver-@&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="c"&gt;#)PROGRAM:LLDB  PROJECT:lldb-1600.0.36.3&lt;/span&gt;
 &lt;span class="k"&gt;for &lt;/span&gt;arm64.
Got a connection, launched process __debug_bin3666561508 &lt;span class="o"&gt;(&lt;/span&gt;pid &lt;span class="o"&gt;=&lt;/span&gt; 43984&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Type &lt;span class="s1"&gt;'dlv help'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;list of commands.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we didn't specify any binary/file to debug (we had &lt;code&gt;:program "."&lt;/code&gt; in &lt;code&gt;.dir-locals.el&lt;/code&gt;). &lt;code&gt;delve&lt;/code&gt; will automatically &lt;em&gt;build&lt;/em&gt; the binary before it launches the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go build &lt;span class="nt"&gt;-gcflags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;all&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-N -l"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Profile 2: Attach to an external debugger
&lt;/h3&gt;

&lt;p&gt;Let's add a profile for connecting to an existing debugging session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Profile 2: Attach to external debugger&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-attach-taskapi&lt;/span&gt;
 &lt;span class="nv"&gt;modes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt; &lt;span class="nv"&gt;go-ts-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nv"&gt;command&lt;/span&gt; &lt;span class="s"&gt;"dlv"&lt;/span&gt;
 &lt;span class="nv"&gt;command-cwd&lt;/span&gt; &lt;span class="nv"&gt;default-directory&lt;/span&gt;
 &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;   &lt;span class="c1"&gt;;; can also be skipped&lt;/span&gt;
 &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;55878&lt;/span&gt;
 &lt;span class="ss"&gt;:request&lt;/span&gt; &lt;span class="s"&gt;"attach"&lt;/span&gt;  &lt;span class="c1"&gt;;; this will run "dlv attach ..."&lt;/span&gt;
 &lt;span class="ss"&gt;:mode&lt;/span&gt; &lt;span class="s"&gt;"remote"&lt;/span&gt;     &lt;span class="c1"&gt;;; connect to a running debugger session&lt;/span&gt;
 &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="s"&gt;"go"&lt;/span&gt;
 &lt;span class="ss"&gt;:showLog&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's start the &lt;strong&gt;debugger&lt;/strong&gt; on the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;go build &lt;span class="nt"&gt;-gcflags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;all&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-N -l"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; taskapi &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;dlv debug taskapi &lt;span class="nt"&gt;--listen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;localhost:55878 &lt;span class="nt"&gt;--headless&lt;/span&gt;
API server listening at: 127.0.0.1:55878
debugserver-@&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="c"&gt;#)PROGRAM:LLDB  PROJECT:lldb-1600.0.36.3&lt;/span&gt;
 &lt;span class="k"&gt;for &lt;/span&gt;arm64.
Got a connection, launched process __debug_bin794004190 &lt;span class="o"&gt;(&lt;/span&gt;pid &lt;span class="o"&gt;=&lt;/span&gt; 23979&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now within Emacs you can launch &lt;code&gt;dape&lt;/code&gt; and select the &lt;code&gt;go-attach-taskapi&lt;/code&gt; profile:&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-attach-to-external-debugger.png"&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%2F02zcuy441x69m1bl100t.png" alt="image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Profile 3: Attach to a running process
&lt;/h3&gt;

&lt;p&gt;In this scenario the application is &lt;em&gt;already&lt;/em&gt; running but you want to &lt;em&gt;attach&lt;/em&gt; the debugger to it. First launch the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./taskapi
2024/11/20 06:34:29 Starting server on :8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find out its process ID (PID):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-A&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-m1&lt;/span&gt; taskapi | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add another debug profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Profile 3: Attach to running process (by PID)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-attach-pid&lt;/span&gt;
 &lt;span class="nv"&gt;modes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt; &lt;span class="nv"&gt;go-ts-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nv"&gt;command&lt;/span&gt; &lt;span class="s"&gt;"dlv"&lt;/span&gt;
 &lt;span class="nv"&gt;command-args&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dap"&lt;/span&gt; &lt;span class="s"&gt;"--listen"&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1:55878"&lt;/span&gt; &lt;span class="s"&gt;"--log"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nv"&gt;command-cwd&lt;/span&gt; &lt;span class="nv"&gt;default-directory&lt;/span&gt;
 &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;
 &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;55878&lt;/span&gt;
 &lt;span class="ss"&gt;:request&lt;/span&gt; &lt;span class="s"&gt;"attach"&lt;/span&gt;
 &lt;span class="ss"&gt;:mode&lt;/span&gt; &lt;span class="s"&gt;"local"&lt;/span&gt;      &lt;span class="c1"&gt;;; Attach to a running process local to the server&lt;/span&gt;
 &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="s"&gt;"go"&lt;/span&gt;
 &lt;span class="ss"&gt;:processId&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;+get-process-id-by-name&lt;/span&gt; &lt;span class="s"&gt;"taskapi"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="ss"&gt;:showLog&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll need a helper function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Add helpful function&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;progn&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;+get-process-id-by-name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;process-name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="s"&gt;"Return the process ID of a process specified by PROCESS-NAME. Works on Unix-like systems (Linux, MacOS)."&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;pid&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cond&lt;/span&gt;
               &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;memq&lt;/span&gt; &lt;span class="nv"&gt;system-type&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;gnu/linux&lt;/span&gt; &lt;span class="nv"&gt;darwin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;pid&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command-to-string&lt;/span&gt;
                           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"pgrep -f %s"&lt;/span&gt;
                                   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-quote-argument&lt;/span&gt; &lt;span class="nv"&gt;process-name&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="s"&gt;"Unsupported system type: %s"&lt;/span&gt; &lt;span class="nv"&gt;system-type&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

              &lt;span class="c1"&gt;;; Clean up the output and return first PID&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;and&lt;/span&gt; &lt;span class="nv"&gt;pid&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;string-empty-p&lt;/span&gt; &lt;span class="nv"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;split-string&lt;/span&gt; &lt;span class="nv"&gt;pid&lt;/span&gt; &lt;span class="s"&gt;"\n"&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)))))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-attach-running-process-breakpoint.png"&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%2Ffth5jg5jlh75gc3227g0.png" alt="image" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I start the debugger:&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-attach-running-process-pid.png"&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%2Fekhq36t5rtb34v8vihrc.png" alt="image" width="800" height="28"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I now send a POST request like this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8080/task/create &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"title":"Learn Debugging","description":"Master Emacs debugging with dape","done":false}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The debugger should automatically halt at the set breakpoint:&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-attach-running-process-debugging.png"&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%2Fvwgkzd7wmjp1shk9qj3m.png" alt="image" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Ginkgo Tests
&lt;/h2&gt;

&lt;p&gt;Being able to debug tests in Golang is crucial. For running ginkgo tests I use &lt;a href="https://github.com/garslo/ginkgo-mode" rel="noopener noreferrer"&gt;ginkgo-mode&lt;/a&gt; which has several features:&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-ginkgo-mode-options.png"&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%2F32f20xl96wscdc49i64b.png" alt="image" width="800" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-ginkgo-focus-on-container.png"&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%2F71utbn34n46kxejo0v64.png" alt="image" width="800" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And as an output I get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Running Suite: Task API Suite - /home/victor/repos/priv/blog/static/code/2024/emacs-golang-debugging
&lt;span class="o"&gt;======================================================================================================&lt;/span&gt;
Random Seed: 1732600680

Will run 1 of 5 specs
•SSSS

Ran 1 of 5 Specs &lt;span class="k"&gt;in &lt;/span&gt;0.001 seconds
SUCCESS! &lt;span class="nt"&gt;--&lt;/span&gt; 1 Passed | 0 Failed | 0 Pending | 4 Skipped
PASS

Ginkgo ran 1 suite &lt;span class="k"&gt;in &lt;/span&gt;1.481440083s
Test Suite Passed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dape Configuration for Ginkgo
&lt;/h3&gt;

&lt;p&gt;This is the basic configuration for debugging Ginkgo tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Profile 4: Debug Ginkgo tests&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-test-ginkgo&lt;/span&gt;
 &lt;span class="nv"&gt;modes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt; &lt;span class="nv"&gt;go-ts-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nv"&gt;command&lt;/span&gt; &lt;span class="s"&gt;"dlv"&lt;/span&gt;
 &lt;span class="nv"&gt;command-args&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dap"&lt;/span&gt; &lt;span class="s"&gt;"--listen"&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1:55878"&lt;/span&gt; &lt;span class="s"&gt;"--log"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nv"&gt;command-cwd&lt;/span&gt; &lt;span class="nv"&gt;default-directory&lt;/span&gt;
 &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;
 &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;55878&lt;/span&gt;
 &lt;span class="ss"&gt;:request&lt;/span&gt; &lt;span class="s"&gt;"launch"&lt;/span&gt;
 &lt;span class="ss"&gt;:mode&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt;      &lt;span class="c1"&gt;;; Debug tests&lt;/span&gt;
 &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="s"&gt;"go"&lt;/span&gt;
 &lt;span class="ss"&gt;:args&lt;/span&gt; &lt;span class="nv"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"-ginkgo.v"&lt;/span&gt; &lt;span class="s"&gt;"-ginkgo.focus"&lt;/span&gt; &lt;span class="s"&gt;"should create and return a task with an ID"&lt;/span&gt;&lt;span class="nv"&gt;]&lt;/span&gt;
 &lt;span class="ss"&gt;:program&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I chose the &lt;code&gt;go-test-ginkgo&lt;/code&gt; debug profile I should be able to debug the tests:&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-debug-ginkgo-call-function.png"&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%2Fyiazzb7a0pn56loqd4c9.png" alt="image" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the configuration is quite static and therefore you cannot preselect the unit test / container. We need to somehow make the parameter &lt;code&gt;-ginkgo.focus&lt;/code&gt; dynamic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;my/dape-debug-ginkgo-focus&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;focus-string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;"Start debugging Ginkgo tests with a specific focus string."&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;interactive&lt;/span&gt; &lt;span class="s"&gt;"sEnter focus string: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-local-variable&lt;/span&gt; &lt;span class="ss"&gt;'dape-configs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;; Make buffer-local copy of dape-configs&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;dape-configs&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;
         &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;debug-focused-test&lt;/span&gt;
           &lt;span class="nv"&gt;modes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="nv"&gt;command&lt;/span&gt; &lt;span class="s"&gt;"dlv"&lt;/span&gt;
           &lt;span class="nv"&gt;command-args&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dap"&lt;/span&gt; &lt;span class="s"&gt;"--listen"&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1:55878"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="nv"&gt;command-cwd&lt;/span&gt; &lt;span class="nv"&gt;default-directory&lt;/span&gt;
           &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;55878&lt;/span&gt;
           &lt;span class="ss"&gt;:request&lt;/span&gt; &lt;span class="s"&gt;"launch"&lt;/span&gt;
           &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="s"&gt;"Debug Focused Test"&lt;/span&gt;
           &lt;span class="ss"&gt;:mode&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt;
           &lt;span class="ss"&gt;:program&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt;
           &lt;span class="ss"&gt;:args&lt;/span&gt; &lt;span class="nv"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"-ginkgo.v"&lt;/span&gt; &lt;span class="s"&gt;"-ginkgo.focus"&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;focus-string]&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="/posts/img/2024/emacs-golang-debugging/emacs-debug-ginkgo-set-focus-string.png"&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%2Fm93djdzychl34fqcc61s.png" alt="image" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Afterwards If I have a look at the &lt;code&gt;dape-configs&lt;/code&gt; variable I should see this value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="nv"&gt;Value:&lt;/span&gt;
&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;debug-focused-test&lt;/span&gt; &lt;span class="nv"&gt;modes&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="nv"&gt;command&lt;/span&gt; &lt;span class="s"&gt;"dlv"&lt;/span&gt; &lt;span class="nv"&gt;command-args&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dap"&lt;/span&gt; &lt;span class="s"&gt;"--listen"&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1:55878"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="nv"&gt;command-cwd&lt;/span&gt; &lt;span class="nv"&gt;default-directory&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;55878&lt;/span&gt; &lt;span class="ss"&gt;:request&lt;/span&gt; &lt;span class="s"&gt;"launch"&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="s"&gt;"Debug Focused Test"&lt;/span&gt; &lt;span class="ss"&gt;:mode&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt; &lt;span class="ss"&gt;:program&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt; &lt;span class="ss"&gt;:args&lt;/span&gt;
                     &lt;span class="nv"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"-ginkgo.v"&lt;/span&gt; &lt;span class="s"&gt;"-ginkgo.focus"&lt;/span&gt; &lt;span class="s"&gt;"when using invalid*"&lt;/span&gt;&lt;span class="nv"&gt;]&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After starting the debugger (with the &lt;code&gt;debug-focused-test&lt;/code&gt; profile) in the dape-repl buffer I get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Welcome to Dape REPL!
Available Dape commands: debug, next, &lt;span class="k"&gt;continue&lt;/span&gt;, pause, step, out, up, down, restart, &lt;span class="nb"&gt;kill&lt;/span&gt;, disconnect, quit
Empty input will rerun last command.

DAP server listening at: 127.0.0.1:55878
debugserver-@&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="c"&gt;#)PROGRAM:LLDB  PROJECT:lldb-1600.0.39.3&lt;/span&gt;
 &lt;span class="k"&gt;for &lt;/span&gt;arm64.
Got a connection, launched process /home/victor/repos/priv/blog/static/code/2024/emacs-golang-debugging/__debug_bin2799839715 &lt;span class="o"&gt;(&lt;/span&gt;pid &lt;span class="o"&gt;=&lt;/span&gt; 31882&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Type &lt;span class="s1"&gt;'dlv help'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;list of commands.
Running Suite: Task API Suite - /home/victor/repos/priv/blog/static/code/2024/emacs-golang-debugging
&lt;span class="o"&gt;======================================================================================================&lt;/span&gt;
Random Seed: 1732685749

❶ Will run 1 of 5 specs
SSSS
&lt;span class="nt"&gt;------------------------------&lt;/span&gt;
❷ Task API GET /task/get when using invalid task ID should handle non-numeric ID gracefully
/home/victor/repos/priv/blog/static/code/2024/emacs-golang-debugging/task_store_test.go:108
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡Notice that just "1 of 5 specs" (❶) were ran, meaning that &lt;code&gt;ginkgo&lt;/code&gt; only focussed on the container we have specified (❷).&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices and Tips
&lt;/h2&gt;

&lt;p&gt;Throughout my debugging experience, I have come to appreciate several best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;version control&lt;/strong&gt; for debugging configurations&lt;/li&gt;
&lt;li&gt;Maintain debug configurations in &lt;code&gt;.dir-locals.el&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;meaningful names&lt;/strong&gt; for configurations&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;project-specific&lt;/strong&gt; debugging &lt;strong&gt;helper functions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Make &lt;strong&gt;customizations locally&lt;/strong&gt; (buffer-specific)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources and References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/vscode-go/blob/master/docs/debugging.md" rel="noopener noreferrer"&gt;vscode-go/docs/debugging.md at master · golang/vscode-go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/emacs-lsp/dap-mode/issues/318" rel="noopener noreferrer"&gt;support delve/dlv dap-mode directly · Issue #318 · emacs-lsp/dap-mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/svaante/dape" rel="noopener noreferrer"&gt;Dape GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/go-delve/delve" rel="noopener noreferrer"&gt;Delve Debugger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/joaotavora/eglot" rel="noopener noreferrer"&gt;Eglot Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://onsi.github.io/ginkgo/" rel="noopener noreferrer"&gt;Ginkgo Testing Framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hugo</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>go</category>
    </item>
    <item>
      <title>Book summaries: May - September 2024</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Wed, 16 Oct 2024 04:59:29 +0000</pubDate>
      <link>https://dev.to/dorneanu/book-summaries-may-september-2024-14km</link>
      <guid>https://dev.to/dorneanu/book-summaries-may-september-2024-14km</guid>
      <description>&lt;p&gt;Keeping with the theme I’ve started a few months ago, here are my own book summaries for the books I’ve read between &lt;em&gt;May&lt;/em&gt; and &lt;em&gt;September&lt;/em&gt; this year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Social Sciences and Psychology
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 Lost Connections
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/34921573-lost-connections" rel="noopener noreferrer"&gt;Lost Connections - Uncovering the Real Causes of Depression and the Unexpected Solutions by Johann Hari&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After reading &lt;a href="https://brainfck.org/book/the-lonely-century" rel="noopener noreferrer"&gt;The Lonely Century&lt;/a&gt; last year, which opened my eyes to the increasing &lt;em&gt;isolation&lt;/em&gt; in our lives, I was kind of motivated to read more on that topic. That’s how I’ve found out about &lt;a href="https://brainfck.org/book/lost-connections" rel="noopener noreferrer"&gt;Lost Connections&lt;/a&gt; which is an exploration of _depression_and its root causes.&lt;/p&gt;

&lt;p&gt;The book introduces the concept of “&lt;em&gt;disconnection&lt;/em&gt;” as a primary cause of depression. Hari outlines seven types of disconnection. He talks about disconnection from &lt;em&gt;meaningful work&lt;/em&gt;,&lt;em&gt;other people&lt;/em&gt;, &lt;em&gt;meaningful values&lt;/em&gt;, &lt;em&gt;childhood trauma&lt;/em&gt;, &lt;em&gt;status and respect&lt;/em&gt;, the &lt;em&gt;natural world_and from a _hopeful or secure future&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What I found particularly insightful was Hari’s exploration of ways to “&lt;em&gt;reconnect&lt;/em&gt;.” These strategies offer paths to a more meaningful and enjoyable life, emphasizing our connections to others and reminding us that “&lt;em&gt;humans are nature&lt;/em&gt;” already. This perspective adds a new dimension to my understanding of focus and attention, placing them within a broader context of human well-being and social connection.&lt;/p&gt;

&lt;p&gt;👉 Read my &lt;a href="https://brainfck.org/book/lost-connections" rel="noopener noreferrer"&gt;notes&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Stolen Focus
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/57933306-stolen-focus" rel="noopener noreferrer"&gt;Stolen Focus - Why You Can’t Pay Attention - and How to Think Deeply Again by Johann Hari&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the impactful experience of reading &lt;a href="https://brainfck.org/book/lost-connections" rel="noopener noreferrer"&gt;Lost Connections&lt;/a&gt; I felt compelled to delve into another of Hari’s works. While “Lost Connections” explored &lt;em&gt;depression&lt;/em&gt; and our daily &lt;em&gt;micro-interactions&lt;/em&gt; with people and nature, “ &lt;strong&gt;Stolen Focus&lt;/strong&gt; ” takes a more scientific, empirical approach to investigating various aspects of &lt;em&gt;attention&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One concept that immediately struck me was &lt;strong&gt;James Willson&lt;/strong&gt; ’s layered &lt;em&gt;model of attention&lt;/em&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Spotlight&lt;/strong&gt; attention (first layer):&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Starlight&lt;/strong&gt; attention (second layer):&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Daylight&lt;/strong&gt; attention (third layer):&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As I continued reading, I was amazed by Hari’s comprehensive approach to the &lt;strong&gt;attention crisis&lt;/strong&gt;. He doesn’t just point to the usual suspects like increasing &lt;em&gt;screen time&lt;/em&gt; and &lt;em&gt;social media usage&lt;/em&gt;. Instead, he adds a more nuanced picture of our changing relationship with information and mental states. Therefore here are some aspects which lead to the deterioration of our ability to focus and pay attention:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The decline of book reading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The loss of mind-wandering&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The state of constant skimming&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These insights have made me reconsider not just how I manage my attention, but how I conceptualize it. It’s clear that reclaiming our focus isn’t just about reducing screen time or blocking distractions – it’s about fundamentally restructuring how we engage with information and allow our minds to work.&lt;/p&gt;

&lt;p&gt;👉 Read my &lt;a href="https://brainfck.org/book/stolen-focus" rel="noopener noreferrer"&gt;notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  History and Anthropology
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 Sapiens
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/23692271-sapiens" rel="noopener noreferrer"&gt;Sapiens - A Brief History of Humankind by Yuval Noah Harari&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After becoming a Harari fan through “21 Lessons for the 21st Century” I was eager to dive into “ &lt;strong&gt;Sapiens&lt;/strong&gt; ”. I consumed both books as audiobooks, each one quite long. While the audio format was convenient, I found myself wishing for a physical or e-book copy to take notes. The depth and breadth of Harari’s books make me think I’ll likely revisit these books in the future for a more in-depth study.&lt;/p&gt;

&lt;p&gt;In a nutshell “Sapiens” is about how &lt;strong&gt;Homo sapiens&lt;/strong&gt; came to dominate the planet. Harari talks about the story of our species’ rise, from &lt;em&gt;outcompeting other human species&lt;/em&gt; (like Neanderthals) to our impact on the animal kingdom, including the &lt;em&gt;extinction of many species&lt;/em&gt; through hunting. This narrative is a very interesting look at our species' historical impact on the planet.&lt;/p&gt;

&lt;p&gt;Despite some criticism (I’ve had some serious discussions with my mother, who strongly dislikes Harari), I believe the author does an excellent job explaining the &lt;em&gt;evolution of fundamental human developments&lt;/em&gt; like writing and reading. He delves into the motivations behind these advancements, providing insights into why and how they occurred.&lt;/p&gt;

&lt;p&gt;What I particularly appreciate about “Sapiens” is its &lt;em&gt;interdisciplinary approach&lt;/em&gt; (I guess this applies to all of his books). Harari touches on various aspects of human development, including &lt;em&gt;religion&lt;/em&gt;, &lt;em&gt;economy&lt;/em&gt;, &lt;em&gt;sociology&lt;/em&gt;, and &lt;em&gt;politics&lt;/em&gt;. This comprehensive view offers readers a deeper understanding of the society we currently live in, explaining the origins of our laws and different political systems.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;key takeaway&lt;/em&gt; from the book, which resonates with thoughts I’ve encountered in other sources, is Harari’s explanation of what distinguishes Homo sapiens from other species:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Our ability to &lt;em&gt;collaborate collectively&lt;/em&gt; towards a common goal.&lt;/li&gt;
&lt;li&gt;Our capacity for abstract thought and &lt;em&gt;storytelling&lt;/em&gt;, which has been the foundation for countless innovations. As Harari points out, everything ever built started as someone’s imagination - an idea also explored by Sir Ken Robinson in “Imagine If”&lt;/li&gt;
&lt;li&gt;The development of &lt;em&gt;language&lt;/em&gt; (both written and spoken), which allowed us to exchange information (across borders and generations).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These unique aspects have allowed our species to create &lt;em&gt;complex societies&lt;/em&gt;, develop_advanced technologies_, and ultimately shape the world as we know it today. I highly recommend “Sapiens” to anyone interested in gaining a deeper understanding of &lt;em&gt;human history&lt;/em&gt;. While it may challenge some preconceptions, it offers a thought-provoking journey through the history of our species that I found both enlightening and engaging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sociology and Current Affairs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 Triggerpunkte (Trigger Points)
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/199211943-triggerpunkte" rel="noopener noreferrer"&gt;Triggerpunkte - Konsens und Konflikt in der Gegenwartsgesellschaft&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the context of Europe’s (and beyond) current political landscape, marked by a noticeable &lt;em&gt;right-wing shift&lt;/em&gt;, “ &lt;strong&gt;Triggerpunkte&lt;/strong&gt; ” offers a insightful analysis of_societal tensions_ in Germany. As someone who doesn’t consider himself politically active, I found myself increasingly concerned about the polarized and extreme nature of political discourse in Germany. The rise of the &lt;em&gt;AfD&lt;/em&gt; to a level of influence that seemed unthinkable just a few years ago exemplifies this shift.&lt;/p&gt;

&lt;p&gt;“Triggerpunkte” presents the findings of a team of sociologists (Steffen Mau, Thomas Lux, Linus Westheuser) who conducted &lt;em&gt;empirical research&lt;/em&gt; across Germany. What struck me about their approach was the diversity of their&lt;a href="https://brainfck.org/book/triggerpunkte/#klassenschema-nach-daniel-oesch" rel="noopener noreferrer"&gt;subject groups&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Participants came from various “&lt;em&gt;political classes&lt;/em&gt;”&lt;/li&gt;
&lt;li&gt;They represented &lt;em&gt;different professions&lt;/em&gt; (teachers, handymen, business people, etc.)&lt;/li&gt;
&lt;li&gt;The study included people from both &lt;em&gt;East and West Germany&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The researchers posed questions on controversed issues such as &lt;em&gt;immigration&lt;/em&gt;,&lt;em&gt;climate change&lt;/em&gt;, &lt;em&gt;LGBTQ+ inclusion&lt;/em&gt;, and &lt;em&gt;income inequality&lt;/em&gt; in Germany. By measuring emotional responses, they identified topics with &lt;em&gt;high conflict potential&lt;/em&gt; across different groups. They also explored &lt;em&gt;correlations&lt;/em&gt; between people’s arguments and factors like educational background, political affiliation, income, age, and origin.&lt;/p&gt;

&lt;p&gt;This book had a profound impact on me. It helped me understand the frustrations many people have with the current German government, their fears about the_impact_ of &lt;em&gt;climate change&lt;/em&gt; countermeasures, and why some perceive immigrants as a significant threat. These insights are crucial for anyone trying to comprehend the current political dynamics in Germany.&lt;/p&gt;

&lt;p&gt;One of the most reassuring&lt;a href="https://brainfck.org/book/triggerpunkte/#politisierung-und-konflikt-in-der-gegenwartsgesellschaft" rel="noopener noreferrer"&gt;findings&lt;/a&gt;from the study, in my opinion, was that overall, German society maintains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A positive stance towards welcoming immigration policies&lt;/li&gt;
&lt;li&gt;Support for better climate protection&lt;/li&gt;
&lt;li&gt;A generally non-homophobic attitude&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, the study also revealed a &lt;em&gt;small group of individuals&lt;/em&gt;(&lt;a href="https://brainfck.org/book/https://brainfck.org/book/triggerpunkte/#polarisierungsunternehmer" rel="noopener noreferrer"&gt;Polarisierungsunternehmer&lt;/a&gt;), some with political interests, propagate extreme arguments. These actors attempt to influence mass media perception through &lt;em&gt;fake news&lt;/em&gt; and &lt;em&gt;whataboutism&lt;/em&gt;, aiming to create more &lt;em&gt;cleavages&lt;/em&gt; within the society. The authors’ discussion of these&lt;a href="https://brainfck.org/book/triggerpunkte/#cleavages" rel="noopener noreferrer"&gt;cleavages&lt;/a&gt; was particularly enlightening.&lt;/p&gt;

&lt;p&gt;Reading “Triggerpunkte” has given me a more nuanced understanding of the complex social and political landscape in contemporary Germany. It’s a crucial read for anyone seeking to understand the underlying factors driving current political trends, not just in Germany but potentially in other countries facing similar challenges.&lt;/p&gt;

&lt;p&gt;👉 Read my &lt;a href="https://brainfck.org/book/triggerpunkte" rel="noopener noreferrer"&gt;notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Health and Psychology
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📚 When the Body Says No
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://www.goodreads.com/book/show/450534.When_the_Body_Says_No" rel="noopener noreferrer"&gt;When the Body Says No: The Cost of Hidden Stress (by Gabor Mate)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My journey to Gabor Maté’s work began with an interview I stumbled upon between Maté and Guy Rose, host of “&lt;a href="https://londonreal.tv/" rel="noopener noreferrer"&gt;London Real&lt;/a&gt;”. I was immediately captivated by Maté’s clear and profound explanations on various aspects of &lt;em&gt;trauma&lt;/em&gt;, which prompted me to delve into his book, “When the Body Says No”.&lt;/p&gt;

&lt;p&gt;At the core of Maté’s argument is the &lt;em&gt;inseparability&lt;/em&gt; of &lt;em&gt;body&lt;/em&gt;, &lt;em&gt;soul&lt;/em&gt;, and &lt;em&gt;mind&lt;/em&gt; - a holistic view that challenges conventional medical approaches. Throughout the book, Maté presents case studies from his medical practice, illustrating how physical pains often have roots in (childhood) trauma that manifest as chronic stress within patients.&lt;/p&gt;

&lt;p&gt;One of the most enlightening aspects of the book is Maté’s exploration of_stress_, drawing on the work of &lt;a href="https://www.goodreads.com/author/list/338094.Hans_Selye" rel="noopener noreferrer"&gt;Hans Selye&lt;/a&gt;. Maté uses Selye’s definition to provide a comprehensive understanding of stress and its various facets:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In searching for a word to capture the meaning of the physical changes he observed in his experiments, Selye “stumbled upon the term stress, which had long been used in common English, and particularly in engineering, to denote the effects of a force acting against a resistance.” He gives the example of changes induced in a stretched rubber band or in a steel spring under pressure. These changes may be noted with the naked eye or may be evident only on microscopic examination.&lt;/p&gt;

&lt;p&gt;Selye’s analogies illustrate an important point: excessive stress occurs when the demands made on an organism exceed that organism’s reasonable capacities to fulfill them. The rubber band snaps, the spring becomes deformed. The stress response can be set off by physical damage, either by infection or injury. It can also be triggered by emotional trauma or just by the threat of such trauma, even if purely imaginary. Physiological stress responses can be evoked when the threat is outside conscious awareness or even when the individual may believe himself to be stressed in a “good” way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This definition of stress provides a crucial framework for understanding how &lt;strong&gt;emotional and psychological experiences can manifest in physical symptoms&lt;/strong&gt;. It underscores Maté’s central thesis that our mental and emotional states have profound impacts on our physical health.&lt;/p&gt;

&lt;p&gt;Maté’s work challenges us to consider the long-term health implications of our emotional experiences and the importance of addressing psychological well-being as a key component of overall health.&lt;/p&gt;

</description>
      <category>books</category>
      <category>reading</category>
    </item>
    <item>
      <title>Bye Bye Cashlink!</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Thu, 11 Jul 2024 07:12:32 +0000</pubDate>
      <link>https://dev.to/dorneanu/bye-bye-cashlink-mm8</link>
      <guid>https://dev.to/dorneanu/bye-bye-cashlink-mm8</guid>
      <description>&lt;p&gt;In the midst of the Corona pandemic back in 2021, I joined the team at &lt;a href="https://cashlink.de/en/" rel="noopener noreferrer"&gt;Cashlink&lt;/a&gt;, a company focused on &lt;strong&gt;tokenization&lt;/strong&gt; and &lt;strong&gt;digital securities&lt;/strong&gt;. With little understanding of these concepts, I embarked on this new journey as a &lt;em&gt;Senior Security Engineer&lt;/em&gt; within the TECH team. Promised a &lt;em&gt;greenfield&lt;/em&gt; environment, I stepped into the unknown, excited yet uncertain about what I was expected to to.&lt;/p&gt;

&lt;p&gt;&lt;a href="/posts/img/2024/bye-bye-cashlink/laptop.png"&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%2Fe657k3osxx7zyo8llv63.png" alt="image" width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I look back on almost three years of knowledge sharing at Cashlink, I realize just how much I’ve learned. Embracing one of Cashlink’s core values, I consistently strived to &lt;em&gt;challenge the status quo&lt;/em&gt;. Throughout this journey, I’ve gained a deep understanding of what DevSecOps truly is about, with a particular focus on the &lt;em&gt;operational side&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Having said this, I’m looking forward to my newest challenge, where I’ll switch focus to the &lt;em&gt;Dev&lt;/em&gt; part in DevSecOps and delve deeper into &lt;em&gt;software engineering&lt;/em&gt;, but still within the Security context. I also anticipate doing more coding, particularly in &lt;em&gt;Golang&lt;/em&gt;, which kind of makes me happy. I remain grateful for all that I’ve experienced and learned at Cashlink and hope to see you all soon again, whether in Frankfurt, Cluj, or Berlin!&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’ve learned
&lt;/h2&gt;

&lt;p&gt;As I was implementing security in the greenfield area, I had the chance to strengthen my knowledge in specific areas but also deep-dive into new ones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IAM&lt;/strong&gt; (as a &lt;em&gt;concept&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;K8s&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smart Contract Security&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Shoutout to
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cashlink Team&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A 💗 thanks to everyone I had the opportunity to meet, for all the conversations we shared, and the lively kicker sessions we enjoyed in Frankfurt. Last but not least, thank you for welcoming me in Cluj, where I had the chance to say “goodbye” in person to (almost) all of you!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Verena&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Thank you for your kindness and patience in just listening and guiding me through some difficult times in my life. See you soon in Berlin!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Dragos&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You might not be able to read this as you’re on your trip on the &lt;a href="https://www.viatransilvanica.com/en/" rel="noopener noreferrer"&gt;Via Transilvanica&lt;/a&gt;. I hope you’ll finish your tour and come back full of energy. Also thanks for our coffee sessions, our discussions and sometimes for some good advice whenever something didn’t go smooth. Let’s do that 🏰 thing again, once we turn 50! 🤎&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Mariano&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You were right! Our first discussion back in Frankfurt was about working in &lt;em&gt;full-remote&lt;/em&gt; and the fact I still need a community / colleagues around me. You remembered that when we met in Cluj this year! I really enjoyed our discussoin around &lt;em&gt;nutrition&lt;/em&gt;, &lt;em&gt;sports&lt;/em&gt; and life in general. Take care and see you end of August 😋&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Aron&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Thanks for your patience and for the fact you were the one to teach me K8s! Let’s keep in touch and conquer the world with Golang, Terraform and Kubernetes. I also wish you all the best with your climbing career 🧗&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Maik&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Let’s go to &lt;em&gt;Aventura&lt;/em&gt;, right? I guess we both won’t forget that evening. I wish you all the best becoming a 🇧🇬 and let’s do the &lt;em&gt;Moldova trip&lt;/em&gt; soon again.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Anca&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;I admire you for your discipline and perseverance! I hope to see you someday at the Olympics 🏃&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;George&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;“Who’s Rosa?” 🤣 I really enjoyed our discussion lately in Cluj! I hope you’ll find your place and get rich soon 😎&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Rafael&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;I’m glad I’ve convinced you to buy a &lt;a href="https://www.lapavoni.com/en/families/domestic-machines/lever-coffee-machines" rel="noopener noreferrer"&gt;La Pavoni&lt;/a&gt;. You definitely have reached nerd level 500 with all the &lt;a href="https://coffee-sensor.com/product-category/la-pavoni-parts-and-accessories-custom-made-from-coffee-sensor/" rel="noopener noreferrer"&gt;mods and customizations&lt;/a&gt; 😎. I’m still looking forward meeting your home roaster.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Yubikey Gang&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Without mentioning any names, y’all know: It was &lt;strong&gt;RDCSLY&lt;/strong&gt; fun spending time with you 🫶&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Book summaries: January - April 2024</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Sun, 05 May 2024 18:03:02 +0000</pubDate>
      <link>https://dev.to/dorneanu/book-summaries-january-april-2024-10lp</link>
      <guid>https://dev.to/dorneanu/book-summaries-january-april-2024-10lp</guid>
      <description>&lt;p&gt;Inspired by Eli Bendersky's &lt;a href="https://eli.thegreenplace.net/tag/book-reviews" rel="noopener noreferrer"&gt;book reviews&lt;/a&gt;, here are my summaries for the books I've read&lt;br&gt;
between &lt;strong&gt;January and April 2024&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;📚 &lt;a href="https://www.goodreads.com/book/show/55539565-think-again" rel="noopener noreferrer"&gt;Think Again: The Power of Knowing What You Don't Know by Adam Grant&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've received this book shortly after reading &lt;a href="https://brainfck.org/book/the-scout-mindset" rel="noopener noreferrer"&gt; The Scout Mindset&lt;/a&gt; where I learned about the &lt;em&gt;soldier&lt;/em&gt; vs &lt;em&gt;scout&lt;/em&gt; mindset where the later one can be shortly described in one quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Your strength as a scout is in your ability… to think in shades of gray instead of black and white.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Think again&lt;/em&gt; is more about different types of thinking (the preacher, the prosecutor, the politian and the scientist) and their main characteristics. I also learned that a debate is more like a &lt;a href="https://brainfck.org/book/think-again/#part-2-interpersonal-rethinking" rel="noopener noreferrer"&gt;dance&lt;/a&gt; where the choreography between the partners has not been negotiated yet. Each one has his own steps in mind but professional debators know how to "end up in rhythm" with their partners. Adam Grant also gives &lt;a href="https://brainfck.org/book/think-again/#actions-for-impact" rel="noopener noreferrer"&gt;concrete advice&lt;/a&gt; how to learn to develop the habit of thinking again and revising your own beliefs.&lt;/p&gt;

&lt;p&gt;👉 Read &lt;a href="https://brainfck.org/book/think-again/" rel="noopener noreferrer"&gt;my notes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📚 &lt;a href="https://www.goodreads.com/book/show/200314620-the-startup-cto-s-handbook" rel="noopener noreferrer"&gt;The Startup CTO's Handbook: Essential skills and best practices for high performing engineering teams by Zach Goldberg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a comprehensive guide for CTOs and technical leaders in startup companies. It covers a wide range of essential topics for these people including technical leadership, team building, technology choices, infrastructure, technical debt. It also gives advice how to master the startup growth, have a fast hiring process, how to retain talent and how to scale technology infrastructure to meet increasing demands.&lt;/p&gt;

&lt;p&gt;Although I didn't know what to expect, for my taste it was too high-level. However, I liked the chapter about the &lt;em&gt;technical debt&lt;/em&gt; and its seven types. I also first learned about DX (Developer Experience) which refers to tools &amp;amp; processes to make it easy to "have highly reliable and reproducible environments and dependency chains".&lt;/p&gt;

&lt;p&gt;👉 Read &lt;a href="https://brainfck.org/book/the-startup-ctos-handbook/" rel="noopener noreferrer"&gt;my notes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📚 &lt;a href="https://www.goodreads.com/en/book/show/37570605" rel="noopener noreferrer"&gt;Company Of One: Why Staying Small Is the Next Big Thing for Business by Paul Jarvis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I remember &lt;a href="https://calnewport.com/" rel="noopener noreferrer"&gt;Cal Newport&lt;/a&gt; once mentioned this book in one of &lt;a href="https://calnewport.com/podcasts/" rel="noopener noreferrer"&gt;his episodes&lt;/a&gt; (this is how I got to read this book). In "Company of One," the capitalistic credo of (continuous) growth is questioned. Instead, "companies of one" should intentionally stay small. The main focus here is not the competitor's growth but rather focusing on customer relationships and their own success. According to Paul Jarvis, if you're focusing on growth, growth will happen. If you, however, want long-term customers and sales, you should focus on your few customers and their needs. There is absolutely no need for infinite growth just for the sake of getting bigger.&lt;/p&gt;

&lt;p&gt;👉 Read &lt;a href="https://brainfck.org/book/company-of-one/" rel="noopener noreferrer"&gt;my notes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📚 &lt;a href="https://www.goodreads.com/en/book/show/56913172" rel="noopener noreferrer"&gt;The Minimalist Entrepreneur: How Great Founders Do More with Less by Sahil Lavingia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you know &lt;a href="https://gumroad.com/" rel="noopener noreferrer"&gt;Gumroad&lt;/a&gt; then you probably also know about &lt;a href="https://sahillavingia.com/" rel="noopener noreferrer"&gt;Sahil Lavingia&lt;/a&gt; who got by this &lt;a href="https://sahillavingia.com/reflecting" rel="noopener noreferrer"&gt;essay&lt;/a&gt;. Compared to the previous books on entrepreneurship, this focused more on the community for which you want to build products. Sahil emphasized the crucial part of identifying your ideal customers and building solutions for their needs. Once you figured out your potential customers, it's time to find out if they're willing to pay for your solutions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A business is a way to solve problems for people your care about - and get paid for it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The author also suggests you first become a creator and then an entrepreneuer. This way you should make sure your creativity is unleashed in order to create the best solutions for your business.&lt;/p&gt;

&lt;p&gt;👉 Read &lt;a href="https://brainfck.org/book/the-minimalist-entrepreneur/" rel="noopener noreferrer"&gt;my notes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📚 &lt;a href="https://www.goodreads.com/book/show/34921573-lost-connections" rel="noopener noreferrer"&gt;Lost Connections: Uncovering the Real Causes of Depression - and the Unexpected Solutions by Johann Hari&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After having heard a lot about depression, its chemical root causes, the effects on humans in Andrew Huberman's &lt;a href="https://www.hubermanlab.com/" rel="noopener noreferrer"&gt;podcast&lt;/a&gt; I was more than determined to read this book. Himself having to deal with depression, Johann Hari takes a journey to find out more about the mental illness that caused him to take pills (a la Prozac) and soon to find out they weren't a long-term solution. What if depression was not solely caused by some "imbalance of serotonin" in your brain? What if depression was merely a mix of environmental factors, childhood traumata, and predisposition (genes) to some behavioral patterns?&lt;/p&gt;

&lt;p&gt;Hari comes up with 9 causes for depression: &lt;em&gt;Disconnection&lt;/em&gt; from 1) meaningful work, 2) from other people, 3) from meaningful values, 4) childhood traume, 5) from status and respect, 6) from the natural world, 7) from a hopeful and secure future and finally 9) role of genes and brain changes. To quote the author, we all need to &lt;em&gt;reconnect&lt;/em&gt; again:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You aren’t a machine with broken parts. You are an animal whose needs are not being met. You need to have a community. You need to have meaningful values, not the junk values you’ve been pumped full of all your life, telling you happiness comes through money and buying objects. You need to have meaningful work. You need the natural world. You need to feel you are respected. You need a secure future. You need connections to all these things. You need to release any shame you might feel for having been mistreated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 Read &lt;a href="https://brainfck.org/book/lost-connections/" rel="noopener noreferrer"&gt;my notes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📚 &lt;a href="https://www.goodreads.com/en/book/show/23692271" rel="noopener noreferrer"&gt;Sapiens: A Brief History of Humankind by Yuval Noah Harari&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During the pandemic, a friend of mine recommended Harari to me and last year I read &lt;a href="https://brainfck.org/book/21-lessons-for-the-21st-century" rel="noopener noreferrer"&gt; 21 Lessons for the 21st Century&lt;/a&gt; by the same author. His thoughts immediately resonated with me so I (chronologically backwards) started to read his other masterpieces.&lt;/p&gt;

&lt;p&gt;From time to time, there has been some criticism about Harari and his criticism of today's humankind. Nevertheless, I think the book is an excellent journey of how &lt;code&gt;homo sapiens&lt;/code&gt; managed to dominate the world, organize in groups, come up with financial, economic, and political systems. For me, it has been an extraordinary time travel which made me understand our world's mechanics.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📚 &lt;a href="https://www.goodreads.com/en/book/show/57933306" rel="noopener noreferrer"&gt;Stolen Focus: Why You Can't Pay Attention - and How to Think Deeply Again by Johann Hari&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ever since I've read about the &lt;a href="https://brainfck.org/t/attention-economy" rel="noopener noreferrer"&gt;Attention Economy&lt;/a&gt; (first in &lt;a href="https://brainfck.org/book/digital-minimalism" rel="noopener noreferrer"&gt;Digital Minimalism&lt;/a&gt;) I knew there is a whole (social media) industry whose main purpose is to monetize &lt;strong&gt;our&lt;/strong&gt; time spent on their platforms. The more time we spend, the more ads can be shown, the more money can be generated.&lt;/p&gt;

&lt;p&gt;But this is just one reason we cannot &lt;strong&gt;focus&lt;/strong&gt; anymore. Among the increased amount of information our brain has to deal with every day, technology that uses insights from behavioral psychology to capture your attention, the collapse of sustained reading (books!) the Hari makes an interesting point:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So we aren’t just facing a crisis of lost spotlight focus – we are facing a crisis of lost mind-wandering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not only have we lost our ability to focus for a longer period of time, but we also no longer allow our minds to wander, which is crucial.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[...] rapidly switching between tasks, and I realised that in our current&lt;br&gt;
culture, most of the time we’re not focusing, but we’re not mind-wandering&lt;br&gt;
either. We’re constantly skimming, in an unsatisfying whirr.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 Read &lt;a href="https://brainfck.org/book/stolen-focus/" rel="noopener noreferrer"&gt;my notes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Some other small books:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  📚 &lt;a href="https://www.goodreads.com/book/show/2558105.Domain_Driven_Design_Quickly" rel="noopener noreferrer"&gt;Domain-Driven Design Quickly by Floyd Marinescu&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>books</category>
      <category>book</category>
    </item>
    <item>
      <title>From Doom to Vanilla Emacs</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Thu, 22 Feb 2024 18:58:33 +0000</pubDate>
      <link>https://dev.to/dorneanu/from-doom-to-vanilla-emacs-5cna</link>
      <guid>https://dev.to/dorneanu/from-doom-to-vanilla-emacs-5cna</guid>
      <description>&lt;h2&gt;
  
  
  Why vanilla?
&lt;/h2&gt;

&lt;p&gt;Let's start with the most obvious question: &lt;em&gt;What's wrong with Doom Emacs&lt;/em&gt;? Short answer: There is &lt;em&gt;nothing&lt;/em&gt; wrong with Doom Emacs. I still use it and I still recommend it for &lt;em&gt;beginners&lt;/em&gt;. Some years ago I started with &lt;code&gt;Spacemacs&lt;/code&gt; and moved to &lt;code&gt;Doom&lt;/code&gt; which, in my humble opinion, is far faster and more stable. So if you're a novice and just entered the "&lt;em&gt;church of Emacs&lt;/em&gt;" I &lt;strong&gt;strongly&lt;/strong&gt; recommend you do &lt;strong&gt;NOT&lt;/strong&gt; start with &lt;code&gt;vanilla&lt;/code&gt;. I recommend &lt;code&gt;Doom&lt;/code&gt; because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  it comes with batteries included&lt;/li&gt;
&lt;li&gt;  I like how you can exclude packages from your configuration&lt;/li&gt;
&lt;li&gt;  you don't have to get into heavy &lt;code&gt;Elisp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  there is a whole group of being taking care of &lt;em&gt;bugs&lt;/em&gt; and making sure
each release works properly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That said, I still wanted to go "vanilla," at least give it a try. My first attempt failed, mainly because I was trying to use someone's config without really understanding how it works. I also had some "hard requirements" for my configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/emacs-evil/evil" rel="noopener noreferrer"&gt;evil mode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've used &lt;code&gt;vim&lt;/code&gt; for more than 10 years and memorized vim like keybindings like my own pocket. Sometimes I find Emacs like keybindings to be more practical, though. That's why I wanted to have both.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;literate config (using &lt;a href="https://orgmode.org/" rel="noopener noreferrer"&gt;ORG mode&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I still don't consider myself efficient in writing &lt;code&gt;Elisp&lt;/code&gt; code. For this reason, I wanted my configuration to be written in ORG mode (like most of my stuff available online) whose &lt;em&gt;parts&lt;/em&gt; can be written (or &lt;em&gt;tangled&lt;/em&gt;) to files (e.g. &lt;code&gt;.el&lt;/code&gt; files) using &lt;a href="https://orgmode.org/worg/org-contrib/babel/" rel="noopener noreferrer"&gt;org-babel&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;modular&lt;/p&gt;

&lt;p&gt;I wanted to &lt;em&gt;group&lt;/em&gt; similar functionalities in the same ORG file. That's why I have a &lt;code&gt;programming.org&lt;/code&gt; file which includes configuration for the programming languages I'm using. At the same time I wanted to easily &lt;em&gt;disable&lt;/em&gt; parts of configuration by deleting the corresponding section or commenting it out (&lt;code&gt;org-toggle-comment&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Of course, &lt;code&gt;Org mode&lt;/code&gt; would then have its own file &lt;code&gt;org.org&lt;/code&gt; 😎&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Go vanilla
&lt;/h2&gt;

&lt;p&gt;If you really decide to continue this journey, I'd like to share some tipps/workflow to make your process more smoothly.&lt;/p&gt;

&lt;p&gt;Ever since I've started my &lt;code&gt;Emacs&lt;/code&gt; journey it seemed like the wholy grail to have your own (vanilla!) configuration without any hard dependencies on frameworks like &lt;a href="https://github.com/doomemacs/doomemacs" rel="noopener noreferrer"&gt;Doom&lt;/a&gt; or &lt;a href="https://www.spacemacs.org/" rel="noopener noreferrer"&gt;Spacemacs&lt;/a&gt;. There are plenty of &lt;code&gt;dotemacs&lt;/code&gt; configurations ouf there which can serve as a great source of inspiration.&lt;/p&gt;

&lt;p&gt;In my case, it was specifically this one which caught my attention: &lt;a href="https://config.phundrak.com/emacs/" rel="noopener noreferrer"&gt;https://config.phundrak.com/emacs/&lt;/a&gt;. It had almost everything I needed, it was using &lt;code&gt;evil mode&lt;/code&gt; and the whole configuration is written in ORG mode. Bingo!&lt;/p&gt;

&lt;h3&gt;
  
  
  Literate config
&lt;/h3&gt;

&lt;p&gt;As a matter of preference I don't like Elisp based Emacs configurations. I find ORG mode and literate config to be more easy to read and understand what's going on.&lt;/p&gt;

&lt;p&gt;You can have a &lt;strong&gt;basic structure&lt;/strong&gt; in your ORG mode file, define sections, and use the outline functionality to jump to each section. You can then &lt;code&gt;tangle&lt;/code&gt; the ORG file to generate the &lt;code&gt;.el&lt;/code&gt; files to be loaded by Emacs. Having spent countless hours (and days) tweaking my configuration, reading others and trying to understand custom &lt;code&gt;Elisp&lt;/code&gt; functions, I think I've reached a level where I &lt;strong&gt;exactly&lt;/strong&gt; know which part of my config is responsible for some misbehavior. Other than that, I've found a &lt;em&gt;structure&lt;/em&gt; that fits my needs and the way I want my configuration to be structured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic structure
&lt;/h3&gt;

&lt;p&gt;Your configuration should have a basic structure. You can either use a &lt;strong&gt;single&lt;/strong&gt; file for the whole configuration or &lt;strong&gt;multiple&lt;/strong&gt; ones. I prefer multiple ones because you can &lt;code&gt;tangle&lt;/code&gt; each one individually and thus make the whole process faster. This is what I have inside my &lt;code&gt;Emacs&lt;/code&gt; folder in my &lt;a href="https://github.com/dorneanu/dotfiles" rel="noopener noreferrer"&gt;dotfiles&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;emacs
├── basic-config.org
├── custom-elisp.org
├── index.org
├── keybinding-managers.org
├── keybindings.org
├── Makefile
├── package-manager.org
├── packages
│   ├── applications.org
│   ├── autocompletion.org
│   ├── editing.org
│   ├── helpful.org
│   ├── org.org
│   ├── programming.org
│   └── visual-config.org
└── tangle_script.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basic structure of my Emacs configuration files&lt;/p&gt;

&lt;p&gt;This structure is more or less &lt;strong&gt;copied&lt;/strong&gt; from &lt;a href="https://config.phundrak.com/emacs/" rel="noopener noreferrer"&gt;Phundrak's one&lt;/a&gt; which served as a really good starting point. Of course I stripped down each file to my needs.&lt;/p&gt;

&lt;p&gt;The point is that each file would host a different set of customizations relevant to specific functionalities. If I want to change some keybindings I'd then go to &lt;code&gt;keybindings.org&lt;/code&gt; and modify stuff. If I want to tweak the autocompletion for lsp-mode I'd then go to &lt;code&gt;autocompletion.org&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tangling
&lt;/h3&gt;

&lt;p&gt;In Emacs and Org mode, &lt;code&gt;tangling&lt;/code&gt; refers to the process of extracting code snippets from an ORG file and writing them to separate source code files. It usually allows you to maintain code and documentation in the same file while keeping them in sync. In my case I use it to generate Elisp code out of my ORG files.&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%2Fw3w5jclzj1wn00uyotwe.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%2Fw3w5jclzj1wn00uyotwe.png" alt="image" width="800" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 My ORG mode config&lt;/small&gt;&lt;/center&gt;

&lt;h4&gt;
  
  
  Automation
&lt;/h4&gt;

&lt;p&gt;I like to automate most of the workflows and therefore I use a &lt;code&gt;Makefile&lt;/code&gt; and some bash script for tangling &lt;strong&gt;all&lt;/strong&gt; files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Phony target to tangle all org files
&lt;/span&gt;&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;tangle&lt;/span&gt;
&lt;span class="nl"&gt;tangle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.org"&lt;/span&gt; &lt;span class="nt"&gt;-exec&lt;/span&gt; sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'echo "[!] Tangling {}"; ./tangle_script.sh "{}"'&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Makefile for my Emacs configuration&lt;/p&gt;

&lt;p&gt;And this is the script I use to tangle one individual file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

emacs &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt; &lt;span class="nt"&gt;--eval&lt;/span&gt; &lt;span class="s2"&gt;"(require 'ob-tangle)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--eval&lt;/span&gt; &lt;span class="s2"&gt;"(setq org-confirm-babel-evaluate nil)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--eval&lt;/span&gt; &lt;span class="s2"&gt;"(org-babel-tangle-file &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tangle script which takes an ORG file as an argument&lt;/p&gt;

&lt;h4&gt;
  
  
  Manually
&lt;/h4&gt;

&lt;p&gt;I would like my overall configuration (at &lt;code&gt;~/.config/emacs&lt;/code&gt;) to be updated immediately whenever I change something in the Org mode files. Therefore I use &lt;code&gt;.dir-locals.el&lt;/code&gt; to define this behaviour for all ORG mode files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;;; Directory Local Variables            -*- no-byte-compile: t -*-&lt;/span&gt;
&lt;span class="c1"&gt;;;; For more information see (info "(emacs) Directory Variables")&lt;/span&gt;

&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;org-mode&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;org-confirm-babel-evaluate&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;progn&lt;/span&gt;
                      &lt;span class="c1"&gt;;; Tangle whole file after being saved&lt;/span&gt;
                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'after-save-hook&lt;/span&gt; &lt;span class="ss"&gt;'org-babel-tangle&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;.dir-locals.el&lt;/p&gt;

&lt;p&gt;First I don't want to be asked every time if I want to &lt;strong&gt;evaluate&lt;/strong&gt; the source code blocks (that's why &lt;code&gt;org-confirm-babel-evaluate&lt;/code&gt; is set to &lt;code&gt;nil&lt;/code&gt; ). Secondly I want to automatically &lt;code&gt;tangle&lt;/code&gt; the file whenever the file gets saved (&lt;code&gt;org-babel-tangle&lt;/code&gt; in the &lt;code&gt;after-save-hook&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This way every time I &lt;em&gt;save&lt;/em&gt; one file, the &lt;code&gt;Elisp&lt;/code&gt; code will be automatically be tangled to the corresponding file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspirations
&lt;/h2&gt;

&lt;p&gt;Sometimes I don't know exactly how to configure a package or which options I should be using. Instead of searching the web for the examples last year I came up with an idea: I started collecting interesting/useful &lt;code&gt;dotfiles~/~dotemacs&lt;/code&gt; collections in a &lt;strong&gt;single&lt;/strong&gt; place. You can find the repository at &lt;a href="https://github.com/dorneanu/dotemacs" rel="noopener noreferrer"&gt;github.com/dorneanu/dotemacs&lt;/a&gt;. So what I usually do is to search inside the folder where I've cloned all repositories for specific keywords. For this purpose I use &lt;a href="https://github.com/dajva/rg.el" rel="noopener noreferrer"&gt;rg.el&lt;/a&gt; and some custom function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;dotemacs-directory&lt;/span&gt; &lt;span class="s"&gt;"/cs/priv/repos/dotemacs"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;rg-define-search&lt;/span&gt; &lt;span class="nv"&gt;my/rg-dotemacs&lt;/span&gt;
  &lt;span class="ss"&gt;:query&lt;/span&gt; &lt;span class="nv"&gt;ask&lt;/span&gt;
  &lt;span class="ss"&gt;:format&lt;/span&gt; &lt;span class="nv"&gt;regexp&lt;/span&gt;
  &lt;span class="ss"&gt;:files&lt;/span&gt; &lt;span class="s"&gt;"everything"&lt;/span&gt;
  &lt;span class="ss"&gt;:dir&lt;/span&gt; &lt;span class="nv"&gt;dotemacs-directory&lt;/span&gt;
  &lt;span class="ss"&gt;:confirm&lt;/span&gt; &lt;span class="nv"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the &lt;code&gt;rg&lt;/code&gt; section in my dotemacs config&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%2F8rcqwpox1jgpi2nzqk08.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%2F8rcqwpox1jgpi2nzqk08.png" alt="image" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Searching with rg&lt;/small&gt;&lt;/center&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Checkout my &lt;a href="https://github.com/dorneanu/dotfiles/tree/master/emacs" rel="noopener noreferrer"&gt;dotfiles&lt;/a&gt; (which I manage using &lt;a href="https://www.chezmoi.io/" rel="noopener noreferrer"&gt;chezmoi&lt;/a&gt;) if you need some inspiration. If you have other tips on how to further improve my workflow or the overall structure, please drop me an email.&lt;/p&gt;

</description>
      <category>emacs</category>
      <category>orgmode</category>
      <category>elisp</category>
      <category>doomemacs</category>
    </item>
    <item>
      <title>My 2023 review</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Tue, 02 Jan 2024 21:23:30 +0000</pubDate>
      <link>https://dev.to/dorneanu/my-2023-review-4aib</link>
      <guid>https://dev.to/dorneanu/my-2023-review-4aib</guid>
      <description>&lt;p&gt;I feel somewhat ashamed for not doing a review last year. However, this year I have set aside some time to reflect on the highlights of this year, what I have learned, the habits I have changed, and the habits I have stucked to. The following is my review for 2023, divided into several sections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Books
&lt;/h2&gt;

&lt;p&gt;This year I've finally reactivated my &lt;a href="https://www.goodreads.com/user/show/121423977-victor-dorneanu" rel="noopener noreferrer"&gt;Goodreads profile&lt;/a&gt; primarily for getting book recommendations. Although I have my own &lt;a href="https://brainfck.org/t/books/todo/" rel="noopener noreferrer"&gt;TODO list&lt;/a&gt; for reading, which continues to grow each year, I'm always curious to see what &lt;em&gt;others&lt;/em&gt; have read addtionally after finishing one book.&lt;/p&gt;

&lt;p&gt;As always you can find my list of read books at &lt;a href="https://brainfck.org/books/" rel="noopener noreferrer"&gt;brainfck.org/books&lt;/a&gt; where also this year I've added tags to the books and restructured the &lt;a href="https://github.com/dorneanu/roam/blob/main/layouts/books/list.html" rel="noopener noreferrer"&gt;Hugo template&lt;/a&gt; to list them as well.&lt;/p&gt;

&lt;p&gt;Instead of trying to summarize &lt;em&gt;each book&lt;/em&gt; here are my 2023 recommendations for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://brainfck.org/tags/politics/" rel="noopener noreferrer"&gt;#politics&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;📖 &lt;a href="https://www.penguinrandomhouse.com/books/570367/the-road-to-unfreedom-by-timothy-snyder/" rel="noopener noreferrer"&gt;The Road to Unfreedom&lt;/a&gt; (by &lt;a href="https://timothysnyder.org/" rel="noopener noreferrer"&gt;Timothy Snyder&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I've read this book mainly because I wanted to know more about Eastern Europe politics and the on-going war in Ucraine. In his book Synder examines the historical and geopolitical aspects that have shaped the world recently, especially highlighting the actions of Russia and its impact on global politics. The book gives the readers insights into the strategies used by influential figures (philosophers, politicians etc.) to undermine democratic values, manipulate public opinion which all gave birth to &lt;em&gt;authoritarianism&lt;/em&gt; and the erosion of democracy.&lt;br&gt;
 &lt;br&gt;
Although this book offers a deep analysis of the Soviet and Russian politics, I think Snyder focussed to much on Russia's actions solely which could be interpreted as the primary influences of global authoritarianism, the war in Ucraine and fake-news.&lt;br&gt;
 &lt;br&gt;
👉 &lt;a href="https://brainfck.org/book/drumul-spre-nelibertate/" rel="noopener noreferrer"&gt; My own notes&lt;/a&gt; (in Romanian)&lt;br&gt;
 &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;a href="https://brainfck.org/tags/society/" rel="noopener noreferrer"&gt;#society&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;📖 &lt;a href="https://www.goodreads.com/en/book/show/56969567" rel="noopener noreferrer"&gt;Mother of Invention: How Good Ideas Get Ignored in an Economy Built for Men&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've chosen this book to be in the top list because it somehow opened my eyes for all the gender biases and inequalities that already &lt;em&gt;have&lt;/em&gt; existed in our society and in the economic world. The author has plenty of (historical) examples how women's ideas and contributions often are ignored and undervalues, despite their potential to drive innovation and progress. Also interesting: Job roles nowadays dominated mainly by men were some decades ago preserved for female workers (e.g. computer programming)&lt;br&gt;
 &lt;br&gt;
As already mentioned by others, this book serves as a call to action, forcing society to address the structural and systemic biases that block women's participation and idea recognition in the economy.&lt;br&gt;
 &lt;br&gt;
👉 &lt;a href="https://brainfck.org/book/die-mutter-der-erfindung/" rel="noopener noreferrer"&gt; My own notes&lt;/a&gt; (in German)&lt;br&gt;
 &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📖 &lt;a href="https://www.goodreads.com/en/book/show/50695158" rel="noopener noreferrer"&gt;The Lonely Century: How to Restore Human Connection in a World That's Pulling Apart&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The issue of loneliness and social disconnection is something I've been observing for years. Despite our inter-connected world with instant messaging at our finger tips and a constant influx of events all over the world, I think we (as human beings) are suffering from real human connections. Also this book serves as a wake-up call to address the isolation we're currently facing and provides strong arguments for building strong, more connected communities.&lt;br&gt;
 &lt;br&gt;
👉 &lt;a href="https://dev.to/2023/01/21/book-summary-the-lonely-century/"&gt;My book summary: The Lonely Century&lt;/a&gt; / &lt;a href="https://brainfck.org/book/the-lonely-century/" rel="noopener noreferrer"&gt; My own notes&lt;/a&gt; (in Romanian)&lt;br&gt;
 &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.goodreads.com/book/show/38820046-21-lessons-for-the-21st-century" rel="noopener noreferrer"&gt;📖 21 Lessons for the 21st Century&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have still not processed all thoughts and ideas presented in this book. But if you decide to read this book, be prepared for a captivating journey into different topics such as technology, &lt;a href="https://dev.to/tags/politics/"&gt;politics&lt;/a&gt; and &lt;a href="https://dev.to/tags/religion/"&gt;religion&lt;/a&gt;. The book also focusses on the intersection of AI and humanity. &lt;em&gt;Yuval Noah Harari&lt;/em&gt; explains the profound implications of AI, raising important questions about its impact on society and our individual lives. He explores the potential &lt;em&gt;disruptions&lt;/em&gt; caused by automation and the potential challanges AI poses to human labor and employment. In this context the author emphasizes the importance of protecting human values (and forces) in an increasingly automated world.\&lt;br&gt;
 &lt;br&gt;
After reading this book I was more than determined to find out more about the author's other publications (e.g. &lt;a href="https://www.goodreads.com/book/show/23692271-sapiens?ac=1&amp;amp;from_search=true&amp;amp;qid=oFIgkOhZW0&amp;amp;rank=1" rel="noopener noreferrer"&gt;Sapiens: A Brief History of Humankind&lt;/a&gt;).&lt;br&gt;
 &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;a href="https://brainfck.org/tags/health/" rel="noopener noreferrer"&gt;#health&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.goodreads.com/en/book/show/49358915" rel="noopener noreferrer"&gt;📖 Exercised: Why Something We Never Evolved to Do Is Healthy and Rewarding&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this book I've learned a lot about the role of &lt;strong&gt;exercise&lt;/strong&gt; in our lives. The author challenges the conventional wisdom on exercise, emphasizing the importance of &lt;em&gt;natural movement&lt;/em&gt; over high-effort exercises. He argues that our bodies are &lt;em&gt;designed&lt;/em&gt; for &lt;em&gt;normal, seasonal physical activity&lt;/em&gt; and that prioritizing activities like walking, running, dancing can have a profound impact on our health and well-being. &lt;em&gt;Lieberman&lt;/em&gt; encourages people to rethink their relationship to exercise and fitness and therefore embrace the benefits of moving naturally, sitting less and engaging in full-body movements.&lt;br&gt;
 &lt;br&gt;
👉 &lt;a href="https://brainfck.org/book/exercised/" rel="noopener noreferrer"&gt; My own notes&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;a href="https://brainfck.org/tags/biography/" rel="noopener noreferrer"&gt;#biography&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The more books I read, the more I realize my affinity for reading (auto-)biographies. This way I can delve into the lives of remarkable individuals who had a profound impact on our world. It is through their accomplishments (and wisdom!) that I continue to cultivate my understanding of our shared human history. Here's my recommendation for 2023:&lt;br&gt;
 &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;📖 &lt;a href="https://www.goodreads.com/book/show/37588710-thirst" rel="noopener noreferrer"&gt;Thirst: A Story of Redemption, Compassion, and a Mission to Bring Clean Water to the World&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This book kept my mind busy for a while, primarily due to one key reason: The undeniable connection between willpower and motivation. In "Thirst" &lt;em&gt;Scott Harrison&lt;/em&gt; shares his personal transformation from a nightclub promoter to the founder of the nonprofit organization "&lt;a href="https://www.charitywater.org/" rel="noopener noreferrer"&gt;Charity: Water&lt;/a&gt;" which aims to provide clean and safe drinking water to communities in need around the world. Along the way, Scott confronts personal challenges and navigates the complexities of the nonprofit world, sharing valuable lessons on resilience, empathy, and the power of collective action.&lt;br&gt;
 &lt;br&gt;
Once you have finished reading the book, be sure to visit &lt;a href="https://www.charitywater.org/thirst" rel="noopener noreferrer"&gt;charitywater.org/thirst&lt;/a&gt; to access the additional digital content, including videos and pictures, that the author has prepared for you. It is truly remarkable and adds an extra layer of depth to the reading experience.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Productivity
&lt;/h2&gt;

&lt;p&gt;I usually don't keep track of productivity tools and workflows, as everyone's needs are unique with regards to project / time / resources management. However, I'd like to share some "tools" that have changed the way I work and deal with new initiatives/projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Scale Planning
&lt;/h3&gt;

&lt;p&gt;As a long time listener of &lt;a href="https://calnewport.com/podcasts/" rel="noopener noreferrer"&gt;Cal Newport's podcast&lt;/a&gt; of course I had the chance to learn more about his productivity hacks and tipps. Even more than his brilliant advice in &lt;a href="https://brainfck.org/book/deep-work" rel="noopener noreferrer"&gt;Deep Work&lt;/a&gt; I've found &lt;a href="https://brainfck.org/t/multi-scale-planning" rel="noopener noreferrer"&gt;Multi-Scale Planning&lt;/a&gt; to be a true game changer.&lt;/p&gt;

&lt;p&gt;While I cannot cover all details (maybe I'll do so in a future post), the main idea is to do planning at &lt;strong&gt;multiple&lt;/strong&gt; time scales such as quarterly/monthly, weekly and daily. Each scale has a different level of details as you move from one scale to another.&lt;/p&gt;

&lt;p&gt;This approach to &lt;em&gt;time management&lt;/em&gt; (because this is what it's about, right?) allowed me to plan in advance but also be &lt;strong&gt;flexible&lt;/strong&gt; whenever something deviated from the &lt;em&gt;initial&lt;/em&gt; plan. This way I was able to come up with some initiatives/projects for the next quarter/month and define small chunks of work I could do on a weekly/daily level.&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%2Fx7ubo6rbbu203fl3cjbq.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%2Fx7ubo6rbbu203fl3cjbq.png" alt="image" width="800" height="404"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Planning using ORG mode&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;It is a very &lt;strong&gt;visual&lt;/strong&gt; system that works well in a &lt;em&gt;digital&lt;/em&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;em&gt;analog&lt;/em&gt; world. No matter which fancy productivity tool you prefer, in the end it's all about the &lt;strong&gt;workflow&lt;/strong&gt; and &lt;strong&gt;processes&lt;/strong&gt; you implement in order to make consistent progress and contribute to your personal and professional growth.&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%2Fwqzgwn3e2luq39c24jfs.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%2Fwqzgwn3e2luq39c24jfs.png" alt="image" width="595" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Weekly planning using an analogue planner&lt;/small&gt;&lt;/center&gt;

&lt;h3&gt;
  
  
  Track focus time
&lt;/h3&gt;

&lt;p&gt;I've found &lt;em&gt;deep work&lt;/em&gt; (as a state of mind) to be very dificult to achieve. Initially I thought I could train this skill while &lt;em&gt;meditating&lt;/em&gt;. It did help to some degree but the true deep work killer gadget turned out to be ... &lt;strong&gt;my watch&lt;/strong&gt;. I used my watch to setup a countdown (e.g. 1 hour) which always reminded I should be focussing whenever I've felt I was mind-wandering.&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%2Fhh9s0am06pv6hdpfo7xf.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%2Fhh9s0am06pv6hdpfo7xf.png" alt="image" width="768" height="1364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Track focus time using a watch&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;Often I thought I was focussing for at least 30 minutes when in reality it was only 10 minutes. For me it was a strong indicator my mind was trying to fool me into jumping to other tasks, force me to &lt;em&gt;procrastinate&lt;/em&gt;.&lt;/p&gt;

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

&lt;center&gt;&lt;small&gt;👉 Time tracker running&lt;/small&gt;&lt;/center&gt;

&lt;h3&gt;
  
  
  Train your visual focus
&lt;/h3&gt;

&lt;p&gt;This is nothing new but still an advice ignored by many. We all know multi-tasking is bad for our attention (and therefore productivity) and to many context switches (switching between different tasks, jump to different windows on your PC) can significantly diminish your ability to focus on one thing.&lt;/p&gt;

&lt;p&gt;Some months ago I was listening to Andrew Huberman's podcast on &lt;a href="https://www.youtube.com/watch?v=LG53Vxum0as&amp;amp;ab_channel=AndrewHuberman" rel="noopener noreferrer"&gt;How to Focus to Change Your Brain&lt;/a&gt; where, simply put, he linked our ability to focus to &lt;strong&gt;visual&lt;/strong&gt; focus.&lt;/p&gt;

&lt;p&gt;He emphasizes that &lt;strong&gt;mental focus&lt;/strong&gt; is closely tied to &lt;strong&gt;where&lt;/strong&gt; and &lt;strong&gt;how&lt;/strong&gt; we focus our eyes. Our visual system can either be unfocused or laser-focused, and this directly impacts our mental focus.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What's interesting and vitally important to understanding how to access neuroplasticity is&lt;br&gt;
that you can use your visual focus, &lt;strong&gt;and you can increase your visual focus as a way of&lt;br&gt;
increasing your mental focus&lt;/strong&gt; focus abilities more broadly.&lt;/p&gt;

&lt;p&gt;-- &lt;a href="https://www.youtube.com/watch?v=LG53Vxum0as&amp;amp;ab_channel=AndrewHuberman" rel="noopener noreferrer"&gt;How to Focus to Change Your Brain (Youtube)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, Huberman suggests that by sharpening visual focus, we can directly influence &lt;strong&gt;neuroplasticity&lt;/strong&gt; which is our ability (or the brain's one) to adapt and learn new information. What's even more important is what exactly you focus on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And the behavioral practices that are anchored in visual focus are going to be the ones that are going to allow you to develop great depth, and duration of focus. So let's think about visual focus for a second. When we focus on something visually, we have two options, we can either look at a very small region of space, with a lot of detail, and a lot of precision. Or we can dilate our gaze, and we can see big pieces of visual space with very little detail. It's a trade off, we can't look at everything at high resolution. This is why we have these the pupil more or less relates to the phobia of the eye, which is the area in which we have the most receptors, the highest density of receptors that perceive light. And so our acuity is much better in the center of our visual field than our periphery.&lt;br&gt;
-- &lt;a href="https://www.youtube.com/watch?v=LG53Vxum0as&amp;amp;ab_channel=AndrewHuberman" rel="noopener noreferrer"&gt;How to Focus to Change Your Brain (Youtube)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a practical way Huberman advises practicing visual focus at the &lt;em&gt;specific distance of one hand&lt;/em&gt;, like reading a book or looking at a screen. This means that reading books and therefore engaging your brain into cognitive tasks will definitely have an impact on your capacity to &lt;strong&gt;focus&lt;/strong&gt; on a certain thing for longer periods of time.&lt;/p&gt;

&lt;p&gt;At the same time (and this is my &lt;strong&gt;own interpretation&lt;/strong&gt;) I think that keeping your eyes focused on a small region on the screen without further distractions (cat pics, gifs, 10 browser tabs opened) will have the same efect. Obviously I would not have writen this without making my own observations before.&lt;/p&gt;

&lt;p&gt;What happened: The more I stick to one window on my laptop without having to switch between apps (e.g. open browser, open mail client) the more focussed I feel. Even if I have to do &lt;a href="https://brainfck.org/t/shallow-work" rel="noopener noreferrer"&gt;shallow work&lt;/a&gt; I try to remain in the same context/window. Just to give some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  I need to add more tasks to a project

&lt;ul&gt;
&lt;li&gt;  I just call my capturing system (&lt;code&gt;org-capture&lt;/code&gt; in Emacs) to quickly write down a note&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  I need to lookup sth on the web

&lt;ul&gt;
&lt;li&gt;  From within Emacs I have multiple options:

&lt;ul&gt;
&lt;li&gt;  Fire up Google search (using &lt;code&gt;xwidget-webkit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;  I can use built-in &lt;em&gt;lookup&lt;/em&gt; mechanisms for searching&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;  I need to check my mails

&lt;ul&gt;
&lt;li&gt;  I just open &lt;code&gt;mu4e&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  I need to ask the AI lords

&lt;ul&gt;
&lt;li&gt;  I open &lt;code&gt;chatgpt-shell&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Some other screenshots:&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%2Fon4oi31kp5f71uwv35wn.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%2Fon4oi31kp5f71uwv35wn.png" alt="image" width="800" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Lookup options in Emacs&lt;/small&gt;&lt;/center&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%2Fik5neptabs5nzmchuck2.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%2Fik5neptabs5nzmchuck2.png" alt="image" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Different search engines in Emacs&lt;/small&gt;&lt;/center&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%2Fg793fnyqvms9qsd1b66z.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%2Fg793fnyqvms9qsd1b66z.png" alt="image" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Open Google search from within Emacs while writing this article&lt;/small&gt;&lt;/center&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%2Frp6194m0zgtnb2ddfqi3.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%2Frp6194m0zgtnb2ddfqi3.png" alt="image" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Use ChatGPT inside Emacs without jumping to an extra window&lt;/small&gt;&lt;/center&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%2Fzttnhjpnuugiq2nxp5by.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%2Fzttnhjpnuugiq2nxp5by.png" alt="image" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Use multiple xwidget-webkit instances to read from multiple sources&lt;/small&gt;&lt;/center&gt;

&lt;h2&gt;
  
  
  Habits
&lt;/h2&gt;

&lt;p&gt;This is where I &lt;em&gt;track&lt;/em&gt; important activities in order to achieve personal goals but also to keep me motivated. I still use the &lt;a href="https://play.google.com/store/apps/details?id=org.isoron.uhabits&amp;amp;hl=en&amp;amp;gl=US" rel="noopener noreferrer"&gt;Loop Habit Tracker&lt;/a&gt; on my smartphone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sports
&lt;/h3&gt;

&lt;p&gt;2 years ago I've felt &lt;a href="https://dev.to/2021/12/13/my-2021-review/#sports-workout"&gt;somehow embarassed&lt;/a&gt; about my sports related activities. That's why my overall goal was to do more sports, no matter what:&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%2Fd9e925m0l2mcfi7jw4ca.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%2Fd9e925m0l2mcfi7jw4ca.png" alt="image" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Sports&lt;/small&gt;&lt;/center&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%2Fvwem87uazey9vmsn1a5g.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%2Fvwem87uazey9vmsn1a5g.png" alt="image" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Sports&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;I not only increased my sport activities noticeably, but I also managed to workout &lt;strong&gt;regularly&lt;/strong&gt; (notice the line on Fridays where I usually go for bouldering).&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%2F7o4sysoxqvcuinjbtsdh.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%2F7o4sysoxqvcuinjbtsdh.png" alt="image" width="607" height="887"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Bouldering in Berlin&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;Also this year I've surfed for the very first time.&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%2Fmetsaz5rypiyckofmn61.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%2Fmetsaz5rypiyckofmn61.png" alt="image" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Surfing in Portugal&lt;/small&gt;&lt;/center&gt;

&lt;h3&gt;
  
  
  Reading
&lt;/h3&gt;

&lt;p&gt;Overall I think this year I've read a lot, sometimes multiple books per month. Instead of buying books, I've extensively used the &lt;a href="https://www.overdrive.com/apps/libby" rel="noopener noreferrer"&gt;Libby App&lt;/a&gt; where you can also rent &lt;em&gt;audio books&lt;/em&gt; from your local library. As I've mentioned before, I've also re-activated my &lt;a href="https://www.goodreads.com/user/show/121423977-victor-dorneanu" rel="noopener noreferrer"&gt;Goodreads account&lt;/a&gt; where I usually keep track of books I'm currently reading.&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%2Fq5d3gf9ad4n43tskd18t.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%2Fq5d3gf9ad4n43tskd18t.png" alt="image" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Reading&lt;/small&gt;&lt;/center&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%2Fqi8b0urt26aldplzp7j6.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%2Fqi8b0urt26aldplzp7j6.png" alt="image" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Reading&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;💡: Don't forget to check out &lt;a href="https://brainfck.org/books/" rel="noopener noreferrer"&gt;my full bookshelf for 2023&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;p&gt;First of all a quick recap of &lt;a href="https://dev.to/2021/12/13/my-2021-review/#outlook"&gt;my goals for 2022&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Learning&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;2 years ago I wrote I'd like to deep-dive more into &lt;strong&gt;TypeScript&lt;/strong&gt;. I still didn't do anything complex in TS but from time to time I still use it (in combination with AWS CDK, like I did for the &lt;a href="https://github.com/dorneanu/aws-custom-resource-golang" rel="noopener noreferrer"&gt;AWS custom resources project&lt;/a&gt;). I also don't expect this to change as for backend I'd still go for &lt;strong&gt;Golang&lt;/strong&gt; (and work-wise I'm "forced" to use Python for small things).&lt;/p&gt;

&lt;p&gt;Besides &lt;strong&gt;TypeScript&lt;/strong&gt; I wanted to learn some &lt;strong&gt;Vue.JS&lt;/strong&gt;. Back then I wrote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to be able to build modern frontend applications and use new technologies beyond HTML, CSS and JavaScript :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I &lt;strong&gt;did&lt;/strong&gt; do some frontend but using different technologies: For implementing &lt;a href="https://dev.to/2022/12/15/releasing-gocial/"&gt;gocial&lt;/a&gt; I've mainly used &lt;a href="https://alpinejs.dev/" rel="noopener noreferrer"&gt;Alpine.js&lt;/a&gt; and &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;. I still have a course to do on Udemy (regarding &lt;strong&gt;Vue.JS&lt;/strong&gt;) but I also need to find time to do it 🙈.&lt;/p&gt;

&lt;p&gt;Among frontend stuff, I was more than motivated to finally learn more about &lt;strong&gt;Web3&lt;/strong&gt; (especially &lt;strong&gt;Ethereum&lt;/strong&gt;). I did some coding in &lt;strong&gt;Solidity&lt;/strong&gt; and also read &lt;a href="https://www.goodreads.com/en/book/show/33584554" rel="noopener noreferrer"&gt;Mastering Ethereum: Building Smart Contracts and DApps&lt;/a&gt;. Additionally I also learned more about &lt;strong&gt;Smart Contract Security&lt;/strong&gt; (I hope to release my notes next year).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Reading&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My reading list for 2022 was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.goodreads.com/book/show/22512931-building-microservices" rel="noopener noreferrer"&gt;Building Microservices: Designing Fine-Grained Systems&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://leanpub.com/visualising-software-architecture" rel="noopener noreferrer"&gt;Visualise, document and explore your software architecture&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://abseil.io/resources/swe-book" rel="noopener noreferrer"&gt;Software Engineering at Google&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dataintensive.net/" rel="noopener noreferrer"&gt;Designing Data-Intensive Applications&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.goodreads.com/book/show/28602719-domain-driven-design-distilled" rel="noopener noreferrer"&gt;Domain-Driven Design Distilled&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/ethereumbook/ethereumbook" rel="noopener noreferrer"&gt;Mastering Ethereum&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/blockquote&gt;

&lt;p&gt;I managed to read &lt;a href="https://brainfck.org/book/building-microservices-2nd-edition/" rel="noopener noreferrer"&gt;Building Microservices(2nd edition)&lt;/a&gt;, &lt;a href="https://brainfck.org/book/mastering-ethereum" rel="noopener noreferrer"&gt;Mastering Ethereum&lt;/a&gt; and I definitely learned something about &lt;a href="https://dev.to/2023/11/02/documentation-as-code-for-cloud-c4-model-structurizr/"&gt;C4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The rest is still on my &lt;a href="https://brainfck.org/t/books/todo/" rel="noopener noreferrer"&gt;TODO list&lt;/a&gt;.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;em&gt;Projects&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Of course there were some ideas and projects I wanted to work on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;  finish &lt;a href="https://github.com/dorneanu/access-key-rotator" rel="noopener noreferrer"&gt;access-key-rotator&lt;/a&gt; and release first version&lt;/li&gt;
&lt;li&gt;  clean up my &lt;a href="https://brainfck.org" rel="noopener noreferrer"&gt;Zettelkasten&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  start working on my &lt;strong&gt;book&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  about Golang and Security :)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, I did some clean-up on &lt;a href="https://brainfck.org" rel="noopener noreferrer"&gt;brainfck.org&lt;/a&gt; but this happens on a regular basis. &lt;a href="https://github.com/dorneanu/access-key-rotator" rel="noopener noreferrer"&gt;access-key-rotator&lt;/a&gt; hasn't been changed since a while and I also did &lt;strong&gt;not&lt;/strong&gt; manage to start working on the book about &lt;a href="https://brainfck.org/t/golang" rel="noopener noreferrer"&gt;Golang&lt;/a&gt; and Security.&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  For 2024
&lt;/h3&gt;

&lt;p&gt;For the up-coming year I'd like to focuss on several things. Continuing in the same scheme&lt;br&gt;
I did for my past goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Learning&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Music&lt;/p&gt;

&lt;p&gt;Besides playing the &lt;strong&gt;Djembe&lt;/strong&gt; this year I've started learning how to play the &lt;strong&gt;Bongos&lt;/strong&gt;. With the help of ChatGPT I was able to read notes again and therefore play some easy to more advanced rhythms on the Bongos. Next year I'd like to keep practicing and get more insights into Latin rhythms (Salsa, Bachata, Merengue, Mambo, Rumba etc.)&lt;/p&gt;

&lt;p&gt;I have played an &lt;strong&gt;acoustic&lt;/strong&gt; guitar for a while, although not with the same proficiency as I have with hand drums. For motivation, I would like to learn to play the &lt;strong&gt;electric&lt;/strong&gt; guitar and make progress in &lt;strong&gt;live looping&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;center&gt;&lt;small&gt;👉 Live looping with a pedal looper&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Projects&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Play with &lt;a href="https://brainfck.org/t/htmx" rel="noopener noreferrer"&gt;HTMX&lt;/a&gt; and &lt;a href="https://brainfck.org/t/golang" rel="noopener noreferrer"&gt;Golang&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd definitely love to do something &lt;em&gt;front-end&lt;/em&gt; related and therefore I'd like to play a little bit with &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;htmx&lt;/a&gt;. But first I need an idea for a small application. This way I plan to code again in Golang (this year I didn't manage to code anything useful).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Security of Github repositories&lt;/p&gt;

&lt;p&gt;While dealing with &lt;em&gt;Github&lt;/em&gt; and the &lt;em&gt;security settings&lt;/em&gt; of &lt;em&gt;repositories&lt;/em&gt;, I wanted to have a small tool at hand which will check for different settings (for each repository in an organization) and report (via Slack, E-Mail) if some settings are not&lt;br&gt;
&lt;em&gt;compliant&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finish "Documentation as Code" series&lt;/p&gt;

&lt;p&gt;This year I've started writing about several documentation techniques (as code) in my &lt;a href="https://dev.to/2023/07/18/documentation-as-code-for-cloud/"&gt;Documentation as Code&lt;/a&gt; series. I definitely want to add at least &lt;a href="https://d2lang.com/" rel="noopener noreferrer"&gt;D2Lang&lt;/a&gt; to it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>review</category>
      <category>productivity</category>
      <category>books</category>
      <category>learning</category>
    </item>
    <item>
      <title>Documentation as Code for Cloud - C4 Model &amp; Structurizr</title>
      <dc:creator>Victor Dorneanu</dc:creator>
      <pubDate>Thu, 02 Nov 2023 19:02:33 +0000</pubDate>
      <link>https://dev.to/dorneanu/documentation-as-code-for-cloud-c4-model-structurizr-1ipe</link>
      <guid>https://dev.to/dorneanu/documentation-as-code-for-cloud-c4-model-structurizr-1ipe</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://blog.dornea.nu/2023/07/30/documentation-as-code-for-cloud-plantuml/" rel="noopener noreferrer"&gt;last post&lt;/a&gt;, I've used &lt;a href="https://brainfck.org/t/plantuml" rel="noopener noreferrer"&gt;PlantUML&lt;/a&gt; to draw things like &lt;strong&gt;groups&lt;/strong&gt;, &lt;strong&gt;accounts&lt;/strong&gt;, and &lt;strong&gt;clusters&lt;/strong&gt;. However, I didn't focus on how different parts inside the business layer interact (usually components related to the main application/system relevant for your business). Now, we'll use a DSL to show these interactions between &lt;em&gt;components&lt;/em&gt;, &lt;em&gt;services&lt;/em&gt;, and &lt;em&gt;systems&lt;/em&gt;. I'll use the &lt;strong&gt;C4 model&lt;/strong&gt; to show the same system in &lt;strong&gt;different ways&lt;/strong&gt; based on who we're showing it to. It allows us to adjust how much detail we include.&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%2Fblog.dornea.nu%2Fposts%2Fimg%2F2023%2Fdocumentation-as-code%2Fstructurizr-LiveDeployment.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%2Fblog.dornea.nu%2Fposts%2Fimg%2F2023%2Fdocumentation-as-code%2Fstructurizr-LiveDeployment.png" alt="image" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 To learn how this diagram was created, continue reading 👇&lt;/small&gt;&lt;/center&gt;

&lt;h2&gt;
  
  
  C4 Model
&lt;/h2&gt;

&lt;p&gt;The C4 model was developed by &lt;a href="https://simonbrown.je/" rel="noopener noreferrer"&gt;Simon Brown&lt;/a&gt; as a means of providing a &lt;strong&gt;visual map&lt;/strong&gt; of system components across &lt;strong&gt;four levels of abstraction&lt;/strong&gt;, as suggested by its title. Each level of abstraction in the C4 model suits different &lt;strong&gt;audiences&lt;/strong&gt;, from the non-technical management level to detailed developer perspectives, each level of abstraction is tailored to meet its observer's understanding. To maintain consistency when describing the system design, the C4 model uniformly applies the same terminology and abstractions across all its levels, effectively implementing ubiquitous language principles from Domain-Driven Design (&lt;a href="https://brainfck.org/t/ddd" rel="noopener noreferrer"&gt;DDD&lt;/a&gt;).&lt;/p&gt;

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

&lt;center&gt;&lt;small&gt;👉 The 4 perspectives in the C4 model&lt;/small&gt;&lt;/center&gt;

&lt;h3&gt;
  
  
  Abstractions
&lt;/h3&gt;

&lt;p&gt;The C4 model uses &lt;a href="https://c4model.com/#Abstractions" rel="noopener noreferrer"&gt;abstractions&lt;/a&gt; to form an hierarchy of well-defined diagrams (at different levels). Currently these abstractions are available:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Person&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Represents human users interacting with the system (e.g., Administrator, End User, Customer).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;System&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A top-level view showing different people interacting with different software systems. (e.g., E-commerce Platform,
Payment Gateway, our self-destructing email service 😎).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Container&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Involves zooming into an individual system to reveal containers within. Examples include server-side applications, client-side applications, databases, etc.&lt;/li&gt;
&lt;li&gt;  not to be confused with Docker containers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Component&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Dives deeper into an individual container to expose its components, like classes, interfaces or objects in your code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Diagram types
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Level 1: Context diagram
&lt;/h4&gt;

&lt;p&gt;Shows how your system fits into the larger system environment (system landscape). It basically shows &lt;strong&gt;interactions&lt;/strong&gt; between users and systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  e.g. A payment system interacting with an user and a banking system&lt;/li&gt;
&lt;/ul&gt;

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

&lt;center&gt;&lt;small&gt;👉 Context diagram&lt;/small&gt;&lt;/center&gt;

&lt;h4&gt;
  
  
  Level 2: Container diagram
&lt;/h4&gt;

&lt;p&gt;Higher level view within a system itself. Shows software "containers" like web servers, standalone apps, or databases. (e.g., An API server, a database, and a client app in a single system)&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%2Foqqypy1eulykc36y847n.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%2Foqqypy1eulykc36y847n.png" alt="image" width="426" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Container diagram&lt;/small&gt;&lt;/center&gt;

&lt;h4&gt;
  
  
  Level 3: Component diagram
&lt;/h4&gt;

&lt;p&gt;Shows internal parts of a container. Mostly used with complex software. (e.g., Controllers, services, repositories inside of a web application)&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%2Fkeu08sg3rkg6ocya8vmo.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%2Fkeu08sg3rkg6ocya8vmo.png" alt="image" width="352" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Component diagram&lt;/small&gt;&lt;/center&gt;

&lt;h4&gt;
  
  
  Level 4: Code diagram
&lt;/h4&gt;

&lt;p&gt;A detailed view of the code level. For systems with little internal complexity, it can be skipped. (e.g., UML class diagrams)&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%2Fc2i9zdsh7bme5hg0ogpm.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%2Fc2i9zdsh7bme5hg0ogpm.png" alt="image" width="392" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Code diagram&lt;/small&gt;&lt;/center&gt;

&lt;h2&gt;
  
  
  Structurizr DSL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://structurizr.com/" rel="noopener noreferrer"&gt;Structurizr&lt;/a&gt; is used for &lt;em&gt;describing&lt;/em&gt; and &lt;em&gt;visualizing&lt;/em&gt; architecture using the C4 model. One of the main selling points is the fact you can define an entire (IT) architecture model using &lt;em&gt;text&lt;/em&gt;. A typical model consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  relationships between abstractions&lt;/li&gt;
&lt;li&gt;  different &lt;strong&gt;views&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's have a look at a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workspace {

    model {
        user = person "User"

        webApp = softwareSystem "Web Application" {
            tags "System"
        }

        database = softwareSystem "Database" {
            tags "Database"
        }

        team = person "Development Team"

        user -&amp;gt; webApp "Uses"
    }

    views {
        container webApp {
            include *
            autoLayout
        }

        styles {
            element "Database" {
                color "#0000ff"
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 1: Structurizr DSL: Basic structure&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;What do we have?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  *&lt;strong&gt;&lt;em&gt;Entities&lt;/em&gt;&lt;/strong&gt;*:

&lt;ul&gt;
&lt;li&gt;  "User": a person who uses the "Web Application".&lt;/li&gt;
&lt;li&gt;  "Web Application": a software system tagged as "System".&lt;/li&gt;
&lt;li&gt;  "Database": another software system tagged as "Database".&lt;/li&gt;
&lt;li&gt;  "Development Team": a person representing the team that develops the "Web Application".&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;em&gt;&lt;strong&gt;&lt;em&gt;Relationships&lt;/em&gt;&lt;/strong&gt;&lt;/em&gt;:

&lt;ul&gt;
&lt;li&gt;  The "User" uses the "Web Application".&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;em&gt;&lt;strong&gt;&lt;em&gt;Container View&lt;/em&gt;&lt;/strong&gt;&lt;/em&gt;:

&lt;ul&gt;
&lt;li&gt;  Focused on "Web Application".&lt;/li&gt;
&lt;li&gt;  Includes all elements in the model.&lt;/li&gt;
&lt;li&gt;  Uses automatic layout.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;em&gt;&lt;strong&gt;&lt;em&gt;Styles&lt;/em&gt;&lt;/strong&gt;&lt;/em&gt;:

&lt;ul&gt;
&lt;li&gt;  The "Database" elements are colored in blue ("#0000ff").&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Before we move on, let's briefly discuss the installation steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;I'd suggest you use the &lt;a href="https://hub.docker.com/r/structurizr/lite" rel="noopener noreferrer"&gt;Docker image&lt;/a&gt; for a safe playground:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 1337:8080 &lt;span class="nt"&gt;-v&lt;/span&gt; ./:/usr/local/structurizr structurizr/lite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will fetch the &lt;code&gt;structurizr/lite&lt;/code&gt; Docker image from &lt;a href="https://hub.docker.com/r/structurizr/lite" rel="noopener noreferrer"&gt;Dockerhub&lt;/a&gt;, start the container, mount the current working directory to &lt;code&gt;/usr/local/structurizr&lt;/code&gt; and setup a port forwarding from &lt;code&gt;localhost:1337&lt;/code&gt; to &lt;code&gt;&amp;lt;docker container&amp;gt;:8000&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Info Notice:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
👉 I've setup a GitHub repository with the code I'll be using in the next sections. Feel free to clone from &lt;a href="https://github.com/dorneanu/ripmail" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Short recap
&lt;/h3&gt;

&lt;p&gt;If you recall my &lt;a href="https://blog.dornea.nu/2023/07/18/documentation-as-code-for-cloud/" rel="noopener noreferrer"&gt;initial post&lt;/a&gt; the entire aim was to document a hypothetical self-destructing e-mail service. In my &lt;a href="https://blog.dornea.nu/2023/07/30/documentation-as-code-for-cloud-plantuml/#sequence-diagrams" rel="noopener noreferrer"&gt;2nd blog post&lt;/a&gt; (about PlantUML) I've generated following &lt;em&gt;sequence diagram&lt;/em&gt;:&lt;/p&gt;

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

&lt;center&gt;👉 &lt;a href="https://github.com/dorneanu/blog/blob/master/static/code/2023/documentation-as-code/plantuml//plantuml-seq-send-aws-logging.puml" rel="noopener noreferrer"&gt;Full PlantUML Code&lt;/a&gt;
&lt;/center&gt;

&lt;p&gt;In the following I'll try to implement exactly this workflow using C4 and Structurizr DSL.&lt;/p&gt;

&lt;h2&gt;
  
  
  ripmail
&lt;/h2&gt;

&lt;p&gt;👉 Checkout the code at &lt;a href="https://github.com/dorneanu/ripmail" rel="noopener noreferrer"&gt;https://github.com/dorneanu/ripmail&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model
&lt;/h3&gt;

&lt;p&gt;Let's start with the basic construct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workspace {  ❶
  name "Self-Destructing Email Service"
  description "The sofware architecture of the self-destructing email service"

  model {    ❷
    //  ...
  }

  views {    ➌
    // System Landscape
 ❺ systemlandscape "SystemLandscape" {
      include *
      # autoLayout
    }

    // Themes
    // You can combine multiple themes!
 ❻ theme https://static.structurizr.com/themes/amazon-web-services-2023.01.31/theme.json

    styles { ❹
      element "Person" {
        color #ffffff
        fontSize 22
        shape Person
      }
      element "Sender" {
        color #ffffff
        background #8FB5FE
        shape Person
      }
      element "Recipient" {
        color #ffffff
        background #E97451
        shape Person
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 2: Basic Structurizr construct&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;So, what do we have?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ❶ &lt;code&gt;workspace&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;  Defines the workspace for a self-destructing email service.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❷ &lt;code&gt;model&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;  This has to be implemented but basically it's a&lt;/li&gt;
&lt;li&gt;  Placeholder section where you'd define the elements (software systems, people, containers) and their relations.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ➌ &lt;code&gt;views&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;  A &lt;strong&gt;System Landscape view&lt;/strong&gt; ❺ that includes all elements defined in the model.&lt;/li&gt;
&lt;li&gt;  The &lt;a href="https://www.structurizr.com/help/themes" rel="noopener noreferrer"&gt;specified theme&lt;/a&gt; ❻ comes from an external JSON file, allowing broad customization of the look-and-feel.&lt;/li&gt;
&lt;li&gt;  Three styles are defined for different types of elements labeled as &lt;em&gt;Person&lt;/em&gt;, &lt;em&gt;Sender&lt;/em&gt;, and &lt;em&gt;Recipient&lt;/em&gt;. These
characters are all represented by the &lt;em&gt;Person&lt;/em&gt; shape.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Let's focus more on the &lt;code&gt;model&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

  model {
 ❶ sender = person "Sender" "Sender creates self-destructing email" {
      tags "Sender"
    }
 ❷ recipient = person "Recipient" "Recipient receives self-destructing email" {
      tags "Recipient"
    }

 ➌ group "Self-Destructing Email Service" {
      // Logging keeps track of several events
 ❹   logging = softwaresystem "Logging System" "Logs several events related to mail generation" {
        tags "Service API"
      }
 ❺   storage = softwaresystem "Storage System" "Stores encrypted mail content" {
        tags "Database"
        storageBackend = container "Storage Backend"
      }

 ❻   notification = softwaresystem "Notification System" "Sends notification to recipient to view email" {
        tags "System"

        // --- Notification Service
        notificationService = group "Notification Service" {
          notificationAPI = container "Notification API" {
            tags "NotificationService" "Service API"
          }
        }
      }

   ...

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

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 3: Adding actors and different systems&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;We have following &lt;strong&gt;elements&lt;/strong&gt; and &lt;strong&gt;groups&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ❶ &lt;em&gt;Sender&lt;/em&gt;: Person who creates the self-destructing email.&lt;/li&gt;
&lt;li&gt;  ❷ &lt;em&gt;Recipient&lt;/em&gt;: Person who receives the self-destructing email.&lt;/li&gt;
&lt;li&gt;  ➌ &lt;em&gt;Self-Destructing Email Service&lt;/em&gt;: Represents the overall service/system being described.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally we have these &lt;strong&gt;systems&lt;/strong&gt; inside the group:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ❹ &lt;em&gt;Logging System&lt;/em&gt;: Keeps track of events related to mail creation.&lt;/li&gt;
&lt;li&gt;  ❺ &lt;em&gt;Storage System&lt;/em&gt;: Stored encrypted email content. Includes a &lt;em&gt;Storage Backend&lt;/em&gt; container.&lt;/li&gt;
&lt;li&gt;  ❻ &lt;em&gt;Notification System&lt;/em&gt;: Sends notification to recipient. Contains a Notification Service group with a &lt;em&gt;Notification
API&lt;/em&gt; container.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Main backend system
&lt;/h4&gt;

&lt;p&gt;Now the &lt;strong&gt;backend system&lt;/strong&gt; responsible for the business logic:&lt;br&gt;
&lt;/p&gt;

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

      // Backend system responsible for the business logic
❶    backend = softwaresystem "Backend System" "Contains logic how self-destructing mails should be created and dispatched to the recipient." {
        tags "BackendSystem"
❷       webapplication = container "Web Application"

        // Services/
        // --- Authentication Service
➌      authService = group "Authentication Service" {
❹        authAPI = container "Auth Service API" {
            tags "AuthService" "Service API"
          }
❺        authDB = container "Auth Service Database" {
            tags "AuthService" "Database"
❻          authAPI -&amp;gt; this "Checks if credentials match"
          }
        }


        // --- Email Composition Service
❼      mailCompositionService = group "Email Composition Service" {
❽        mailCompositionAPI = container "Email Composition API" {
            tags "EmailCompositionService" "Service API"
          }
❾        mailDB = container "Email Composition Database" {
            tags "Emailcompositionservice" "Database"
❿          mailCompositionAPI -&amp;gt; this "Stores metadata of mails"
          }

        }

        // --- Email Composition Service
⓫      viewEmailService = group "View Email Service" {
⓬          viewEmailFrontend = container "Email View Frontend" {
            tags "ViewEmailService"
          }
        }

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

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 4: Main backend system and ther underlying services&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;The &lt;em&gt;Backend System&lt;/em&gt; is the core system, with business logic, for creating/dispatching self-destructing mails.&lt;br&gt;
of following &lt;strong&gt;containers&lt;/strong&gt; and &lt;strong&gt;services&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ❷ &lt;em&gt;Web Application&lt;/em&gt;: The &lt;strong&gt;frontend&lt;/strong&gt; component within the backend system for &lt;em&gt;creating&lt;/em&gt; mails.&lt;/li&gt;
&lt;li&gt;  ➌ &lt;em&gt;Authentication Service&lt;/em&gt;: Group handling user credential verification.

&lt;ul&gt;
&lt;li&gt;  ❹ &lt;em&gt;Auth Service API&lt;/em&gt;: Provides interface for authentication service.&lt;/li&gt;
&lt;li&gt;  ❺ &lt;em&gt;Auth Service Database&lt;/em&gt;: Stores user credential data.&lt;/li&gt;
&lt;li&gt;  ❻ &lt;em&gt;Auth Service API-&amp;gt;Auth Service Database&lt;/em&gt;: Indicates API checks credentials against this database.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  ❼ &lt;em&gt;Email Composition Service&lt;/em&gt;: Group handling creation/storage of emails.

&lt;ul&gt;
&lt;li&gt;  ❽ &lt;em&gt;Email Composition API&lt;/em&gt;: Interface for the email composition service.&lt;/li&gt;
&lt;li&gt;  ❾ &lt;em&gt;Email Composition Database&lt;/em&gt;: Stores meta-information of emails.&lt;/li&gt;
&lt;li&gt;  ❿ &lt;em&gt;Email Composition API -&amp;gt; Email Composition Database&lt;/em&gt;: Indicates API stores mail metadata in this database.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  ⓫ &lt;em&gt;View Email Service&lt;/em&gt;: Group handling email display.

&lt;ul&gt;
&lt;li&gt;  ⓬ &lt;em&gt;Email View Frontend&lt;/em&gt;: The &lt;strong&gt;frontend&lt;/strong&gt; component withing the backend system for &lt;em&gt;viewing&lt;/em&gt; emails.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Relationships
&lt;/h4&gt;

&lt;p&gt;And finally the &lt;strong&gt;relationships&lt;/strong&gt; between different components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
        // Store mail data and encrypted content
        mailCompositionAPI -&amp;gt; storage "Store mail metadata and content"

        // Notify recipient
        mailCompositionAPI -&amp;gt; notificationAPI "Notify recipient"
        notificationAPI -&amp;gt; mailcompositionAPI "Recipient notified"

        // Log events
        notificationAPI -&amp;gt; logging "Log Email sent event"

        // Sender creates new email
        sender -&amp;gt; webapplication "Create new mail"
        webapplication -&amp;gt; authAPI "Authenticate user"
        webapplication -&amp;gt; mailCompositionAPI "Create mails"
        notification -&amp;gt; recipient "Send out notification"
        backend -&amp;gt; logging "Create events"

        // Recipient receives new mail
        recipient -&amp;gt; webapplication "View self-destructing mail"
        webapplication -&amp;gt; viewEmailFrontend "View email"
        viewEmailFrontend -&amp;gt; mailDB
        viewEmailFrontend -&amp;gt; storage
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 5: Relationships between different components&lt;/small&gt;&lt;/center&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;From&lt;/th&gt;
&lt;th&gt;To&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mail Composition API&lt;/td&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Store mail metadata and encrypted content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mail Composition API&lt;/td&gt;
&lt;td&gt;Notification API&lt;/td&gt;
&lt;td&gt;Notify recipient&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notification API&lt;/td&gt;
&lt;td&gt;Mail Composition API&lt;/td&gt;
&lt;td&gt;Recipient notified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notification API&lt;/td&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;Log Email sent event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sender&lt;/td&gt;
&lt;td&gt;Web Application&lt;/td&gt;
&lt;td&gt;Create new mail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Application&lt;/td&gt;
&lt;td&gt;Auth API&lt;/td&gt;
&lt;td&gt;Authenticate user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Application&lt;/td&gt;
&lt;td&gt;Mail Composition API&lt;/td&gt;
&lt;td&gt;Create mails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notification&lt;/td&gt;
&lt;td&gt;Recipient&lt;/td&gt;
&lt;td&gt;Send out notification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend System&lt;/td&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;Create events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recipient&lt;/td&gt;
&lt;td&gt;Web Application&lt;/td&gt;
&lt;td&gt;View self-destructing mail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Application&lt;/td&gt;
&lt;td&gt;View Email Frontend&lt;/td&gt;
&lt;td&gt;View email&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View Email Frontend&lt;/td&gt;
&lt;td&gt;MailDB&lt;/td&gt;
&lt;td&gt;Fetches email data for visualization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View Email Frontend&lt;/td&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Fetches email details for visualization&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Deployments
&lt;/h4&gt;

&lt;p&gt;Deployment components are required for the deployment diagrams. These illustrate how software systems are deployed onto infrastructure elements in an environment. They also enable you to visualize how containers within a system map onto the infrastructure.&lt;/p&gt;

&lt;p&gt;This kind of diagrams are very important as they provide important information regarding system runtime environment such as scaling, redundancy, network topology, and communication protocols. They are crucial to understanding the physical aspects and deployment context of a system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workspace {

  model {
  //  ...
  live = deploymentEnvironment "Live" { ❶
    // AWS
    deploymentNode "Amazon Web Services" { ❷
        tags "Amazon Web Services - Cloud"

          // Which region
    ➌     deploymentNode "eu-central-1" {
            tags "Amazon Web Services - Region"
            ...
          }
    }
  }
  }

  views {
  // ...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 6: The live deployment environment&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;We're still defining the &lt;code&gt;model&lt;/code&gt;. Now we have defined a &lt;code&gt;deploymentEnvironment&lt;/code&gt; &lt;em&gt;live&lt;/em&gt; ❶ which should be deployed into the AWS Cloud ❷, namely in &lt;code&gt;eu-central-1&lt;/code&gt; ➌. In this region we'll have different &lt;em&gt;organizational units&lt;/em&gt; (OUs):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OU: Tech&lt;/p&gt;

&lt;p&gt;This will host the &lt;strong&gt;EKS cluster&lt;/strong&gt; as well as the &lt;strong&gt;API Gateway&lt;/strong&gt; which serves as the main entrypoint for API calls.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OU: Security&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;alert &amp;amp; monitoring&lt;/strong&gt; will take place. Also here relevant data to the mail will be stored within &lt;strong&gt;S3 buckets&lt;/strong&gt;. Finally we use &lt;strong&gt;IAM&lt;/strong&gt; capabilities to make sure authentication and authorization works properly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OU: DevOps&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;CI/CD&lt;/strong&gt; build pipeline and &lt;strong&gt;infrastructure provisioning&lt;/strong&gt; will take place here. The software artefacts will be built here and deployed into the accounts&lt;br&gt;
inside "OU: Tech".&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

       // Which region
       deploymentNode "eu-central-1" {
         tags "Amazon Web Services - Region"

         // ------------------------------------------------
         // Organizational Unit: DevOps
         // ------------------------------------------------
         deploymentNode "OU-DevOps" {...}

         // ------------------------------------------------
         // Organizational Unit: Tech
         // ------------------------------------------------
         ou_tech = deploymentNode "OU-Tech" {...}


         // ------------------------------------------------
         // Organizational Unit: Security
         // ------------------------------------------------
         deploymentNode "OU-Security" {...}
       }

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

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 7: Outline main organizational units (OUs)&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OU: DevOps&lt;/p&gt;

&lt;p&gt;But one thing at a time:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      // --------------------------------------------
      // Organizational Unit: DevOps
      // --------------------------------------------
      deploymentNode "OU-DevOps" {
❶      tags "Amazon Web Services - AWS Organizations Organizational Unit"

❷        deploymentNode "acc-devops-prod" {
➌          tags "Amazon Web Services - AWS Organizations Account"

❹          vpc_management = deploymentNode "VPC (management)" {
❺            tags "Amazon Web Services - VPC Virtual private cloud VPC"

❻            gitlab_server = infrastructureNode "Gitlab Server" {
❼              tags "Amazon Web Services - EC2"
            }

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


&lt;center&gt;&lt;small&gt;Code Snippet 8: Deployment components for the OU DevOps&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;The DevOps OU deployment components are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Organizational Unit (&lt;strong&gt;OU-DevOps&lt;/strong&gt;): Represents a unit in the organization.

&lt;ul&gt;
&lt;li&gt;  ❶ Tagged as an Amazon Web Services (AWS) Organizations Organizational Unit.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❷ &lt;em&gt;acc-devops-prod&lt;/em&gt;: Represents an account within the &lt;strong&gt;OU-DevOps&lt;/strong&gt; unit.

&lt;ul&gt;
&lt;li&gt;  ➌ Tagged as an AWS Organizations Account.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❹ VPC (&lt;em&gt;vpc_management&lt;/em&gt;): A Virtual Private Cloud (VPC) within the &lt;em&gt;acc-devops-prod&lt;/em&gt; account.

&lt;ul&gt;
&lt;li&gt;  ❺ Tagged as an AWS VPC Virtual private cloud VPC.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❻ Gitlab Server (&lt;em&gt;gitlab_server&lt;/em&gt;): Infrastructure node within the VPC.

&lt;ul&gt;
&lt;li&gt;  ❼ Tagged as AWS EC2.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;OU: Security&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     // ---------------------------------------------
     // Organizational Unit: Security
     // ---------------------------------------------
❶    deploymentNode "OU-Security" {
❷      tags "Amazon Web Services - AWS Organizations Organizational Unit"

➌      deploymentNode "acc-security-logging" {
❹        tags "Amazon Web Services - AWS Organizations Account"

❺        s3_logging = infrastructureNode "S3 Bucket" {
❻          tags "Amazon Web Services - Simple Storage Service"
         }

❼        infrastructureNode "CloudWatch Logs" {
❽          tags "Amazon Web Services - CloudWatch Logs"
         }
       }

❾      deploymentNode "acc-security-monitoring" {
❿        tags "Amazon Web Services - AWS Organizations Account"

⓫        infrastructureNode "CloudWatch" {
⓬          tags "Amazon Web Services - CloudWatch Alarm"
         }
       }
     }

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



&lt;center&gt;
&lt;small&gt;
Code Snippet 9: Deployment components for the OU Security
&lt;/small&gt;
&lt;/center&gt;

&lt;p&gt;The Security OU deployment components are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Organizational Unit (&lt;strong&gt;OU-Security&lt;/strong&gt;): Represents a security unit in the organization.

&lt;ul&gt;
&lt;li&gt;  ❶ Tagged as an AWS Organizations Organizational Unit.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ➌ &lt;em&gt;acc-security-logging&lt;/em&gt;: Represents an account within the &lt;strong&gt;OU-Security&lt;/strong&gt; unit for logging purposes.

&lt;ul&gt;
&lt;li&gt;  ❹ Tagged as an AWS Organizations Account.&lt;/li&gt;
&lt;li&gt;  ❺ Contains an "S3 Bucket" infrastructure node.

&lt;ul&gt;
&lt;li&gt;  ❻ Tagged as AWS Simple Storage Service.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❼ Contains a "CloudWatch Logs" infrastructure node.

&lt;ul&gt;
&lt;li&gt;  ❽ Tagged as AWS CloudWatch Logs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;  ❾ &lt;em&gt;acc-security-monitoring&lt;/em&gt;: Represents another account within the &lt;strong&gt;OU-Security&lt;/strong&gt; unit for monitoring purposes.

&lt;ul&gt;
&lt;li&gt;  ❿ Tagged as an AWS Organizations Account.&lt;/li&gt;
&lt;li&gt;  ⓫ Contains a "CloudWatch" infrastructure node.

&lt;ul&gt;
&lt;li&gt;  ⓬ Tagged as AWS CloudWatch Alarm.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;OU: TECH&lt;/p&gt;

&lt;p&gt;Now the most complicated one:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     // --------------------------------------------
     // Organizational Unit: Tech
     // --------------------------------------------
❶    ou_tech = deploymentNode "OU-Tech" {
       tags "Amazon Web Services - AWS Organizations Organizational Unit"

❷      deploymentNode "acc-tech-prod" {
         tags "Amazon Web Services - AWS Organizations Account"

         // EKS control plane
➌        eks_vpc = deploymentNode "EKS VPC" {
           tags = "Amazon Web Services - VPC Virtual private cloud VPC"

❹          eks_control_plane = infrastructureNode "EKS Control Plane" {
             tags = "Amazon Web Services - EKS Cloud"
           }
         }

         // ECR
❺        ecr = infrastructureNode "ECR" {
           tags "Amazon Web Services - Elastic Container Registry"
           description "Private ECR registry"
         }

         // EKS cluster
❻        workload_vpc = deploymentNode "Workload VPC" {...}

         // DynamoDB instances
❼        dbs = group "Databases" {...}

         // S3 (Storage System)
❽        s3_storage = infrastructureNode "S3 Bucket (storage)" {
           tags "Amazon Web Services - Simple Storage Service"
         }

       }
     }

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



&lt;center&gt;
&lt;small&gt;
Code Snippet 10: Deployment components for the OU Tech
&lt;/small&gt;
&lt;/center&gt;

&lt;p&gt;This will result in following components hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ❶ Organizational Unit (OU-Tech): Represents a technology unit within the organization.&lt;/li&gt;
&lt;li&gt;  ❷ &lt;em&gt;acc-tech-prod&lt;/em&gt;: Represents a production account within the "&lt;strong&gt;OU-Tech&lt;/strong&gt;" unit.

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;EKS control plane&lt;/strong&gt; deployed within an EKS VPC.

&lt;ul&gt;
&lt;li&gt;  ➌ &lt;em&gt;EKS VPC&lt;/em&gt;: VPC where the EKS control plane is deployed,&lt;/li&gt;
&lt;li&gt;  ❹ &lt;em&gt;EKS Control Plane&lt;/em&gt;: infrastructure node within EKS VPC.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❺ &lt;em&gt;ECR&lt;/em&gt;: Infrastructure node for the Elastic Container Registry with private ECR registry.&lt;/li&gt;

&lt;li&gt;  ❻ &lt;em&gt;Workload VPC&lt;/em&gt;: Deployment node holding different workloads.&lt;/li&gt;

&lt;li&gt;  ❼ Databases group holds &lt;em&gt;DynamoDB&lt;/em&gt; instances.&lt;/li&gt;

&lt;li&gt;  ❽ &lt;em&gt;S3 Bucket (storage)&lt;/em&gt;: Infrastructure node for the storage system.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Let's have a look what's inside the &lt;em&gt;workload VPC&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // EKS cluster
  workload_vpc = deploymentNode "Workload VPC" {
    tags = "Amazon Web Services - VPC Virtual private cloud VPC"

    // AZ 1
❶   deploymentNode "Availability Zone 1" {
      tags = "Amazon Web Services - Region"

❷     deploymentNode "Subnet 1" {
        tags = "Amazon Web Services - VPC VPN Gateway"

➌       eks_node_group1 = deploymentNode "EKS Managed Node Group" {
          tags = "Amazon Web Services - EKS Cloud"

❹         eks_node_group1_pod1 = deploymentNode "Pod 1" {
            tags = "Kubernetes - pod"
❺           pod1_authAPI = containerInstance authAPI
          }

❻         eks_node_group1_pod2 = deploymentNode "Pod 2" {
            tags = "Kubernetes - pod"
❼           pod2_mailCompositionAPI = containerInstance mailcompositionAPI
❽           pod2_notificationAPI = containerInstance notificationAPI

          }

        }
      }

    }

    // AZ 2
❾   deploymentNode "Availability Zone 2" {
      tags = "Amazon Web Services - Region"

❿     deploymentNode "Subnet 1" {
        tags = "Amazon Web Services - VPC VPN Gateway"

⓫       eks_node_group2 = infrastructureNode "EKS Managed Node Group" {
          tags = "Amazon Web Services - EKS Cloud"
        }

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



&lt;center&gt;
&lt;small&gt;
Code Snippet 11: Components of the workload VPC
&lt;/small&gt;
&lt;/center&gt;

&lt;p&gt;The workload VPC consists of 2 availability zones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ❶ &lt;strong&gt;Availability Zone 1&lt;/strong&gt;: A separate deployment node categorized as an AWS Region.

&lt;ul&gt;
&lt;li&gt;  ❷ &lt;em&gt;Subnet 1&lt;/em&gt;: Deployment node within Availability Zone 1.&lt;/li&gt;
&lt;li&gt;  ➌ &lt;em&gt;EKS Managed Node Group&lt;/em&gt;: Node group for managing EKS resources.&lt;/li&gt;
&lt;li&gt;  ❹ &lt;em&gt;Pod 1&lt;/em&gt;: Deployment node within the &lt;em&gt;EKS Managed Node Group&lt;/em&gt;.

&lt;ul&gt;
&lt;li&gt;  ❺ Houses instance of &lt;em&gt;authAPI&lt;/em&gt; container.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❻ &lt;em&gt;Pod 2&lt;/em&gt;: Another deployment node within the &lt;em&gt;EKS Managed Node Group&lt;/em&gt;.

&lt;ul&gt;
&lt;li&gt;  ❼ Houses instance of &lt;em&gt;mailcompositionAPI&lt;/em&gt; container.&lt;/li&gt;
&lt;li&gt;  ❽ Houses instance of &lt;em&gt;notificationAPI&lt;/em&gt; container.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;  ❾ &lt;em&gt;Availability Zone 2&lt;/em&gt;: Another separate deployment node categorized as an AWS Region.

&lt;ul&gt;
&lt;li&gt;  ❿ &lt;em&gt;Subnet 1&lt;/em&gt;: Deployment node within Availability Zone 2.&lt;/li&gt;
&lt;li&gt;  ⓫ &lt;em&gt;EKS Managed Node Group&lt;/em&gt;: Infrastructure node for managing EKS resources.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Let's also have a look how we can use &lt;code&gt;containerInstance&lt;/code&gt; for the databases:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     // DynamoDB instances
❶  dbs = group "Databases" {
       deploymentNode "DB VPC" {
         tags = "Amazon Web Services - VPC Virtual private cloud VPC"

❷      deploymentNode "DynamoDB (Auth)" {
           tags "Amazon Web Services - DynamoDB"

➌        liveUserDB = containerInstance authDB
         }

❹      deploymentNode "DynamoDB (Mails)" {
           tags "Amazon Web Services - DynamoDB"

❺        liveMailDB = containerInstance mailDB
         }
       }
     }

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



&lt;center&gt;
&lt;small&gt;
Code Snippet 12: Components of the DB VPC
&lt;/small&gt;
&lt;/center&gt;

&lt;p&gt;This will create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ❶ &lt;em&gt;Databases&lt;/em&gt;: A group of databases within a DB VPC deployment node.&lt;/li&gt;
&lt;li&gt;  ❷ &lt;em&gt;DynamoDB (Auth)&lt;/em&gt;: DynamoDB instance for authentication.

&lt;ul&gt;
&lt;li&gt;  ➌ Contains a live instance of &lt;em&gt;authDB&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  ❹ &lt;em&gt;DynamoDB (Mails)&lt;/em&gt;: DynamoDB instance for mail metadata.

&lt;ul&gt;
&lt;li&gt;  ❺ Contains a live instance of &lt;em&gt;mailDB&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Views
&lt;/h3&gt;

&lt;p&gt;Views in Structurizr are used to create &lt;strong&gt;visual&lt;/strong&gt; diagrams of your software architecture model. They provide a way to communicate the different aspects of your system to &lt;strong&gt;various stakeholders&lt;/strong&gt;. Views can be thought of as 'camera angles' on your architecture model, each designed to present a certain perspective of the system.&lt;/p&gt;

&lt;h4&gt;
  
  
  System Landscape
&lt;/h4&gt;

&lt;p&gt;The &lt;em&gt;System Landscape&lt;/em&gt; view in Structurizr is the &lt;strong&gt;highest&lt;/strong&gt; level view of a software system's architecture. It shows all users, software systems and external systems or services in scope. It informs about the overall system context and interaction among systems and users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // System Landscape
    systemlandscape "SystemLandscape" {
      include *
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 13: The System Landscape where every component (*) is included in the diagram&lt;/small&gt;&lt;/center&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%2Fs92rmy0a8wahliii38lb.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%2Fs92rmy0a8wahliii38lb.png" alt="image" width="800" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 System Landscape&lt;/small&gt;&lt;/center&gt;

&lt;h4&gt;
  
  
  Deployment Live
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;Deployment View&lt;/strong&gt; in Structurizr is a type of view that visualizes the &lt;strong&gt;mapping of software building blocks&lt;/strong&gt; (like Containers or Components) to &lt;strong&gt;infrastructure elements&lt;/strong&gt;, including servers, containers or cloud services. It gives a clear indication of how and where the software system runs in different environments (like development, staging, production).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Deployment live
    deployment backend live "LiveDeployment"  {
      include *
      description "An example live deployment for the self-destructing email service"
    }

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

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 14: The deployment view for live&lt;/small&gt;&lt;/center&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%2Fblog.dornea.nu%2Fposts%2Fimg%2F2023%2Fdocumentation-as-code%2Fstructurizr-LiveDeployment.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%2Fblog.dornea.nu%2Fposts%2Fimg%2F2023%2Fdocumentation-as-code%2Fstructurizr-LiveDeployment.png" alt="image" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Deployment View&lt;/small&gt;&lt;/center&gt;

&lt;h4&gt;
  
  
  Containers
&lt;/h4&gt;

&lt;p&gt;In Structurizr, a &lt;em&gt;Container&lt;/em&gt; represents an &lt;strong&gt;executable unit&lt;/strong&gt; (application, data store, microservice, etc.) that encapsulates a portion of your software system. Containers run inside software systems and have interfaces that let them interact with other containers and/or software systems. The Container view shows the internal layout of a software system, specifying contained components and their interactions. This level of abstraction is valuable for developers and others dealing with system implementation and operation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Backend
    container backend "Containers_All" {
      include *
      # autolayout
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;&lt;small&gt;Code Snippet 15: The container view for all resources&lt;/small&gt;&lt;/center&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%2Fqgxgktlodjbu5g8cx7q0.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%2Fqgxgktlodjbu5g8cx7q0.png" alt="image" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 Containers (global)&lt;/small&gt;&lt;/center&gt;

&lt;p&gt;And now for specific services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Notification Service&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    container backend "Containers_NotificationService" {
      include -&amp;gt;notificationService-&amp;gt;
      autolayout
    }
&lt;/code&gt;&lt;/pre&gt;


&lt;center&gt;
&lt;small&gt;
Code Snippet 16: Container view for the notification service
&lt;/small&gt;
&lt;/center&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%2F43wzr990znuh0jioepm5.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%2F43wzr990znuh0jioepm5.png" alt="image" width="800" height="843"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;small&gt;👉 Container view for the notification service&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Mail Composition Service&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    container backend "Containers_MailCompositionService" {
      include -&amp;gt;mailCompositionService-&amp;gt;
      autolayout
    }
&lt;/code&gt;&lt;/pre&gt;



  &lt;span&gt;Code Snippet 17:&lt;/span&gt;
  Container view for the email composition service


&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%2Fpx5n2q2hisjbz3tsauti.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%2Fpx5n2q2hisjbz3tsauti.png" alt="image" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;small&gt;👉 Container view for the Mail Composition Service&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Authentication Service&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    container backend "Containers_AuthenticationService" {
      include -&amp;gt;authService-&amp;gt;
      autolayout
    }
&lt;/code&gt;&lt;/pre&gt;



  &lt;span&gt;Code Snippet 18:&lt;/span&gt;
  Container view for the authentication service


&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%2F133vpc7pacm59r4v3lvs.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%2F133vpc7pacm59r4v3lvs.png" alt="image" width="800" height="1793"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;small&gt;👉 Container view for the Authentication Service&lt;/small&gt;&lt;/center&gt;

&lt;h2&gt;
  
  
  Extra features
&lt;/h2&gt;

&lt;p&gt;With the &lt;a href="https://www.structurizr.com/dsl" rel="noopener noreferrer"&gt;online version of Structurizr&lt;/a&gt; you get access to diffeerent exporting features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;PlantUML&lt;/strong&gt;: Export your model as PlantUML diagrams.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;C4-PlantUML&lt;/strong&gt;: Export your model as &lt;a href="https://github.com/plantuml-stdlib/C4-PlantUML" rel="noopener noreferrer"&gt;C4-PlantUML diagrams&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Mermaid&lt;/strong&gt;: Generate Mermaid diagrams from your model.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;DOT&lt;/strong&gt;: Export containers and components as DOT graph description language.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;ilograph&lt;/strong&gt;: Export the model and the views for &lt;a href="https://www.ilograph.com/" rel="noopener noreferrer"&gt;ilograph.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among these I've found &lt;strong&gt;ilograph&lt;/strong&gt; to be the most interactive one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ilograph
&lt;/h3&gt;

&lt;p&gt;Once you've exported your &lt;em&gt;workspace&lt;/em&gt; in ilograph format, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://app.ilograph.com/?createNew=1" rel="noopener noreferrer"&gt;Create a new ilograph diagram&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Paste in the exported ilograph code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is what you get:&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%2Fw375ahtlzr3nyr6c1dy6.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%2Fw375ahtlzr3nyr6c1dy6.png" alt="image" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 ilograph with code&lt;/small&gt;&lt;/center&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%2Fu9zzws3cqccxpui9579d.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%2Fu9zzws3cqccxpui9579d.png" alt="image" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👉 ilograph without code&lt;/small&gt;&lt;/center&gt;

&lt;ul&gt;
&lt;li&gt;  👉 Here's the &lt;a href="https://github.com/dorneanu/ripmail/tree/main/docs/ilograph" rel="noopener noreferrer"&gt;ilograph code&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  👉 Check out &lt;a href="https://www.ilograph.com/architecture-center/index.html" rel="noopener noreferrer"&gt;other architecture diagrams&lt;/a&gt; made with ilograph.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;The resources I've consumed for generating the content and diagrams for this blog post:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2023-10-05 ◦ &lt;a href="https://icepanel.io/blog/2022-10-03-c4-model-for-system-architecture-design?utm_source=dev_to&amp;amp;utm_medium=post&amp;amp;utm_campaign=should_you_use_c4" rel="noopener noreferrer"&gt;IcePanel.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;visual&lt;/em&gt; modelling tool for C4&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2023-10-05 ◦ &lt;a href="https://github.com/plantuml-stdlib/C4-PlantUML" rel="noopener noreferrer"&gt;C4-PlantUML&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C4-PlantUML combines the benefits of PlantUML and the C4 model for providing a simple way of describing and communicate software architectures&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Articles&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  2023-10-08 ◦ &lt;a href="https://www.dandoescode.com/blog/c4-models-with-structurizr" rel="noopener noreferrer"&gt;Software Diagrams - C4 Models with Structurizr&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  2023-07-10 ◦ &lt;a href="https://practical.li/engineering-playbook/architecture/structurizr/" rel="noopener noreferrer"&gt;Structurizr - Practicalli Engineering Playbook&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  2022-10-31 ◦ &lt;a href="https://dev.to/icepanel/c4-model-for-system-architecture-design-16dh"&gt;C4 model for system architecture design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  2022-10-10 ◦ &lt;a href="https://dev.to/indrive_tech/c4-models-architecture-from-simple-to-complex-38fk"&gt;C4 Models: Architecture From Simple To Complex&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Structurizr&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  2023-10-07 ◦ &lt;a href="https://www.structurizr.com/help/themes" rel="noopener noreferrer"&gt;Structurizr - Help - Themes&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Videos&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  2023-07-10 ◦ &lt;a href="https://www.youtube.com/watch?v=f7i2wxQVffk&amp;amp;list=PLEx5khR4g7PLf2kQn3nYaZJC2Zv2GPbnY&amp;amp;ab_channel=GOTOConferences" rel="noopener noreferrer"&gt;C4 Models as Code • Simon Brown • YOW! 2022 - YouTube&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Outlook
&lt;/h2&gt;

&lt;p&gt;In the next post I'll deep-dive into the &lt;a href="https://d2lang.com/" rel="noopener noreferrer"&gt;D2&lt;/a&gt; language which also has a huge set of features. Stay tuned.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>architecture</category>
      <category>c4model</category>
      <category>structurizr</category>
    </item>
  </channel>
</rss>
