<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
    <title type="text">David Chico Pham | Cooking Code and Eating Knowledge</title>
    <subtitle type="text">Bloggin is back, baby.</subtitle>

    <id>https://davidchicopham.com/writing/feed.xml</id>
    <link rel="alternate" type="text/html" href="https://davidchicopham.com" />
    <link rel="self" type="application/atom+xml" href="https://davidchicopham.com/writing/feed.xml" />

    <updated>2026-10-08T19:50:39Z</updated>
    <author>
        <name>David Pham</name>
        <email></email>
    </author>
    <generator uri="https://www.11ty.dev/">Eleventy.js</generator>
            
            <entry>
                <title></title><link href="https://davidchicopham.com/this-is-my-next/2026-03-3-day-2-atproto-talk-june-2025-todos/"/><updated>2026-10-08T19:50:39Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/2026-03-3-day-2-atproto-talk-june-2025-todos/</id>
                <content type="html">&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Set up atproto project section
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Create the markdown file&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Add the video embed and screenshots&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Update workflow in adding images to posts with cloundinary and pre-commit hook
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Write the upload script&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Add the pre-commit hook with husky&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Php fundementals
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Developer Notebook set up&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Third Newsroom
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; buy domain&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; set up codebase
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; sanity backend&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; AstroJS frontend&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Postgres DB&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; checked=&quot;true&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; deploy to netlify and render&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content>
            </entry>
            
              
            <entry>
                <title>Rethinking AI - JEV as realtime intellience in code</title><link href="https://www.youtube.com/watch?v=3MwcIgBRras"/><updated>2026-10-08T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/Rethinking-AI-JEV-as-realtime-intelligence-in-code/</id>
                <content type="html">&lt;h1 id=&quot;notes-on-megadev-workshop-on-jev&quot; tabindex=&quot;-1&quot;&gt;Notes on Mega.dev workshop on JEV:&lt;/h1&gt;
&lt;p&gt;The user input does not go into LLM, but into JEV&lt;br&gt;
&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-1.png&quot; alt=&quot;image-1|700x480&quot;&gt;&lt;/p&gt;
&lt;p&gt;if you give JEV to infer on, you can throw all conditions at the same time. You can discard that don&#39;t matter and apply logic that matters.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-2.png&quot; alt=&quot;image-2&quot;&gt;&lt;/p&gt;
&lt;p&gt;As you preload, as things float the top, you can pick what is most relevant.&lt;/p&gt;
&lt;p&gt;Support emails to 1 of 4 teams?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-3.png&quot; alt=&quot;image-3&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-4.png&quot; alt=&quot;image-4&quot;&gt;&lt;/p&gt;
&lt;p&gt;Haiku v JEV&lt;br&gt;
JEV finishes way before Haiku&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-5.png&quot; alt=&quot;image-5&quot;&gt;&lt;/p&gt;
&lt;p&gt;A system one model, after the fast thinking in pyschology&lt;/p&gt;
&lt;p&gt;Typesafe AI -&amp;gt; Confidence routing&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-6.png&quot; alt=&quot;image-6&quot;&gt;&lt;/p&gt;
&lt;p&gt;Confidence score sets one floor per action&lt;/p&gt;
&lt;p&gt;How can we apply JEV and it&#39;s confidence scoring to privacy engineering?&lt;/p&gt;
&lt;p&gt;AI can be so cheap (JEV) it can be difficult to measure. JEV will go barely gong&lt;/p&gt;
&lt;p&gt;Categorize email, bulk data, toss any questions against it. If below a threshold, you can automate. Above a threshold, defer to a person as a fallback. A default if a function does not match, is to defer to a person.&lt;/p&gt;
&lt;p&gt;Logs can capture what falls through and you can evolve the code.&lt;/p&gt;
&lt;p&gt;The speed is almost instantaneous. What to build realtime AI? Its faster than human perceptions. Debouncing is important.&lt;/p&gt;
&lt;p&gt;Browser use Demo: Chrome extension&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-7.png&quot; alt=&quot;image-7&quot;&gt;&lt;/p&gt;
&lt;p&gt;John L. speech to text searching for flights.&lt;br&gt;
&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-8.png&quot; alt=&quot;image-8&quot;&gt;&lt;/p&gt;
&lt;p&gt;For typing, has to hand off to Haiku. You can take this approach and hand off to anything visual&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Catchpoint tests, turbo charged.&lt;/li&gt;
&lt;li&gt;e2e tests turbo charged&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-9.png&quot; alt=&quot;image-9&quot;&gt;&lt;/p&gt;
&lt;p&gt;Smart time to pick from the UI elements&lt;/p&gt;
&lt;h2 id=&quot;doing-multiple-things-at-the-time&quot; tabindex=&quot;-1&quot;&gt;doing multiple things at the time&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-10.png&quot; alt=&quot;image-10&quot;&gt;&lt;/p&gt;
&lt;p&gt;You get this experience, and saying things to wanting to happen. UI needed to show what is happening. When building ux, providing animations to convey what is occurring -- because it&#39;s too darn fast!&lt;/p&gt;
&lt;p&gt;Things are developing into a game loop. Its becoming much more interactive experience and less of clicking around.&lt;/p&gt;
&lt;h2 id=&quot;breaking-down-a-sentence&quot; tabindex=&quot;-1&quot;&gt;breaking down a sentence.&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-11.png&quot; alt=&quot;image-11&quot;&gt;&lt;/p&gt;
&lt;p&gt;It&#39;s important to see, all questions are answered at the same time. When you have a little data, what do you need to ask it in order to get where it needs to go in relation to buckets (to match in db)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-12.png&quot; alt=&quot;image-12&quot;&gt;&lt;/p&gt;
&lt;p&gt;Think of your job, the content of the menu and how it&#39;s strucuture, and customers are placing orders in human speech. Your job is to set up the menu and instructions. Think yourself what questions are asking. Skills that Typesafe shares is a cookbook, you can JEV a question.&lt;/p&gt;
&lt;p&gt;Ask questions that could applied, known as Speculative Fan out (TypeSafe)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-13.png&quot; alt=&quot;image-13&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;search-hours-of-video-in-one-video&quot; tabindex=&quot;-1&quot;&gt;Search hours of video in one video&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-14.png&quot; alt=&quot;image-14&quot;&gt;&lt;/p&gt;
&lt;p&gt;six youtube videos. its going to do video processing. Fire a question, based on each video&#39;s transcript&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-15.png&quot; alt=&quot;image-15&quot;&gt;&lt;/p&gt;
&lt;p&gt;Find the exact portion each video&lt;/p&gt;
&lt;p&gt;Taking each chunk and reassemble into a one video&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-16.png&quot; alt=&quot;image-16&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-17.png&quot; alt=&quot;image-17&quot;&gt;&lt;/p&gt;
&lt;p&gt;another round in answering if the filer stays or drops?&lt;/p&gt;
&lt;p&gt;3 rounds, eight requests in blazing speed.&lt;/p&gt;
&lt;p&gt;Composite scoring&lt;br&gt;
&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-18.png&quot; alt=&quot;image-18&quot;&gt;&lt;/p&gt;
&lt;p&gt;The ranking lives in your code. the weights&lt;/p&gt;
&lt;p&gt;Different from keyword finding because it&#39;s inferring from words. A smarter search&lt;/p&gt;
&lt;h2 id=&quot;wikipedia-ends-up-in-philosophy&quot; tabindex=&quot;-1&quot;&gt;Wikipedia ends up in philosophy&lt;/h2&gt;
&lt;p&gt;JEV uses wikipedia api to find philosophy&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-19.png&quot; alt=&quot;image-19&quot;&gt;&lt;/p&gt;
&lt;p&gt;Agentic engine optimization, to find the broken paths or fastest paths to get from A to B. thinking about the users.&lt;/p&gt;
&lt;p&gt;Which one gets you closer to philosophy?&lt;br&gt;
&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-20.png&quot; alt=&quot;image-20&quot;&gt;&lt;/p&gt;
&lt;p&gt;this is throwing JEV, whatever is user or agent facing, crawling and walking arrive it&#39;s destination using every navigate it on the page. You can surface your project, or UI like dropdowns, you can ask JEV to test for you. User test is still necessary. You can tell Opus make up 50 case scenarios, JEV can surface where the tensions and friction is.&lt;/p&gt;
&lt;h2 id=&quot;send-three-robots-at-a-job&quot; tabindex=&quot;-1&quot;&gt;send three robots at a job&lt;/h2&gt;
&lt;p&gt;Functions and with state&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-21.png&quot; alt=&quot;image-21&quot;&gt;&lt;/p&gt;
&lt;p&gt;There is a lot tasks that depends on state (like time), that might block a function the agent uses and blocks them. This allows for a router to get to task.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-22.png&quot; alt=&quot;image-22&quot;&gt;&lt;/p&gt;
&lt;p&gt;JEV makes the judgement calls and the code does the rest.&lt;/p&gt;
&lt;p&gt;Share a plan, in queue order&lt;br&gt;
Planning the building data model needs reasoner&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-23.png&quot; alt=&quot;image-23&quot;&gt;&lt;/p&gt;
&lt;p&gt;Mechanical changes, the builder 1 and 2 can take on those.&lt;/p&gt;
&lt;p&gt;Kind of like a dynamic state machine.&lt;/p&gt;
&lt;p&gt;What about a lot tasks to choose from, or has similar tasks?&lt;br&gt;
&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-24.png&quot; alt=&quot;image-24&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;intent-routing&quot; tabindex=&quot;-1&quot;&gt;intent routing&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-25.png&quot; alt=&quot;image-25&quot;&gt;&lt;/p&gt;
&lt;p&gt;JEV, a date parser and router for plain code&lt;/p&gt;
&lt;p&gt;narrows the task list to a few candidates&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-26.png&quot; alt=&quot;image-26&quot;&gt;&lt;/p&gt;
&lt;p&gt;The list stays short, narrow it in code first and it needs to be deterministic keep it code&lt;/p&gt;
&lt;p&gt;JEV makes the quick decisions. JEV does not replace for everything. Avoid forcing it in things that have been solved in traditional programming.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-27.png&quot; alt=&quot;image-27&quot;&gt;&lt;/p&gt;
&lt;p&gt;Todo app, matching app and narrowing down for JEV to pick from. JEV will get more expensive. It&#39;s meant for quick questions with messy data and messy users.&lt;/p&gt;
&lt;h2 id=&quot;before-you-ship&quot; tabindex=&quot;-1&quot;&gt;before you ship&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-28.png&quot; alt=&quot;image-28&quot;&gt;&lt;/p&gt;
&lt;p&gt;Every message walks through JEV&lt;/p&gt;
&lt;p&gt;log how JEV walks. Code the path and avoid using JEV&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-29.png&quot; alt=&quot;image-29&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-30.png&quot; alt=&quot;image-30&quot;&gt;&lt;/p&gt;
&lt;p&gt;Four patterns TypeSafe cites in their docs&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-31.png&quot; alt=&quot;image-31&quot;&gt;&lt;/p&gt;
&lt;p&gt;Pave what repeats:&lt;br&gt;
&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image-32.png&quot; alt=&quot;image-32&quot;&gt;&lt;/p&gt;
&lt;p&gt;Cheap: JEV and Perplexity option&lt;/p&gt;
&lt;p&gt;A little smarter, but 10x the cost. JEV has the best balance. As any product, they are going to try to win over users.&lt;/p&gt;
&lt;p&gt;John L. spent $6. millions of requests. A dollar will translate a month of usage&lt;/p&gt;
&lt;p&gt;OpenRouter? look into it. Between it&#39;s decisions can vary in scores by decimals. You won&#39;t be able switch JEV to another thing because it may work differently. There is statical anonomlies.&lt;/p&gt;
&lt;p&gt;Your product is your factory; your factory is your product. You can point a video and analyze and Opus will reverse engineer it in 15 minutes.&lt;/p&gt;
&lt;h2 id=&quot;megadev-next-things&quot; tabindex=&quot;-1&quot;&gt;mega.dev next things&lt;/h2&gt;
&lt;p&gt;Personal software is easy. Production good software is much more difficult.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dog fooding and caring about your users&lt;/li&gt;
&lt;li&gt;If you don&#39;t use the tool, it will show.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Managing software with agents. Feedback systems conversing with your team and getting back with agents is critical.&lt;/p&gt;
&lt;p&gt;you can do research with similar products and surface the pain points.&lt;/p&gt;
&lt;p&gt;You can customize the tools on the terminal level and build tools for teams.&lt;/p&gt;
&lt;p&gt;Read the article at &lt;a href=&quot;https://www.youtube.com/watch?v=3MwcIgBRras&quot;&gt;Rethinking AI with Jev: Instant, Nearly Free, and Unlocking Whats Next&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://davidchicopham.com/feed-img.svg&quot; width=&quot;50&quot; height=&quot;50&quot; alt=&quot;Site logo&quot; /&gt;</content>
            </entry>
            
            <entry>
                <title>How to design a rate limiter</title><link href="https://davidchicopham.com/this-is-my-next/rate-limiter/"/><updated>2026-10-07T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/rate-limiter/</id>
                <content type="html">&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/image.png&quot; alt=&quot;image|700x655&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;token-bucket-algo-takes-two-parameters&quot; tabindex=&quot;-1&quot;&gt;Token Bucket algo takes two parameters&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Bucket size: max number of tokens allowed in the bucket.&lt;/li&gt;
