<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ahitagni Saha</title>
    <description>The latest articles on DEV Community by Ahitagni Saha (@ahitagni07).</description>
    <link>https://dev.to/ahitagni07</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4149581%2F5fa20953-522a-4910-8211-24548d005451.jpg</url>
      <title>DEV Community: Ahitagni Saha</title>
      <link>https://dev.to/ahitagni07</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahitagni07"/>
    <language>en</language>
    <item>
      <title>"Can I ignore this?" — I built Handle It NL for a friend navigating Dutch letters</title>
      <dc:creator>Ahitagni Saha</dc:creator>
      <pubDate>Sun, 04 Oct 2026 18:30:42 +0000</pubDate>
      <link>https://dev.to/ahitagni07/can-i-ignore-this-i-built-handle-it-nl-for-a-friend-navigating-dutch-letters-l72</link>
      <guid>https://dev.to/ahitagni07/can-i-ignore-this-i-built-handle-it-nl-for-a-friend-navigating-dutch-letters-l72</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Handle It NL&lt;/strong&gt;, an AI assistant that helps expats understand Dutch administrative letters and figure out what they actually need to do.&lt;/p&gt;

&lt;p&gt;I originally built it for my wife. She recently moved to the Netherlands and is learning Dutch, but official letters from municipalities and government organisations can still be difficult to understand.&lt;/p&gt;

&lt;p&gt;The problem is that translation is only half the job.&lt;/p&gt;

&lt;p&gt;Even after translating a letter, you can still be left asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Okay... but what am I supposed to do?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is it serious?&lt;br&gt;&lt;br&gt;
Can I ignore it?&lt;br&gt;&lt;br&gt;
Is there a payment?&lt;br&gt;&lt;br&gt;
What is the deadline?&lt;br&gt;&lt;br&gt;
Do I need to visit somewhere?&lt;br&gt;&lt;br&gt;
What should I bring?&lt;/p&gt;

&lt;p&gt;That became the idea behind &lt;strong&gt;Handle It NL&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A user uploads a photo, screenshot, or scanned PDF and the app explains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WHAT IS THIS?

CAN I IGNORE IT?

WHAT DO I NEED TO DO?

BY WHEN?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It classifies letters as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment required&lt;/li&gt;
&lt;li&gt;Appointment / visit&lt;/li&gt;
&lt;li&gt;Action required&lt;/li&gt;
&lt;li&gt;Information only&lt;/li&gt;
&lt;li&gt;Mixed&lt;/li&gt;
&lt;li&gt;Needs review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can also extract deadlines, payment information, appointment details, things to bring, and important Dutch terms.&lt;/p&gt;

&lt;p&gt;When useful, the AI can call tools to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;verify a Dutch address through PDOK;&lt;/li&gt;
&lt;li&gt;prepare an &lt;code&gt;.ics&lt;/code&gt; calendar event;&lt;/li&gt;
&lt;li&gt;generate a Google Calendar link;&lt;/li&gt;
&lt;li&gt;save a deadline or appointment;&lt;/li&gt;
&lt;li&gt;look up selected Dutch process guidance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important rule behind the application is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The model interprets. Deterministic tools execute.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model can decide that an address should be checked, but PDOK performs the verification.&lt;/p&gt;

&lt;p&gt;The model can identify an appointment, but Python creates the actual calendar file and SQLite confirms whether the deadline was saved.&lt;/p&gt;

&lt;p&gt;I also added safeguards after discovering that the same PDF could sometimes produce slightly different AI wording.&lt;/p&gt;

&lt;p&gt;Appointments are now deduplicated using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;date/time + physical location
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and uploaded files are hashed with SHA-256.&lt;/p&gt;

&lt;p&gt;So uploading the exact same document again reuses the stored analysis instead of generating another potentially inconsistent interpretation.&lt;/p&gt;

&lt;p&gt;If the AI cannot produce a reliable structured result, the app shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MANUAL REVIEW NEEDED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of incorrectly suggesting that no action is necessary.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Live Demo
&lt;/h3&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://nl-expat-copilot-1.onrender.com" rel="noopener noreferrer"&gt;https://nl-expat-copilot-1.onrender.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The demo uses synthetic Dutch administrative letters rather than real personal correspondence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5fznmzddyxi8ip10nbiz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5fznmzddyxi8ip10nbiz.png" alt="Upload document" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: municipality appointment
&lt;/h3&gt;

&lt;p&gt;For a Burgerzaken appointment letter, Handle It NL can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explain the letter in plain English;&lt;/li&gt;
&lt;li&gt;identify the appointment time;&lt;/li&gt;
&lt;li&gt;list what the user should bring;&lt;/li&gt;
&lt;li&gt;verify the address through PDOK;&lt;/li&gt;
&lt;li&gt;prepare a calendar event;&lt;/li&gt;
&lt;li&gt;save the appointment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fopp87ntdkprsr1bbzslc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fopp87ntdkprsr1bbzslc.png" alt="agent trace" width="799" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Saved deadlines
&lt;/h3&gt;

&lt;p&gt;Important appointments and deadlines appear in a dashboard and can be reopened later with the full explanation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp32l6u5yow8hui342ab8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp32l6u5yow8hui342ab8.PNG" alt="saved deadlines" width="800" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app also handles the opposite case.&lt;/p&gt;

&lt;p&gt;If a letter is purely informational, it can return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFORMATION ONLY
NO ACTION NEEDED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without creating unnecessary deadlines or calendar events.&lt;/p&gt;

