<?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: Malawige Inusha Thathsara Gunasekara</title>
    <description>The latest articles on DEV Community by Malawige Inusha Thathsara Gunasekara (@inushathathsara).</description>
    <link>https://dev.to/inushathathsara</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%2F3688375%2F884c13e5-87d4-49ec-a3d1-a73e5f71b94c.png</url>
      <title>DEV Community: Malawige Inusha Thathsara Gunasekara</title>
      <link>https://dev.to/inushathathsara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/inushathathsara"/>
    <language>en</language>
    <item>
      <title>Reverse-Engineering an Old Node.js Crossword App into a Modern Next.js Stack</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Mon, 22 Jun 2026 15:30:39 +0000</pubDate>
      <link>https://dev.to/inushathathsara/reverse-engineering-an-old-nodejs-crossword-app-into-a-modern-nextjs-stack-2oe0</link>
      <guid>https://dev.to/inushathathsara/reverse-engineering-an-old-nodejs-crossword-app-into-a-modern-nextjs-stack-2oe0</guid>
      <description>&lt;p&gt;As an IT undergrad at the University of Moratuwa, I’ve built my fair share of projects. Recently, I looked back at an old project of mine—a traditional &lt;a href="https://github.com/inusha-thathsara/CrosswordNodeApp" rel="noopener noreferrer"&gt;Node.js Crossword App&lt;/a&gt; and realized it was time for a complete teardown.&lt;/p&gt;

&lt;p&gt;The old app worked, but the architecture felt dated. I wanted to modernize it, improve the performance, and implement a cleaner, editorial-style UI. Instead of just refactoring, I decided to reverse-engineer the core logic of my own app and rebuild it from the ground up using &lt;strong&gt;Next.js 16, Neon PostgreSQL, Better Auth, and v0 by Vercel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is how I broke down the legacy system and engineered the new application, &lt;strong&gt;Crosshatch&lt;/strong&gt;. You can check out the live deployment here: &lt;a href="https://crossword-web-app.vercel.app" rel="noopener noreferrer"&gt;crossword-web-app.vercel.app&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The Teardown: Reverse-Engineering the Core Loop
&lt;/h3&gt;

&lt;p&gt;When reverse-engineering an existing app—even your own—the goal is to separate the underlying business logic from the legacy plumbing. I ignored the old routing and view layers and focused entirely on the data structures and the game loop.&lt;/p&gt;

&lt;p&gt;I identified three critical systems that needed to be extracted and modernized:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Grid Generation:&lt;/strong&gt; How words intersect and fit into a 10x10 matrix.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Management:&lt;/strong&gt; Tracking user input, active cells, and directional navigation (Across vs. Down).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session &amp;amp; Progress:&lt;/strong&gt; How to persist a user's progress without hammering the database.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once I had the core logic mapped out, I started the rebuild.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accelerating the UI with v0
&lt;/h3&gt;

&lt;p&gt;I wanted the new app to have a calm, newspaper-inspired light theme. To move fast, I leveraged &lt;strong&gt;v0 by Vercel&lt;/strong&gt; to generate the initial React components.&lt;/p&gt;

&lt;p&gt;By prompting v0 with my required game state constraints (e.g., handling keyboard events like Tab, Shift+Tab, and arrow keys for navigation), I was able to rapidly prototype the 10x10 interactive grid. v0 handled the Tailwind CSS boilerplate, allowing me to focus on wiring up the complex state machine using a custom &lt;code&gt;useCrossword&lt;/code&gt; React hook.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Modern Stack &amp;amp; Architecture
&lt;/h3&gt;

&lt;p&gt;With the UI taking shape, I built out a robust backend architecture to support it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Framework:&lt;/strong&gt; Next.js 16 (App Router)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; Neon PostgreSQL with Drizzle ORM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication:&lt;/strong&gt; Better Auth (handling secure email/password flows and session management)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the key technical problems I had to solve during the rebuild:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Deterministic Puzzle Generation
&lt;/h4&gt;

&lt;p&gt;In the old app, puzzle generation could be unpredictable. For the new build, I implemented a &lt;strong&gt;Seeded RNG algorithm&lt;/strong&gt;. By using the puzzle's ID (e.g., &lt;code&gt;animals-1&lt;/code&gt;) as the seed, the generation is completely deterministic. It shuffles the word list, places the first word at &lt;code&gt;(0,0)&lt;/code&gt;, and maps intersecting cells. If you and a friend both load &lt;code&gt;animals-1&lt;/code&gt;, you are guaranteed to get the exact same layout.&lt;/p&gt;

&lt;p&gt;Because generating a puzzle is CPU-intensive, I implemented a caching layer. The server generates the puzzle once, caches it in a Map, and serves it instantly on subsequent requests.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Smart Autosave &amp;amp; The Visibility API
&lt;/h4&gt;

&lt;p&gt;Losing crossword progress is frustrating. I built a system that autosaves every 5 seconds. To prevent excessive database writes, I used a PostgreSQL &lt;code&gt;UPSERT&lt;/code&gt; pattern via Drizzle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;puzzle_progress&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;puzzleId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elapsedSeconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;CONFLICT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;puzzleId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;DO&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elapsedSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updatedAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Additionally, the puzzle timer uses the browser's &lt;strong&gt;Visibility API&lt;/strong&gt;. If you switch tabs, the timer automatically pauses, ensuring your "Solve Time" stats remain accurate to your actual active playtime.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Data Integrity: The "No Double-Credit" Problem
&lt;/h4&gt;

&lt;p&gt;I built a user dashboard to track completions, best times, and average solve times. But what happens if a user submits the same completed puzzle twice?&lt;/p&gt;

&lt;p&gt;Instead of writing complex application-level checks, I let the database handle it. I added a unique constraint on &lt;code&gt;(userId, puzzleId)&lt;/code&gt; in the &lt;code&gt;completion&lt;/code&gt; table and utilized the &lt;code&gt;ON CONFLICT DO NOTHING&lt;/code&gt; clause. If a user solves a puzzle for the first time, it records their time. If they re-submit it, the database ignores the insert, returning a response that acknowledges the correct answers without skewing their dashboard analytics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Reverse-engineering an older project and rebuilding it with modern tooling is one of the best ways to measure your growth as a developer. By moving to Next.js and leveraging v0 for rapid UI prototyping, I was able to spend my time solving actual engineering problems (like deterministic generation and state synchronization) rather than wrestling with basic CSS.&lt;/p&gt;

&lt;p&gt;Check out the live app at &lt;a href="https://crossword-web-app.vercel.app" rel="noopener noreferrer"&gt;crossword-web-app.vercel.app&lt;/a&gt; and let me know what you think of the architecture! I’m always open to technical feedback.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Stop Funding History: Building a Demand Prediction App to Optimize Trade Spend</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Mon, 22 Jun 2026 15:00:24 +0000</pubDate>
      <link>https://dev.to/inushathathsara/stop-funding-history-building-a-demand-prediction-app-to-optimize-trade-spend-4iak</link>
      <guid>https://dev.to/inushathathsara/stop-funding-history-building-a-demand-prediction-app-to-optimize-trade-spend-4iak</guid>
      <description>&lt;p&gt;Let’s be honest: in the FMCG (Fast-Moving Consumer Goods) space, trade marketing budgets are almost always misallocated. Companies tend to fund invoice history rather than actual potential.&lt;/p&gt;