&lt;li&gt;Refill rate: number of tokens put into the second per second&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How many buckets do we need? It depends!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Different buckets for different API endpoints&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;leaky-bucket-algorithm&quot; tabindex=&quot;-1&quot;&gt;Leaky Bucket Algorithm&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/this-is-my-next/leaky-bucket-algorithm.png&quot; alt=&quot;leaky bucket algorithm|700x300&quot;&gt;&lt;/p&gt;
&lt;p&gt;Leaky bucket takes 2 parameters&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;bucket size: it is equal to the queue size. The queue holds the requests to be processed at a fixed rate&lt;/li&gt;
&lt;li&gt;outflow rate: it defines how many requests can be processed at a fixed rate, usually in seconds&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Shopify uses this algorithm&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Memory efficient given the limited queue size&lt;/li&gt;
&lt;li&gt;If you have a stable outflow rate, the fixed rate works well&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;burst of traffic fills up the queue with old requests, and if they are not processed in time, recent requests will be rate limited&lt;/li&gt;
&lt;li&gt;just 2 parameters makes tuning and calibrating more difficult.&lt;/li&gt;
&lt;/ul&gt;
</content>
            </entry>
            
              
            <entry>
                <title>Ai Agents that never sleep instructed by Scott Moss</title><link href="https://master.dev/workshops/background-agents/"/><updated>2026-09-29T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/ai-agents-that-never-sleep/</id>
                <content type="html">&lt;h1 id=&quot;building-custom-harness&quot; tabindex=&quot;-1&quot;&gt;Building custom harness&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://master.dev/workshops/background-agents/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://master.dev/workshops/background-agents/&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://github.com/davidpham5/xeno-agents&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://github.com/davidpham5/xeno-agents&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://github.com/Hendrixer/background-agents&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://github.com/Hendrixer/background-agents&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;what is background agent?&lt;br&gt;
