<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Posts on Bui Nam</title>
    <link>https://buinam.pages.dev/posts/</link>
    <description>Recent content in Posts on Bui Nam</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 23 Jun 2026 11:46:05 +0700</lastBuildDate>
    <atom:link href="https://buinam.pages.dev/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Papermod - Installation</title>
      <link>https://buinam.pages.dev/posts/papermod-installation/</link>
      <pubDate>Tue, 15 Sep 2020 09:00:00 +0700</pubDate>
      <guid>https://buinam.pages.dev/posts/papermod-installation/</guid>
      <description>Follow this guide to set up Hugo, install PaperMod, and start a new site with a clean local workflow.</description>
    </item>
    <item>
      <title>Papermod - Features</title>
      <link>https://buinam.pages.dev/posts/papermod-features/</link>
      <pubDate>Wed, 16 Sep 2020 09:00:00 +0700</pubDate>
      <guid>https://buinam.pages.dev/posts/papermod-features/</guid>
      <description>A quick look at the parts of PaperMod that matter most in day-to-day writing: speed, clean post cards, taxonomies, and simple configuration.</description>
    </item>
    <item>
      <title>Markdown Syntax Guide</title>
      <link>https://buinam.pages.dev/posts/markdown-syntax-guide/</link>
      <pubDate>Mon, 11 Mar 2019 09:00:00 +0700</pubDate>
      <guid>https://buinam.pages.dev/posts/markdown-syntax-guide/</guid>
      <description>A compact reference for headings, lists, code blocks, tables, and the Markdown patterns Hugo renders cleanly out of the box.</description>
    </item>
    <item>
      <title>Hello World</title>
      <link>https://buinam.pages.dev/posts/hello-world/</link>
      <pubDate>Tue, 23 Jun 2026 11:46:05 +0700</pubDate>
      <guid>https://buinam.pages.dev/posts/hello-world/</guid>
      <description>&lt;h1 id=&#34;agent--email-service-architecture&#34;&gt;Agent → Email Service Architecture&lt;/h1&gt;
&lt;p&gt;High-throughput, async, durable email pipeline. Agent (ECS) enqueues; Email (Lambda) sends via SES; DynamoDB is source of truth; SQS/SNS decouple producers from consumers.&lt;/p&gt;
&lt;h2 id=&#34;components&#34;&gt;Components&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Component&lt;/th&gt;
          &lt;th&gt;Role&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Agent (ECS Fargate, NestJS)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;API surface. Accepts single/batch send requests, writes job rows to DynamoDB, publishes to SQS.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Email Lambda (plain Node/TS)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;SQS-triggered worker. Renders + sends via SES, updates DynamoDB. No DI framework — handler is a plain function for fast cold starts.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Event Lambda (plain Node/TS)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;SNS-triggered. Updates job status, maintains suppression.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;SQS Standard (&lt;code&gt;email-jobs&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Main work queue. High throughput, at-least-once.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;SQS DLQ (&lt;code&gt;email-jobs-dlq&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Catches messages exceeding maxReceiveCount.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;SQS DLQ (&lt;code&gt;event-lambda-dlq&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Catches SNS deliveries Event Lambda failed to process after retries.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;SNS (&lt;code&gt;ses-events&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Fan-out for SES bounce/complaint/delivery notifications.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;DynamoDB &lt;code&gt;EmailJobs&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Job state, idempotency, audit trail.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;DynamoDB &lt;code&gt;Suppression&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Bounce/complaint suppression list (checked before send).&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;SES&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Actual mail transport.&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;high-level-flow&#34;&gt;High-Level Flow&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    Client[Client / Upstream] --&amp;gt;|POST /emails| Agent[Agent ECS Fargate]
    Agent --&amp;gt;|PutItem job=PENDING| DDB[(DynamoDB EmailJobs)]
    Agent --&amp;gt;|SendMessage| SQS[[SQS email-jobs]]
    SQS --&amp;gt;|trigger batch| Lambda[Email Lambda]
    Lambda --&amp;gt;|GetItem| DDB
    Lambda --&amp;gt;|check| Supp[(DynamoDB Suppression)]
    Lambda --&amp;gt;|SendEmail / SendBulkEmail| SES[SES]
    Lambda --&amp;gt;|UpdateItem SENT/FAILED| DDB
    SES --&amp;gt;|bounce/complaint/delivery| SNS[[SNS ses-events]]
    SNS --&amp;gt; EvtLambda[Event Lambda]
    EvtLambda --&amp;gt;|UpdateItem| DDB
    EvtLambda --&amp;gt;|PutItem| Supp
    SQS -. failures .-&amp;gt; DLQ[[SQS DLQ]]
    SNS -. failures .-&amp;gt; EDLQ[[Event DLQ]]
    DLQ --&amp;gt; Alarm{{CloudWatch Alarm}}
    EDLQ --&amp;gt; Alarm
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
  </channel>
</rss>