&lt;p&gt;For the DataStorm 7.0 competition, our team, &lt;strong&gt;Stack Kings&lt;/strong&gt;, decided to stop guessing and start modeling latent demand. We built an analytics pipeline and a Next.js field app to optimize a LKR 5M trade spend across 20,000 retail outlets in Sri Lanka. Here is the unvarnished breakdown of how we achieved a +253% lift over a naive budget allocation.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Empty Shelf" Problem (Right-Censoring)
&lt;/h3&gt;

&lt;p&gt;The core data science issue here is a concept called right-censoring. The monthly sales volumes we observed in the 2.3M transaction records were just a lower bound. If a small shop shows low sales, it might just be under-stocked or credit-constrained, not lacking in customer demand.&lt;/p&gt;

&lt;p&gt;Because of this, standard averages systematically underestimate a shop's true potential. Instead of using standard textbook models like Tobit—which require strict indicators of exactly when a shop ran out of stock (which we didn't have)—we built an ensemble model.&lt;/p&gt;

&lt;p&gt;We took a two-pronged approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lookalike Clustering:&lt;/strong&gt; We clustered similar outlets to see what the top performers in that specific group were achieving, assuming that less-constrained shops reveal the true ceiling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Upper-Tail Regression:&lt;/strong&gt; We used a specific type of regression (Quantile Regression) designed to estimate the maximum possible demand based on a shop's features, rather than the average.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Taking the maximum of these two estimates ensured we weren't artificially pulling down a shop's potential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mapping the Real World (Spatial Features)
&lt;/h3&gt;

&lt;p&gt;To give the models a real signal, we engineered spatial features using OpenStreetMap Points of Interest (POIs).&lt;/p&gt;

&lt;p&gt;Rather than using arbitrary "flat disk" counts—like just counting how many shops are within a 3km radius—we implemented a distance-decay model. In plain English: a bus stop 200 meters away matters a lot more to foot traffic than one 2 kilometers away.&lt;/p&gt;

&lt;p&gt;We grouped locations into tiers. Transport and food places have a "fast" drop-off in influence, meaning you need to be right next to them to get the benefit. Meanwhile, schools and temples cast a wider, "slower" net of influence over the entire neighborhood.&lt;/p&gt;

&lt;h3&gt;
  
  
  Squeezing Every Drop of Budget (The Optimizer)
&lt;/h3&gt;

&lt;p&gt;Ranking outlets by potential isn't enough; you need to maximize the incremental liters gained per rupee spent.&lt;/p&gt;

&lt;p&gt;We modeled the volume response to trade spend as a curve with diminishing returns. Simply put, the more you spend on a single shop, the less extra volume you get for your next rupee.&lt;/p&gt;

&lt;p&gt;To solve this efficiently across 9,000 Western Province outlets, we broke that curve into straight-line segments. This allowed us to use a Linear Programming solver to allocate the LKR 5M budget mathematically perfectly. The result? A massive 253% lift compared to the standard gut-feel approach of just splitting the money evenly among top shops.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Trust with the Field App
&lt;/h3&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="stackkings.inusha.me" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;stackkings.inusha.me&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
A complex optimizer is useless if field sales reps don't trust the numbers. They need to know &lt;em&gt;why&lt;/em&gt; a shop is getting a certain budget.

&lt;p&gt;We built a live Outlet Intelligence Web App using Next.js and Postgres. To explain the outputs, we added an Explainable AI (XAI) layer. It uses a local Ollama process (gemma3:1b) running in the browser to generate a structured SWOT summary. If the local AI is offline, it falls back to a Gemini cloud API or a safe deterministic template.&lt;/p&gt;

&lt;p&gt;Crucially, the AI doesn't make the predictions. It simply translates our hard, pre-computed data into plain business language so the sales reps can actually use it on the ground.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dirty Reality of Data
&lt;/h3&gt;

&lt;p&gt;Data engineering isn't glamorous. We built a strict Medallion architecture. We didn't silently drop messy data. We explicitly quarantined 37,205 records using failure reason codes. We even retained 7,417 "blackout" outlets (shops with zero December transactions), treating them correctly as supply signals rather than zero demand.&lt;br&gt;&lt;br&gt;
Check out the live production app at &lt;a href="//stackkings.inusha.me"&gt;stackkings.inusha.me&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We don't fund history. We fund potential.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>datascience</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Made Tyre Size Detection App Using Gemma4:e4b</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Tue, 19 May 2026 18:21:37 +0000</pubDate>
      <link>https://dev.to/inushathathsara/i-made-tyre-size-detection-app-using-gemma4e4b-490e</link>
      <guid>https://dev.to/inushathathsara/i-made-tyre-size-detection-app-using-gemma4e4b-490e</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Build with Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;NewTyre-AI&lt;/strong&gt; is a secure, localized full-stack web application designed to automate a deceptively complex industrial task: passenger vehicle tyre sidewall size extraction.&lt;/p&gt;

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

&lt;p&gt;Traditional computer vision pipelines frequently default to cloud-dependent architectures to process visual data. While convenient, this approach introduces persistent operational liabilities for businesses: recurring cloud API bills, data transit latencies, and corporate data privacy exposure. Furthermore, reading alphanumeric characters from a tyre sidewall is difficult for traditional linear Optical Character Recognition (OCR) tools because text printed on rubber is non-linear, low-contrast, heavily textured, and curved.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;NewTyre-AI solves this by shifting the entire visual processing workload onto a local, physical on-premise company server. The system ingests sidewall photos, filters them through a localized multimodal edge model, and returns an un-hallucinated, deterministic 9-character tyre size code (e.g., 205/60R16) to the technician with zero ongoing cloud compute or external API costs.&lt;/p&gt;

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

&lt;p&gt;Video Demo(30 sec): &lt;a href="https://drive.google.com/file/d/1sp0odXgkxL9jELnCiXovkT5TY1zEmCjg/view?usp=sharing" rel="noopener noreferrer"&gt;Google Drive&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/inusha-thathsara/NewTyre-AI" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Gemma 4
&lt;/h2&gt;

&lt;p&gt;For this project, I deliberately selected the Gemma4:e4b (Effective 4B) parameter model rather than scaling up to the massive dense weights or downgrading to the highly lightweight e2b version. 2B model lack the visual cross-attention layer density required to accurately map characters in noisy geometric layouts, while 32B model is a overkill. The e4b model retains the precise structural transformer resolution required to read curved, dirty text on dark rubber cylinders without throwing a wave of false positives.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>Built an AI Study Tool That Refuses to Give You the Answers for UoM</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Sun, 01 Mar 2026 17:10:22 +0000</pubDate>
      <link>https://dev.to/inushathathsara/built-an-ai-study-tool-that-refuses-to-give-you-the-answers-for-uom-1eho</link>
      <guid>https://dev.to/inushathathsara/built-an-ai-study-tool-that-refuses-to-give-you-the-answers-for-uom-1eho</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;I am an IT undergraduate at the &lt;strong&gt;University of Moratuwa&lt;/strong&gt;(UoM), Sri Lanka. In our community, the night before a brutal technical exam is chaotic. When faced with a massive, complicated past-paper question that we don't understand, students often hit a wall of panic and just give up (we call it going "Bora").&lt;/p&gt;

&lt;p&gt;The problem with existing AI study tools is that they just give you the final answer or the raw code. That doesn't help you learn; it just helps you cheat. I wanted to build a tool for my batchmates that acts like a senior student holding a late-night study session(a "Kuppi") guiding you to the answer without actually giving it to you.&lt;/p&gt;

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