&lt;h3&gt;
  
  
  What my wife thought
&lt;/h3&gt;

&lt;p&gt;When I showed the application to my wife, what surprised her most was that it felt more useful than a normal translation tool.&lt;/p&gt;

&lt;p&gt;A translator can explain what a Dutch sentence says, but Handle It NL also tries to explain &lt;strong&gt;how important the letter is, whether action is required, what the deadline is, and what she should do next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That extra context was what stood out to her.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;GitHub:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/Ahitagni07/nl-expat-copilot" rel="noopener noreferrer"&gt;https://github.com/Ahitagni07/nl-expat-copilot&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Main stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend: Angular 22
Backend: FastAPI
AI: DeepSeek V4.1 Flash via OpenRouter
PDF processing: PyMuPDF
Storage: SQLite
Address verification: PDOK
Hosting: Render
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       Dutch letter / scanned PDF
                  │
                  ▼
               Angular
                  │
                  ▼
               FastAPI
                  │
                  ▼
              OpenRouter
                  │
                  ▼
        DeepSeek V4.1 Flash
                  │
          decides what it needs
                  │
       ┌──────────┼──────────┐
       ▼          ▼          ▼
     PDOK      Calendar    SQLite
       │                     │
       └──────────┬──────────┘
                  ▼
          Actionable result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multimodal document analysis
&lt;/h3&gt;

&lt;p&gt;FastAPI accepts images and scanned PDFs.&lt;/p&gt;

&lt;p&gt;For PDFs, PyMuPDF renders the first few pages into optimized images before sending them to the multimodal model.&lt;/p&gt;

&lt;p&gt;The model handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;document understanding;&lt;/li&gt;
&lt;li&gt;classification;&lt;/li&gt;
&lt;li&gt;structured extraction;&lt;/li&gt;
&lt;li&gt;deciding whether a tool is useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tool calling
&lt;/h3&gt;

&lt;p&gt;The available tools include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lookup_official_process()
verify_dutch_address()
prepare_calendar_event()
save_deadline()
get_upcoming_deadlines()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A typical appointment flow looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model reads document
        ↓
verify_dutch_address()
        ↓
PDOK verifies location
        ↓
prepare_calendar_event()
        ↓
Python creates .ics
        ↓
save_deadline()
        ↓
SQLite confirms saved/already exists
        ↓
final explanation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend shows these actions as an &lt;strong&gt;Agent Trace&lt;/strong&gt;, so the user can see which real tools were used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Safety
&lt;/h3&gt;

&lt;p&gt;Handle It NL never performs payments.&lt;/p&gt;

&lt;p&gt;For payment letters it may extract an amount, deadline, or reference, but the user is told to verify payment details against the original document or official portal.&lt;/p&gt;

&lt;p&gt;Calendar events are also never silently added. The app creates an &lt;code&gt;.ics&lt;/code&gt; file or pre-filled calendar link and leaves the final action to the user.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Handle It NL uses &lt;strong&gt;DeepSeek V4.1 Flash&lt;/strong&gt;, an open-weight multimodal model, through OpenRouter.&lt;/p&gt;

&lt;p&gt;I use hosted inference for this demo because running a model of this size locally on my laptop is not practical.&lt;/p&gt;

&lt;p&gt;But the application is not designed around one closed model provider.&lt;/p&gt;

&lt;p&gt;The model is responsible for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;understand
extract
classify
choose a tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while normal application code handles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;address verification
deadline storage
duplicate detection
calendar generation
structured validation
safety rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That separation means the inference layer could later move from OpenRouter to self-hosted or local open-weight inference without rewriting the entire application.&lt;/p&gt;

&lt;p&gt;This is especially useful for an application dealing with personal correspondence, where privacy, data residency, cost, and model choice may matter.&lt;/p&gt;

&lt;p&gt;The current public demo is not fully local, so I use synthetic documents and make that trade-off explicit.&lt;/p&gt;

&lt;p&gt;For me, open innovation matters because it keeps the intelligence layer replaceable while the application continues to own its behaviour.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Best Use of Render
&lt;/h3&gt;

&lt;p&gt;I am entering &lt;strong&gt;Best Use of Render&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The public demo runs entirely on Render:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular is hosted as a &lt;strong&gt;Render Static Site&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;FastAPI runs as a &lt;strong&gt;Render Web Service&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Render rewrite rules route frontend &lt;code&gt;/api/*&lt;/code&gt; requests to the FastAPI backend, allowing the same Angular API paths to work locally and in production.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://nl-expat-copilot-1.onrender.com" rel="noopener noreferrer"&gt;https://nl-expat-copilot-1.onrender.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The most interesting problems were not about calling an AI model.&lt;/p&gt;

&lt;p&gt;They were about deciding &lt;strong&gt;when not to trust it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;During the weekend I had to solve issues such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;duplicate appointments;&lt;/li&gt;
&lt;li&gt;inconsistent wording from the same document;&lt;/li&gt;
&lt;li&gt;structured-output failures;&lt;/li&gt;
&lt;li&gt;address verification;&lt;/li&gt;
&lt;li&gt;avoiding false “No action needed” results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of those problems moved more responsibility from the model into deterministic application code.&lt;/p&gt;

&lt;p&gt;That ultimately made Handle It NL much more useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Handle It NL started with one simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Translation can tell someone what a Dutch letter says. But who tells them what they should actually do next?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the problem I wanted to solve.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