agent handles the job. background agent activates task from events from the outside. It does not have to. They are the real productivity unlock. You can always going as fast as your prompt.&lt;/p&gt;
&lt;p&gt;The best way to increase productivity is a machine does the work of a team and when to do the job and how to the job well.&lt;/p&gt;
&lt;p&gt;A background agent is to reach a state. The BA is to reach the state. BA more durable. It is as if you asked someone to go figure out work arounds to blockers.&lt;/p&gt;
&lt;p&gt;Who has the authority now? Fully auto mode? Add to a block list? add to a allow list. who has the authority to recognize permission.&lt;/p&gt;
&lt;p&gt;What the LLM to do versus what the harness to do. The harness is deterministic.&lt;/p&gt;
&lt;p&gt;The thinking framework: &lt;strong&gt;Observe, Decide, and Act Loop&lt;/strong&gt;. Similar to how most Agent frameworks work today. No tooling calling today. We can have agent wait on background actions&lt;/p&gt;
&lt;p&gt;It usually can&#39;t suspend. state might changed. connection closed.&lt;br&gt;
Wait period, no compute is being used.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;get a neon new db&lt;br&gt;
openapi secret key&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-ai-agents-that-never-sleep-6&quot; id=&quot;skip-to-code-skip-ai-agents-that-never-sleep-6&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run db:push&lt;br&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run preflight &lt;span class=&quot;token comment&quot;&gt;# you have dependencies ready&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run db:seed &lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-ai-agents-that-never-sleep-6&quot;&gt;Spin up a few things now:&lt;/p&gt;
&lt;p&gt;Set up agent endpoint to run the agent.&lt;br&gt;
Run the web app&lt;br&gt;
Actual checkout service&lt;br&gt;
--&amp;gt; all in &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ingest spins up the endpoint&lt;br&gt;
&lt;code&gt;npm run dev:checkout&lt;/code&gt; to spin up the checkout service&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;if you want watch instead live code, you can git switch lessons or ask the agent to get you caught up.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;What if we build an environment that provides more intelligent context. For example, screen shots and point out things in the screenshot. For this project, is the state of the server. Snapshot that and let it act on that.&lt;/p&gt;
&lt;p&gt;Observing the current world is something the agent does not get to decide that. The agent will choose action, based on historical actions. The next action is to say i am done? or ask for help? or learn more?&lt;/p&gt;
&lt;p&gt;Harness then validates and executes. Avoid losing important data, money, etc. Rollbacks are destructive. It does not distinguish a person doing the rollback or a machine.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;mock a fault&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-ai-agents-that-never-sleep-5&quot; id=&quot;skip-to-code-skip-ai-agents-that-never-sleep-5&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev:checkout -- &lt;span class=&quot;token parameter variable&quot;&gt;--fault&lt;/span&gt; feature&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-ai-agents-that-never-sleep-5&quot;&gt;we are going to building a custom harness.&lt;/p&gt;
&lt;p&gt;Inngest: how you can make your code durable.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;code&gt;agent-workflow&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;redux reducer pattern&lt;/p&gt;
&lt;p&gt;LLM part is the easy part. It&#39;s the harness is where the hard work because thats the interface for LLM&lt;/p&gt;
&lt;p&gt;Structured Outputs -&amp;gt; ai engineering course. return a promise to handle a output you defined. &lt;code&gt;decisionSchema&lt;/code&gt; in &lt;code&gt;agent-brain.ts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;JEV will be good for what is the likely actions. JEV wont generate new tokens for a new argument Not a drop in replacement. new archiecture is needed.&lt;/p&gt;
&lt;p&gt;Tool loop, not ready to answer, so it calls other tools or infra.&lt;/p&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li&gt;at some point break the loop and the harness&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; revisit AI engineering to go over structured inputs and outputs.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; also look into freecodecamp&#39;s building a harness from scratch&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;agents-workflow&lt;/code&gt; summary&lt;/strong&gt;&lt;br&gt;
if not any the return events, it will keep looping. Maybe we can&#39;t close the gap in reasoning, we need to have an agent reach for the LLM.&lt;/p&gt;
&lt;p&gt;lets spin up the entire service:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-ai-agents-that-never-sleep-4&quot; id=&quot;skip-to-code-skip-ai-agents-that-never-sleep-4&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;dev:checkout&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tsx service/checkout.ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token property&quot;&gt;&quot;dev:operator&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INNGEST_DEV=1 tsx watch server/operator.ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token property&quot;&gt;&quot;dev:agent&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INNGEST_DEV=1 tsx watch server/agent.ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token property&quot;&gt;&quot;dev:web&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vite --host 127.0.0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token property&quot;&gt;&quot;dev:inngest&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;inngest dev -u http://127.0.0.1:3002/api/inngest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-ai-agents-that-never-sleep-4&quot;&gt;an action that stops the loop or terminates the loop&lt;/p&gt;
&lt;p&gt;double check you ran the fault,&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-ai-agents-that-never-sleep-3&quot; id=&quot;skip-to-code-skip-ai-agents-that-never-sleep-3&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; run dev:checkout -- &lt;span class=&quot;token parameter variable&quot;&gt;--fault&lt;/span&gt; feature&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-ai-agents-that-never-sleep-3&quot;&gt;Inngest has a cool dashboard.&lt;/p&gt;
&lt;p&gt;what actions require a human to judge what to do?&lt;br&gt;
what guardrails, that has infrastructure implications&lt;/p&gt;
&lt;p&gt;&amp;quot;It&#39;s a like a state machine&amp;quot;&lt;/p&gt;
&lt;p&gt;you can check in the inngest server dashboard at &lt;a href=&quot;http://127.0.0.1:8288/runs&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;http://127.0.0.1:8288/runs&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;add act step in agent-workflows&lt;/p&gt;
&lt;p&gt;A step is much like a &lt;code&gt;useMemo&lt;/code&gt;. Re-executed loop. Step is something that is expensive and we want it save deterministically&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-ai-agents-that-never-sleep-2&quot; id=&quot;skip-to-code-skip-ai-agents-that-never-sleep-2&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// this is going to hit our LLM. You often wants to put this in a step because this cost money/tokens&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// we do not want LLM at top because its probalistic and its different every time.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// thinks a step is a useMemo() in react.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; decision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;choose-action-$cycle}&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token function&quot;&gt;chooseAction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;goal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-ai-agents-that-never-sleep-2&quot;&gt;we do not want to put LLM outside of a step&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tool-policy&lt;/code&gt;&lt;br&gt;
different type of policies we have.&lt;/p&gt;
&lt;p&gt;steps should be idempotent because you don&#39;t want execute an action over again and change the state.&lt;/p&gt;
&lt;p&gt;validate stuff. its just on and without prompt&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;lesson 03&lt;br&gt;
there is an incident but we don&#39;t have enough information, so wait for more info. or we&#39;ve seen this error before and we can ignore, but if we see this other error, then do something.&lt;/p&gt;
&lt;p&gt;a dependency may recover while the agent is idle. Doorbell by event. it may go back to sleep before there is more.&lt;/p&gt;
&lt;p&gt;We want the model to choose to wait. we can force the agent to wait.&lt;/p&gt;
&lt;p&gt;if 3rd party dependency, does the agent ask for help or wait or what? there are many cases an agent will wait.&lt;/p&gt;
&lt;p&gt;timeout is 3 days! thats why these steps have to be deterministic. Inngest docs.&lt;br&gt;
Treat this step as async function and not suspending the call stack.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;inngest.createFunction()&lt;/code&gt; wraps the workflow in a deterministic shell. Everything inside it must be deterministic, outside a step(). Instead, the steps themselves have to be idempotent. So what does that mean? If the workflow was based on date and it responds to dates, its not deterministic.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;lesson 4 Human back in control&lt;/p&gt;
&lt;p&gt;The agent can signal that it needs help.&lt;br&gt;
Inngest has docs to bring humans in the loop. They treat slack as their inbox instead of building an inbox&lt;/p&gt;
&lt;p&gt;Human Ai decision making can skew Ai&#39;s actions. Don&#39;t tell it that you reviewing it.&lt;/p&gt;
&lt;p&gt;Approval is not a universal safety shield&lt;/p&gt;
&lt;p&gt;De-risk or build a rollout mechanism. looking at a inbox and why are you doing that.&lt;/p&gt;
&lt;p&gt;AgentDojo: read the paper about prompt injection by using human in the loop&lt;/p&gt;
&lt;p&gt;we take a snapshot of the snapshot for the state. You may get different results if you run this&lt;/p&gt;
&lt;p&gt;Does the state drifted so much when the proposed action was brought forth.&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-ai-agents-that-never-sleep-1&quot; id=&quot;skip-to-code-skip-ai-agents-that-never-sleep-1&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; proposalId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;propose-action-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;cycle&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; proposal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;proposeAction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;              environmentId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;              runId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;              actionId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;              decision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;              input&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; proposal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token comment&quot;&gt;// why create a proposal to only get the id and then here&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token comment&quot;&gt;// and then make a proposal here?&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token comment&quot;&gt;// because proposal overwrite. Get variable from DB and not cache value at some point&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token comment&quot;&gt;// Getting stale proposals from the above will lead to a bug&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; proposal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;read-human-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;cycle&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;br&gt;          &lt;span class=&quot;token function&quot;&gt;getProposal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;proposalId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;we got an inbox notification!&lt;/li&gt;
&lt;li&gt;we finished approval request&lt;/li&gt;
&lt;li&gt;and approved&lt;/li&gt;
&lt;li&gt;Run completed!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;lesson 5 - Idemopentecy&lt;br&gt;
Aws has good doc on it: &lt;a href=&quot;https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;stripe won&#39;t make transaction happen more than once. because it has idemopotency&lt;/p&gt;
&lt;ul class=&quot;task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; read the papers from the Labs and challenge you that you have not thought about. With the help AI, slowly insight appear. Connections can then be made.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; Replicate some of the experiments&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input disabled=&quot;true&quot; type=&quot;checkbox&quot; class=&quot;markdown-todo&quot;&gt;&lt;/input&gt; you will be ahead of the game.&lt;br&gt;
Scott Moss has used research papers in his Netflx job. Then he&#39;ll communicated it. His team then will share that worked a bit!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the article at &lt;a href=&quot;https://master.dev/workshops/background-agents/&quot;&gt;Ai Agents that never sleep i&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://davidchicopham.com/feed-img.svg&quot; width=&quot;50&quot; height=&quot;50&quot; alt=&quot;Site logo&quot; /&gt;</content>
            </entry>
            
            <entry>
                <title>n8n for blogging is back, baby</title><link href="https://davidchicopham.com/this-is-my-next/n8n-for-blogging-is-back-baby/"/><updated>2026-05-02T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/n8n-for-blogging-is-back-baby/</id>
                <content type="html">&lt;p&gt;I want to set up a n8n self hosting instance on my server and run a marketing funnel for this site. I want to present a pop up like substack to subscribe to a newsletter and build an audience. And at the end, turn some readers to paid members.&lt;/p&gt;
