<?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: Ahmad Akmal Abdullah</title>
    <description>The latest articles on DEV Community by Ahmad Akmal Abdullah (@ruumidev).</description>
    <link>https://dev.to/ruumidev</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%2F4027804%2F55cc8bd3-b9a7-4514-a6a4-1457b41b7953.png</url>
      <title>DEV Community: Ahmad Akmal Abdullah</title>
      <link>https://dev.to/ruumidev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ruumidev"/>
    <language>en</language>
    <item>
      <title>Engineering the WingZone POS: State Management for Group Ordering &amp; Dual Receipts in Kotlin</title>
      <dc:creator>Ahmad Akmal Abdullah</dc:creator>
      <pubDate>Wed, 09 Sep 2026 02:43:03 +0000</pubDate>
      <link>https://dev.to/ruumidev/architecting-wingzone-a-secure-serverless-pos-and-mobile-ordering-ecosystem-8pi</link>
      <guid>https://dev.to/ruumidev/architecting-wingzone-a-secure-serverless-pos-and-mobile-ordering-ecosystem-8pi</guid>
      <description>&lt;p&gt;One of the most notoriously difficult problems in food and beverage (F&amp;amp;B) software is handling large group orders. When a table of eight wants to order together but pay separately, standard POS systems either force the cashier to input eight separate orders or manually calculate the splits on a calculator.&lt;/p&gt;

&lt;p&gt;I built the &lt;strong&gt;WingZone App&lt;/strong&gt;—a native Kotlin-based POS application—to solve this exact workflow bottleneck. It is engineered specifically to handle complex state management for group orders, isolated payments, and hardware receipt generation.&lt;/p&gt;