&lt;p&gt;I built &lt;strong&gt;Triage AI&lt;/strong&gt;, a cross-platform (Next.js Web + Flutter Android) tool designed specifically for technical exam preparation. You simply snap a photo of a difficult past paper question, and the app uses AI to break it down.&lt;/p&gt;

&lt;p&gt;Instead of solving the problem, it returns three specific things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Concepts:&lt;/strong&gt; The exact fundamental topics you need to Google to understand the question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Trap:&lt;/strong&gt; It identifies the subtle pitfall or trick hidden in the question designed to make students fail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack Plan:&lt;/strong&gt; A step-by-step strategic breakdown of how to approach the solution.&lt;/p&gt;

&lt;p&gt;If you are still stuck, Triage AI features a "Practice" mode that generates a similar question, and a "Hint" system that provides progressive, helpful nudges (never the answer) to get you unblocked.&lt;/p&gt;

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

&lt;p&gt;Live: &lt;a href="https://bora-quiz-helper.vercel.app" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;&lt;br&gt;
This weekend sprint proved to me that AI doesn't have to be a shortcut that ruins learning. When built with the right constraints, it can be the ultimate teaching assistant. &lt;/p&gt;

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

&lt;p&gt;Source Code: &lt;a href="https://github.com/inusha-thathsara/Bora-Quiz-Helper" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Balancing this weekend challenge with my strict university workload was tough. As an IT undergraduate, I couldn't afford to ignore my own university assignments to build an app. Because I was juggling coursework and only had the weekend to code, I needed to keep the technical setup extremely lean and fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Brain:&lt;/strong&gt; I used the Google Gemini 2.5 Flash API because it can process uploaded images incredibly fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Logic:&lt;/strong&gt; I built a Next.js application to handle the requests. I wrote strict prompts and set up Gemini to return structured data, which made it easy to display the results in clean UI cards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The App:&lt;/strong&gt; The Next.js backend powers both a smooth React web app and a native Flutter Android app(kinda buggy though) at the same time.&lt;/p&gt;

&lt;p&gt;Aside from time management, the hardest technical challenge was the Hint System. To ensure the AI didn't repeat itself or accidentally reveal the answer, the app keeps track of the clues you've already seen. It sends this history back to Gemini so that the next hint is a progressively more specific nudge in the right direction.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Good luck with exams, batchmates!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How I Built a 15,000+ Line Flutter App with Gemini to "Hack" My University Attendance</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Wed, 25 Feb 2026 18:55:37 +0000</pubDate>
      <link>https://dev.to/inushathathsara/how-i-built-a-15000-line-flutter-app-with-gemini-to-hack-my-university-attendance-3p2i</link>
      <guid>https://dev.to/inushathathsara/how-i-built-a-15000-line-flutter-app-with-gemini-to-hack-my-university-attendance-3p2i</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/mlh-built-with-google-gemini-02-25-26"&gt;Built with Google Gemini: Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built with Google Gemini
&lt;/h2&gt;

&lt;p&gt;As an IT undergraduate balancing startup ambitions and a heavy coursework load, missing too many classes can lead to disastrous exam bans. To solve this, I built Attendance Tracker (code-named "The 80%"). It's a cross-platform Flutter application designed to mathematically optimize university attendance using offline-first storage and AI.&lt;/p&gt;

&lt;p&gt;The app features a "Danger Zone Planner" that calculates the exact margin for absences across specific sessions (Lectures, Labs, Tutorials). This allows students to simulate granular scenarios and understand their attendance buffer, ensuring they never accidentally drop below their mandatory academic thresholds.&lt;/p&gt;

&lt;p&gt;Google Gemini played a massive, two-fold role in this project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Architecture (Agentic AI): This project scaled to over 15,000 lines of code. I used the Gemini 3 Pro (High) model inside the Antigravity IDE as an autonomous coding agent to help architect the offline-first database (Hive), manage state (Provider), and handle complex UI animations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Core Feature (API Integration): The biggest friction point in attendance apps is manual data entry. I integrated the Gemini 2.5 Flash API to handle multimodal timetable extraction. Users simply upload their official university schedule as a PDF or image, and Gemini intelligently parses the unstructured data into a clean matrix of subjects, times, and session types.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;You can experience the live web app directly in your browser:&lt;/p&gt;

&lt;p&gt;Live Web App: &lt;a href="https://attendance-tracker-5d550.web.app" rel="noopener noreferrer"&gt;Attendance Tracker Web&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source Code: &lt;a href="https://github.com/inusha-thathsara/attendance-tracker-demo/tree/main" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt; (Only the Demo source code is available with the latest apk releases)&lt;/p&gt;

&lt;p&gt;Screenshot:&lt;/p&gt;

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

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

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

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

&lt;p&gt;Building a 15,000+ line production app taught me several critical lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Background Asynchronous Processing: Because parsing detail-heavy timetable PDFs via the Gemini API can take time, I had to learn how to run these complex tasks in the background. This ensures the UI doesn't freeze, allowing users to navigate the app while waiting for an in-app "Timetable Ready" notification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defensive Engineering: AI isn't perfect. I learned to build a robust "Draft Review" step so users can verify and edit the AI's extracted timetable before committing it to the Firebase database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;System Design: Implementing an offline-first architecture with Hive local caching and syncing it seamlessly with Firebase Firestore taught me how to handle complex data states across varying network conditions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Google Gemini Feedback
&lt;/h2&gt;

&lt;p&gt;The Good:&lt;br&gt;
The multimodal capabilities of gemini-2.5-flash are incredible. It flawlessly handled messy, poorly formatted university PDFs and images, turning unstructured visual data into a clean, usable dataset. Using Gemini 3 Pro (High) as an agentic coding partner felt like having a senior engineer on call, saving me weeks of boilerplate coding and UI tweaking.&lt;/p&gt;

&lt;p&gt;The Bad and The Ugly:&lt;br&gt;
When you let an AI agent loose on a 15,000-line codebase, you push context windows to their absolute limits. Occasionally, the IDE agent would lose the thread of the architecture, hallucinating variable names or forgetting how distant files interconnected.&lt;/p&gt;

&lt;p&gt;On the API side, relying heavily on Gemini 2.5 Flash for file parsing introduced the reality of rate limits. To prevent the app from breaking for users during high-traffic periods, I had to engineer a Multi-API Key Support system, allowing the app to rotate through different user-provided Gemini keys to ensure uninterrupted parsing. Additionally, highly non-standard timetable layouts occasionally confused the model, making the manual draft review step an absolute necessity. Overall, it's a powerhouse, but it requires strict guardrails in a production environment.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>geminireflections</category>
      <category>gemini</category>
    </item>
    <item>
      <title>The Shores of Denial – The World that Shouldn't Exist</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Fri, 23 Jan 2026 13:23:07 +0000</pubDate>
      <link>https://dev.to/inushathathsara/the-shores-of-denial-the-world-that-shouldnt-exist-3dpb</link>
      <guid>https://dev.to/inushathathsara/the-shores-of-denial-the-world-that-shouldnt-exist-3dpb</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;My Voluntary Descent&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When I first stepped onto the Fort Oasis pier as Tyler, the atmosphere was immediately suffocating. My first instinct wasn't to explore, it was to leave. I was given the functioning boat , then took the exit, and triggered the ending within minutes. But as the credits rolled, I realized I hadn’t actually played the game; I had simply committed a "coward’s move." I chose the "Safe Lie" because the reality of the island was too unsettling. I believe everyone have tried that in their first playthrough. &lt;/p&gt;