&lt;h2 id=&quot;part-1-self-host-n8n-on-digitalocean&quot; tabindex=&quot;-1&quot;&gt;Part 1: Self-Host n8n on DigitalOcean&lt;/h2&gt;
&lt;h3 id=&quot;11-create-a-droplet&quot; tabindex=&quot;-1&quot;&gt;1.1 Create a Droplet&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Log into DigitalOcean → Create → Droplets&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Image:&lt;/strong&gt; Ubuntu 24.04 LTS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plan:&lt;/strong&gt; Basic, $6/mo (1 GB RAM, 25 GB SSD) — sufficient for n8n&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Region:&lt;/strong&gt; NYC1 or closest to you (East Coast)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authentication:&lt;/strong&gt; SSH key (recommended) or password&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hostname:&lt;/strong&gt; &lt;code&gt;n8n-server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;12-install-docker-n8n&quot; tabindex=&quot;-1&quot;&gt;1.2 Install Docker + n8n&lt;/h3&gt;
&lt;p&gt;SSH into your droplet:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-8&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-8&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; root@YOUR_DROPLET_IP&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-8&quot;&gt;Install Docker:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-7&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-7&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; update &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; upgrade &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt; docker.io &lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt;&lt;br&gt;systemctl &lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-7&quot;&gt;Create n8n directory and docker-compose file:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-6&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-6&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; /opt/n8n &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /opt/n8n&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-6&quot;&gt;Create &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-5&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-5&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;3.8&#39;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token key atrule&quot;&gt;n8n&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; n8nio/n8n&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5678:5678&quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; N8N_HOST=n8n.davidchicopham.com&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; N8N_PORT=5678&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; N8N_PROTOCOL=https&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; WEBHOOK_URL=https&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//n8n.davidchicopham.com/&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; GENERIC_TIMEZONE=America/New_York&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; TZ=America/New_York&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; n8n_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/home/node/.n8n&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token key atrule&quot;&gt;n8n_data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-5&quot;&gt;Start n8n:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-4&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-4&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker-compose&lt;/span&gt; up &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;13-set-up-domain-ssl&quot; tabindex=&quot;-1&quot;&gt;1.3 Set Up Domain + SSL&lt;/h3&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-4&quot;&gt;Point a DNS A record for &lt;code&gt;n8n.davidchicopham.com&lt;/code&gt; → your droplet IP.&lt;/p&gt;
&lt;p&gt;Install Caddy as a reverse proxy (handles SSL automatically):&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-3&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-3&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt; caddy&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-3&quot;&gt;Edit &lt;code&gt;/etc/caddy/Caddyfile&lt;/code&gt;:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-2&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-2&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n8n.davidchicopham.com {
    reverse_proxy localhost:5678
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-2&quot;&gt;Restart Caddy:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-n8n-for-blogging-is-back-baby-1&quot; id=&quot;skip-to-code-skip-n8n-for-blogging-is-back-baby-1&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl restart caddy&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-n8n-for-blogging-is-back-baby-1&quot;&gt;Wait a few minutes for SSL provisioning. Visit &lt;code&gt;https://n8n.davidchicopham.com&lt;/code&gt; — you should see the n8n login screen.&lt;/p&gt;
&lt;h3 id=&quot;14-verify&quot; tabindex=&quot;-1&quot;&gt;1.4 Verify&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Log in with the basic auth credentials you set&lt;/li&gt;
&lt;li&gt;Create a test workflow with a Webhook trigger node&lt;/li&gt;
&lt;li&gt;Copy the webhook URL — you&#39;ll need it in Part 3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What is n8n? It&#39;s like Zapier or Make, a canvas drag and drop flow chart that can build triggers, actions, and output stuff. It&#39;s source can be self hosted or through paid cloud account.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=e3OV3LnrS7o&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;Master 80% of n8n in 36 Minutes - YouTube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There is a number of actions a trigger could attach to. Actions are apps like dropbox, google sheets, or airtable. It occurred to me that a level of automation could happen in organizing. For example, when we were recruiting for elected officials or stewards, we used a conversion logger that fed into a google sheet.&lt;/p&gt;
&lt;p&gt;If that conversation was an assessment, e.g. how interested are you in becoming a steward, a scale from 1 to 5, 1 being LFG to 5 being don&#39;t ask me ever again -- a friend said politely to me that he was not interested in further involvement with the union and didn&#39;t want to be asked again -- that&#39;s a 5, then based on that assessment, follow up automated email is sent a couple days later with an ask for a 1 on 1.&lt;/p&gt;
&lt;p&gt;Or how about an outreach plan triggers a text/phone bank.&lt;/p&gt;
&lt;p&gt;I can imagine also a directional change could be tracked like when voters switch from republican to democrat, visualized with arrows on a map of congressional districts, but for assessment conversations.&lt;/p&gt;
&lt;p&gt;Another example in n8n development and organizing is something like a virtual organizer. Imagine the system prompt had the role of someone like Jane McAlevey (rest in power) and you can ask how did a conversation go and what are next steps to organizing a person. Instead of a AI personal assistant, how about a personal co-organizer?&lt;/p&gt;
&lt;p&gt;Structural tests can be signals to who is engaged. It reminds me of the like button by Facebook that sent a signal to the platform, or even the skip button on youtube is a signal. What about structural tests such as an emoji response?&lt;/p&gt;
&lt;h2 id=&quot;asking-claude-to-develop-a-plan-for-the-n8n-newsletter-and-plausibleio-integration&quot; tabindex=&quot;-1&quot;&gt;Asking Claude to develop a plan for the n8n newsletter &amp;amp; &lt;a href=&quot;http://plausible.io&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;plausible.io&lt;/a&gt; integration.&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;I want to set up a n8n self hosting instance on my server and run a marketing funnel for this site. I want to present a pop up like substack to subscribe to a newsletter and build an audience. And at the end, turn some readers to paid members.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/obra/superpowers&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;plugin, superpowers&lt;/a&gt; used to plan newsletter component.&lt;/p&gt;
&lt;p&gt;To achieve substack fade to popup as a user scrolls down content, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;Intersection Observer API - Web APIs | MDN&lt;/a&gt; will observe an element threshold to which the popup will come into view. Once that threshold is hit, the observer will disconnect. Notably, intersection observer solves for implementing infinite scroll.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Current song on the iPod: Thnks fr th mmris by Fallout Boy&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Where does this stack hook into &lt;a href=&quot;http://plausible.io&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;plausible.io&lt;/a&gt;? Maybe via n8n&lt;/p&gt;
&lt;p&gt;How to handle errors:&lt;/p&gt;
&lt;h2 id=&quot;error-handling&quot; tabindex=&quot;-1&quot;&gt;Error Handling&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure&lt;/th&gt;
&lt;th&gt;What user sees&lt;/th&gt;
&lt;th&gt;What system does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Honeypot tripped&lt;/td&gt;
&lt;td&gt;&amp;quot;Thanks — check your inbox&amp;quot; (lie)&lt;/td&gt;
&lt;td&gt;Edge fn returns 200, no Buttondown call, no n8n call&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Submit &amp;lt;2s after popup shown&lt;/td&gt;
&lt;td&gt;Same as above&lt;/td&gt;
&lt;td&gt;Same — silent rejection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invalid email format&lt;/td&gt;
&lt;td&gt;Inline form error: &amp;quot;Enter a valid email&amp;quot;&lt;/td&gt;
&lt;td&gt;Edge fn returns 400, no downstream calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Buttondown 5xx / network error&lt;/td&gt;
&lt;td&gt;&amp;quot;Something went wrong, try again in a moment&amp;quot;&lt;/td&gt;
&lt;td&gt;Edge fn returns 502; no localStorage write; user can retry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Buttondown &amp;quot;already subscribed&amp;quot; (400 with &lt;code&gt;email_already_exists&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&amp;quot;Thanks for being a subscriber&amp;quot;&lt;/td&gt;
&lt;td&gt;Edge fn returns &lt;code&gt;{ ok: true, already: true }&lt;/code&gt;; localStorage marks subscribed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n8n down (submit path)&lt;/td&gt;
&lt;td&gt;Success (Buttondown succeeded)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Promise.allSettled&lt;/code&gt; — n8n failure logged, doesn&#39;t affect user response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n8n down (event-only path)&lt;/td&gt;
&lt;td&gt;Nothing&lt;/td&gt;
&lt;td&gt;sendBeacon fires fire-and-forget; events lost — acceptable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User has JS disabled&lt;/td&gt;
&lt;td&gt;Popup never shows; inline form is inert HTML with &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; link to &lt;code&gt;/newsletter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No subscribe path; acceptable degradation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;localStorage blocked (private mode)&lt;/td&gt;
&lt;td&gt;Popup may show repeatedly across sessions&lt;/td&gt;
&lt;td&gt;Acceptable — small audience, graceful degradation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge function down&lt;/td&gt;
&lt;td&gt;Submit fails with network error; user sees retry message&lt;/td&gt;
&lt;td&gt;No silent data loss&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content>
            </entry>
            
            <entry>
                <title>NodeJS API Design</title><link href="https://davidchicopham.com/this-is-my-next/nodejs-api-design/"/><updated>2026-04-27T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/nodejs-api-design/</id>
                <content type="html">&lt;p&gt;One of the things I am weak at as a fullstack engineer is the backend. I very comfortable in developing interfaces for users. I&#39;m much more confident in CSS, HTML, and JS than I am in NodeJS and Express.&lt;/p&gt;
&lt;p&gt;For the past 3 weeks, I&#39;ve been going through Frontend Masters NodeJS API Design, presented by Scott Moss of Netflix. It&#39;s really helpful in understanding the backend.&lt;/p&gt;
&lt;p&gt;Here are my notes:&lt;br&gt;
04-02-2026&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://frontendmasters.com/courses/api-design-nodejs-v5/node-js-servers-overview/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://frontendmasters.com/courses/api-design-nodejs-v5/node-js-servers-overview/&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://api-design-with-node-v5.super.site/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://api-design-with-node-v5.super.site/&lt;/a&gt;&lt;br&gt;
NodeJS primary purpose: build servers, access file systems, interact with databases&lt;br&gt;
API: file system, networking, process management, crypto&lt;br&gt;
secuirty: you roll. your own. DENO has an optin to security&lt;/p&gt;
&lt;p&gt;from a frontend perspective&lt;/p&gt;
&lt;p&gt;the mental model shift&lt;br&gt;
you write fetch() and assign results&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-nodejs-api-design-6&quot; id=&quot;skip-to-code-skip-nodejs-api-design-6&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/api/users&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; users &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-nodejs-api-design-6&quot;&gt;backend perspective&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-nodejs-api-design-5&quot; id=&quot;skip-to-code-skip-nodejs-api-design-5&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/api/users&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;	&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; users &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br&gt;		&lt;span class=&quot;token string&quot;&gt;&#39;SELECT * FROM users&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;	&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;	res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;users&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-nodejs-api-design-5&quot;&gt;the browser gives us free security&lt;br&gt;
you can natively use ES modules in the browsers&lt;/p&gt;
&lt;h2 id=&quot;serverless-functions&quot; tabindex=&quot;-1&quot;&gt;Serverless Functions&lt;/h2&gt;
&lt;p&gt;allows for functions to  fire when api hits it. They don&#39;t have to be always on but this comes at the cost of speed. something like web sockets is that lives long cant use serverless.&lt;/p&gt;
&lt;h2 id=&quot;cdn&quot; tabindex=&quot;-1&quot;&gt;CDN&lt;/h2&gt;
&lt;p&gt;You can write pure JS now on CDN. 10 years ago you could do some logic but nothing like scripting&lt;/p&gt;
&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 334.4295249690302 152.25994272304698&quot; width=&quot;334.4295249690302&quot; height=&quot;152.25994272304698&quot;&gt;
  &lt;!-- svg-source:excalidraw --&gt;
  &lt;defs&gt;
    &lt;style class=&quot;style-fonts&quot;&gt;
      @font-face {
        font-family: Excalifont;
        src: url(data:font/woff2;base64,d09GMgABAAAAAAb0AA4AAAAADCQAAAahAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbgWQcegZgAFQRCAqNDIl6CxgAATYCJAMsBCAFgxgHIBuHCVGUUFIc2Y+EzM0bzS4qlc4VFQois7PXReWXfHja5vsXHIKYeWYHJhaoG64rWEYQRGs6fx8SmlgZ1iSTEtlKYFdhRGWFK++gW8mt8F8lAWqqI1bZFm4NaxLEznySukwW+f/v3ddrD/RvaolGiScy5v9bL/A/jxq0JgWyATtpoGPRA2lyxwssQA8DjTzblozAXoPrERIhPWSIRNNvISAA9VAAoBAUIaSBT+EpHDOOT82FyaFSLoPJqVzaDJOrqs5WmGAAuBtll1J5K4QgeAwqxiDUasUfBwxHKwEOEicDDfAoaqjlGBZDgEJjEQwOKchgnwFT8dSrxvoqStEjCJoIiQZYmaHESzUQZK+DqUOuTLlkIpYwjU6FAFJ4EbKFt19AJMEYu0xIx0Hw2vPuf6OxeTfp5oEFAEBe7ccBPCGAAtAAPTTCzIxIgDohCoNXp5FMe/wHvBqCaHtpvEcV82JOzEKOECMkQ9xXGAA0gOoA1Bv0MR8JKtEz45ue+mzomoN69qYte61th9bel6A5WkJxa+ZXX65/kGf7r4YHk8SMddShsIR0qc//HAnyBCQPu3y/T4ZKcGHuokMUpmJzTUp3wS1ju789ameVkclatp+8AslOJ3BiZiqWVzLlINGxiva99z7uYQ++evk7LTSkj3uquMP8lrwtfaMPvvGdTXano6JH+2Klye8vHu/v3+9bytsze9g55gm/qxHSDUOt/2Fz9mgfejk4YLqU0pSmUNQoFNvT8d5oYXilX9njy9ELw10AQhIQJLEe76Mj2DuDOnDJHLYTLPjeXwfJYA9WkYBLFe1RTOTcCnDnOe79hr1yc/ZmL4kIWAG5SnL9SefQCFIhYLo5O0usoEiaIMhjBeNDuQjSWZm2am25vSV3ZVp4MCDAJUqDMSXhRWERHbvfl69n23xaN974b7SQ3+QnmIPnne9+KOV2mqZ0BIWK9I6OB/pLE8eFQqag+xRjSikUXl3UZSU3t/8/7mvhXu7+dXJ2by6uqQFTmJuYg+fhcemNvt956STWFrTLb1lBGEcvoVidnT9a4ZdO6TKnRbZL7UWp/CAsNNcfc3WFaofDdadVG33jR4/WW267VFQqOWiS9alG6/YvQXzrhMEGFQ4vIlVWdRcj7FQH6Utfgy5Neznpo6PvHio6ZOln799pZPMlK/fljHqXYbmO18lb638KssI4tYwhPenqD5Mdw2mOVnICT4PadB2tcip054ds0xm+yByoN9taptlGVnkUmJlGJlu89uP0Wt4Zt7ZqJiQdUfkubd9mZfi9wDVsmv4iKkEtV+oDh81R27qm8KxUo081BzuyIuyZrCLaQN9Hdu+kxoqD1CG6g1S3Y+R21nqPhmcaZGUw0U6xNsWverGKr1Eicyrnic/4Dn290971i7BJNOlzxKNTj75OzMCeFUX6A2wstSYGbyHNBsZZo418tyimyDOpPsuHrP6uw8q8Nj14X3XUdmEO6fYM9pNL0oWJl44n9dX9fnlGuAs+65vG6C+0NzTuFrLCQLMBYu5OGiYcevTTnBctf6zS1c7MnhY50rvHRkmCtAu0RxidWQpJw5TL5Ao5E/OX9sfO67e0XXYTWnsQysOpCYN0DVX3SD8jCScSnzChxOdclQZmltQAlk4QSdwku8rTFoSO4zcskfSocIdxbtyf9JtpbHJuXB/lODMieWSEyid+XURLP7Ov0nZPPsUx3yApMF4ctbCeWOe6u1oe262dOylW6OAiJqKWD5svMVfe3n4rf5+2Q4JoRQV1VZJdqhY74MNJ3TgJN+XawjPxr3r/d63h1reyfecxatTwDtcUXDt5lv/0/aGm+kmJ8bnr7b6JUzQX3Gj0YN/d39tW2T4TN1EqCjZQbJ1EZLnOO9b7oYKzleT5cOM2DBbEYaL8eG2mIOd94IVNulkTH2z5YgIAAAEQUHzc9q/QDP0qFNMvAOCh0jkWAB4tft3n/9D/PswrJgiAEMWQuNOcW9RRyN+fxNKIe4rzasRlE4F84lMZnJIxTLOP8dMXaHkI31QIz2SMgGx6/EMAYtchAMAfCAUiASs5xWikoAZA5hKmj9Cz30fRsNFHczbcx7BV7WOFs72HgC0gTm81qsg0qtOmVSc32aTqdZGpIpdPSk6hUcvneXHn2fYLkUBGqV0DBZ4Pd96sOVbwHh7AyT0M3+i2fKwcCdKFmBqptarFMLZTKl6jeg2b3u2ohhOeN0/efPGqKfFWrCUf2It7wSiy5vB2zlAITcog1bopr5Y7GqL9/4cFAA==);
          }
    &lt;/style&gt;
  &lt;/defs&gt;
  &lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;334.4295249690302&quot; height=&quot;152.25994272304698&quot; fill=&quot;#ffffff&quot;&gt;&lt;/rect&gt;&lt;g mask=&quot;url(#mask-_Vr_sf7jrqZkL__Ha67Bd)&quot; stroke-linecap=&quot;round&quot;&gt;&lt;g transform=&quot;translate(324.06185815194624 11.587089569475495) rotate(0 -157.390625 64.744140625)&quot;&gt;&lt;path d=&quot;M0.37 -0.36 C-52.03 21.42, -261.24 108.93, -313.69 130.67 M-0.9 -1.59 C-53.42 19.88, -261.74 107.56, -314.06 129.17&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(324.06185815194624 11.587089569475495) rotate(0 -157.390625 64.744140625)&quot;&gt;&lt;path d=&quot;M-295.68 112.23 C-302.83 120.16, -306.83 125.18, -314.06 129.17 M-295.68 112.23 C-301.34 117.15, -307.77 123.24, -314.06 129.17&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(324.06185815194624 11.587089569475495) rotate(0 -157.390625 64.744140625)&quot;&gt;&lt;path d=&quot;M-289.09 128.02 C-298.6 130.33, -304.96 129.7, -314.06 129.17 M-289.09 128.02 C-296.91 127.33, -305.66 127.88, -314.06 129.17&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;mask id=&quot;mask-_Vr_sf7jrqZkL__Ha67Bd&quot;&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; fill=&quot;#fff&quot; width=&quot;738.8431081519462&quot; height=&quot;241.0753708194755&quot;&gt;&lt;/rect&gt;&lt;rect x=&quot;117.37127587655561&quot; y=&quot;63.831230194475495&quot; fill=&quot;#000&quot; width=&quot;98.59991455078125&quot; height=&quot;25&quot; opacity=&quot;1&quot;&gt;&lt;/rect&gt;&lt;/mask&gt;&lt;g transform=&quot;translate(117.37127587655561 63.831230194475495) rotate(0 49.84348660795948 12.298741167047993)&quot;&gt;&lt;text x=&quot;49.299957275390625&quot; y=&quot;17.619999999999997&quot; font-family=&quot;Excalifont, Segoe UI Emoji&quot; font-size=&quot;20px&quot; fill=&quot;#1e1e1e&quot; text-anchor=&quot;middle&quot; style=&quot;white-space: pre;&quot; direction=&quot;ltr&quot; dominant-baseline=&quot;alphabetic&quot;&gt;file copied&lt;/text&gt;&lt;/g&gt;&lt;/svg&gt;
&lt;p&gt;Edge function is programmable CDN&lt;/p&gt;
&lt;h2 id=&quot;background-job&quot; tabindex=&quot;-1&quot;&gt;background job&lt;/h2&gt;
&lt;p&gt;async job. tasks that run outside the request-response cycle&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;send email&lt;/li&gt;
&lt;li&gt;processing images&lt;/li&gt;
&lt;li&gt;data  sync&lt;/li&gt;
&lt;li&gt;heavy computation&lt;br&gt;
They have less to do with the user and more to with architecture choices&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cron-job&quot; tabindex=&quot;-1&quot;&gt;Cron job&lt;/h2&gt;
&lt;p&gt;A type of background job that runs at an interval&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is an HTTP verb in the context of server routing?&lt;/strong&gt;&lt;br&gt;
An HTTP verb is an action or type of request indicating the desired operation to be performed on a server, such as GET, POST, PUT, DELETE, etc.&lt;/p&gt;
&lt;h2 id=&quot;env&quot; tabindex=&quot;-1&quot;&gt;env&lt;/h2&gt;
&lt;p&gt;an important thing to know about &lt;code&gt;.env&lt;/code&gt; is that when we use &lt;code&gt;process.env.SECRET&lt;/code&gt; the value is rendered at runtime for client side frameworks. Sure you have it shared in github but it&#39;s exposed still.&lt;/p&gt;
&lt;p&gt;It&#39;s a great way to change configuration without changing your code. the EQUIVALENT on the frontend is a feature flag.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;They allow dynamic value changes without hard-coding variables, making it easier to manage different settings for staging, production, and local development environments&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;this is not type unless you look at &lt;code&gt;.env&lt;/code&gt;. they can be a lot env variables. so how do we keep track of them? &lt;a href=&quot;https://frontendmasters.com/courses/api-design-nodejs-v5/dev-production-variables/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://frontendmasters.com/courses/api-design-nodejs-v5/dev-production-variables/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;challenges with env:&lt;br&gt;
They are not typed, and it&#39;s difficult to know which ones exist without checking the .env file or consulting an experienced team member&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why create multiple .env files like .env, .env.example, and .env.test?&lt;/strong&gt;&lt;br&gt;
To separate environment configurations, keep secrets out of version control, and provide example variable names for team members while allowing different configurations for testing&lt;/p&gt;
&lt;p&gt;Zod&lt;br&gt;
Zod provides runtime type-checking and schema validation, allowing verification of environment variable types and presence at runtime&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rotating Secrets&lt;/strong&gt;&lt;br&gt;
What is a strategy for managing secrets and sensitive configuration values?&lt;br&gt;
Rotate secrets periodically, use secrets management tools like HashiCorp Vault, and avoid hardcoding sensitive information&lt;/p&gt;
&lt;h2 id=&quot;understand-http-routing&quot; tabindex=&quot;-1&quot;&gt;understand HTTP routing&lt;/h2&gt;
&lt;p&gt;it&#39;s combination of a verb and path pattern&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;verb&lt;/th&gt;
&lt;th&gt;purppose&lt;/th&gt;
&lt;th&gt;example&lt;/th&gt;
&lt;th&gt;expected result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;fetch data&lt;/td&gt;
&lt;td&gt;GET &lt;code&gt;/api/users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;list of users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;Create new resource&lt;/td&gt;
&lt;td&gt;POST &lt;code&gt;/api/users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;create new user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;update (replace) entire resource&lt;/td&gt;
&lt;td&gt;PUT &lt;code&gt;/api/users/123&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User 123 completely updated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PATCH&lt;/td&gt;
&lt;td&gt;partial update&lt;/td&gt;
&lt;td&gt;PATCH &lt;code&gt;api/users/123&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;user 123 partially updated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;remove resource&lt;/td&gt;
&lt;td&gt;DELETE &lt;code&gt;/api/user/123&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User 123 deleted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;if you do graphql, you care about POST requests&lt;/td&gt;
&lt;td&gt;&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;p&gt;&lt;strong&gt;what is RESTful&lt;/strong&gt;&lt;br&gt;
for every &#39;resource&#39;, like tags, user, comment, file, you will have a CRUD routes on a resources&lt;br&gt;
&lt;a href=&quot;https://frontendmasters.com/courses/api-design-nodejs-v5/http-verbs-restful-route-patterns/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://frontendmasters.com/courses/api-design-nodejs-v5/http-verbs-restful-route-patterns/&lt;/a&gt;&lt;br&gt;
GET === READ&lt;br&gt;
POST === CREATE&lt;br&gt;
PUT/PATCH === UPDATE&lt;br&gt;
DELETE === DELETE&lt;/p&gt;
&lt;p&gt;if you need a concurrence of resources, and therefore need to call a few APIs,  you may overfetch. GraphQL provides a way to query many APIs and get the exact data you want. the trade offs are significant: permissions, cache, query optimizations&lt;/p&gt;
&lt;p&gt;RESTful API is a beautiful thing because we just agree to it and built CRUD apps that serve the web for everyone.&lt;/p&gt;
&lt;p&gt;The server provides a level of freedom a frontend dev does not have. A backend dev tells you want the routes are and how they are defined&lt;/p&gt;
&lt;h2 id=&quot;routes&quot; tabindex=&quot;-1&quot;&gt;Routes&lt;/h2&gt;
&lt;p&gt;Sub-routers are individual routers for specific resources that can be mounted onto a top-level router. They are typically created by importing the Router from Express and are organized by resource type (e.g., User Routes, Habit Routes).&lt;/p&gt;
&lt;p&gt;typical CRUD routes for a Habit resource include: GET / (get all habits), GET /:id (get a single habit), POST / (create a habit), DELETE /:id (delete a habit), and potentially custom routes like POST /complete/:id.&lt;/p&gt;
&lt;h2 id=&quot;mounting-via-use&quot; tabindex=&quot;-1&quot;&gt;Mounting via &lt;code&gt;use&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://frontendmasters.com/courses/api-design-nodejs-v5/mounting-routes-with-use-middleware/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://frontendmasters.com/courses/api-design-nodejs-v5/mounting-routes-with-use-middleware/&lt;/a&gt;&lt;br&gt;
&lt;code&gt;use&lt;/code&gt; is for no http verb related to the route. It&#39;s a way to apply an action to a route. For example, dev wants to hit &lt;code&gt;/api/auth&lt;/code&gt;, instead of a callback like &lt;code&gt;(res, req) =&amp;gt; {}&lt;/code&gt; we use our &lt;code&gt;authRoutes&lt;/code&gt;&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-nodejs-api-design-4&quot; id=&quot;skip-to-code-skip-nodejs-api-design-4&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; authRoutes &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./routes/authRoutes.ts&#39;&lt;/span&gt;&lt;br&gt;&lt;br&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/api/auth&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; authRoutes&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-nodejs-api-design-4&quot;&gt;Anyone who hits a route, defined in &lt;code&gt;authRoutes&lt;/code&gt;, &lt;code&gt;/api/auth/register&lt;/code&gt; then use that handler. &lt;code&gt;.use()&lt;/code&gt; handles all HTTP methods for a given route regardless of the specific verb. Subroutes allow you to mount routes under a specific base path, so a route like &lt;code&gt;/register&lt;/code&gt; under &lt;code&gt;/api/auth&lt;/code&gt; would become &lt;code&gt;/api/auth/register&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Mounting allows you to specify a base route path for a group of routes, so routes can be decoupled and easily relocated without changing internal route definitions&lt;/p&gt;
&lt;h2 id=&quot;&quot; tabindex=&quot;-1&quot;&gt;&lt;a href=&quot;/stubs&quot;&gt;Middleware&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;NextJS has middleware.ts&lt;br&gt;
edge functions on the network layer before the server&lt;br&gt;
CDN edge functions&lt;/p&gt;
&lt;p&gt;HTTP interceptors -&amp;gt; axios fetch, apollo interceptor&lt;/p&gt;
&lt;p&gt;our foucs is backend middleware&lt;br&gt;
using &lt;code&gt;use()&lt;/code&gt; without a path is known as global middleware, e.g. logging&lt;br&gt;
how is middleware built?&lt;br&gt;
Express, middleware is left to right. if you are going to respond, in middleware, don&#39;t run next()&lt;br&gt;
simply it&#39;s an array of functions. each function is wrapped in a next() function. Its known as a controlled loop.&lt;/p&gt;
&lt;h2 id=&quot;understanding-next&quot; tabindex=&quot;-1&quot;&gt;understanding &lt;code&gt;next()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;doing a side effect like analytics log&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;another good example of middleware is credit card check, like expiration date is checked&lt;/li&gt;
&lt;li&gt;passing an arg in &lt;code&gt;next()&lt;/code&gt; will be handle by Express as an error&lt;/li&gt;
&lt;li&gt;error handling is just middleware too&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The dominate pattern: &lt;code&gt;(req, res, next)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;What is the recommended practice when responding inside middleware?&lt;br&gt;
Always call &lt;code&gt;return&lt;/code&gt; after responding, unless it&#39;s the last line of code. This prevents subsequent code from running after the response has been sent.&lt;/p&gt;
&lt;h2 id=&quot;cors&quot; tabindex=&quot;-1&quot;&gt;CORS&lt;/h2&gt;
&lt;p&gt;Options request -&amp;gt; preflight&lt;br&gt;
allowList? unless you are writing in the server&lt;br&gt;
&lt;code&gt;helmet&lt;/code&gt; security package&lt;br&gt;
&lt;code&gt;morgan&lt;/code&gt; is a request logger&lt;/p&gt;
&lt;h2 id=&quot;validate-inputs&quot; tabindex=&quot;-1&quot;&gt;validate inputs:&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://frontendmasters.com/courses/api-design-nodejs-v5/validation-middleware/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://frontendmasters.com/courses/api-design-nodejs-v5/validation-middleware/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;to avoid checking them with a bunch if/else statements&lt;/p&gt;
&lt;p&gt;asnyc middleware wrapper: avoid wrriting a lot of try-catch  statements, and instead wrap it in a function curry&lt;br&gt;
&lt;a href=&quot;https://frontendmasters.com/courses/api-design-nodejs-v5/async-middleware-pitfalls/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://frontendmasters.com/courses/api-design-nodejs-v5/async-middleware-pitfalls/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;databases&quot; tabindex=&quot;-1&quot;&gt;Databases&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://frontendmasters.com/courses/api-design-nodejs-v5/database-schemas/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://frontendmasters.com/courses/api-design-nodejs-v5/database-schemas/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Migrations: they suck! &lt;a href=&quot;https://api-design-with-node-v5.super.site/4-db-setup-and-schema&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;https://api-design-with-node-v5.super.site/4-db-setup-and-schema&lt;/a&gt;&lt;br&gt;
Think of them as database versioned.&lt;br&gt;
&lt;strong&gt;Migration Workflow:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Develop&lt;/strong&gt;: Make schema changes in code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generate&lt;/strong&gt;: Create migration files automatically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Review&lt;/strong&gt;: Inspect generated SQL before applying&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply&lt;/strong&gt;: Run migrations against database&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy&lt;/strong&gt;: Apply same migrations in production&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you can find a way to do only non-destructive changes, then make your life a lot easier&lt;/p&gt;
&lt;h3 id=&quot;orm-benefits-for-apis&quot; tabindex=&quot;-1&quot;&gt;ORM Benefits for APIs&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Benefit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Impact&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Compile-time error checking&lt;/td&gt;
&lt;td&gt;Fewer runtime bugs, better DX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query Building&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Programmatic query construction&lt;/td&gt;
&lt;td&gt;Dynamic filtering, pagination&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Relationship Loading&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automatic joins and includes&lt;/td&gt;
&lt;td&gt;Less code, optimized queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Schema Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Version-controlled database changes&lt;/td&gt;
&lt;td&gt;Reliable deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Migration System&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automated schema evolution&lt;/td&gt;
&lt;td&gt;Safe production updates&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;migrations-database-version-control&quot; tabindex=&quot;-1&quot;&gt;Migrations: Database Version Control&lt;/h2&gt;
&lt;p&gt;Migrations are versioned scripts that modify your database schema over time:&lt;/p&gt;
&lt;h2 id=&quot;drizzle-vs-other-orms&quot; tabindex=&quot;-1&quot;&gt;Drizzle vs Other ORMs&lt;/h2&gt;
&lt;h3 id=&quot;why-drizzle-over-prisma&quot; tabindex=&quot;-1&quot;&gt;Why Drizzle Over Prisma?&lt;/h3&gt;
&lt;h3 id=&quot;prisma-approach&quot; tabindex=&quot;-1&quot;&gt;Prisma Approach&lt;/h3&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-nodejs-api-design-3&quot; id=&quot;skip-to-code-skip-nodejs-api-design-3&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// schema.prisma
model User {
  id    String @id @default(cuid())
  email String @unique
  habits Habit[]
}

model Habit {
  id     String @id @default(cuid())
  name   String
  userId String
  user   User   @relation(fields: [userId], references: [id])
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-nodejs-api-design-3&quot;&gt;&lt;strong&gt;Requires:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Schema definition in Prisma language&lt;/li&gt;
&lt;li&gt;Generated client (&lt;code&gt;prisma generate&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Build step in deployment&lt;/li&gt;
&lt;li&gt;Black box query generation&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;drizzle-approach&quot; tabindex=&quot;-1&quot;&gt;Drizzle Approach&lt;/h3&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-nodejs-api-design-2&quot; id=&quot;skip-to-code-skip-nodejs-api-design-2&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Pure TypeScript schema&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; users &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pgTable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;users&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;primaryKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;email&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; length&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; habits &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pgTable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;habits&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;primaryKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;name&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; length&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  userId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;user_id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;references&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; users&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-nodejs-api-design-2&quot;&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pure TypeScript - no DSL&lt;/li&gt;
&lt;li&gt;No code generation step&lt;/li&gt;
&lt;li&gt;SQL-like API - predictable queries&lt;/li&gt;
&lt;li&gt;Lightweight and fast&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;implementing-the-schema&quot; tabindex=&quot;-1&quot;&gt;Implementing the Schema&lt;/h2&gt;
&lt;p&gt;refer to coding project&lt;br&gt;
&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;src/db/schema.ts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Habits Table schema&lt;/strong&gt;&lt;br&gt;
key features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;foreign key with cascade: when the user is deleted, their habits attached to them is deleted as well.&lt;/li&gt;
&lt;li&gt;frequency system: flexible habit scheduling, e.g. daily, weekly, monthly&lt;/li&gt;
&lt;li&gt;target count: support habit like &amp;quot;drink 8 glasses of water daily&amp;quot;&lt;/li&gt;
&lt;li&gt;soft delete: &lt;code&gt;isActive&lt;/code&gt; allows hiding w/o losing history&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;many to many relationship&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-nodejs-api-design-1&quot; id=&quot;skip-to-code-skip-nodejs-api-design-1&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; habitTags &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pgTable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;habitTags&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;primaryKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultRandom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  habitId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;habit_id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;references&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; habits&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;      onDelete&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;cascade&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;notNull&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  tagId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;tag_id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;references&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; tags&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    onDelete&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;cascade&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-nodejs-api-design-1&quot;&gt;The point of this &lt;code&gt;habitTags&lt;/code&gt; is that I can query &lt;code&gt;habitId&lt;/code&gt; and see all the tags associated with that habit and vice versa. If I want to see how many tags have habits, I can query the above table.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the purpose of a unique index in a database schema?&lt;/strong&gt;&lt;br&gt;
A unique index allows quick data retrieval and ensures that no two records have the same value in the indexed column, preventing duplicate entries like emails. It helps locate data quickly in constant time without scanning the entire table.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the primary purpose of using UUID as a primary key?&lt;/strong&gt;&lt;br&gt;
UUID (Universally Unique Identifier) serves as a unique, randomly generated identifier for database records, providing a globally unique value that can be generated without potential conflicts across different systems or databases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How does a foreign key relationship work in a database schema?&lt;/strong&gt;&lt;br&gt;
A foreign key creates a link between two tables by &lt;strong&gt;referencing&lt;/strong&gt; the &lt;em&gt;primary key&lt;/em&gt; of another table, establishing a relationship. In this schema, it allows actions like cascade delete and enables querying related entities across different tables.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the benefit of using a join table for managing many-to-many relationships?&lt;/strong&gt;&lt;br&gt;
A join table allows flexible and normalized data storage by creating connections between two entities, enabling bidirectional querying. It helps manage complex relationships by storing links between related tables without directly embedding foreign keys.&lt;/p&gt;
</content>
            </entry>
            
              
            <entry>
                <title>Edmund Edgar - Bluesky, atproto, how to hack on it and why it matters</title><link href="https://www.youtube.com/watch?v=2YtvMImH_SE"/><updated>2026-03-31T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/2026-03-3-day-2-atproto-talk-june-2025/</id>
                <content type="html">&lt;div class=&quot;embed-container&quot;&gt;
&lt;iframe src=&quot;https://www.youtube.com/embed/2YtvMImH_SE?si=U0zrYmTrFyo2CkNK&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/projects/project-atproto-20260331235629984.jpg&quot; alt=&quot;project - atproto-20260331235629984&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=2YtvMImH_SE&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;Protocol Berg v2: Edmund Edgar - Bluesky, atproto, how to hack on it and why it matters - YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-pds-v-my-old-web-server&quot; tabindex=&quot;-1&quot;&gt;The PDS v My Old Web Server&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Structured data
&lt;ul&gt;
&lt;li&gt;web server was for document data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;attached to an identity&lt;/li&gt;
&lt;li&gt;contained the social graph
&lt;ul&gt;
&lt;li&gt;all the entries can refer to other entries on other pds&#39;s&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cryptographically signed and content addressed.
&lt;ul&gt;
&lt;li&gt;you dont have to get all the content from the person&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;you can self host on a crappy vps, you get viral and your pds can stay up because not going get a data from pds&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-job-of-the-relay&quot; tabindex=&quot;-1&quot;&gt;The Job of the Relay&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/projects/project-atproto-20260331235700488.jpg&quot; alt=&quot;project - atproto-20260331235700488&quot;&gt;&lt;br&gt;
to get the latest changes from the various PDSs and put them in a massive stream known as the Firehose.&lt;br&gt;
Run you run a bunch of a &lt;code&gt;appview&lt;/code&gt; which are backend servers.&lt;br&gt;
Bluesky is running them but also other people are running their own.&lt;/p&gt;
&lt;h2 id=&quot;what-happens-when-you-post-on-bluesky&quot; tabindex=&quot;-1&quot;&gt;what happens when you post on bluesky&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dpham5/image/upload/f_auto,q_auto,w_800/blog/projects/project-atproto-20260331235730436.jpg&quot; alt=&quot;project - atproto-20260331235730436&quot;&gt;&lt;/p&gt;
&lt;p&gt;Assign an id, &lt;code&gt;cid&lt;/code&gt; hashed to make a CID.&lt;/p&gt;
&lt;p&gt;Encoded with DAG-CBOR: a compact binary way encoded structure data and easily roundtrip with json, and easily pass. DAG is a subset of CBOR.&lt;/p&gt;
&lt;p&gt;cid is Content Id&lt;/p&gt;
&lt;p&gt;commit node on top and merkle root. and verify your content&lt;/p&gt;
&lt;h2 id=&quot;identity&quot; tabindex=&quot;-1&quot;&gt;identity&lt;/h2&gt;
&lt;p&gt;Two takes on identity&lt;br&gt;
&lt;code&gt;DID:Web&lt;/code&gt; predate at-proto and part of web standards. Just put a document on a web server&lt;br&gt;
&lt;code&gt;DID:PLC&lt;/code&gt; placeholder or Public Ledger of Credentials ( created by at proto team)&lt;/p&gt;
&lt;p&gt;We want to get close as we can to Content REST data. Take the doc that tells you what you need to know about my identity.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Put in username&lt;/li&gt;
&lt;li&gt;put in key that controls the identity&lt;/li&gt;
&lt;li&gt;hash on the first update&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;sign with a key in the previous rotationKeys. If you got a chain of updates, and can be verify&lt;br&gt;
&lt;strong&gt;Trade Off&lt;/strong&gt;&lt;br&gt;
if you change your roationkey and someone got your hold of your key, no one could tell when a malicious line of updates goes through - At proto team handles this with a trusted sequencer&lt;/p&gt;
&lt;h2 id=&quot;missing-features-means-one-dominate-client-like-facebook&quot; tabindex=&quot;-1&quot;&gt;missing features means one dominate client ( like facebook )&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Curation -&amp;gt; for you feed. &amp;quot;Discover&amp;quot; tab
&lt;ul&gt;
&lt;li&gt;anyone can make a feed&lt;/li&gt;
&lt;li&gt;its easy. listen to changes to the firehouse. pick up the users ids and iterate a bunch ids and any user can take that feed.&lt;/li&gt;
&lt;li&gt;you can make block list or follow list&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-else-can-we-do-with-atproto&quot; tabindex=&quot;-1&quot;&gt;what else can we do with atproto&lt;/h2&gt;
&lt;p&gt;Everyone in the world gets a self-sovereign crypotgraphically verifiable semantic data store. This is what we should have done&lt;/p&gt;
&lt;p&gt;You can write records on the user behalf to their PDS.&lt;br&gt;
You can auth via OAuth&lt;br&gt;
Oauth flow can create a new account on a PDS host&lt;br&gt;
you can onboard the user to atproto&lt;/p&gt;
&lt;h2 id=&quot;lexicon&quot; tabindex=&quot;-1&quot;&gt;lexicon&lt;/h2&gt;
&lt;p&gt;You want to follow a lexicon&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;decentralized github -&amp;gt; &lt;a href=&quot;http://tangled.sh&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;tangled.sh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PR tracking&lt;br&gt;
instead of github its on your own git on your PDS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;blockchain -&amp;gt; commons data&lt;br&gt;
you have limit who can write to the blockchain&lt;/p&gt;
&lt;p&gt;You need data written by the user and owned by the user.&lt;/p&gt;
&lt;p&gt;Read the article at &lt;a href=&quot;https://www.youtube.com/watch?v=2YtvMImH_SE&quot;&gt;link&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://davidchicopham.com/feed-img.svg&quot; width=&quot;50&quot; height=&quot;50&quot; alt=&quot;Site logo&quot; /&gt;</content>
            </entry>
            
            <entry>
                <title>Day 1: Setting Up This Is My Next</title><link href="https://davidchicopham.com/this-is-my-next/day-1-setting-up/"/><updated>2026-03-15T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/day-1-setting-up/</id>
                <content type="html">&lt;p&gt;This section is called &lt;strong&gt;This Is My Next&lt;/strong&gt; — a dev log inspired by &lt;a href=&quot;https://fightwithtools.dev/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;Fight With Tools&lt;/a&gt;. Each entry is a timestamped snapshot of what I&#39;m building, what I&#39;m stuck on, and what I&#39;m figuring out.&lt;/p&gt;
&lt;p&gt;The idea: short, honest notes. Not polished essays. Just progress.&lt;/p&gt;
&lt;h2 id=&quot;what-i-built-today&quot; tabindex=&quot;-1&quot;&gt;What I Built Today&lt;/h2&gt;
&lt;p&gt;The whole infrastructure for this section in one sitting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A new &lt;code&gt;timn&lt;/code&gt; content type with its own layout&lt;/li&gt;
&lt;li&gt;A TODO checklist component that reads from frontmatter&lt;/li&gt;
&lt;li&gt;VS Code Dark+ syntax highlighting scoped to this section only&lt;/li&gt;
&lt;li&gt;A Bluesky share button on every post&lt;/li&gt;
&lt;li&gt;An archive page at &lt;code&gt;/this-is-my-next/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&#39;s the 11tydata.js that powers the content type:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-day-1-setting-up-2&quot; id=&quot;skip-to-code-skip-day-1-setting-up-2&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;layouts/page-timn-post.njk&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;contentType&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;timn&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;excludeFromFeed&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;eleventyComputed&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token function-variable function&quot;&gt;permalink&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/this-is-my-next/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fileSlug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;code-skip-day-1-setting-up-2&quot;&gt;And the TODO frontmatter format looks like this:&lt;/p&gt;
&lt;p class=&quot;skip-link-graf&quot;&gt;
&lt;a href=&quot;#code-skip-day-1-setting-up-1&quot; id=&quot;skip-to-code-skip-day-1-setting-up-1&quot; class=&quot;skip-link&quot;&gt;Skip code block ▼&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Set up monorepo&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;subtasks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Pick package manager&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Write first post&lt;br&gt;    &lt;span class=&quot;token key atrule&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;next-up&quot; tabindex=&quot;-1&quot;&gt;Next Up&lt;/h2&gt;
&lt;p id=&quot;code-skip-day-1-setting-up-1&quot;&gt;Collect and read links as recommend by Aram, and share as a post.&lt;/p&gt;
</content>
            </entry>
            
            <entry>
                <title>Why I&#39;m Starting This Section</title><link href="https://davidchicopham.com/this-is-my-next/why-this-section/"/><updated>2026-03-10T00:00:00Z</updated>
                <id>https://davidchicopham.com/this-is-my-next/why-this-section/</id>
                <content type="html">&lt;p&gt;I had something missing on my site for a while. I thought maybe &lt;code&gt;/projects&lt;/code&gt; could serve as a way to deep dive into a technology, e.g. &lt;em&gt;Astro&lt;/em&gt; or &lt;em&gt;htmx&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The challenge was that I&#39;d have starts and stops on a projects. I would end up forgetting what I was doing and didn&#39;t have a good way to kickstart a project. In fact last year, I developed deep sense of alienation from my work. I felt I didn&#39;t have any direction to pursue. I was bored and importantly, my work didn&#39;t feel like my own. Also the world is falling apart. That also distracted me.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fightwithtools.dev/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot;&gt;Aram Zucker-Scharff&#39;s blog&lt;/a&gt; &lt;code&gt;fightwithtools&lt;/code&gt; is a &lt;em&gt;work log&lt;/em&gt; of his projects, that serves as a bit of inspiration. After chatting with Aram, he shared that the blog helps him organize his projects and allows him to pause for a period of time and pick it back up when ready.&lt;/p&gt;
&lt;p&gt;I want that for myself.&lt;/p&gt;
&lt;p&gt;This site has essays, storystreams, and turbocharged links. But nothing that captures the texture of &lt;em&gt;building in progress&lt;/em&gt;. This Is My Next is that space.&lt;/p&gt;
&lt;h2 id=&quot;the-rules&quot; tabindex=&quot;-1&quot;&gt;The Rules&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Share what I am learning as rough unedited progress logs.&lt;/li&gt;
&lt;li&gt;The TODO section is stick and sits before the post&lt;/li&gt;
&lt;li&gt;Learning for learning sake is fun&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;what-im-working-on&quot; tabindex=&quot;-1&quot;&gt;What I&#39;m Working On&lt;/h2&gt;
&lt;p&gt;I am using Claude Code to build out features so I can write, discover, and share more. So to that end, I am exploring at-proto as the next big thing in web development. Claude Code is enabling a bicycle of my creativity, innovation, and ambition. I am aim to teach myself to take advantage of the tools of my peers and have this technology serve me and my goals.&lt;/p&gt;
</content>
            </entry>
            
            <entry>
                <title>Sleeping Deeply and Dreaming</title><link href="https://davidchicopham.com/posts/sleeping-deeply-and-dreaming/"/><updated>2025-09-26T00:00:00Z</updated>
                <id>https://davidchicopham.com/posts/sleeping-deeply-and-dreaming/</id>
                <content type="html">&lt;p&gt;We dream in the dark. Darkness everywhere we see. Blind to what is to come next.&lt;/p&gt;
&lt;p&gt;Fear and dread make our bed. Gentle heads slumber in the dead of night.&lt;/p&gt;
&lt;p&gt;Do not wake me. I need to sleep deeply. I want to see what could be, dreams of democracy.&lt;/p&gt;
</content>
            </entry>
</feed>