&lt;p&gt;Here is a breakdown of the architecture that secured 1st Place across all courses at the 2026 KPTM Ipoh FYP Exhibition.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;p&gt;Instead of building a web wrapper, this project required native execution to ensure zero latency at the checkout counter and direct hardware communication with receipt printers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Core:&lt;/strong&gt; Kotlin (Native Desktop &lt;code&gt;.exe&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Architecture Pattern:&lt;/strong&gt; MVVM (Model-View-ViewModel)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Local State Management:&lt;/strong&gt; Kotlin Coroutines &amp;amp; StateFlow&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architectural Highlights
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The Group Ordering Data Structure
&lt;/h3&gt;

&lt;p&gt;The core challenge was structuring the data so a single "Master Order" could hold multiple "Sub-Orders" (individuals), without losing track of the total table state. &lt;/p&gt;

&lt;p&gt;I designed a nested data model where a &lt;code&gt;GroupSession&lt;/code&gt; acts as the parent object. When a group approaches the counter, the cashier opens a &lt;code&gt;GroupSession&lt;/code&gt;. As each person orders, their items are appended to a unique &lt;code&gt;SubOrder&lt;/code&gt; array inside that session. &lt;/p&gt;

&lt;p&gt;This allows the UI to display the grand total for the kitchen, while keeping the financial data strictly compartmentalized for when it is time to pay. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Isolated Payment &amp;amp; Bill Splitting Logic
&lt;/h3&gt;

&lt;p&gt;Because of the &lt;code&gt;GroupSession&lt;/code&gt; structure, checkout becomes mathematically frictionless. The UI provides two checkout paths: &lt;strong&gt;Pay Full&lt;/strong&gt; or &lt;strong&gt;Split by Individual&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When "Split by Individual" is triggered, the app iteratively locks each &lt;code&gt;SubOrder&lt;/code&gt; as the payments are processed. This state is managed using Kotlin &lt;code&gt;StateFlow&lt;/code&gt;. If a customer pays their specific portion, their sub-order state flips to &lt;code&gt;PAID&lt;/code&gt;, but the parent &lt;code&gt;GroupSession&lt;/code&gt; remains &lt;code&gt;PENDING&lt;/code&gt; until every individual array is cleared. This guarantees that no items slip through the cracks during a chaotic group checkout.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dual-Receipt Generation Pipeline
&lt;/h3&gt;

&lt;p&gt;Printing receipts for group orders requires different data for different stakeholders. The kitchen needs to see everything at once, while the customer only needs to see what they paid for.&lt;/p&gt;

&lt;p&gt;To solve this, I engineered a &lt;strong&gt;Dual-Receipt Generation Pipeline&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Kitchen Ticket:&lt;/strong&gt; When the order is confirmed, the app flattens the &lt;code&gt;GroupSession&lt;/code&gt; array into a single, consolidated list, grouping duplicate items (e.g., combining 4 separate "Fries" into a single "4x Fries" line item) to reduce reading time for the chefs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Individual Tickets:&lt;/strong&gt; Upon payment, the app queries the specific &lt;code&gt;SubOrder&lt;/code&gt;, formats the string payload, and sends it to the thermal printer, generating a personalized receipt containing only that customer's items and their specific tax calculations.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;The WingZone App replaced inefficient, manual checkout calculations with a structured, native Kotlin POS system designed around human F&amp;amp;B behavior. By solving the group-ordering and dual-receipt bottlenecks, the system drastically reduced queue times. &lt;/p&gt;

&lt;p&gt;The architecture and practical utility of the app earned &lt;strong&gt;1st Place overall at the KPTM Ipoh 2026 FYP Exhibition&lt;/strong&gt;, outperforming projects from every other course.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ahmad Akmal (RuumiDev), Founder of MiraiWorks and an Independent Builder specializing in robust systems and interactive UI. If you prefer structured, practical engineering, let's connect:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/RuumiDev" rel="noopener noreferrer"&gt;github.com/RuumiDev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://ahmadakmal.dev" rel="noopener noreferrer"&gt;ahmadakmal.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kotlin</category>
      <category>firebase</category>
      <category>architecture</category>
      <category>android</category>
    </item>
    <item>
      <title>Architecting Project Nero: Real-Time Exam Attendance via Local Computer Vision</title>
      <dc:creator>Ahmad Akmal Abdullah</dc:creator>
      <pubDate>Wed, 09 Sep 2026 02:34:59 +0000</pubDate>
      <link>https://dev.to/ruumidev/architecting-project-nero-real-time-exam-attendance-via-local-computer-vision-150e</link>
      <guid>https://dev.to/ruumidev/architecting-project-nero-real-time-exam-attendance-via-local-computer-vision-150e</guid>
      <description>&lt;p&gt;Taking attendance during university exams is a universally inefficient process. Invigilators waste the first 15 minutes of a critical testing period walking around with clipboards, checking IDs, and matching faces to names. It is a manual data-entry problem masquerading as a security protocol.&lt;/p&gt;

&lt;p&gt;I wanted to automate this completely. The goal was to build a system that could passively scan students as they entered the hall and log their attendance in real-time, requiring zero manual input. &lt;/p&gt;

&lt;p&gt;The result is &lt;strong&gt;Project Nero&lt;/strong&gt;—a local facial-recognition attendance tracking system. &lt;/p&gt;

&lt;p&gt;Here is how I architected the computer vision pipeline to make it fast, accurate, and completely independent of expensive cloud APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;p&gt;Streaming live video to a cloud AI endpoint is slow, bandwidth-heavy, and raises massive privacy concerns for student data. To solve this, Nero processes everything on the edge (locally) using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Core:&lt;/strong&gt; Python&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Video Processing:&lt;/strong&gt; OpenCV &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Facial Recognition:&lt;/strong&gt; DeepFace / MediaPipe&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Data Mapping:&lt;/strong&gt; External Spreadsheet Integration&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  1. Frame Capture &amp;amp; Face Detection (OpenCV)
&lt;/h3&gt;

&lt;p&gt;The system initializes a local Python camera script that hooks directly into the hardware webcam. Using &lt;strong&gt;OpenCV&lt;/strong&gt;, the script captures the live video feed and breaks it down into individual frames. &lt;/p&gt;

&lt;p&gt;Before we can identify &lt;em&gt;who&lt;/em&gt; is in the frame, the system must figure out &lt;em&gt;where&lt;/em&gt; the faces are. I utilize a lightweight cascade classifier to isolate bounding boxes around human faces in real-time, cropping the frame down to just the necessary pixels to save processing power.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Facial Categorization (DeepFace)
&lt;/h3&gt;

&lt;p&gt;Once a face is isolated, the cropped image is passed to the &lt;strong&gt;DeepFace&lt;/strong&gt; library. &lt;/p&gt;

&lt;p&gt;DeepFace acts as the core recognition engine. Instead of retraining a model from scratch, DeepFace wraps state-of-the-art models to generate a high-dimensional facial embedding (a mathematical representation of the face's features). It compares this real-time embedding against a pre-registered local directory of student photos. &lt;/p&gt;

&lt;p&gt;If the similarity score breaches the confidence threshold, the system successfully categorizes the face and returns the student's unique ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Real-Time State Mapping (Spreadsheet Integration)
&lt;/h3&gt;

&lt;p&gt;Recognizing a face is only half the battle; the system needs to log the data. &lt;/p&gt;

&lt;p&gt;Once DeepFace returns a matched student ID, the Python script triggers an external spreadsheet integration. It maps the recognized ID against the master student roster, flips their attendance state from "Absent" to "Present," and logs the exact timestamp of entry. &lt;/p&gt;

&lt;p&gt;To prevent the system from spamming the spreadsheet with 30 requests per second while a student stands in front of the camera, I implemented a local state-cache. Once a student is logged, their ID is cached in memory, and the system ignores them for the rest of the session.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Project Nero eliminates the manual bottleneck of exam invigilation. By combining OpenCV for rapid frame processing and DeepFace for accurate categorization, the entire pipeline runs locally on standard hardware. It is privacy-conscious, requires no cloud compute costs, and completely automates the administrative overhead of tracking students.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ahmad Akmal (RuumiDev), a software developer specializing in interface design, systems architecture, and practical AI. If you prefer structured, practical engineering, let's connect:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/RuumiDev" rel="noopener noreferrer"&gt;github.com/RuumiDev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://ahmadakmal.dev" rel="noopener noreferrer"&gt;ahmadakmal.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>computervision</category>
      <category>opencv</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Building Project Airi: An Autonomous WhatsApp Fiscal Bot with GPT-4o &amp; Tesseract.js</title>
      <dc:creator>Ahmad Akmal Abdullah</dc:creator>
      <pubDate>Wed, 09 Sep 2026 02:27:29 +0000</pubDate>
      <link>https://dev.to/ruumidev/building-project-airi-an-autonomous-whatsapp-fiscal-bot-with-gpt-4o-tesseractjs-23f2</link>
      <guid>https://dev.to/ruumidev/building-project-airi-an-autonomous-whatsapp-fiscal-bot-with-gpt-4o-tesseractjs-23f2</guid>
      <description>&lt;p&gt;Managing shared living expenses—like rent, WiFi, and utilities—is universally frustrating. The standard solution is forcing all your housemates to download a split-bill app, which no one ever updates. &lt;/p&gt;

&lt;p&gt;I wanted a frictionless solution. People already use WhatsApp to coordinate bills and send screenshots of bank transfer receipts. So, I built &lt;strong&gt;Project Airi&lt;/strong&gt;: an autonomous fiscal assistant that lives entirely inside WhatsApp. &lt;/p&gt;

&lt;p&gt;Instead of manual data entry, users simply drop a bank receipt into the chat, and the bot reads the image, validates the payment, and updates the database. Here is the technical architecture behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;p&gt;To make the bot fast, strongly typed, and resilient, I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Core:&lt;/strong&gt; Node.js &amp;amp; TypeScript&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL managed via Prisma ORM&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Computer Vision:&lt;/strong&gt; Tesseract.js (for local Optical Character Recognition)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;NLP Engine:&lt;/strong&gt; OpenAI GPT-4o API&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Platform:&lt;/strong&gt; WhatsApp Web.js (headless client integration)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Core Problem: Processing Bank Receipts
&lt;/h2&gt;

&lt;p&gt;The biggest engineering hurdle was data extraction. Bank transfer receipts are messy. Different banks use entirely different layouts, fonts, and terminologies. A standard regex script would fail the moment a new bank layout was introduced.&lt;/p&gt;

&lt;p&gt;To solve this, I built a two-step extraction pipeline: &lt;strong&gt;Local OCR $\rightarrow$ LLM Structuring&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Local OCR with Tesseract.js
&lt;/h3&gt;

&lt;p&gt;When a user uploads a receipt image to the WhatsApp chat, the bot intercepts the media payload. Instead of sending the heavy image file directly to an expensive cloud API, I process it locally using &lt;code&gt;Tesseract.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The OCR engine scans the image and extracts the raw text. The output is highly unstructured and often contains noise (like battery percentages from the screenshot or random UI text), but it secures the critical data: amounts, dates, and reference numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: NLP Structuring with GPT-4o
&lt;/h3&gt;

&lt;p&gt;This is where the bot becomes intelligent. I pipe the raw, noisy text string from Tesseract directly into the GPT-4o API with a strict system prompt. &lt;/p&gt;

&lt;p&gt;The LLM acts as a data parser. It is instructed to ignore the noise and extract only the verified transaction amount, the date, and the payer. It then returns this data in a perfectly formatted JSON object. &lt;/p&gt;

&lt;p&gt;By combining local OCR with an LLM, I created a highly fault-tolerant extraction system that doesn't care what bank the receipt came from. &lt;/p&gt;

&lt;h2&gt;
  
  
  State Management &amp;amp; Database
&lt;/h2&gt;

&lt;p&gt;Once GPT-4o returns the validated JSON data, the backend takes over. &lt;/p&gt;

&lt;p&gt;I utilized &lt;strong&gt;Prisma&lt;/strong&gt; as my ORM to interface with a &lt;strong&gt;PostgreSQL&lt;/strong&gt; database. The bot checks the extracted payment amount against the pending bills for that specific user. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If the math checks out, Prisma updates the user's ledger to "Paid."&lt;/li&gt;
&lt;li&gt;  The bot then pings the WhatsApp chat, confirming the payment and outputting a generated financial summary of who still owes what.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Project Airi completely automates fiscal tracking for shared living spaces. No new apps to download, no manual spreadsheets to update. It was built as a competitive proposal for APC2026, proving that advanced AI integrations don't need complex user interfaces—sometimes, the best UI is the chat app everyone is already using.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ahmad Akmal (RuumiDev), a software developer specializing in interface design, systems architecture, and practical AI. If you prefer structured, practical engineering, let's connect:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/RuumiDev" rel="noopener noreferrer"&gt;github.com/RuumiDev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://ahmadakmal.dev" rel="noopener noreferrer"&gt;ahmadakmal.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>openai</category>
      <category>node</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Engineering Mikira: The Award-Winning AI Study &amp; Music Bot for Discord</title>
      <dc:creator>Ahmad Akmal Abdullah</dc:creator>
      <pubDate>Tue, 18 Aug 2026 07:57:07 +0000</pubDate>
      <link>https://dev.to/ruumidev/engineering-mikira-the-award-winning-ai-study-music-bot-for-discord-3nl1</link>
      <guid>https://dev.to/ruumidev/engineering-mikira-the-award-winning-ai-study-music-bot-for-discord-3nl1</guid>
      <description>&lt;p&gt;If you manage a Discord community for developers or students, you already know the infrastructure pain: you need one bot for music, another for moderation, and a third for studying. Half the time, the music bot crashes due to YouTube API limits, and the study bot is just a glorified text dumper.&lt;/p&gt;

&lt;p&gt;I wanted to fix this. I didn't want just another generic bot; I wanted a unified, production-grade tool that handled complex audio pipelines and gamified programming education without ever forcing the user to leave the platform. &lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Mikira&lt;/strong&gt;—a multi-purpose Discord bot built on a modern asynchronous Python architecture. &lt;/p&gt;

&lt;p&gt;It hasn't just solved the problem for local servers; it recently secured &lt;strong&gt;6 international awards (4 Gold, 2 Silver)&lt;/strong&gt; and has been officially registered under the &lt;strong&gt;Intellectual Property Corporation of Malaysia (MyIPO)&lt;/strong&gt; as an AI Study Companion (Credential ID: CRLY2026E03369)&lt;/p&gt;

&lt;p&gt;Here is a breakdown of how I architected Mikira, the tech stack, and the engineering methodology behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture &amp;amp; Tech Stack
&lt;/h2&gt;

&lt;p&gt;Mikira is written in Python 3.10+ and relies heavily on asynchronous event loops. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Framework:&lt;/strong&gt; &lt;code&gt;py-cord&lt;/code&gt; (for modern slash commands, voice, and interactive UI views).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Audio Pipeline:&lt;/strong&gt; &lt;code&gt;yt-dlp&lt;/code&gt;, &lt;code&gt;spotipy&lt;/code&gt;, and system-level &lt;code&gt;FFmpeg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Concurrency:&lt;/strong&gt; Python's native &lt;code&gt;asyncio&lt;/code&gt; and &lt;code&gt;concurrent.futures&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Data Persistence:&lt;/strong&gt; JSON-backed per-guild settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Cog-Based Modular Design
&lt;/h3&gt;

&lt;p&gt;To make the codebase scalable, I split the domains (Music, General, Study) into independent Discord Cogs. This isolates the logic. If a music stream fails, it doesn't take down the quiz system. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Per-Guild State Isolation
&lt;/h3&gt;

&lt;p&gt;One of the biggest issues with multi-server bots is state bleeding. Mikira uses global dictionaries (&lt;code&gt;guild_to_audiocontroller&lt;/code&gt; and &lt;code&gt;guild_to_settings&lt;/code&gt;) to ensure absolute isolation. Each server gets its own playback queue, volume settings, and auto-timeout timers. What happens in Server A never impacts Server B.&lt;/p&gt;

&lt;h2&gt;
  
  
  Engineering the Audio Pipeline
&lt;/h2&gt;

&lt;p&gt;Building a music bot that doesn't break constantly requires aggressive fallback logic. &lt;/p&gt;

&lt;p&gt;When a user fires &lt;code&gt;/play&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;URL Identification:&lt;/strong&gt; The bot detects if the link is YouTube, Spotify, SoundCloud, Bandcamp, or a direct media file[cite: 1]. Spotify tracks are automatically reverse-searched into YouTube queries via &lt;code&gt;spotipy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Lazy Stream Resolution:&lt;/strong&gt; To prevent massive latency when loading large playlists, songs are queued as metadata "shells" in an O(1) &lt;code&gt;collections.deque&lt;/code&gt;. The actual audio stream is only hydrated right before playback.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Concurrent Preloading:&lt;/strong&gt; While a song is playing, Mikira uses &lt;code&gt;asyncio.ensure_future&lt;/code&gt; to preload upcoming tracks in the background, minimizing the gap between songs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Cookie Auth &amp;amp; Fallbacks:&lt;/strong&gt; To bypass age-restricted or region-locked content, &lt;code&gt;yt-dlp&lt;/code&gt; hooks into a Netscape cookie file[cite: 1]. If the primary extraction format fails, it gracefully falls back to a secondary format[cite: 1]. If that fails, it skips the track entirely rather than crashing the bot.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Interactive Study Hub
&lt;/h2&gt;

&lt;p&gt;The real utility of Mikira is the &lt;code&gt;/study&lt;/code&gt; command. Instead of dumping PDFs into a chat, I engineered a fully interactive, button-driven UI using Discord's &lt;code&gt;Views&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Curriculum:&lt;/strong&gt; It covers Python, JavaScript, Java, and C++ across 4 core CS chapters (Variables, Control Flow, Functions, OOP).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Active Recall Quizzes:&lt;/strong&gt; Users can take multiple-choice quizzes where both the questions and answers are randomized on every attempt to prevent position memorization.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Live Scoring &amp;amp; UI:&lt;/strong&gt; The bot provides instant visual feedback—correct answers turn green, wrong answers turn red. It tracks the score dynamically and outputs a performance tier (e.g., 90%+ is "Outstanding") with a visual progress bar (&lt;code&gt;🟩⬜&lt;/code&gt;). &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Validation &amp;amp; Impact
&lt;/h2&gt;

&lt;p&gt;Because of its resilient architecture and dual-purpose utility, Mikira was recognized at international innovation exhibitions, taking home 4 Gold and 3 Silver awards. Protecting the source code and brand was crucial, leading to its official MyIPO registration.&lt;/p&gt;

&lt;p&gt;The bot proves that Discord doesn't just have to be a chat app. With the right async architecture and interactive components, you can turn it into a gamified Learning Management System (LMS) and a resilient media player simultaneously.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ahmad Akmal (RuumiDev), a software developer specializing in interface design, systems architecture, and practical AI. If you prefer structured, practical engineering, let's connect:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/RuumiDev" rel="noopener noreferrer"&gt;github.com/RuumiDev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://ahmadakmal.dev" rel="noopener noreferrer"&gt;ahmadakmal.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>architecture</category>
      <category>coding</category>
    </item>
    <item>
      <title>Escaping the Boring Portfolio: Building a Cinematic IDE Experience</title>
      <dc:creator>Ahmad Akmal Abdullah</dc:creator>
      <pubDate>Tue, 18 Aug 2026 07:37:19 +0000</pubDate>
      <link>https://dev.to/ruumidev/escaping-the-boring-portfolio-building-a-cinematic-ide-experience-4o20</link>
      <guid>https://dev.to/ruumidev/escaping-the-boring-portfolio-building-a-cinematic-ide-experience-4o20</guid>
      <description>&lt;p&gt;Most developer portfolios look exactly the same: a generic hero section, some floating mockups, and a standard contact form. As a software developer with a background in multimedia, I wanted to build something that didn't just &lt;em&gt;tell&lt;/em&gt; visitors I write code—I wanted it to physically &lt;em&gt;feel&lt;/em&gt; like a developer's environment.&lt;/p&gt;

&lt;p&gt;I decided to ditch the standard web layout and build a cinematic, IDE-style terminal portfolio from scratch. Here is a breakdown of the architecture, the micro-interactions, and how I deployed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Vision &amp;amp; Tech Stack
&lt;/h2&gt;

&lt;p&gt;The goal was simple: build a production-ready, highly structural interface that mimics a code editor, complete with a dark theme, file-tree navigation, and zero fluff. &lt;/p&gt;

&lt;p&gt;To execute this, I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;React / Next.js:&lt;/strong&gt; For the component architecture and routing.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Tailwind CSS:&lt;/strong&gt; For strict, geometrical styling and rapid UI iteration.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;GSAP (GreenSock):&lt;/strong&gt; For complex timeline choreography and physical transition elements.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;dotLottie:&lt;/strong&gt; For lightweight, buttery-smooth vector animations.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Vercel:&lt;/strong&gt; For serverless deployment and CI/CD.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nailing the Boot Sequence (The Preloader)
&lt;/h2&gt;

&lt;p&gt;A standard page load feels disconnected. I wanted the user to feel like they were actively booting up a terminal session that transitions smoothly into a workspace.&lt;/p&gt;

&lt;p&gt;Instead of a basic spinning wheel, I built a dedicated &lt;code&gt;&amp;lt;Preloader /&amp;gt;&lt;/code&gt; component utilizing GSAP for a "split-gate" eyelid reveal.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Terminal Execution:&lt;/strong&gt; On initial load, a lightweight dotLottie animation plays while a React &lt;code&gt;useEffect&lt;/code&gt; interval simulates a snappy typing effect: &lt;code&gt;mal@portfolio:~$ booting kernel...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;CSS Micro-Interactions:&lt;/strong&gt; I mapped a &lt;code&gt;@keyframes&lt;/code&gt; block to a solid CSS square to mimic an authentic, blinking terminal cursor, bringing the text to life.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The GSAP Split-Gate:&lt;/strong&gt; Once the virtual workspace "initializes", a GSAP timeline takes over. Instead of fading out, the dark background physically splits in half, sliding up and down to unveil the fully rendered IDE underneath.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Structuring the IDE Interface
&lt;/h2&gt;

&lt;p&gt;The core layout is heavily inspired by VS Code. It requires strict CSS grid structuring to ensure the layout never breaks, regardless of screen size. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;File Tree Navigation:&lt;/strong&gt; The left sidebar acts as the primary router. Clicking files like &lt;code&gt;about.html&lt;/code&gt;, &lt;code&gt;projects.js&lt;/code&gt;, or &lt;code&gt;experience.ts&lt;/code&gt; dynamically swaps out the main viewing pane.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Mobile Auto-Retraction:&lt;/strong&gt; One of the trickiest UX details was handling mobile view. Standard sidebars stay open after you click a link, covering the content. I engineered the mobile state dispatcher to auto-retract the navigation tree the absolute millisecond a file is selected, ensuring the user can immediately read the content without fighting the UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deployment &amp;amp; Routing Architecture
&lt;/h2&gt;

&lt;p&gt;To keep the repository entirely private while maintaining an automated deployment pipeline, I hosted the project on &lt;strong&gt;Vercel&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Since the project uses Next.js, Vercel's serverless infrastructure automatically compiled the &lt;code&gt;.next&lt;/code&gt; output directory without any friction. Finally, I routed my custom domain (&lt;code&gt;ahmadakmal.dev&lt;/code&gt;) directly through Vercel's nameservers to enforce global HTTPS (a strict requirement for &lt;code&gt;.dev&lt;/code&gt; top-level domains) and ensure ultra-low latency via their edge network.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;The final build is fast, structured, and entirely fluff-free. It serves as a direct reflection of how I approach systems architecture and interface design. &lt;/p&gt;

&lt;p&gt;You can run the live "boot sequence" and check out the IDE yourself here: &lt;br&gt;
🔗 &lt;strong&gt;&lt;a href="https://ahmadakmal.dev" rel="noopener noreferrer"&gt;ahmadakmal.dev&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ahmad Akmal (RuumiDev), a software developer studying multimedia in Malaysia. I spend my time building practical AI applications, clean interfaces, and production-ready systems. Let's connect:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/RuumiDev" rel="noopener noreferrer"&gt;github.com/RuumiDev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Instagram:&lt;/strong&gt; &lt;a href="https://www.instagram.com/unsaltedsalt_" rel="noopener noreferrer"&gt;instagram.com/unsaltedsalt_&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/ahmadakmal-ruumidev" rel="noopener noreferrer"&gt;linkedin.com/in/ahmadakmal-ruumidev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>ui</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>How I Built My Next.js Developer Portfolio &amp; Optimized It for the Web</title>
      <dc:creator>Ahmad Akmal Abdullah</dc:creator>
      <pubDate>Mon, 13 Jul 2026 21:07:18 +0000</pubDate>
      <link>https://dev.to/ruumidev/how-i-built-my-nextjs-developer-portfolio-optimized-it-for-the-web-4p4d</link>
      <guid>https://dev.to/ruumidev/how-i-built-my-nextjs-developer-portfolio-optimized-it-for-the-web-4p4d</guid>
      <description>&lt;p&gt;When most developers build their personal websites, they focus entirely on UI animations, responsive layouts, and interactive components. While visual polish is essential, it means nothing if search engines cannot discover, crawl, and understand your site.&lt;/p&gt;

&lt;p&gt;I am Ahmad Akmal Abdullah (known online as RuumiDev), a Full-Stack Web Developer and Founder of MiraiWorks. When I set out to architect my official developer platform at ahmadakmal.dev, my goal was twofold: ship a high-performance web application, and engineer a closed-loop SEO structure that cleanly links my legal name, developer alias, and development brand across the web.&lt;/p&gt;

&lt;p&gt;Here is a practical breakdown of how I structured the project using Next.js App Router, solved common Single Page Application (SPA) indexing bottlenecks, and used structured JSON-LD schemas to build domain authority.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Core Architecture: Next.js App Router &amp;amp; Server-Side Rendering
Many modern portfolios are built as static client-side React or Vue applications. The problem with pure Client-Side Rendering (CSR) is that web crawlers must execute JavaScript just to read the basic text on your page—often resulting in delayed indexing or completely missed content.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By utilizing the Next.js App Router, ahmadakmal.dev leverages Server-Side Rendering (SSR) and React Server Components (RSC).&lt;/p&gt;

&lt;p&gt;Instant Payload Delivery: When Googlebot or Bingbot requests a page, the server immediately delivers fully rendered HTML containing my professional bio, core stack, and project histories.&lt;/p&gt;

&lt;p&gt;Component-Level Modularization: Features like dynamic project showcases, interactive terminal layouts, and responsive UI components are isolated, keeping client-side bundle sizes minimal and Core Web Vitals high.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Solving Identity Fragmentation with JSON-LD Structured Data
As a developer operating under an alias (RuumiDev) while managing a brand (MiraiWorks), search engines initially saw fragmented entities. A standard search for my legal name wouldn't naturally surface my technical repositories or brand milestones.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To fix this, I bypassed basic meta tags and injected a formal Schema.org JSON-LD Graph directly into the initial server-rendered HTML of the root layout. This explicitly instructs the Google Knowledge Graph that these separate digital footprints represent the exact same entity.&lt;/p&gt;

&lt;p&gt;Here is a simplified view of the schema structure implemented in the layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@graph"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ahmad Akmal Abdullah"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"alternateName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RuumiDev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ahmadakmal.dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"jobTitle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Full-Stack Web Developer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"worksFor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Organization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MiraiWorks"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sameAs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/RuumiDev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"https://linkedin.com/in/ahmadakmal-ruumidev"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Organization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MiraiWorks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ahmadakmal.dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"founder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ahmad Akmal Abdullah"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By establishing two-way links—where external platforms point to my domain, and my domain's schema claims those platforms—search algorithms can confidently index and consolidate my domain authority.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Programmatic Sitemaps &amp;amp; Crawler Routing
Static sitemap.xml files are prone to falling out of sync as you add new case studies, resume updates, or project logs. In Next.js App Router, I replaced static XML maintenance with a programmatic routing pipeline using app/sitemap.ts and app/robots.ts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of manually editing XML nodes, Next.js dynamically evaluates my route tree at build time and generates an optimized sitemap complete with specific crawl priorities:&lt;/p&gt;

&lt;p&gt;Primary Hub (/): Priority 1.0 with daily change frequency.&lt;/p&gt;

&lt;p&gt;Core Showcases (/projects, /about, /experience): Priority 0.8 for rapid re-crawling when new software updates are deployed.&lt;/p&gt;

&lt;p&gt;Support Pages (/skills, /contact): Priority 0.5 for structural completeness.&lt;/p&gt;

&lt;p&gt;Combined with an explicit robots.ts rule set that grants unrestricted crawler access to all major user agents while preventing accidental indexing of internal API routes, the site practically feeds itself to search indexers.&lt;/p&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
With the structural SEO and web architecture locked in, my current focus at MiraiWorks is scaling production-ready web applications, integrating computer vision pipelines, and deploying enterprise-grade AI architectures.&lt;/p&gt;

&lt;p&gt;If you are building complex web systems or want to connect regarding full-stack software development, feel free to explore my work or reach out across any of my active channels:&lt;/p&gt;

&lt;p&gt;Official Portfolio &amp;amp; Case Studies: ahmadakmal.dev&lt;/p&gt;

&lt;p&gt;GitHub Repositories: github.com/RuumiDev&lt;/p&gt;

&lt;p&gt;Professional Network: linkedin.com/in/ahmadakmal-ruumidev&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>seo</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