&lt;p&gt;On my second run, I refused the boat. I stayed because I wanted the content. By staying, I felt like I was actively validating Tyler’s internal chaos. The game stopped being a survival horror and started feeling like a psychological autopsy I was performing on myself.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Navigating a Broken Mind&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As I explored Fort Oasis, I realized it isn't just a game with a map; there are some metaphors. Since the game doesn't tell us the direct story, I explored the internet and found that the story explains about the terminal disease and the depression on the character I'm playing. I began to see the environment as a manifestation of Tyler’s isolation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Mining Colony:&lt;/strong&gt; This is the skeletal remains of a life once filled with productivity and purpose, now hollowed out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Rot:&lt;/strong&gt; The black, organic corruption "overwrite" the walls was visceral. It’s the visual language of a terminal illness that doesn't just inhabit the world but replaces it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Permafrost:&lt;/strong&gt; The cold represents an emotional numbness I think Tyler uses to shield himself from the memory of Leda’s love (Leda is Tyler's wife). It is the "Distant Embrace" of a death that has already begun.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Realization of the Mission&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the beginning, I followed the story believing I was on a rescue mission. However, the deeper I went, the more I felt manipulated. I wasn't there to save a colony; I was there to witness the final shutdown of me(actually the Tyler).&lt;/p&gt;

&lt;p&gt;The most haunting part of my experience was the silence. Before the monsters ever appeared, the weight of being &lt;strong&gt;all alone in a dying world&lt;/strong&gt; was more terrifying than any jump-scare. That silence is the bridge between Tyler’s past and the "Total Chaos" of his current mental state and the void left behind when love is replaced by a diagnosis.&lt;/p&gt;

</description>
      <category>fps</category>
      <category>singleplayer</category>
      <category>strategygames</category>
    </item>
    <item>
      <title>I Built a Cyberpunk Terminal Portfolio with Next.js, Antigravity and Gemini AI</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Fri, 16 Jan 2026 19:16:04 +0000</pubDate>
      <link>https://dev.to/inushathathsara/i-built-a-cyberpunk-terminal-portfolio-with-nextjs-antigravity-and-gemini-ai-5457</link>
      <guid>https://dev.to/inushathathsara/i-built-a-cyberpunk-terminal-portfolio-with-nextjs-antigravity-and-gemini-ai-5457</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/new-year-new-you-google-ai-2025-12-31"&gt;New Year, New You Portfolio Challenge Presented by Google AI&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’m Inusha Gunasekara, an IT undergraduate at the University of Moratuwa, Sri Lanka, and the co-founder of Tekkeys, where we're building agentic AI tools.&lt;/p&gt;

&lt;p&gt;For this challenge, I didn’t want to build just another "landing page." I wanted to build a Digital Twin. I conceptualized "System 1"—a sentient, terminal-based operating system that represents my skills, projects, and personality as code. The goal was to create an interface that feels alive, combining the raw utility of a CLI with the polished aesthetics of a cyberpunk interface.&lt;/p&gt;

&lt;p&gt;I initially engineered the system as a fully autonomous clone powered by the Gemini 2.5 Flash-Lite API. However, to guarantee 100% uptime and zero latency for public access, I pivoted the architecture to a deterministic "Simulation Mode." This hybrid approach preserves the sentient "vibe" of the AI while ensuring the reliability required for a production-grade portfolio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Portfolio
&lt;/h2&gt;


&lt;div class="ltag__cloud-run"&gt;
  &lt;iframe height="600px" src="https://inusha-portfolio-326006174526.us-central1.run.app"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://inusha-portfolio-326006174526.us-central1.run.app" rel="noopener noreferrer"&gt;https://inusha-portfolio-326006174526.us-central1.run.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Type "help" to see available commands, or try "projects" to see what I'm working on.)&lt;/p&gt;

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

&lt;p&gt;My portfolio is a &lt;strong&gt;Stateless Terminal&lt;/strong&gt; built for extreme performance, security, and zero-cost scaling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Tech Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Framework:&lt;/strong&gt; Next.js 16 (App Router) for the core React architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling:&lt;/strong&gt; Tailwind CSS v4 for the utility-first, cyberpunk aesthetic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure:&lt;/strong&gt; Google Cloud Run (Serverless) for scalable, containerized deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containerization:&lt;/strong&gt; Docker (Multi-stage build) using the &lt;code&gt;standalone&lt;/code&gt; output mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The "Digital Twin" Architecture:&lt;/strong&gt;&lt;br&gt;
The core of this project is "System 1"—a digital representation of my persona.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial Prototype:&lt;/strong&gt; I originally built a fully autonomous agent using the &lt;strong&gt;Gemini 2.5 Flash-Lite API&lt;/strong&gt;. While powerful, I identified that relying on a metered API for a high-traffic public landing page introduced potential latency and quota risks ("The Reddit Hug of Death").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Optimization:&lt;/strong&gt; To ensure a production-grade user experience, I engineered a &lt;strong&gt;Deterministic Simulation Engine&lt;/strong&gt;. This engine mimics the streaming "typing effect" of an LLM but pulls from an optimized, local knowledge graph. This decision reduced API latency from ~400ms to &lt;strong&gt;&amp;lt;5ms&lt;/strong&gt; and eliminated all running costs, while preserving the "sentient" feel of the terminal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deploying to Google Cloud Run:&lt;/strong&gt;&lt;br&gt;
I chose Cloud Run for its "Scale to Zero" capability. By using a multi-stage Dockerfile, I reduced the final container size by approximately 80%. This ensures the portfolio spins up instantly when a user visits but costs $0 when idle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm Most Proud Of
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The "Halt Sequence" (&lt;code&gt;sudo delete&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;I wanted the terminal to feel like a real, vulnerable operating system, not just a read-only website. I implemented a hidden "kill switch" where users can type &lt;code&gt;sudo delete&lt;/code&gt; followed by &lt;code&gt;confirm&lt;/code&gt;. This triggers a dramatic, system-wide crash simulation—turning the screen black and forcing a "reboot" sequence. It adds a layer of gamification that encourages users to explore the boundaries of the interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Engineering the "Simulation Engine"
&lt;/h3&gt;

&lt;p&gt;While it was tempting to keep the live Gemini API connection, I am most proud of the decision to build a &lt;strong&gt;Deterministic Simulation Engine&lt;/strong&gt;. I realized that for a portfolio, &lt;strong&gt;reliability is a feature&lt;/strong&gt;. By architecting a local "mock stream" that replicates the exact typing patterns and latency of an LLM, I achieved the "sentient AI" feel without the risk of API quotas or network latency. It taught me that sometimes the best engineering solution is removing a dependency, not adding one.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Secure Live Data (Gas Tracker)
&lt;/h3&gt;

&lt;p&gt;I built a real-time Ethereum Gas Tracker that fetches live data from Etherscan. Instead of exposing my API keys on the client side, I built a secure &lt;strong&gt;Next.js Server-Side Proxy&lt;/strong&gt;. This route acts as a gateway, injecting the secrets on the server before forwarding the request to Etherscan. &lt;/p&gt;

&lt;h3&gt;
  
  
  4. The "Cyberpunk" Polish
&lt;/h3&gt;

&lt;p&gt;I spent significant effort fine-tuning the visual details. Balancing these high-fidelity "glitch" effects with the performance requirements of a web app (using Tailwind CSS v4) was a rewarding challenge in frontend optimization.&lt;/p&gt;

&lt;p&gt;Check The portfolio live in action: &lt;a href="https://inusha-portfolio-326006174526.us-central1.run.app" rel="noopener noreferrer"&gt;https://inusha-portfolio-326006174526.us-central1.run.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleaichallenge</category>
      <category>portfolio</category>
      <category>gemini</category>
    </item>
    <item>
      <title>The Features I Killed to Ship "The 80%" App in 4 Weeks</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Mon, 12 Jan 2026 15:02:41 +0000</pubDate>
      <link>https://dev.to/inushathathsara/the-features-i-killed-to-ship-the-80-percent-app-in-4-weeks-30op</link>
      <guid>https://dev.to/inushathathsara/the-features-i-killed-to-ship-the-80-percent-app-in-4-weeks-30op</guid>
      <description>&lt;p&gt;I almost fell into a trap believing that "more features" equals a "better product." When I started building &lt;strong&gt;The 80%&lt;/strong&gt;, an assistant tool which helps students to keep track of their attendance, medicals and GPA. I had a strict four-week deadline to ship a production-ready attendance tracker. I quickly realized that if I tried to build everything I &lt;em&gt;wanted&lt;/em&gt;, I would never ship what the user &lt;em&gt;needed&lt;/em&gt;. Then I remembered what Elon Musk said, &lt;strong&gt;"The Best Part is No Part."&lt;/strong&gt; I didn't just cut features to save time; I cut them to save the architecture from unnecessary complexity.&lt;/p&gt;

&lt;p&gt;Here are the five worth-mentioning features I killed in &lt;strong&gt;The 80%&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Backup Server Trap
&lt;/h3&gt;

&lt;p&gt;I wasted the first few days being obsessed with 100% uptime. I wanted to build a secondary failover server just in case Firebase went down. I realized I was solving an imaginary problem. Firebase has 99.99% uptime, while the probability of my users having poor campus Wi-Fi is high. The real risk wasn't Google servers failing. It was the connection dropping between the classroom and the cloud. I abandoned the backup server entirely and embraced an &lt;strong&gt;Offline-First Architecture&lt;/strong&gt; using Hive. By treating the user's device as the primary data source, the app works perfectly regardless of server status, I learned that I shouldn't build complex distributed systems when a local database solves the actual problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Medical Cloud Storage Nightmare
&lt;/h3&gt;

&lt;p&gt;I planned to add a feature allowing students to upload photos of their medical certificates to the cloud so they would never lose them. But as I designed it, two major problems appeared: the extreme cost of storing images for thousands of users on the Firebase Free Tier, and the liability of holding &lt;strong&gt;Personally Identifiable Information (PII)&lt;/strong&gt;. If I held medical records, I was responsible for protecting them from data breaches. As a student developer, I didn't want the risk of a data breach hanging over my head. To solve this, I built the &lt;strong&gt;"The Local Wallet."&lt;/strong&gt; within the app itself. Instead of uploading files, the app simply saves the images in the device's local sandbox and stores a link to the file path. The data stays 100% on the user's phone, resulting in zero cloud costs and zero privacy liability. I learned that the most secure data is the data you never collect.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The "Automated Email" Fantasy
&lt;/h3&gt;

&lt;p&gt;I wanted to build a productivity hack where the app would automatically send official emails from the student's university account using SMTP or OAuth. It sounded like a great productivity hack until I looked at the technical reality. University firewalls and Multi-Factor Authentication (MFA) makes this feature hard to implement. Making it work I had two bad choices. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Requesting Credentials from the User:&lt;/strong&gt; Asking users for their university passwords which leads to a a massive security violation that looks exactly like phishing.
or &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Verification:&lt;/strong&gt; I would have to navigate the university's bureaucracy to get official OAuth approval. I avoided this method in order to reduce the complexity of the app.
I killed this automation entirely and stuck with the traditional email flow. The app automatically opens the default email app, then the user can send the drafted email with the medical report. I learned two major lessons here. First one is "Trust is harder to build than a feature." And as developers we shouldn't compromise security for a "cool" automation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4. All University Supported Grading System
&lt;/h3&gt;

&lt;p&gt;I had a plan to create a database containing the grading scales for all major universities all around the world to automate the GPA calculation process. But I quickly realized that this needs constant maintainability, which I don't have time to do as a undergraduate. It would require weeks of manual data entry and maintenance, and if a university changed their grading policy, my app would be instantly outdated. It simply wasn't worth the effort for my app. Instead, I built a feature that allows the user to configure their &lt;strong&gt;own grading scale&lt;/strong&gt;. This taught me that when shipping, flexibility is often better than hard-coded perfection.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Sync Custom Profile Picture Across Devices
&lt;/h3&gt;

&lt;p&gt;I wanted users to be able to pick a photo from their gallery and have that custom profile picture sync across all their devices via Firebase. This led me to the "Cost" problem again. I would need a paid Firebase plan to store these custom images, or I would have to bloat the database by storing base64 strings, which requires unnecessary processing power and time. I compromised by removing the ability to upload custom photos and instead provided a set of high-quality, pre-defined 3D avatars. I only sync the &lt;strong&gt;Avatar ID&lt;/strong&gt; (a simple integer) across devices, keeping the data transfer minimal. This was a valuable lesson in distinguishing between what is &lt;em&gt;needed&lt;/em&gt; (identifying users) versus what is &lt;em&gt;wanted&lt;/em&gt; (full customizability).&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;It is easy to add features. It is hard to remove them. By killing these features, I didn't just save time; I built a product that is faster, cheaper to run, and more secure. I learned that my job isn't to build the most complex version of an idea, but to ship the version that actually works. &lt;strong&gt;The 80%&lt;/strong&gt; proved to me that sometimes, the best code is the code you delete.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔗 Explore the Project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📂 GitHub Repository:&lt;/strong&gt;&amp;nbsp;&lt;a href="https://github.com/inusha-thathsara/attendance-tracker-demo/tree/main" rel="noopener noreferrer"&gt;View the demo code and releases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📝 Project Documentation:&lt;/strong&gt;&amp;nbsp;&lt;a href="https://hill-grenadilla-8a4.notion.site/The-80-Attendance-Strategy-for-Undergrads-2d4d8852a123808c900cd5c78f7de104?pvs=74" rel="noopener noreferrer"&gt;Read the Notion Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>softwareengineering</category>
      <category>devops</category>
      <category>learning</category>
    </item>
    <item>
      <title>Building AI Agents: Concepts &amp; Architecture</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Wed, 07 Jan 2026 15:11:40 +0000</pubDate>
      <link>https://dev.to/inushathathsara/building-ai-agents-concepts-architecture-4cb8</link>
      <guid>https://dev.to/inushathathsara/building-ai-agents-concepts-architecture-4cb8</guid>
      <description>&lt;p&gt;If you look past the hype cycle, &lt;strong&gt;AI Agents&lt;/strong&gt; represent a fundamental shift in how we write software. We are moving from defining &lt;em&gt;how&lt;/em&gt; a task is done (traditional automation) to defining &lt;em&gt;what&lt;/em&gt; the goal is and letting the system figure out the rest.&lt;/p&gt;

&lt;p&gt;This article breaks down the conceptual architecture of AI agents, how they differ from standard automation, and the memory systems required to make them actually useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Definition: What is an Agent?
&lt;/h2&gt;

&lt;p&gt;An AI Agent is a computational entity that acts independently on a user's behalf. Unlike a standard script that executes a rigid sequence of commands, an agent creates its own plan.&lt;/p&gt;

&lt;p&gt;To be considered "Agentic," a system generally needs these characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reflective:&lt;/strong&gt; It learns from previous steps (loops back to correct errors).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autonomous:&lt;/strong&gt; It executes without manual hand-holding after the initial prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reactive:&lt;/strong&gt; It responds to environmental changes (e.g. an API failure or new data).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proactive:&lt;/strong&gt; It can schedule actions based on recognized patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Paradigm Shift: Automation vs. Agentic Systems
&lt;/h2&gt;

&lt;p&gt;As developers, we are used to &lt;strong&gt;Deterministic Execution&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditional Automation: &lt;em&gt;Input ---&amp;gt; Process A ---&amp;gt; Process B ---&amp;gt; Output&lt;/em&gt;.
If the input is unstructured or ambiguous, the pipeline breaks. It relies on fixed decision trees.&lt;/li&gt;
&lt;li&gt;Agentic Systems: Non-Deterministic Execution.
The agent receives an ambiguous goal (e.g. "Plan a trip to Tokyo based on my emails"). It uses an LLM to reason about the request, decomposes it into sub-tasks, and decides which tools to call.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Reality Check:&lt;/strong&gt; The critical difference is the ability to handle "fuzzy" inputs. Agents thrive where drop-down menus fail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Agent Architecture
&lt;/h2&gt;

&lt;p&gt;A functional agent consists of four core components. Think of this as the anatomy of the system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Perception:&lt;/strong&gt; How the agent "sees" (Text, Audio, Images).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Planning (The Brain):&lt;/strong&gt; The LLM. This handles reasoning, reflection, and task decomposition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools (The Hands):&lt;/strong&gt; Python functions, APIs, or Microservices. The agent doesn't "know" how to search the web; it "knows" it has a tool called &lt;code&gt;search_web()&lt;/code&gt; and decides when to invoke it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory:&lt;/strong&gt; The context and state storage.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Deep Dive: Memory Systems
&lt;/h2&gt;

&lt;p&gt;Most developers stop at "Context Window" (Short-term memory), but robust agents require a memory architecture inspired by human cognition.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Memory Type&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Human Parallel&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;AI Implementation&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Short-term&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remembering a phone number for 12s.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Context Window:&lt;/strong&gt; Limited by token counts (OpenAI/Anthropic). Enhanced via caching.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Long-term&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Knowledge retained for years (e.g. specialized skills).&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;RAG (Retrieval-Augmented Generation):&lt;/strong&gt; Vector databases (like MongoDB) storing domain-specific docs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Working&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Processing new info during a conversation.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Hybrid RAG:&lt;/strong&gt; Combining real-time internet search (e.g. Tavily) with stored knowledge.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Episodic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remembering specific past events.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Interaction Logs:&lt;/strong&gt; Storing user specific past sessions to recall context later.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Semantic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Memories triggered by meaning (rose = love).&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Semantic Cache:&lt;/strong&gt; Retrieving similar past queries to save API costs and speed up responses.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Tech Stack for Memory:&lt;/p&gt;

&lt;p&gt;Modern stacks often use a unified database (like MongoDB) to handle both operational metadata (JSON) and vector embeddings. This avoids the "synchronization hell" of trying to keep a SQL database in sync with a separate Vector DB like Pinecone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The RAG Pipeline (Retrieval Architecture)
&lt;/h2&gt;

&lt;p&gt;If the Agent is the brain, RAG is the library it references. A standard pipeline involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Prep:&lt;/strong&gt; Cleaning, anomaly detection, and "chunking" data (breaking text into embedding-suitable segments).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ingestion:&lt;/strong&gt; Passing chunks through an embedding model to get vectors, stored in your DB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieval:&lt;/strong&gt; The agent converts a user query into a vector, performs a &lt;strong&gt;Vector Search&lt;/strong&gt; (semantic similarity) or &lt;strong&gt;Hybrid Search&lt;/strong&gt; (keyword + semantic), and feeds the relevant chunks to the LLM.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A Framework for Building
&lt;/h2&gt;

&lt;p&gt;Don't open your IDE yet. The biggest mistake developers make is jumping into code without mapping the reasoning flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 0: The Paper Phase&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Map the manual process step-by-step.&lt;/li&gt;
&lt;li&gt;Identify which steps are computational (calculating a sum) vs. reasoning (deciding if a tone is rude).&lt;/li&gt;
&lt;li&gt;Determine where you need a human-in-the-loop for reliability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Level 1: The Prototype&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single Agent, Single Tool.&lt;/li&gt;
&lt;li&gt;Use a notebook. Do not overengineer a multi-agent swarm for a simple task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Level 2: The MVP&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect 3 functions/tools to 1 agent.&lt;/li&gt;
&lt;li&gt;Focus on the problem, not the technology. Ask: "Does this actually save time, or is it just cool?"&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building agents is less about prompt engineering and more about &lt;strong&gt;systems engineering&lt;/strong&gt;. It requires managing state, designing robust tools, and structuring memory effectively.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How I Built a Flutter + Gemini AI App to "Hack" My University Attendance (Open Source)</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Sat, 03 Jan 2026 17:59:33 +0000</pubDate>
      <link>https://dev.to/inushathathsara/how-i-built-a-flutter-gemini-ai-app-to-hack-my-university-attendance-open-source-292i</link>
      <guid>https://dev.to/inushathathsara/how-i-built-a-flutter-gemini-ai-app-to-hack-my-university-attendance-open-source-292i</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: The "80% Anxiety"
&lt;/h2&gt;

&lt;p&gt;If you are an engineering student (like me at the University of Moratuwa), you know the terror of the &lt;strong&gt;80% Rule&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s simple math: Attend 80% of classes or get banned from the exam.&lt;/p&gt;

&lt;p&gt;But in reality, it’s a nightmare.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"If I skip today's lecture, does my percentage drop to 79.9%?"&lt;/li&gt;
&lt;li&gt;"Did the lecturer count that medical leave?"&lt;/li&gt;
&lt;li&gt;"Can I afford to sleep in tomorrow?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found myself doing complex algebra at 2 AM just to decide if I could skip a morning lecture. I needed a tool that didn't just "track" habits, but actually &lt;strong&gt;strategized&lt;/strong&gt; for me.&lt;/p&gt;

&lt;p&gt;So, I built &lt;strong&gt;&lt;a href="https://github.com/inusha-thathsara/attendance-tracker-demo/tree/main" rel="noopener noreferrer"&gt;The 80 Percent&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is how I engineered the fullstack software using &lt;strong&gt;Flutter&lt;/strong&gt;, &lt;strong&gt;Google Gemini AI&lt;/strong&gt;, and a heavily optimized &lt;strong&gt;Firebase&lt;/strong&gt; backend, all while staying on the Free Tier.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Strategy Engine: "Safe to Skip" Logic
&lt;/h2&gt;

&lt;p&gt;Most habit trackers just say &lt;em&gt;"You are at 75%."&lt;/em&gt; That’s useless information. I needed actionable advice.&lt;/p&gt;

&lt;p&gt;I wrote a custom algorithm that looks at the &lt;strong&gt;future&lt;/strong&gt; remaining sessions of the semester to calculate a "Safety Margin."&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Buffer" Formula
&lt;/h3&gt;

&lt;p&gt;If you are above your target, how many classes can you miss before you hit the danger zone?&lt;/p&gt;

&lt;p&gt;I implemented this formula in Dart:&lt;/p&gt;

&lt;p&gt;Dart&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// The Magic Formula
int calculateSafeSkips(int present, int total, double target) {
  // Formula: Floor( (Present / Target) - Total )
  int skips = ((present / target) - total).floor();
  return skips &amp;lt; 0 ? 0 : skips;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scenario:&lt;/strong&gt; You attended 18/20 classes. Target is 80%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; You can safely skip &lt;strong&gt;2&lt;/strong&gt; more classes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; It stops students from panic-attending classes they don't need to, preventing burnout.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The "Recovery" Formula
&lt;/h3&gt;

&lt;p&gt;If you are &lt;em&gt;failing&lt;/em&gt;, how many classes must you attend in a row to survive?&lt;/p&gt;

&lt;p&gt;Dart&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// The Recovery Formula
int calculateRecovery(int present, int total, double target) {
   // Formula: Ceil( (Target * Total - Present) / (1 - Target) )
   return ((target * total - present) / (1 - target)).ceil();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was critical because a student at 70% needs to know &lt;em&gt;exactly&lt;/em&gt; when they will be safe again.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. The AI Challenge: Parsing Timetables with Gemini 2.5
&lt;/h3&gt;

&lt;p&gt;The biggest friction in any student app is &lt;strong&gt;Setup&lt;/strong&gt;. Nobody wants to manually type in 15 modules and timeslots.&lt;/p&gt;

&lt;p&gt;I wanted a feature where a user could upload their official PDF/image timetable, and the app would set itself up instantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Gemini 2.5 Flash?
&lt;/h3&gt;

&lt;p&gt;I chose Google's &lt;strong&gt;Gemini 2.5 Flash&lt;/strong&gt; because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed &amp;amp; Cost:&lt;/strong&gt; It is the current standard for high-speed, low-cost inference, perfect for a free student app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multimodal Intelligence:&lt;/strong&gt; It accepts PDF/Image inputs directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Shot Capability:&lt;/strong&gt; Unlike older models that needed endless examples, 2.5 Flash is smart enough to extract complex grid data with just a single, well-structured system instruction.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Implementation
&lt;/h3&gt;

&lt;p&gt;Instead of wasting tokens on "few-shot" examples, I used a &lt;strong&gt;System Instruction&lt;/strong&gt; approach. I defined the exact JSON schema in the prompt and let the model do the heavy lifting.&lt;/p&gt;

&lt;p&gt;Dart&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Actual Code from the App
final model = GenerativeModel(
  model: 'gemini-2.5-flash', 
  apiKey: apiKey
);

final prompt = """
You are an intelligent assistant that extracts university timetable data.
**GOAL**: Extract timetable metadata, modules, and classes into structured JSON.
**SCHEMA**:
{
  "modules": [{"code":String, "name":String...}],
  "classes": [{"day":String, "time":String, "location":String...}]
}
""";

final response = await model.generateContent([
  Content.text(prompt),
  Content.data('image/png', timetableImageBytes)
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app parses the JSON response and batch-writes the classes to the local database. This "Zero-Shot" approach keeps the request payload small and fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The Architecture: Surviving the Firebase Free Tier
&lt;/h2&gt;

&lt;p&gt;As a student, I have $0 budget.&lt;/p&gt;

&lt;p&gt;Firebase is great, but the Firestore limits (50,000 reads/day) are a trap. If I have 500 users and they open the app 10 times a day, fetching 10 records each... that’s 50,000 reads. Quota exceeded on Day 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  My "Offline-First" Solution
&lt;/h3&gt;

&lt;p&gt;I designed the app to be &lt;strong&gt;Offline-First&lt;/strong&gt; using a Repository Pattern.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local Caching:&lt;/strong&gt; When a user opens the app, it loads data from the local cache &lt;em&gt;instantly&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy Syncing:&lt;/strong&gt; It only writes to Firestore when the user explicitly changes something (Marking Attendance).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Images in DB:&lt;/strong&gt; I initially wanted to sync profile pictures, but storing images requires the "Blaze" (Paid) plan or Base64 hacks that bloat document size. I cut this feature to ensure the app stays 100% free and fast.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This architecture means I can scale to thousands of users without paying a cent.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Result: A Production-Ready Beta
&lt;/h2&gt;

&lt;p&gt;"The 80%" isn't just a calculator; it's a full-stack academic tool.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tech Stack:&lt;/strong&gt; Flutter, Firebase Auth/Firestore, Provider, Gemini API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status:&lt;/strong&gt; Open Source &amp;amp; Beta Live.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building this taught me that &lt;strong&gt;Engineering is about tradeoffs.&lt;/strong&gt; I had to trade fancy features (cloud images) for stability (free tier limits), and I had to trade simple logic for complex math to make the app actually useful.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Try it out
&lt;/h3&gt;

&lt;p&gt;I’m looking for feedback from fellow developers and students.&lt;/p&gt;

&lt;p&gt;Check out the ecosystem:&lt;br&gt;
👉 &lt;a href="https://hill-grenadilla-8a4.notion.site/The-80-Attendance-Strategy-for-Undergrads-2d4d8852a123808c900cd5c78f7de104?pvs=74" rel="noopener noreferrer"&gt;Notion Documentation&lt;/a&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/inusha-thathsara/attendance-tracker-demo/tree/main" rel="noopener noreferrer"&gt;Demo code and APK file&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Star the repo if you think the project is cool! ⭐)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>firebase</category>
      <category>gemini</category>
      <category>fullstack</category>
    </item>
    <item>
      <title>The AI Filmmaking Pipeline: Directing Without a Camera</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Sat, 03 Jan 2026 16:48:45 +0000</pubDate>
      <link>https://dev.to/inushathathsara/the-ai-filmmaking-pipeline-directing-without-a-camera-lop</link>
      <guid>https://dev.to/inushathathsara/the-ai-filmmaking-pipeline-directing-without-a-camera-lop</guid>
      <description>&lt;p&gt;As IT students, we are used to pipelines: CI/CD, data processing, rendering. Surprisingly, modern filmmaking is evolving into just another&amp;nbsp;&lt;strong&gt;computational pipeline&lt;/strong&gt;. Here is the no-nonsense guide to the tools and logic you need to replace a film crew with a GPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Pre-Production: The Logic Layer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before generating pixels, you need to generate structure. This phase is about planning and visualization essentially the "architecture design" of your film.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Brainstorming &amp;amp; Scripting:&lt;/strong&gt;&amp;nbsp;Don't stare at a blank page. Use&amp;nbsp;&lt;strong&gt;Claude&lt;/strong&gt;&amp;nbsp;for brainstorming concepts and&amp;nbsp;&lt;strong&gt;ChatGPT&lt;/strong&gt;&amp;nbsp;to structure the actual script and treatment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Framework:&lt;/strong&gt;&amp;nbsp;The session introduced a structured approach to story generation that feels very similar to debugging:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Objective (Why?):&lt;/strong&gt;&amp;nbsp;What is the core message?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idea (What?):&lt;/strong&gt;&amp;nbsp;The plot points.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Story (How?):&lt;/strong&gt;&amp;nbsp;The narrative structure.
## &lt;strong&gt;2. Production: The Generative Engine&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is where the heavy lifting happens. We are swapping cameras for diffusion models.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Midjourney:&lt;/strong&gt;&amp;nbsp;For generating high-fidelity static shots and storyboards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google VEO 3:&lt;/strong&gt;&amp;nbsp;The heavy hitter for realistic video generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kling AI &amp;amp; Krea AI:&lt;/strong&gt;&amp;nbsp;For converting static images into motion (Image-to-Video).
### &lt;strong&gt;The "Master Prompt" Algorithm&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developers, this is the most valuable takeaway. You don't just type "cool scene." You use a parameterized function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Formula:&lt;/strong&gt;&amp;nbsp;&lt;code&gt;[Emotional tone] + [Visual reference] + [Subject] + [Composition] + [Lighting] + [Camera settings]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Example Code:&lt;/strong&gt;&amp;nbsp;&lt;code&gt;[Royal, epic, ancient] meets [Lord of the Rings, 300] of [Krishna speaking with Pandavas] inside [Hastinapur palace] shot on [IMAX film camera]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. Post-Production: The Audio-Visual Merge&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Raw video is silent. To sell the illusion, you need the "audio stack."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Music:&lt;/strong&gt;&amp;nbsp;&lt;strong&gt;Suno&lt;/strong&gt;&amp;nbsp;generates original soundtracks based on mood prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Voice:&lt;/strong&gt;&amp;nbsp;&lt;strong&gt;ElevenLabs&lt;/strong&gt;&amp;nbsp;handles realistic voiceovers and cloning, removing the need for actors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt;&amp;nbsp;Bring it all together in&amp;nbsp;&lt;strong&gt;CapCut&lt;/strong&gt;&amp;nbsp;or&amp;nbsp;&lt;strong&gt;DaVinci Resolve&lt;/strong&gt;.
## &lt;strong&gt;Summary: The New Workflow&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The workflow has shifted from&amp;nbsp;&lt;em&gt;capture&lt;/em&gt;&amp;nbsp;to&amp;nbsp;&lt;em&gt;synthesis&lt;/em&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ideate&lt;/strong&gt;&amp;nbsp;with LLMs (Claude/Gemini).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate&lt;/strong&gt;&amp;nbsp;assets with Diffusion models (Midjourney/VEO).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Animate&lt;/strong&gt;&amp;nbsp;with Motion models (Kling).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthesize&lt;/strong&gt;&amp;nbsp;audio (Suno/ElevenLabs).&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>animation</category>
      <category>genai</category>
      <category>cicd</category>
      <category>automation</category>
    </item>
    <item>
      <title>Bitcoin 101: From Barter to Blockchain</title>
      <dc:creator>Malawige Inusha Thathsara Gunasekara</dc:creator>
      <pubDate>Thu, 01 Jan 2026 13:44:48 +0000</pubDate>
      <link>https://dev.to/inushathathsara/bitcoin-101-from-barter-to-blockchain-1kp7</link>
      <guid>https://dev.to/inushathathsara/bitcoin-101-from-barter-to-blockchain-1kp7</guid>
      <description>&lt;p&gt;Money has evolved significantly over human history. We started with the &lt;strong&gt;barter system&lt;/strong&gt;, trading goods directly, which was inefficient. We moved to &lt;strong&gt;commodity money&lt;/strong&gt; like gold and salt, then to &lt;strong&gt;fiat money&lt;/strong&gt; (USD, EUR) backed by governments, and eventually to digital banking.&lt;/p&gt;

&lt;p&gt;But in 2009, &lt;strong&gt;Bitcoin&lt;/strong&gt; emerged as the first decentralized, borderless, and scarce digital currency, removing the need for central authorities.&lt;/p&gt;

&lt;p&gt;In this article, we’ll break down the technical fundamentals of Bitcoin, from the whitepaper to the architecture of a block.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Vision: The 2008 Whitepaper&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Satoshi Nakamoto’s whitepaper introduced a &lt;strong&gt;peer-to-peer digital currency&lt;/strong&gt; that solved the double-spending problem using &lt;strong&gt;Proof-of-Work (PoW)&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Core Principles&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fixed Supply:&lt;/strong&gt; There will never be more than &lt;strong&gt;21 million BTC&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decentralization:&lt;/strong&gt; No single authority controls the network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutability:&lt;/strong&gt; Once a transaction is on the blockchain ledger, it cannot be altered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Censorship Resistance:&lt;/strong&gt; Anyone can transact; no one can be blocked.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Under the Hood: Block Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A blockchain is essentially a timestamped chain of blocks. Think of a block like a "page" in a ledger.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Structure of a Block&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every block contains three main components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Block Header:&lt;/strong&gt; Metadata about the block.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction Counter:&lt;/strong&gt; The number of transactions included.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transactions:&lt;/strong&gt; The actual list of payments.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Block Header&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The header is critical for mining and validation. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version:&lt;/strong&gt; The rules the block follows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Previous Block Hash:&lt;/strong&gt; The link to the previous block (creating the "chain").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merkle Root:&lt;/strong&gt; A summary of all transactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timestamp:&lt;/strong&gt; When the block was mined.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Difficulty Target (nBits):&lt;/strong&gt; Defines how hard it is to mine the block.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nonce:&lt;/strong&gt; The variable number miners change to solve the cryptographic puzzle.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Data Structures: Merkle Trees &amp;amp; Roots&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Bitcoin uses &lt;strong&gt;Merkle Trees&lt;/strong&gt; (a type of binary tree) to verify data efficiently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Merkle Tree:&lt;/strong&gt; Hashes every transaction, pairs them up, and hashes them again until only one hash remains.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Merkle Root:&lt;/strong&gt; This single "root" hash acts as a &lt;strong&gt;fingerprint&lt;/strong&gt; for the entire block.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why is this useful?&lt;/strong&gt; It allows for &lt;strong&gt;Simplified Payment Verification (SPV)&lt;/strong&gt;. A user can verify a specific transaction existed without downloading the entire blockchain history. If even one bit of a transaction changes, the Merkle Root changes completely.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Consensus: Proof-of-Work (PoW)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;How does the network agree on the truth? Through mining.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Miners collect transactions.&lt;/li&gt;
&lt;li&gt;They compete to solve a cryptographic puzzle by adjusting the &lt;strong&gt;Nonce&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The winner gets the &lt;strong&gt;block reward&lt;/strong&gt; (new BTC + transaction fees).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While secure and decentralized, PoW is energy-intensive and has limited scalability.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Scaling &amp;amp; Evolution&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Rise of Altcoins&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Following Bitcoin, "1st Gen" altcoins emerged. Most were forks of Bitcoin with minor tweaks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Litecoin:&lt;/strong&gt; Faster block times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Namecoin:&lt;/strong&gt; Decentralized DNS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ethereum:&lt;/strong&gt; Eventually introduced smart contracts, moving beyond simple currency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Lightning Network (Layer 2)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Bitcoin processes only ~7 transactions per second. To solve this, the &lt;strong&gt;Lightning Network&lt;/strong&gt; was built as a Layer 2 solution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How it works:&lt;/strong&gt; Users open payment channels and transact &lt;strong&gt;off-chain&lt;/strong&gt; instantly and cheaply.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Settlement:&lt;/strong&gt; Only the final balances are recorded on the main blockchain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This enables fast micropayments, though it comes with challenges like routing complexity and liquidity constraints.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Bitcoin revolutionized money by combining cryptography, game theory, and distributed systems. Understanding these fundamentals—Merkle trees, block headers, and consensus mechanisms—is the first step to mastering the wider Web3 landscape.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>bitcoin</category>
    </item>
  </channel>
</rss>
