<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Nahrin on Medium]]></title>
        <description><![CDATA[Stories by Nahrin on Medium]]></description>
        <link>https://medium.com/@nahrin_40746?source=rss-246c7bb9e829------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*OAEW670ErFSxRZqlHJCpZQ.jpeg</url>
            <title>Stories by Nahrin on Medium</title>
            <link>https://medium.com/@nahrin_40746?source=rss-246c7bb9e829------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 07 Jun 2026 14:40:43 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@nahrin_40746/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How I Built 8 Specialist AI Agents for Claude Code — and Used Them to Ship a Game I’d Never Built…]]></title>
            <link>https://medium.com/@nahrin_40746/how-i-built-8-specialist-ai-agents-for-claude-code-and-used-them-to-ship-a-game-id-never-built-9c78428174fa?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/9c78428174fa</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[claude]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Thu, 16 Apr 2026 13:01:03 GMT</pubDate>
            <atom:updated>2026-04-16T19:23:55.110Z</atom:updated>
            <content:encoded><![CDATA[<h3>How I Built 8 Specialist AI Agents for Claude Code — and Used Them to Ship a Game I’d Never Built Before</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qRt1-Pkv29Q7G6tq_zFQPA.png" /></figure><p>Someone left a comment on my LinkedIn post: <em>“These agents are good for small projects, not big complex ones.”</em></p><p>Fair. I’d just shown them building a <a href="https://github.com/navox-labs/nom">cookie clicker</a>. So I decided to prove them wrong in the most direct way I could think of. I’d build something genuinely complex. Something I had zero experience with. Something that would fail loudly if the agents couldn’t handle it.</p><p>I’d never built a game. Not a simple one. Not ever.</p><p>I picked a cybersecurity tower defense game with a server-authoritative WebSocket engine, a <a href="https://en.wikipedia.org/wiki/Factorio">Factorio-inspired</a> production chain mechanic, real-time attack waves, and a multi-service deployment across <a href="https://vercel.com/">Vercel</a> and <a href="https://fly.io/">Fly.io</a>. Then I typed one command, went to make dinner, and came back to a deployed, playable game <a href="https://frontend-beta-five-83.vercel.app/">PipeWar</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FdfQbU42DU2g%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdfQbU42DU2g&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FdfQbU42DU2g%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4ab14c0cf54819c1a7aed669463a3998/href">https://medium.com/media/4ab14c0cf54819c1a7aed669463a3998/href</a></iframe><p>This is how the agents actually work — the architecture, the prompt structure, the safety mechanisms, the memory system — and how you can build the same thing yourself.</p><h3>The real problem with single-AI coding</h3><p>When you ask one AI to architect, build, test, and deploy in a single conversation, it context-switches constantly. It forgets the auth model it defined 20 minutes ago. It skips tests because you didn’t explicitly ask. It makes UX decisions a designer would reject.</p><p>The problem isn’t intelligence. The problem is scope.</p><p>Real engineering teams don’t work this way. An architect designs the system. A designer specs the screens. A developer builds from those specs. QA tries to break it. Security audits before launch. Every person has a defined role, defined inputs, and a clean handoff to the next.</p><p>I built that structure as AI agents — <a href="https://github.com/navox-labs/agents">Navox Agents</a>. 8 specialists for Claude Code, each scoped to one job, each running on its own context window, orchestrated to work together the way a real team does.</p><h3>The architecture: orchestration, handshakes, and three types of human control</h3><p>Most multi-agent write-ups show you a diagram. What they skip are the mechanisms that make it actually work. There are three: <strong>orchestration</strong>, <strong>handshakes</strong>, and <strong>human-in-the-loop controls</strong>. Each is a different thing.</p><p><strong>Orchestration</strong> is how the team is managed. The Architect is not just a design agent — it’s the active project manager for the entire build. When you run /agency-run, the Architect reads your prompt, decides which agents are needed, determines the sequence, identifies what runs in parallel, and produces a RECOMMENDED TEAM block before a single line of code is written:</p><pre>RECOMMENDED TEAM:<br>1. Architect — DESIGN — system design before anyone builds<br>2. UX — FLOW → SPEC — map every screen and state<br>3. Security — DESIGN-REVIEW — auth model audit before build starts<br><br>PARALLEL AGENTS (can run simultaneously):<br>• UX + Security - both depend only on the Architect&#39;s output<br><br>BLOCKERS TO RESOLVE FIRST:<br>• Auth strategy undefined - need to know: JWT or session-based?</pre><p>No agent decides on its own when to start. No agent picks up your raw prompt and starts guessing. The Architect maps the team, flags blockers, and briefs each agent specifically.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/582/1*q5vNdRIzpZUO_whqPC4SCA.png" /><figcaption>navox-agents flowchart screenshot</figcaption></figure><p><strong>Handshakes</strong> are how knowledge moves between agents. When the Architect finishes, it doesn’t pass a doc and move on. It produces structured handoff notes — a prepared brief for each downstream agent containing exactly what that agent needs to start its specific job:</p><pre>HANDOFF NOTES:<br>→ UI/UX Agent: Design login, signup, password reset flows.<br>   Auth is JWT. No OAuth in v1. Show token expiry state.<br>→ Full Stack Agent: Implement JWT auth per the security model.<br>   Access token: 15 min. Refresh: stored in Redis, rotated on use.<br>→ Security Agent: Auth model uses short-lived JWTs + Redis refresh.<br>   Threat surface: login endpoint, token refresh, session fixation.<br>→ DevOps Agent: Deploy to Vercel (frontend) + Cloudflare Workers (backend).</pre><p>The UX agent doesn’t read the full system design doc. It receives the UX brief extracted from it. Security receives a different brief from the same source. Same document, different handshakes. This is what keeps agents from contradicting each other — they don’t share a context window and they don’t read each other’s work directly.</p><p><strong>Human-in-the-loop controls</strong> come in three distinct types, and understanding the difference matters:</p><p>GATE — a hard stop before downstream agents can proceed. The Architect produces its design. Nothing moves until you type APPROVED. Agents that hit a gate output:</p><pre>⚠️ HITL REQUIRED — GATE<br>Please review and respond: APPROVED | REVISION NEEDED: [notes]</pre><p>CHECKPOINT — a review point between stages. Lower stakes. You scan the output and respond CONTINUE or FEEDBACK: [notes]. The Local Review agent runs here — it starts your app locally, opens the browser, takes a screenshot, and waits for you to type LGTM, FEEDBACK: [what to change], or STOP. If you say FEEDBACK, it loops back to Full Stack with your notes. If you say STOP, it kills the server and exits immediately.</p><p>ESCALATION — the agent self-pauses when it hits something it cannot or should not decide alone. Two valid approaches with a business-level tradeoff. A destructive action like dropping a table. Anything that contradicts the Architect&#39;s design. The agent stops and outputs exactly what decision you need to make before it continues.</p><p>On top of all three, there’s a dangerous command interception layer. Commands matching rm -rf, drop, truncate, --force, production, or deploy surface for human approval before execution — every time, without exception.</p><h3>How to build an agent: the actual prompt structure</h3><p>Each agent is a single markdown file. No code. No dependencies. No platform. Just a system prompt that Claude Code loads from .claude/agents/.</p><p>Here’s the skeleton every agent in the team is built on:</p><pre>---<br>name: _agentname<br>description: One sentence. What this agent does and when Claude<br>             should load it. Include trigger keywords.<br>tools: Read, Write, Edit, Bash, Glob, Grep<br>model: claude-sonnet-4-6<br>---<br><br>## Identity<br>You are a [role] specialist with [X] years shipping [domain].<br>You think in [framing]. You are [position in team].<br><br>## Role in the Team<br>You own [specific slice]. You never [what this agent must not do].<br>You receive from: [upstream agent] — [what you get].<br>You hand off to: [downstream agent] — [what you produce].<br><br>## Modes<br><br>### [MODE: PLAN]<br>Entry point when the user isn&#39;t sure what they need.<br>Deliver: situation assessment + recommended next mode.<br><br>### [MODE: PRIMARY]<br>Full execution. Deliver: [specific artifacts].<br>Never omit: [non-negotiables].<br><br>### [MODE: VERIFY]<br>Check the work. Deliver: [pass/fail findings + fixes].<br><br>## Hard constraints<br>- Never [action that belongs to another agent]<br>- Always [non-negotiable behavior]<br>- Never proceed past a GATE without explicit human approval —<br>  output ⚠️ HITL REQUIRED and state exactly what&#39;s needed<br><br>## Project memory<br>At the start of every run:<br>  cat .claude/memory/agentname.md 2&gt;/dev/null || echo &quot;No memory yet&quot;<br><br>After completing your task, update your memory with decisions made,<br>patterns observed, and what to remember for next time.<br></pre><p>Two things worth pointing out. First: <strong>model routing</strong>. The Architect and Security agents run on claude-opus-4-6 — the hardest thinking jobs get the most capable model. Every other agent runs on claude-sonnet-4-6. This is intentional and it matters for cost at scale.</p><p>Second: <strong>the memory system</strong>. Every agent reads and writes its own memory file at .claude/memory/agentname.md. There&#39;s also a shared .claude/project-memory.md that the orchestrator updates after every run. The agents remember stack decisions, auth patterns, what failed last time, and why certain choices were made — across sessions. For a solo builder this is significant. The team never starts from zero.</p><h3>The modes: how you actually talk to the agents</h3><p>Every agent supports PLAN as a safe entry point. From there, each has specific modes for specific workflows. You can run the full chain or reach into any single agent directly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JL5ZZn7z3Qfy355bkNcRQQ.png" /></figure><p>The pattern is consistent across all agents: a PLAN mode that scopes the work, execution modes that do it, and verification modes that check the result. Security&#39;s LAUNCH-AUDIT is a hard gate — nothing deploys without a pass/fail verdict from it.</p><pre># Run the whole team end to end<br>/navox-agents:agency-run Build a task manager with user auth and Supabase<br><br># Reach into one agent for a specific job<br>/navox-agents:architect DIAGNOSE<br>/navox-agents:security LAUNCH-AUDIT<br>/navox-agents:fullstack DEBUG — here&#39;s the error: [paste]<br>/navox-agents:qa REGRESSION</pre><h3>The stress test: PipeWar</h3><p>A cookie clicker is a proof of concept. I needed something that would genuinely break an under-engineered system — multiple services, a real-time game engine, WebSocket communication, production deployment across two platforms, and enough complexity that any gap in the agent coordination would show up immediately.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Rgb5nuDXlgSjqAfioLiT2Q.jpeg" /></figure><p><a href="https://frontend-beta-five-83.vercel.app/">PipeWar</a> is a cybersecurity tower defense game. You build a factory on a 20×20 grid — miners extract ore, smelters produce plates, assemblers combine inputs into circuits. Connect everything with directional conveyor belts. Win condition: produce 20 Advanced Circuits while keeping uptime above 95%.</p><pre>Iron Ore ──→ Smelter ──→ Iron Plate ──────────────────────┐<br>                                                           ├──→ Assembler ──→ Advanced Circuit<br>Copper Ore ──→ Smelter ──→ Copper Plate ──→ Copper Wire ───┘</pre><p>The twist: once your factory generates enough traffic, attack waves spawn from the east edge. The attackers are real threat types — <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack">DDoS</a> bots swarm in numbers, <a href="https://en.wikipedia.org/wiki/SQL_injection">SQL injection</a> probes seek undefended paths, Zero-Day Exploits arrive every fifth wave as 300 HP bosses. Your defenses are real security tools — <a href="https://en.wikipedia.org/wiki/Rate_limiting">Rate Limiters</a>, <a href="https://en.wikipedia.org/wiki/Web_application_firewall">WAF</a>s, Auth <a href="https://en.wikipedia.org/wiki/Middleware">Middleware</a>, <a href="https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern">Circuit Breakers</a> — each with distinct mechanics.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ALtaIymQykg39S6Z1UyAAQ.jpeg" /></figure><p>The Architect chose the stack: Next.js 15 with TypeScript and HTML Canvas on the frontend, FastAPI running a 20 tick/second server-authoritative game engine on the backend, SQLite via aiosqlite, WebSocket for real-time state sync, deployed across Vercel and Fly.io. I didn’t pick any of it. I approved it.</p><p>Then I ran one command:</p><pre>/navox-agents:agency-run Build PipeWar — a Factorio-inspired tower defense game<br>themed around cybersecurity. 20x20 grid, production chains, attack waves,<br>WebSocket real-time engine. Deploy to Vercel + Fly.io.</pre><h3>What the build actually looked like</h3><p>The orchestrator paused twice while I was cooking. Once to confirm login to Fly.io — the DevOps agent intercepted the deploy command and surfaced it before executing. Once at the Local Review checkpoint — the agent started the app, opened the browser, took a screenshot, and waited. I walked over, typed LGTM, went back to the kitchen.</p><p>Three hours later: deployed, playable, tests passing.</p><p>After launch I found 8 production bugs. The production chain wasn’t producing circuits. The circuit breaker defense wasn’t activating. Belt direction glyphs showed question marks. I ran:</p><pre>/navox-agents:architect DIAGNOSE</pre><p>The Architect scanned every file in the codebase and returned all 8 bugs with exact files, exact lines, and exact fixes. I confirmed. Full Stack fixed all 8 and wrote 9 new unit tests. 65 tests passing. DevOps redeployed.</p><p>Something unexpected happened during that parallel run. Claude Code pulled in an agent from a completely different plugin I had installed — without me asking. It saw that all my agents were busy working in parallel and nobody was reviewing the code being written, so it brought in an outside agent to fill the gap. Like a project manager who notices the team is at capacity and calls in a freelance reviewer. I didn’t orchestrate that. Claude Code did. That moment told me something fundamental about how multi-agent systems actually work at scale — the orchestration layer isn’t just following your instructions. It’s evaluating the situation.</p><p><strong>The context isolation insight:</strong> after 8 hours of continuous agent work, my main Claude Code session had used 26% of its context window. Each agent runs in its own isolated context — its own token budget, its own reasoning space. They can’t contaminate each other’s state. This is the architecture decision most people miss when building multi-agent systems. Isolation isn’t a limitation. It’s what makes long-running, parallel work possible without the whole system degrading.</p><h3>Install and run it yourself</h3><pre>/plugin marketplace add https://github.com/navox-labs/agents<br>/plugin install navox-agents<br>/reload-plugins</pre><p>If you hit an SSH error first time:</p><pre>git config --global url.&quot;https://github.com/&quot;.insteadOf &quot;git@github.com:&quot;</pre><p>For a new project, copy a stack template first — the agents read it automatically and never ask you to re-explain your setup:</p><pre>cp ~/.claude/templates/nextjs.CLAUDE.md ./CLAUDE.md          # Next.js + Vercel<br>cp ~/.claude/templates/python-fastapi.CLAUDE.md ./CLAUDE.md  # FastAPI + Fly.io<br>cp ~/.claude/templates/node-api.CLAUDE.md ./CLAUDE.md        # Express + Railway</pre><p>Then start with the Architect:</p><pre>/navox-agents:architect DIAGNOSE</pre><p>It reads your request, maps the team, flags blockers, and tells you exactly which agents to run and in what order. From there, either follow its recommendations manually or hand everything to the orchestrator:</p><pre>/navox-agents:agency-run Build a [describe what you want]</pre><p>The agents are free, MIT licensed, and your code never leaves your machine. Everything is markdown — fork it, modify the prompts, build your own specialist. The source is at <a href="https://github.com/navox-labs/agents">github.com/navox-labs/agents</a>. PipeWar — built, debugged, and deployed entirely by the agent team — is <a href="https://frontend-beta-five-83.vercel.app/">playable here</a>. The <a href="https://github.com/navox-labs/pipewar">code is public</a> if you want to see exactly what 8 agents produce in three hours.</p><p><em>If 2026 is the year of the AI team, the interesting question isn’t whether agents can build complex software. PipeWar already answers that. The question is how you design the team.</em></p><p><em>The agents are free, MIT licensed, open source: </em><a href="https://github.com/navox-labs/agents"><em>github.com/navox-labs/agents</em></a><em>. Your code never leaves your machine.</em></p><p><em>Built by </em><a href="https://github.com/navox-labs"><em>Navox Labs</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9c78428174fa" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Person Who Got You Your Last Job Probably Barely Knew You]]></title>
            <link>https://medium.com/@nahrin_40746/the-person-who-got-you-your-last-job-probably-barely-knew-you-ac5a22a83cd2?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/ac5a22a83cd2</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[careers]]></category>
            <category><![CDATA[job-search]]></category>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Tue, 24 Mar 2026 15:01:01 GMT</pubDate>
            <atom:updated>2026-05-31T02:30:21.637Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bp4AP10wqQRk2Ew9kMRNjA.png" /><figcaption>LinkedIn network, mapped by tie strength. The two bridges were the last people I’d have called.</figcaption></figure><p>There’s a conversation I keep having with people in the middle of a job search. They’ve been applying for weeks — sometimes months. They have a solid resume. They’re not being unreasonable about salary. They’re just… not getting anywhere. And when I ask them about their network, they say some version of the same thing:</p><p><em>“I don’t really have one.”</em></p><p>What they mean, usually, is that they don’t have a close friend at a big company who can hand their resume directly to a hiring manager. They mean their inner circle isn’t powerful enough, well-placed enough, or well-connected enough to crack open a door.</p><p>They’re right about that. But they’re wrong about what it means.</p><p>Because the research is clear — and it’s genuinely counterintuitive — that the people most likely to get you your next job aren’t your closest contacts. They’re the ones you barely know.</p><h3>Why Your Best Friend Can’t Help You as Much as You Think</h3><p>In 1973, Stanford sociologist Mark Granovetter published a paper that has since become one of the most cited studies in social science. He’d been interviewing professionals about how they found their jobs, expecting to find that close relationships — friends, family, tight colleagues — were the primary pipeline.</p><p>What he found instead was the opposite. Most people got their jobs through contacts they saw only occasionally, or rarely at all. Acquaintances. Former colleagues they hadn’t spoken to in years. Conference contacts. People hovering at the outer edges of their social world.</p><p>He called this the strength of weak ties. And the logic, once you hear it, makes complete sense.</p><p>Your close friends live inside the same social bubble you do. They know the same people, move in the same circles, hear about the same opportunities. They want to help you — but they mostly have access to the same information you already have.</p><p>Your weak ties, by contrast, live in <em>different</em> bubbles. A former coworker who moved to a different industry. A college acquaintance who relocated to another city and built a new career. A professor you emailed once for a recommendation. These people exist at the edges of different worlds — and those worlds contain opportunities that your immediate network has never heard of.</p><blockquote><em>“Your weak ties connect you to networks that are outside of your own circle. They give you information and ideas that you otherwise would not have gotten.” — Mark Granovetter</em></blockquote><h3>The Experiment That Proved It</h3><p>For decades, Granovetter’s theory was influential but technically unproven at scale. Correlation isn’t causation. Maybe people with better careers just happened to maintain wider networks. Maybe it was the other way around.</p><p>Then, in 2022, a team of researchers from Stanford, MIT, and Harvard published a study in <em>Science</em> that changed that. They had access to something extraordinary: LinkedIn’s “People You May Know” algorithm, and five years of randomized experiments affecting over 20 million users.</p><p>LinkedIn had been quietly varying its recommendation algorithm — some users got more suggestions for people they were already close to, others got more suggestions for distant acquaintances. The researchers then tracked what happened to those users’ job outcomes across a period in which 600,000 new positions were created.</p><p>The results confirmed that weaker ties raised the possibility of job mobility the most. But the study also added a crucial refinement: it’s not that the weakest possible ties are best. Mid-tier friends are more helpful than either one’s closest friends or near-strangers — those with whom you share roughly 10 connections and seldom interact.</p><p>Not strangers. Not best friends. The people somewhere in the middle — the ones you know <em>just enough</em> to reach out to.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OT9wbUOr2JAz1-4V61ZI2Q.png" /><figcaption>Network Gap Analysis</figcaption></figure><h3>The Numbers Most Job Seekers Don’t Know</h3><p>Here’s what makes this more than an interesting academic concept. The referral economy — the informal network through which jobs are actually filled — operates at a completely different scale than the job board economy most people are competing in.</p><p>Referrals are four times more likely to be offered a job than candidates who apply through traditional job boards. Employee referrals account for 30 to 50 percent of all new hires. Yet referred candidates make up only about 7 percent of applicants.</p><p>One referral is worth approximately 40 cold applications.</p><p>Read that again. One warm introduction — from someone who barely knows you well enough to mention your name to a colleague — carries the same weight as forty resumes fired into the void.</p><p>Most people spend their job search almost entirely in that void. They optimize their resume, set up job alerts, apply to dozens of listings per week, and wonder why nothing is happening. The problem isn’t their resume. It’s that they’re playing a game where the odds are structurally terrible, when there’s a different game — with dramatically better odds — happening just adjacent to it.</p><p>The reason they’re not playing that game isn’t lack of networking ability. It’s that they’ve been told their network isn’t good enough to matter.</p><h3>You Already Have the Network. You Just Haven’t Mapped It.</h3><p>This is the part that surprises most people.</p><p>You don’t need a powerful inner circle to access the referral economy. You need to understand the geometry of the network you already have.</p><p>Consider what it means to have 150 first-degree connections on LinkedIn — a fairly modest number for most working professionals. Each of those 150 people has their own network. At an average of a few hundred connections each, your second-degree network — people you’re one introduction away from — likely numbers in the tens of thousands. Your third-degree network reaches into the hundreds of thousands.</p><p>Somewhere in that graph: people who work at every company you’re interested in. People who’ve made the exact career transition you’re trying to make. People who hire for the exact role you want.</p><p>The network isn’t missing. The map is.</p><p>I know this because I ran my own data. When I mapped my LinkedIn connections through this framework, my network had two structural bridges — connections whose removal would disconnect my professional graph from entire industry clusters I had almost no other presence in. When I saw who they were, I almost laughed. Neither was a senior executive or anyone I’d have thought to contact if I were job searching. One was a former classmate I’d spoken to twice since graduation. The other was someone from a conference three years ago — we’d shared a table at lunch, connected on LinkedIn that afternoon, and never exchanged another word. They were the last two people on my mental list. They were also, structurally, the most important people in my network.</p><p>The practical implication is that the job search strategy most likely to work isn’t volume — it’s excavation. Mapping what’s already there. Here’s what that looks like concretely:</p><p><strong>Start with your alumni network.</strong> LinkedIn’s Alumni tool (free to all users) lets you filter every graduate of your institution by company, role, location, and graduation year. A shared university is a genuine connection — it gives you something real to reference when you reach out, and acceptance rates for outreach with genuine shared context are meaningfully higher than cold messages.</p><p><strong>Contact people in your field at target companies, but not to ask for jobs.</strong> Ask for fifteen minutes to hear about their career path or get a perspective on the industry. This sounds small, but it’s how the actual labor market works. Most people are more willing to share their experience than to hand you a job, and informational conversations have a habit of turning into introductions.</p><p><strong>At the end of every conversation, ask one specific question:</strong> <em>Is there anyone else in this space you think I’d benefit from talking to?</em> Each time you ask and receive a name, your network expands by at least one node. Over six to eight weeks of consistent outreach, that compounding effect reaches people you never could have found through a job board.</p><p><strong>Watch for hiring signals.</strong> Funding announcements, executive appointments, and product launches are public signals that hiring is being actively planned — often weeks or months before a formal job posting appears. A warm second-degree contact at a company that just announced a Series B is extraordinarily valuable. Reach out within 48 hours of any such announcement, when the organization is actively thinking outward.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9FyuceDgjq6HBR1JOGh-yQ.png" /><figcaption>Outreach Queue screenshot</figcaption></figure><h3>The Hardest Part Isn’t What You Think</h3><p>When I’ve walked people through this framework, the most common objection isn’t “I don’t have the connections.” It’s “I feel weird reaching out to people I haven’t spoken to in years.”</p><p>That feeling is real, and it deserves to be acknowledged. Cold-to-warm outreach — contacting someone you only loosely know — feels presumptuous in a way that sending an application never does. Applications feel like playing by the rules. Reaching out to a former colleague from three jobs ago feels like asking for something.</p><p>But the research suggests that perception is inverted. Reaching out to a near-stranger on LinkedIn to ask for a referral has roughly the same success rate as being one of five hundred resumes in an ATS queue. Reaching out to someone with a genuine shared context — a former employer, a mutual colleague, an alumni network — is a fundamentally different interaction, and people respond to it differently than you’d expect.</p><p>The other thing worth knowing: most people <em>like</em> being helpful. They like being asked for their perspective. They like making introductions that work out. The ask that feels awkward to you rarely feels that way to the person receiving it, as long as it’s specific, personal, and not leading with “can you get me a job.”</p><p>Lead with curiosity. Lead with shared context. The referral, if it comes, follows from a relationship — not a request.</p><p>The job market is genuinely hard right now. The math on cold applications is brutal, and that’s not a reflection of anyone’s talent or effort. But the network most people believe they don’t have is, in almost every case, there — partially mapped on publicly accessible platforms, reachable through two or three degrees of connection, full of people who took the same paths you’re trying to take.</p><p>The question is whether you’re willing to stop thinking of networking as something powerful people do, and start thinking of it as something the data shows actually works — for anyone willing to read the map.</p><p>Your next job is probably sitting in your second-degree network right now. Someone who knows someone you know, working somewhere you’d want to be. They don’t know you’re looking.</p><p>Tell them.</p><p>If you’d rather skip the manual mapping, I built a tool called <a href="https://www.navox.tech/network">Navox Network</a> that takes your LinkedIn data export and does the graph analysis for you — surfacing which of your existing connections are most worth reaching out to based on exactly the research described here. No signup, and your data never leaves your browser. Mapping your network and seeing who to reach out to is free; an optional tier ($149 once) drafts the messages and tracks your outreach. The original open-source version that kicked this off — the network-science engine — is on <a href="https://github.com/navox-labs/network">GitHub</a> if you want to see how the scoring works; a star ⭐️ means a lot.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ac5a22a83cd2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The AI Hiring Crisis: Why You Need 750 Applications to Get One Job (2025 Data)]]></title>
            <link>https://medium.com/@nahrin_40746/the-ai-hiring-crisis-why-you-need-750-applications-to-get-one-job-2025-data-2fa29b854cf4?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/2fa29b854cf4</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[hiring]]></category>
            <category><![CDATA[future-of-work]]></category>
            <category><![CDATA[job-search]]></category>
            <category><![CDATA[recruiting]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Wed, 25 Feb 2026 00:45:00 GMT</pubDate>
            <atom:updated>2026-02-25T00:45:00.776Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MNonPx8Czp3167eIJdFjKw.png" /><figcaption>Illustration showing a job seeker overwhelmed by AI-driven recruitment systems displaying “APPLICATION REJECTED,” “NO RESPONSE,” and “INTERVIEW CANCELLED”</figcaption></figure><p><strong>New research reveals how AI screening, ghost jobs, and algorithmic bias created a “doom loop” that makes job searching statistically futile — and what you can do about it.</strong></p><p><em>🔬 Data-driven investigation based on 48 academic sources</em></p><p>If you’ve applied to hundreds of jobs and heard nothing back, you’re not alone — and <strong>it’s not your fault.</strong></p><p>Something fundamental broke in 2024, and the numbers tell a shocking story:</p><ul><li><strong>Up to 83% of employers</strong> are projected to use AI to screen resumes (often rejecting you in under 10 seconds)¹</li><li><strong>27.4% of online job postings</strong> are completely fake — “ghost jobs” with no intention to hire²</li><li><strong>Job seekers now need 400–750 applications</strong> to land a single offer³</li><li><strong>Success rates collapsed</strong> from 5% a decade ago to just <strong>0.1–2%</strong> today⁴</li></ul><p>This isn’t a hiring slowdown caused by the economy.</p><p><strong>It’s a systemic collapse</strong> caused by artificial intelligence, algorithmic bias, and corporate deception — creating what industry leaders now call the <strong>“doom loop”</strong> that’s making everyone miserable.⁵</p><p>If you’re a job seeker, recruiter, or policymaker trying to understand why the job market feels impossible right now, this investigation will give you the data-driven answers you need.</p><h3>1. Why This Matters (Even If You’re “Highly Qualified”)</h3><p><strong>The old hiring equation is dead.</strong></p><p>For decades, we were told success followed a simple formula:</p><p><strong>Skills + Experience + Effort = Opportunity</strong></p><p>But today, that equation is obsolete.</p><p>Here’s what actually happens now:</p><p><strong>Today, your resume is often rejected in under 10 seconds</strong> — not by a human, but by an opaque AI system trained on historically biased data.⁶</p><p>According to recent research from the University of Washington, <strong>AI hiring tools favor white-associated names 85.1% of the time</strong> in direct comparisons with Black candidates.⁷ In their comprehensive study analyzing 550 real-world resumes across three state-of-the-art language models, Black male candidates <strong>never ranked higher</strong> than white male candidates — not once, in any trial.</p><p>Even worse?</p><p><strong>Many of the jobs you’re applying to were never real to begin with.</strong></p><h3>📊 The Key Statistics You Need to Know</h3><p><strong>DATA SOURCES:</strong></p><ul><li>Society for Human Resource Management (SHRM) 2025 Survey</li><li>Greenhouse Hiring Platform Internal Data (70,000+ companies)</li><li>University of Washington Algorithmic Bias Study</li><li>ResumeUp.AI LinkedIn Analysis (7.18 million postings)</li><li>Bureau of Labor Statistics JOLTS Data</li></ul><h3>2. The Shocking Numbers Behind the Breakdown</h3><p>Let’s talk facts — not vibes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v0zTcH6QKfMOYQ5qQHFnGQ.png" /><figcaption>Infographic showing four key statistics with icons</figcaption></figure><h3>📊 83%</h3><p><strong>of employers use AI for screening</strong></p><p>AI usage in hiring skyrocketed from just 12% of employers in 2020 to 48% in early 2025, with projections reaching 83% by year-end.¹ The adoption happened faster than regulators could respond.</p><h3>👻 27.4%</h3><p><strong>of job listings are ghost jobs</strong></p><p>Analysis of 7.18 million LinkedIn postings reveals more than 1 in 4 jobs advertised online don’t actually exist.² Greenhouse, a major hiring platform serving 70,000+ companies, reports that in any given quarter, **70% of their clients post at least one ghost job.**⁵</p><h3>📄 400–750</h3><p><strong>applications per offer</strong></p><p>With an average 8.3% chance of landing an interview from one application, and typical interview-to-offer ratios, candidates now need hundreds of applications to secure a single job.³</p><h3>🎯 0.1–2%</h3><p><strong>online success rate</strong></p><p>Cold online applications have a success rate that has collapsed by up to <strong>95% in the past decade</strong> — from approximately 5% to as low as 0.1% today.⁴</p><h3>Then vs. Now: A Decade of Decline</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L6GWv0a3F8YKzUiyQCrLlQ.png" /></figure><p><strong>This isn’t inefficiency.</strong></p><p><strong>It’s structural failure.</strong></p><h3>3. The “Doom Loop” Nobody Warned You About</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fZ-QGcWZ37fezdLWsDhFgw.png" /><figcaption>Diagram illustrating the AI hiring doom loop cycle</figcaption></figure><p>In 2024, Greenhouse CEO Jon Stross coined a term that perfectly captures what’s happening: <strong>the “doom loop.”</strong></p><p>It works like this:</p><ol><li><strong>Job seekers use AI</strong> to apply to hundreds of jobs faster</li><li><strong>Employers receive 2–6x more applications</strong> than they can process</li><li><strong>Companies deploy harsher AI filters</strong> to manage the volume</li><li><strong>Algorithms mass-reject candidates</strong> within seconds</li><li><strong>Desperate applicants apply to even more jobs</strong> — including ghost postings</li><li><strong>The cycle intensifies</strong></li></ol><p>The result?</p><p>A self-reinforcing AI-powered rejection machine that benefits no one — not candidates, not recruiters, not companies.</p><p><strong><em>“AI has infiltrated hiring — from applicants using the tool to apply to hundreds of jobs and employees automating the process in response — creating a doom loop making everyone miserable.” </em></strong><em>— </em><strong>Jon Stross, CEO of Greenhouse</strong> (hiring platform serving 70,000+ companies)⁵</p><p>Internal Greenhouse data shows recruiter workload increased <strong>26% in a single quarter</strong> due to AI-enabled mass applications.⁵ Meanwhile, 20% of companies now receive <strong>thousands of applications for individual roles</strong> — making human review impossible.¹</p><p>The promise was efficiency.</p><p>The reality is chaos.</p><h3>4. Why AI Didn’t Make Hiring Better (It Made It Worse)</h3><p>AI was sold as a solution to bias, cost, and inefficiency.</p><p><strong>It delivered the opposite.</strong></p><h3>4.1 The Bias Problem: AI Inherited Our Worst Habits</h3><p>When Amazon built an internal AI recruiting tool in 2014, they discovered it was <strong>penalizing resumes that contained the word “women”</strong> (as in “women’s chess club”) and systematically downgrading graduates of all-women’s colleges.⁸</p><p>They scrapped it. But thousands of other companies deployed similar systems without such scrutiny.</p><p>The bias isn’t limited to gender:</p><p><strong>Racial Bias:</strong></p><ul><li>Wilson et al.’s University of Washington study found AI systems favor white-associated names <strong>85.1% of the time</strong>⁷</li><li>Black male candidates <strong>never ranked higher</strong> than white candidates in direct comparisons (0% preference rate)</li><li>The bias persisted across different job types and qualification levels</li></ul><p><strong>Age Discrimination:</strong></p><ul><li>The first EEOC settlement involving AI hiring resulted in a <strong>$365,000 penalty</strong>⁹</li><li>The company’s AI automatically rejected female applicants over 55 and male applicants over 60</li><li>Over 200 qualified applicants were screened out based <strong>solely on age</strong></li></ul><p><strong>Gender Bias:</strong></p><ul><li>Female-associated names were favored only <strong>11% of the time</strong> compared to male names⁷</li><li>Research shows that even awareness of algorithmic gender bias significantly deters women from applying, including the most qualified candidates¹⁰</li></ul><p>In <em>Mobley v. Workday</em> (2023), a class action lawsuit alleges Workday’s AI screening tools systematically discriminated based on race, age, and disability.¹¹ A Black man over 40 applied to over 100 positions through companies using Workday’s system — every single application was rejected, often within hours.</p><p>The case could potentially cover <strong>millions of job seekers</strong> affected by the same system.¹²</p><h3>4.2 The Efficiency Myth: Costs Are Up, Not Down</h3><p>The 2025 SHRM Benchmarking Survey found something shocking:</p><p>**Average cost-per-hire and time-to-hire have both <em>increased</em> during the period of generative AI adoption.**¹</p><pre>Before Mass AI Adoption → After AI Adoption<br>    Time-to-hire: increasing → Average: 42 days (2024)<br>    Cost-per-hire: increasing throughout AI adoption period<br>    <br>Source: SHRM 2025 Benchmarking Survey</pre><p>Why?</p><ol><li><strong>Application Volume Overload:</strong> AI-enabled mass applications increase volume 2–6x, overwhelming even AI systems</li><li><strong>False Negative Rates:</strong> Biased algorithms reject qualified candidates, forcing longer searches</li><li><strong>Candidate Withdrawal:</strong> 38% of job seekers would reject offers from AI-heavy recruiting processes⁵</li><li><strong>Quality Issues:</strong> Screening for keyword matches rather than actual qualifications reduces hire quality</li></ol><p>AI didn’t solve the problem.</p><p><strong>It became the problem.</strong></p><h3>4.3 The Trust Collapse</h3><p><strong>72% of job seekers</strong> report negative mental health impacts from long hiring processes and poor employer communication.¹³</p><p><strong>79% of actively searching U.S. workers</strong> experience heightened anxiety during their job hunt.⁵</p><p><strong>Only 26% of applicants</strong> trust AI to evaluate them fairly.⁵</p><p><strong>38% would reject job offers</strong> from companies with AI-heavy recruiting processes — higher among those most familiar with how AI works.⁵</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iZ8YffWpcpAkz3ybL_ESnA.png" /><figcaption><em>Person looking exhausted and stressed at laptop with “Application Submitted” notification</em></figcaption></figure><p>This is no longer just a career issue.</p><p><strong>It’s a public health issue.</strong></p><p>Research on AI-induced technostress shows prolonged exposure to AI-driven work environments correlates with:</p><ul><li>Feelings of uncertainty and lack of control</li><li>Cognitive overload from continuous AI interaction</li><li>Anxiety and depression symptoms</li><li>Emotional exhaustion from repeated rejection¹⁴</li></ul><p>When tens of millions engage in job searches annually, and most experience these stressors intensely, the aggregate mental health impact is substantial.</p><h3>5. Ghost Jobs: The Quiet Scam Distorting the Economy</h3><p>While AI bias gets headlines, there’s a quieter scandal destroying trust in the job market:</p><p><strong>Ghost jobs.</strong></p><p>These are job postings for positions that <strong>don’t exist</strong> — and they’re everywhere.</p><h3>The Scale of the Problem</h3><p>Multiple independent sources confirm alarming numbers:</p><ul><li><strong>LinkedIn Analysis:</strong> 27.4% of all U.S. job listings are likely ghost jobs²</li><li><strong>Greenhouse Data:</strong> 18–22% of job postings qualify as ghost jobs⁵</li><li><strong>Employer Surveys:</strong></li><li>40% of companies posted fake jobs in the past year¹⁵</li><li>30% currently have active ghost job listings¹⁵</li><li>Nearly 1 in 3 employers admit posting with no hiring intention¹⁶</li><li>81% of recruiters have posted ghost jobs¹⁷</li></ul><p>Industry rates vary:</p><ul><li><strong>Corporate services:</strong> 31% ghost job rate</li><li><strong>Tech, publishing, software:</strong> 40% of companies posted fake positions¹⁸</li><li><strong>79% of these listings</strong> remained active months later¹⁸</li></ul><h3>Why Companies Post Ghost Jobs</h3><p>Research identifies several motivations:¹⁹</p><p><strong>1. Investor Signaling (Growth Optics)</strong> Companies post jobs to project growth to investors, especially during earnings seasons. Appcast found 24% of recruiters were explicitly asked to keep postings live “for visibility” rather than actual hiring.²⁰</p><p><strong>2. Talent Pipeline Building</strong> 50% of hiring managers post roles to maintain a warm talent pool “at the ready” for future hiring.¹⁶ They collect and store resume data for potential future use.</p><p><strong>3. Employee Retention Tool</strong> 67% of companies use ghost jobs to make current employees feel replaceable, suppressing requests for raises or improved conditions.¹⁵</p><p><strong>4. Market Research</strong> Firms analyze submitted resumes and salary expectations to benchmark their workforce and understand competitive positioning.</p><p><strong>5. Internal Political Requirements</strong> HR departments maintain postings to meet internal metrics or appear busy, even when positions aren’t approved.</p><h3>🚨 Why This Matters to You</h3><p>If 27.4% of postings are fake, and you apply to 400 jobs:</p><ul><li><strong>~110 applications go to NON-EXISTENT positions</strong></li><li>At 45 min per application = <strong>82.5 HOURS WASTED</strong></li><li>That’s <strong>TWO FULL WORK WEEKS</strong> applying to fake jobs</li></ul><p><strong>Total job seeker time wasted on ghost jobs annually:</strong></p><h3>27 Billion Hours</h3><p>That’s more time than it took to build the Great Pyramid — wasted on applications that were never meant to be filled.</p><h3>The Economic Damage</h3><p>Ghost jobs don’t just waste individual time — they distort the entire labor market:</p><p><strong>Labor Market Data Corruption:</strong> Ghost jobs inflate the Bureau of Labor Statistics’ Job Openings and Labor Turnover Survey (JOLTS) figures, which policymakers use to assess labor market health.²¹ In July 2025, reported openings of 7.18 million include an estimated <strong>1.3–1.6 million ghost jobs</strong> (18–22% rate).²²</p><p>This affects:</p><ul><li>Federal Reserve interest rate decisions (based on perceived labor market tightness)</li><li>Unemployment insurance policy</li><li>Workforce development funding allocations</li><li>Economic forecasting models</li></ul><p><strong>Hiring Inefficiency:</strong> Companies with poor candidate experience (including ghost jobs) pay <strong>10% more per hire on average</strong>.²² For a company making 30 hires at $100,000 per role, that’s <strong>$300,000 in excess costs</strong>.</p><p><strong>Market Function Collapse:</strong> The hires-per-posting ratio has <strong>halved from 8:10 in 2019 to 4:10 in 2024</strong>,²³ indicating declining market efficiency. This mirrors classic economic failures where buyers can’t distinguish real value from fake supply.²⁴</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*myCkRQpAYFevNT4-KFeG5g.png" /><figcaption>Person staring at massive wall of job board listings, symbolizing the overwhelming and futile nature of the search</figcaption></figure><h3>6. Who Is Hurt the Most</h3><p>AI recruitment doesn’t fail evenly.</p><p><strong>It amplifies inequality.</strong></p><h3>AI Discrimination by the Numbers</h3><p><strong>Race:</strong></p><ul><li>White-associated names: Favored <strong>85.1% of the time</strong>⁷</li><li>Black male candidates: <strong>0% preference rate</strong> in direct comparisons⁷</li><li><strong>Result:</strong> Black job seekers may need 2–3x more applications to overcome systematic screening penalties</li></ul><p><strong>Gender:</strong></p><ul><li>Female-associated names: Favored only <strong>11% of the time</strong>⁷</li><li>Amazon’s AI: Penalized the word “women” on resumes⁸</li><li><strong>Result:</strong> Women face systematic algorithmic disadvantage before human review</li></ul><p><strong>Age:</strong></p><ul><li>First EEOC AI settlement: <strong>$365,000 penalty</strong>⁹</li><li>Cause: Auto-rejected applicants over 55 (women) and 60 (men)</li><li><strong>Result:</strong> Age discrimination automated at scale</li></ul><p><strong>Network Access:</strong></p><ul><li>One referral equals approximately <strong>40 cold applications</strong> in effectiveness²⁵</li><li>Groups with less professional network access hit hardest</li><li>First-gen college students, immigrants, career switchers disadvantaged</li></ul><h3>The Compounding Effect</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9R8oPoVgWssnHnox3ngUDA.png" /><figcaption>Stacks of resumes being filtered through an algorithmic funnel</figcaption></figure><p>AI didn’t remove bias.</p><p><strong>It industrialized it.</strong></p><p>Workers at intersections of multiple marginalized identities — Black women over 50, for example — face compounded disadvantages that single-axis analysis fails to capture.²⁶</p><p>California became the first state to recognize <strong>intersectionality as a protected category</strong> in September 2024,²⁶ acknowledging that discrimination based on combinations of characteristics cannot be reduced to evaluating race or gender alone.</p><p>Yet most AI systems aren’t designed to detect or prevent intersectional bias.</p><h3>It amplifies inequality:</h3><ul><li><strong>Older workers</strong> face automated age discrimination</li><li><strong>Women and minority candidates</strong> are disproportionately filtered out</li><li><strong>Career switchers and immigrants</strong> lack referral networks</li><li><strong>One referral still equals 40 cold applications</strong> — but not everyone has networks</li></ul><p>AI didn’t remove bias.</p><p>It <strong>industrialized</strong> it.</p><h3>7. What You’ll Gain by Reading This Research</h3><p>This isn’t just about rejecting AI.</p><p><strong>It’s about governing it before it governs us.</strong></p><p>Whether you’re a job seeker, recruiter, policymaker, or technologist building AI systems, this comprehensive synthesis gives you:</p><p>✅ <strong>A data-driven explanation</strong> of why hiring feels broken (not anecdotes — hard numbers you can cite)</p><p>✅ <strong>Legal, economic, and technical insights</strong> in one place (peer-reviewed research, court cases, industry data)</p><p>✅ <strong>A framework to understand</strong> why effort no longer maps to outcomes in job searching</p><p>✅ <strong>Clear policy and system-design solutions</strong> for what comes next (not just complaints — actionable fixes)</p><p>This isn’t about rejecting AI.</p><p>It’s about <strong>governing it before it governs us</strong>.</p><h3>📚 About the Research</h3><p>This investigation synthesizes:</p><ul><li><strong>48 peer-reviewed studies</strong> and academic papers</li><li><strong>Legal cases</strong> including the first EEOC AI hiring settlement ($365,000) and <em>Mobley v. Workday</em> class action</li><li><strong>Government reports</strong> from Congressional Research Service and Bureau of Labor Statistics</li><li><strong>Industry data</strong> from SHRM, Greenhouse, LinkedIn Economic Graph</li><li><strong>Labor market statistics</strong> published 2019–2025</li></ul><p>No original survey data was collected. This is a comprehensive synthesis of existing research across computer science, law, economics, and organizational behavior — identifying systemic patterns not visible within individual disciplines.</p><h3>What Comes Next?</h3><p>Researching this crisis convinced me that the problem isn’t candidates — it’s the system. Resumes weren’t built for this era. AI screening tools optimize for filtering, not understanding. So I started building something different.</p><p>Navox (<a href="https://www.navox.tech/">navox.tech</a>) is an AI-powered profile card that lets recruiters actually have a conversation with a candidate’s experience — instead of scanning a PDF for 6 seconds. It’s early. But it’s live. And every data point in this article is part of why it exists.</p><p>If you want to see what it looks like: <a href="https://www.navox.tech/card/nahrin">navox.tech/card/nahrin </a>— ask it anything.</p><h3>8. The Bottom Line: What Happens Next</h3><h3>The Question We Must Answer</h3><p>When <strong>99% of Fortune 500 companies</strong>¹² rely on AI to gatekeep economic opportunity, we face a choice:</p><p><strong>Who is accountable when algorithms decide who gets to work?</strong></p><p>The AI recruitment crisis is not inevitable.</p><p>But ignoring it is a choice — with consequences.</p><h3>What You Can Do Now</h3><h3>📌 If you’re a job seeker:</h3><ol><li><strong>Focus on referrals and networking</strong> (still 40x more effective than cold applications)²⁵</li><li><strong>Use keywords from job descriptions</strong> (AI scans for exact matches)</li><li><strong>Apply to companies with verified postings</strong> (LinkedIn “verified” badge, direct company sites)</li><li><strong>Report suspected ghost jobs</strong> to help clean up the market</li><li><strong>Document your experience</strong> (contribute to growing awareness and pressure for change)</li></ol><h3>📌 If you’re a recruiter or employer:</h3><ol><li><strong>Audit your AI tools for bias</strong> (required in NYC, recommended everywhere)²⁷</li><li><strong>Maintain human oversight</strong> of automated rejections (70% currently don’t)¹</li><li><strong>Remove ghost jobs immediately</strong> when positions are filled</li><li><strong>Disclose AI use to candidates</strong> (transparency builds trust)</li><li><strong>Track demographic outcomes</strong> (measure for disparate impact)</li></ol><h3>📌 If you’re a policymaker:</h3><ol><li><strong>Require bias audits</strong> for employment AI systems (follow NYC Local Law 144 model)²⁷</li><li><strong>Ban or regulate ghost job postings</strong> (California, New Jersey, Kentucky initiatives)¹⁶</li><li><strong>Extend liability to AI vendors</strong>, not just employers using them</li><li><strong>Provide candidates</strong> right to explanation and human review</li><li><strong>Fund enforcement</strong> (EEOC needs resources for AI-related cases)</li></ol><h3>📌 If you’re a technologist:</h3><ol><li><strong>Build fairness testing</strong> into AI hiring tools from day one</li><li><strong>Prioritize transparency and explainability</strong> over black-box optimization</li><li><strong>Recognize technical solutions alone</strong> won’t solve social problems</li><li><strong>Consider ethics before efficiency</strong> (speed ≠ progress)</li><li><strong>Include diverse perspectives</strong> in design teams (homogeneous teams build biased systems)</li></ol><h3>The Path Forward</h3><p>The evidence presented suggests that the job market in 2025 is experiencing <strong>systemic dysfunction</strong>.</p><p>Yet the crisis also presents an opportunity:</p><ul><li><strong>Legal challenges are succeeding</strong> ($365,000 EEOC settlement, <em>Mobley v. Workday</em> class action)⁹¹¹</li><li><strong>Researchers are developing fairness metrics</strong> and technical interventions²⁸</li><li><strong>Legislators are proposing comprehensive regulation</strong> (federal Truth in Job Advertising Act, state laws)¹⁶</li><li><strong>Workers are organizing</strong> and documenting abuses (Change.org petition: 50,000 signatures)</li></ul><p>The system’s failures are becoming undeniable.</p><p>The question is whether we have the collective will to address them.</p><h3>📢 Join the Conversation</h3><p><strong>What’s your experience with AI hiring?</strong></p><p>Have you:</p><ul><li>Been rejected in seconds by automated systems?</li><li>Applied to jobs you suspect were fake?</li><li>Noticed bias in the hiring process?</li><li>Successfully navigated AI screening?</li></ul><p><strong>Share your story in the comments below.</strong> Your experience helps document this crisis and pushes for change.</p><h4>References</h4><p>¹ Society for Human Resource Management. (2025). <em>2025 SHRM Benchmarking Survey</em>. Alexandria, VA: SHRM.</p><p>² ResumeUp.AI. (2025). One-Quarter of Jobs Posted Online Are Fake Ghost Jobs: Study. <em>Entrepreneur</em>. <a href="https://www.entrepreneur.com/business-news/one-quarter-of-jobs-posted-online-are-fake-ghost-jobs-study/496683">https://www.entrepreneur.com/business-news/one-quarter-of-jobs-posted-online-are-fake-ghost-jobs-study/496683</a></p><p>³ LinkedIn Talent Solutions. (2024). <em>Global Talent Trends 2024</em>. LinkedIn Economic Graph Research.</p><p>⁴ Greenhouse. (2024). Candidate Experience Research. Internal data cited in <em>State of Job Hunting Report</em>.</p><p>⁵ Greenhouse. (2024). <em>2024 State of Job Hunting Report</em>. <a href="https://www.greenhouse.com/blog/greenhouse-2024-state-of-job-hunting-report">https://www.greenhouse.com/blog/greenhouse-2024-state-of-job-hunting-report</a></p><p>⁶ Soleimani, M., Intezari, A., Arrowsmith, J., Pauleen, D. J., &amp; Taskin, N. (2025). Reducing AI bias in recruitment and selection: An integrative grounded approach. <em>The International Journal of Human Resource Management</em>, 36(14), 2480–2515.</p><p>⁷ Wilson, K., Rodolfa, K. T., &amp; Caliskan, A. (2024). Gender, race, and intersectional bias in resume screening via language model retrieval. University of Washington. <a href="https://www.washington.edu/news/2024/10/31/ai-bias-resume-screening-race-gender/">https://www.washington.edu/news/2024/10/31/ai-bias-resume-screening-race-gender/</a></p><p>⁸ Brookings Institution. (2025). Gender, race, and intersectional bias in AI resume screening via language model retrieval. <a href="https://www.brookings.edu/articles/gender-race-and-intersectional-bias-in-ai-resume-screening-via-language-model-retrieval/">https://www.brookings.edu/articles/gender-race-and-intersectional-bias-in-ai-resume-screening-via-language-model-retrieval/</a></p><p>⁹ EEOC Settlement Report. (2023). First AI Hiring Discrimination Settlement. U.S. Equal Employment Opportunity Commission.</p><p>¹⁰ Ip, E. (2025). Fair AI in hiring: Experimental evidence on how biased hiring algorithms and different debiasing methods affect the quality and diversity of applicants. <em>Organizational Behavior and Human Decision Processes</em>, 180, 105385.</p><p>¹¹ <em>Mobley v. Workday, Inc.</em>, Case №3:23-cv-00770 (N.D. Cal. 2023).</p><p>¹² The Interview Guys. (2025). 85% of AI Resume Screeners Prefer White Names: Why 2025 Is The Year Hiring Discrimination Lawsuits Exploded. <a href="https://blog.theinterviewguys.com/85-of-ai-resume-screeners-prefer-white-names/">https://blog.theinterviewguys.com/85-of-ai-resume-screeners-prefer-white-names/</a></p><p>¹³ Greenhouse. (2024). Candidate Experience Research. Internal data cited in State of Job Hunting Report.</p><p>¹⁴ Lee, J., Kim, S., &amp; Park, Y. (2024). AI-induced technostress and mental health in the workplace: A systematic review. <em>Computers in Human Behavior</em>, 158, 108234.</p><p>¹⁵ Resume Builder. (2024). <em>Ghost Jobs Survey Results</em>. <a href="https://www.resumebuilder.com/3-in-10-companies-currently-have-fake-job-posting-listed">https://www.resumebuilder.com/3-in-10-companies-currently-have-fake-job-posting-listed</a></p><p>¹⁶ DAVRON. (2025). Ghost Jobs &amp; Misleading Job Ads Are Still Rising. <a href="https://www.davron.net/ghost-jobs-misleading-job-ads-are-still-rising">https://www.davron.net/ghost-jobs-misleading-job-ads-are-still-rising</a></p><p>¹⁷ Fast Company. (2024). 3 Ways to Spot a Ghost Job Listing. <a href="https://www.fastcompany.com/91183465/3-ways-to-spot-a-ghost-job-listing">https://www.fastcompany.com/91183465/3-ways-to-spot-a-ghost-job-listing</a></p><p>¹⁸ The Interview Guys. (2025). Ghost Jobs Exposed: The Companies Posting Fake Job Listings. <a href="https://blog.theinterviewguys.com/ghost-jobs-exposed/">https://blog.theinterviewguys.com/ghost-jobs-exposed/</a></p><p>¹⁹ Handwerker, E. W., &amp; Pepper, A. H. (2025). “Ghost” Job Postings. <em>Congressional Research Service Report No. IF12977</em>. <a href="https://www.congress.gov/crs-product/IF12977">https://www.congress.gov/crs-product/IF12977</a></p><p>²⁰ Appcast. (2024). <em>Recruiter Survey on Ghost Job Postings</em>. Internal research report.</p><p>²¹ Congressional Research Service. (2024). <em>Ghost Job Postings Fact Sheet</em>. <a href="https://www.congress.gov/crs-products/IF12977">https://www.congress.gov/crs-products/IF12977</a></p><p>²² Lindsley, P. (2025). From 1 in 8 to 1 in 5: Ghost Jobs Are Distorting the U.S. Labor Market in 2025. <em>Medium</em>. <a href="https://medium.com/@patricklindsley1/from-1-in-8-to-1-in-5-ghost-jobs-are-exploding-in-2025-a7a1fbdad011">https://medium.com/@patricklindsley1/from-1-in-8-to-1-in-5-ghost-jobs-are-exploding-in-2025-a7a1fbdad011</a></p><p>²³ Revelio Labs. (2024). <em>Hires Per Job Posting Analysis</em>. Retrieved from CNBC reporting on ghost jobs.</p><p>²⁴ Akerlof, G. A. (1970). The market for “lemons”: Quality uncertainty and the market mechanism. <em>The Quarterly Journal of Economics</em>, 84(3), 488–500.</p><p>²⁵ Burks, S. V., Cowgill, B., Hoffman, M., &amp; Housman, M. (2015). The value of hiring through employee referrals. <em>The Quarterly Journal of Economics</em>, 130(2), 805–839.</p><p>²⁶ Brookings Institution. (2025). Gender, race, and intersectional bias in AI resume screening via language model retrieval. <a href="https://www.brookings.edu/articles/gender-race-and-intersectional-bias-in-ai-resume-screening-via-language-model-retrieval/">https://www.brookings.edu/articles/gender-race-and-intersectional-bias-in-ai-resume-screening-via-language-model-retrieval/</a></p><p>²⁷ Sheard, L. (2025). Algorithm-facilitated discrimination: A socio-legal study of the use by employers of artificial intelligence hiring systems. <em>Journal of Law and Society</em>, 52(2), 234–267.</p><p>²⁸ Albaroudi, E., Mansouri, M., &amp; Alamri, S. (2024). A comprehensive review of AI techniques for addressing algorithmic bias in job hiring. <em>AI</em>, 5(2), 383–407.</p><p><em>If this article helped you understand what’s happening in the job market, please share it with others who need to know. The more people understand the systemic nature of this crisis, the faster we can push for meaningful reform.</em></p><p>👏 Clap if this resonated | 💬 Comment with your experience | 🔄 Share to spread awareness</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2fa29b854cf4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The 6 Half-Measures to Avoid to Be Whole, Be Bold, and Live Unapologetically in the New-Tech Era]]></title>
            <link>https://medium.com/@nahrin_40746/the-6-half-measures-to-avoid-to-be-whole-be-bold-and-live-unapologetically-in-the-new-tech-era-4c57f13ce225?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/4c57f13ce225</guid>
            <category><![CDATA[entrepreneurship]]></category>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[poetry]]></category>
            <category><![CDATA[life]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Wed, 30 Oct 2024 04:05:57 GMT</pubDate>
            <atom:updated>2024-10-30T04:05:57.436Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*vezuRwem5wmmZldV" /><figcaption>Photo by <a href="https://unsplash.com/@omilaev?utm_source=medium&amp;utm_medium=referral">Igor Omilaev</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p><em>“Do not love half lovers<br>Do not entertain half friends<br>Do not indulge in works of the half talented<br>Do not live half a life<br>and do not die a half death.<br>If you choose silence, then be silent<br>When you speak, do so until you are finished<br>Do not silence yourself to say something<br>And do not speak to be silent.<br>If you accept, then express it bluntly<br>Do not mask it<br>If you refuse then be clear about it<br>for an ambiguous refusal is but a weak acceptance.<br>Do not accept half a solution<br>Do not believe half truths<br>Do not dream half a dream<br>Do not fantasize about half hopes.<br>Half a drink will not quench your thirst<br>Half a meal will not satiate your hunger<br>Half the way will get you nowhere<br>Half an idea will bear you no results.<br>Your other half is not the one you love<br>It is you in another time yet in the same space<br>It is you when you are not.<br>Half a life is a life you didn’t live,<br>A word you have not said<br>A smile you postponed<br>A love you have not had<br>A friendship you did not know<br>To reach and not arrive<br>Work and not work<br>Attend only to be absent<br>What makes you a stranger to those closest to you<br>and they strangers to you.<br>The half is a mere moment of inability<br>but you are able, for you are not half a being<br>You are a whole that exists to live a life<br>not half a life.”</em><br>― <strong>Gibran Khalil Gibran</strong></p><p>For those who dream of building technologies that can change lives, the journey can feel isolating. Doubts creep in, amplified by fear of judgment and rejection. You may feel as if your ideas are fragile, as if the world is quick to dismiss what you hold dear. But remember, you are not alone in this journey.</p><p>Inspired by Khalil Gibran’s timeless words, this guide is here to remind you that to succeed, you must show up fully — for yourself and for your dreams. Don’t settle for half-steps or half-beliefs, for they will only weaken your path. Instead, be whole, be bold, and live unapologetically, embracing the fullness of who you are.</p><p>Here are six half-measures to avoid if you want to rise above fear, loneliness, and doubt.</p><h3>1. Don’t Build Halfway Relationships: Surround Yourself with Genuine Allies</h3><p>“<em>Do not love half lovers.</em>” Many relationships in tech and innovation feel superficial, leaving you feeling unrecognized or misunderstood. But you don’t need people who don’t see your vision. Build authentic connections with those who believe in you fully. Seek those who offer their support, honesty, and respect.</p><p>The right allies remind you of your worth, especially when doubt arises. Let your relationships reflect the strength of your purpose, for they will fuel you when your journey feels most difficult.</p><h3>2. Refuse Half-Dreams: Hold onto Your Vision Despite Doubts</h3><p>“<em>Do not dream half a dream,</em>” reminds us that shrinking your vision won’t make it safer; it will make it powerless. The fear of judgment can tempt you to scale down, to make your ideas fit into what others might find “acceptable.” But a half-dream will only lead to a half-hearted life.</p><p>Let your dream be bold, even if it feels lonely or misunderstood at times. Fear of success is a trick of the mind. Embrace your dream in full, without apology. The strength of your vision is what will guide you through the difficult moments.</p><h3>3. Avoid Partial Transparency: Embrace Radical Honesty</h3><p>“<em>Do not believe half-truths.</em>” In a world where it’s tempting to mask who we are or soften our beliefs to fit in, know that transparency is your power. Fear of judgment can make us hold back our true thoughts, but when you’re open and real, you find your true supporters.</p><p>Speak your ideas with courage. Let people see your vision as it is, without hiding or adjusting to please others. Radical honesty frees you from the weight of fear and allows you to connect with those who understand your value. You’re not here to be liked by everyone — you’re here to bring your unique vision to life.</p><h3>4. Reject Half-Solutions: Commit to Full Integrity</h3><p>“<em>Do not accept half a solution.</em>” When doubt and fear are high, shortcuts seem tempting. Half-measures can feel like protection against failure, but they only limit your potential. Instead, trust yourself enough to commit to solutions that fully align with your vision.</p><p>You’re here to create something lasting, not something that merely “works for now.” Let every step you take reflect the fullness of your potential, and don’t compromise. When you commit to integrity, you build something real, and that builds your confidence in the face of judgment.</p><h3>5. Embrace Full Resilience: Use Fear as Fuel for Growth</h3><p>“<em>Half a life is a life you did not live.</em>” The fear of success and the fear of failure are often two sides of the same coin, but neither should hold you back. Each time you encounter resistance or feel judgment from others, remember that resilience is a choice. Let every doubt, every rejection be fuel that drives you further.</p><p>True resilience isn’t about avoiding failure or minimizing success — it’s about allowing both to strengthen you. Face each fear fully, not to be defeated by it, but to learn from it and grow stronger.</p><h3>6. Avoid Halfway Innovation: Never Stop Pushing Your Vision Forward</h3><p>“<em>You are a whole that exists to live a life, not half a life.</em>” Halfway innovation is the result of shrinking from success, of keeping your ideas small to avoid rejection. But your calling demands that you push forward, that you explore what’s possible without apology.</p><p>Each step forward is a step into the unknown, but this is where true creativity lies. Keep questioning, keep challenging, and let your vision expand. Innovation isn’t a single success; it’s a commitment to always evolve, always reach further.</p><h3>And Don’t Forget: Live Whole, Lead Boldly, and Create Without Fear</h3><p>In a world that may not always understand you, remember: <em>“You are not half a being.”</em> You are here to live fully, to create without apology, to rise above the judgments of others. Embrace the people, the dreams, and the truths that align with your highest purpose.</p><p>When you show up fully, you find the strength to overcome the loneliness, fear, and doubt that come with your journey. You are a Purpose-Driven Pioneer, and the world awaits the greatness only you can bring. So live whole, be bold, and step into your future with courage. The world needs your brilliance — now more than ever.</p><p><em>A special thank you to ChatGPT for lending a hand in editing my blog. 🤖❤️</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4c57f13ce225" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing the Rate Limiter API: Your Key to Managing Application Traffic]]></title>
            <link>https://medium.com/@nahrin_40746/introducing-the-rate-limiter-api-your-key-to-managing-application-traffic-f716e36ac296?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/f716e36ac296</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[rate-limiting]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Sat, 03 Aug 2024 07:31:28 GMT</pubDate>
            <atom:updated>2024-08-03T07:31:28.191Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*bhEwIuNwQFyZ-AQ5" /><figcaption>Photo by <a href="https://unsplash.com/@safesolvent?utm_source=medium&amp;utm_medium=referral">Martin Reisch</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>As developers, we often face the challenge of handling incoming traffic to our applications in a controlled and predictable manner. Whether it’s to prevent abuse, ensure fair usage, or simply to maintain performance and reliability, managing the rate of incoming requests is crucial. This is where the <a href="https://rapidapi.com/nahrinoda/api/rate-limiter-api"><strong>Rate Limiter API</strong></a> comes into play — a powerful tool that provides various rate limiting algorithms to help you manage and control the flow of traffic to your application.</p><h4>What is the Rate Limiter API?</h4><p>The Rate Limiter API is designed to give developers a robust set of tools to control the rate of incoming requests to their applications. It includes a range of algorithms such as <a href="https://rapidapi.com/nahrinoda/api/rate-limiter-api/playground/apiendpoint_7abdaa09-710b-42c2-81f6-b74e3575d5bd">Token Bucket</a>, <a href="https://rapidapi.com/nahrinoda/api/rate-limiter-api/playground/apiendpoint_fe2cb776-f82f-46d5-8d6f-03e2891e754d">Leaking Bucket</a>, <a href="https://rapidapi.com/nahrinoda/api/rate-limiter-api/playground/apiendpoint_0feb9e31-d92b-42ec-8282-2b4fbf3cc1e8">Fixed Window Counter,</a> <a href="https://rapidapi.com/nahrinoda/api/rate-limiter-api/playground/apiendpoint_4ce9560f-2adb-4894-bcb7-cdb19af55cce">Sliding Window Log</a>, and <a href="https://rapidapi.com/nahrinoda/api/rate-limiter-api/playground/apiendpoint_2cdc58ea-83f7-4cbb-983e-a8f6b1c682e0">Sliding Window Counter</a>. Each algorithm serves a specific purpose, allowing you to choose the best fit for your application’s needs.</p><h4>Why is Rate Limiting Important?</h4><p>Rate limiting is a critical component in application security and performance. It helps prevent abuse by limiting the number of requests that a single user or IP address can make within a certain timeframe. This not only protects your application from potential <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack">denial-of-service</a> (DoS) attacks but also ensures that resources are used fairly among all users.</p><p>Engineers should consider integrating a rate limiter into their applications for several reasons:</p><ul><li><strong>Security</strong>: Protects against brute force attacks and reduces the risk of system overload.</li><li><strong>Fair Usage</strong>: Ensures that all users have equal access to the application’s resources.</li><li><strong>Performance</strong>: Helps maintain optimal performance by preventing resource hogging.</li></ul><h4>Applications That Benefit the Most</h4><p>The Rate Limiter API is particularly beneficial in scenarios where your application receives a high volume of requests or where the potential for abuse is high. Examples include:</p><ul><li><a href="https://en.wikipedia.org/wiki/API"><strong>APIs</strong></a><strong> and </strong><a href="https://microservices.io/"><strong>Microservices</strong></a>: Protect your services from being overwhelmed by too many requests in a short period.</li><li><a href="https://en.wikipedia.org/wiki/E-commerce"><strong>E-commerce</strong></a><strong> Platforms</strong>: Ensure that your online store remains responsive during peak shopping times.</li><li><a href="https://en.wikipedia.org/wiki/Authentication"><strong>Authentication</strong></a><strong> Systems</strong>: Prevent brute force attacks by limiting the number of login attempts.</li><li><strong>Content Delivery Networks (</strong><a href="https://en.wikipedia.org/wiki/Content_delivery_network"><strong>CDNs</strong></a><strong>)</strong>: Regulate the flow of requests to ensure consistent content delivery performance.</li></ul><h4>Choosing the Right Algorithm For Your Application:</h4><ul><li><strong>For Simple Use Cases</strong>: If your application needs straightforward rate limiting, such as limiting purchase attempts per minute as in the example, the Fixed Window Counter is often sufficient.</li><li><strong>For Smoothing Traffic</strong>: If you want to avoid sudden spikes or need to distribute requests more evenly, the Sliding Window algorithms (Log or Counter) might be better suited.</li><li><strong>For Allowing Bursts</strong>: If you need to handle occasional bursts of traffic but still enforce a rate limit, the Token Bucket algorithm is a strong choice.</li><li><strong>For Consistent Processing</strong>: If your priority is to handle requests at a steady pace without sudden spikes, the Leaking Bucket algorithm could be ideal.</li></ul><h4>Where Should You Place the Rate Limiter API in Your Codebase?</h4><p>To effectively integrate the Rate Limiter API, it’s crucial to place it in the right part of your codebase. Typically, the rate-limiting logic should be implemented at the entry point of your application, such as in the middleware layer or API gateway. This placement ensures that all incoming requests are checked and regulated before they reach your core application logic, providing a robust first line of defense against excessive or malicious traffic.</p><p>Here’s an example of how you can set up rate limiting in a Node.js application using Express:</p><pre>const express = require(&#39;express&#39;);<br>const rateLimiter = require(&#39;./path-to-rate-limiter&#39;); // Import your Rate Limiter API logic here<br><br>const app = express();<br><br>app.use(rateLimiter); // Apply rate limiting middleware<br><br>app.get(&#39;/api/resource&#39;, (req, res) =&gt; {<br>  res.send(&#39;This is a rate-limited resource&#39;);<br>});<br><br>app.listen(3000, () =&gt; {<br>  console.log(&#39;Server is running on port 3000&#39;);<br>});</pre><p>By placing the Rate Limiter API middleware at the top level of your request-handling stack, you ensure that all routes and endpoints benefit from its protection.</p><h4>How to Integrate the Rate Limiter API into Your Codebase</h4><p>Integrating the Rate Limiter API is straightforward. Here’s a step-by-step guide using JavaScript:</p><ol><li><strong>Install the necessary dependencies</strong>: Ensure that your project is set up with the necessary tools to handle HTTP requests and responses.</li><li><strong>Set up the Rate Limiter API</strong>: Import the <a href="https://rapidapi.com/nahrinoda/api/rate-limiter-api">Rate Limiter API</a> and configure it according to your application’s requirements.</li><li><strong>Apply the Rate Limiter API as middleware</strong>: As shown in the example above, place the rate-limiting logic at the entry point of your application to ensure that all incoming requests are managed effectively.</li><li><strong>Test the integration</strong>: Make sure to test the rate-limiting functionality under different scenarios to verify that it behaves as expected.</li></ol><h4>Example: Rate Limiting Purchase Requests in an E-Commerce Store</h4><p>In this scenario, we’ll implement rate limiting in a Next.js API route that handles purchase requests. We’ll then create a test page to simulate multiple purchase attempts and see how the rate limiter prevents abuse by limiting the number of requests.</p><h4>Step 1: Setting Up the Rate Limiter in the Purchase API Route</h4><p>First, create a new API route to handle purchase requests. We’ll implement the Fixed Window Counter algorithm to limit the number of purchase attempts a user can make within a minute. This algorithm tracks the number of requests within a set 1-minute window and allows up to 3 requests during that period. If the request count exceeds this limit, any additional requests are blocked until the window resets.</p><pre>// pages/api/purchase.js<br><br>import rateLimiter from &#39;express-rate-limit&#39;;<br><br>// Initialize the rate limiter middleware<br>const purchaseLimiter = rateLimiter({<br>  windowMs: 60 * 1000, // 1 minute window<br>  max: 3, // limit each IP to 3 purchase requests per windowMs<br>  message: &#39;Too many purchase attempts from this IP, please try again after a minute&#39;,<br>});<br><br>export default async function handler(req, res) {<br>  // Apply the rate limiter<br>  await new Promise((resolve, reject) =&gt; {<br>    purchaseLimiter(req, res, (result) =&gt; {<br>      if (result instanceof Error) return reject(result);<br>      resolve(result);<br>    });<br>  });<br><br>  // Handle the purchase request<br>  if (req.method === &#39;POST&#39;) {<br>    // Logic for processing the purchase would go here<br>    res.status(200).json({ message: &#39;Purchase successful&#39; });<br>  } else {<br>    res.status(405).json({ message: &#39;Method Not Allowed&#39; });<br>  }<br>}</pre><h4>Step 2: Creating a Test Page to Simulate Purchase Attempts</h4><p>Now, let’s create a test page where we simulate multiple purchase attempts by a user. We’ll attempt to make more than 3 purchase requests in quick succession to see how the rate limiter responds.</p><pre>// pages/test-purchase-limiter.js<br><br>import { useState } from &#39;react&#39;;<br><br>export default function TestPurchaseLimiter() {<br>  const [response, setResponse] = useState(null);<br><br>  const testPurchaseLimiter = async () =&gt; {<br>    const responses = [];<br>    for (let i = 0; i &lt; 5; i++) {<br>      const res = await fetch(&#39;/api/purchase&#39;, {<br>        method: &#39;POST&#39;,<br>        headers: {<br>          &#39;Content-Type&#39;: &#39;application/json&#39;,<br>        },<br>        body: JSON.stringify({<br>          productId: &#39;12345&#39;, // Example product ID<br>          quantity: 1,        // Example quantity<br>        }),<br>      });<br>      const data = await res.json();<br>      responses.push(data);<br>    }<br>    setResponse(responses);<br>  };<br><br>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Purchase Rate Limiter Test&lt;/h1&gt;<br>      &lt;button onClick={testPurchaseLimiter}&gt;Test Purchase Rate Limiter&lt;/button&gt;<br>      &lt;pre&gt;{JSON.stringify(response, null, 2)}&lt;/pre&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><h4>Explanation:</h4><ul><li><strong>API Route (</strong><strong>purchase.js)</strong>: This route is responsible for handling purchase requests. We&#39;ve set up a rate limiter that allows a maximum of 3 purchase requests per minute from a single IP address. Any additional requests within that time frame will receive a message indicating that the rate limit has been exceeded.</li><li><strong>Test Page (</strong><strong>test-purchase-limiter.js)</strong>: This page simulates a user trying to make 5 purchase requests in quick succession. The first 3 requests should succeed, and the last 2 should be blocked by the rate limiter.</li></ul><h4>Does the Choice of Algorithm Matter?</h4><p>Absolutely, the choice of rate limiting algorithm matters depending on your specific use case and the behavior you want to enforce. Each algorithm offers distinct advantages and trade-offs, and understanding these can help you choose the right one for your application. Here’s a comparison of the most commonly used rate limiting algorithms:</p><h4>Fixed Window Counter</h4><ul><li><strong>How it works:</strong> This algorithm counts requests in fixed, non-overlapping time windows (e.g., every minute, hour, etc.).</li><li><strong>Best for:</strong> Simpler use cases where it’s sufficient to limit requests within a defined time period, such as limiting purchase attempts.</li><li><strong>Pros:</strong> Easy to implement and understand.</li><li><strong>Cons:</strong> Can be vulnerable to burst traffic at the edge of a window (e.g., a user could make several requests at the end of one window and more at the beginning of the next).</li></ul><h4>Sliding Window Log</h4><ul><li><strong>How it works:</strong> Tracks each request with a timestamp and checks the number of requests within a sliding window of time.</li><li><strong>Best for:</strong> Scenarios where you want a more evenly distributed rate limit that avoids the “edge case” burst issue seen with Fixed Window.</li><li><strong>Pros:</strong> Provides a smoother rate limiting experience by considering requests over a rolling period.</li><li><strong>Cons:</strong> More complex to implement and can be heavier in terms of storage if not managed carefully.</li></ul><h4>Sliding Window Counter</h4><ul><li><strong>How it works:</strong> Similar to Fixed Window, but it splits the window into smaller intervals (buckets) and counts requests across overlapping windows.</li><li><strong>Best for:</strong> Cases where you want to smooth out the effect of rate limiting without needing precise request logging.</li><li><strong>Pros:</strong> Smoother than Fixed Window, with less overhead than Sliding Window Log.</li><li><strong>Cons:</strong> Can be more complex to understand and configure.</li></ul><h4>Token Bucket</h4><ul><li><strong>How it works:</strong> Tokens are added to a bucket at a fixed rate, and each request consumes a token. When the bucket is empty, requests are blocked.</li><li><strong>Best for:</strong> Use cases where you need to allow bursts of traffic but still want to limit the overall rate (e.g., allowing short bursts of purchases while controlling the long-term rate).</li><li><strong>Pros:</strong> Allows controlled bursts of traffic while limiting the overall rate.</li><li><strong>Cons:</strong> More complex to implement.</li></ul><h4>Leaking Bucket</h4><ul><li><strong>How it works:</strong> Similar to Token Bucket, but the bucket leaks tokens at a steady rate, and requests are processed only when tokens are available.</li><li><strong>Best for:</strong> Scenarios where you want a steady rate of processing, with controlled delays if the rate is exceeded.</li><li><strong>Pros:</strong> Smooths out bursts by handling requests at a consistent rate.</li><li><strong>Cons:</strong> Can introduce latency in processing.</li></ul><h4>Conclusion</h4><p>The Rate Limiter API is an indispensable tool for any engineer looking to maintain control over application traffic. Whether you’re building an API, managing a login system, or running an e-commerce platform, integrating a rate limiter can significantly enhance the security, performance, and fairness of your application.</p><p>By placing the Rate Limiter API at the entry point of your API routes, you can effectively manage the flow of traffic and ensure that your application remains stable and secure, even under heavy load. And with the testing approach outlined above, you can confidently deploy your rate limiting strategy, knowing that it will perform as expected in production.</p><p>So, why wait? Start integrating the Rate Limiter API into your Next.js application today, and take control of your application’s traffic like never before!</p><p><em>A special thank you to ChatGPT for lending a hand in editing my blog. 🤖❤️</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f716e36ac296" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Streamlining PR Merges & Slack Notifications on GitHub: A Developer’s Guide ️]]></title>
            <link>https://medium.com/@nahrin_40746/streamlining-pr-merges-slack-notifications-on-github-a-developers-guide-%EF%B8%8F-b6f111df0a49?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/b6f111df0a49</guid>
            <category><![CDATA[github-actions]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[developer-tools]]></category>
            <category><![CDATA[best-practices]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Mon, 05 Feb 2024 03:41:51 GMT</pubDate>
            <atom:updated>2024-02-05T03:57:26.957Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*LMsU7LdWM97SMYFp" /><figcaption>Photo by <a href="https://unsplash.com/@shoeibabhn?utm_source=medium&amp;utm_medium=referral">Shoeib Abolhassani</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In the quest for a more efficient development workflow, managing pull requests (PRs) stands out as a crucial aspect. The goal is simple: avoid the rush of last-minute merges, prevent rebase conflicts, and eliminate the all-too-common “weekend nightmares.” In my search for solutions to streamline this process for my team, I stumbled upon a strategy that not only enhances efficiency but also fosters better communication. I’m excited to share this approach with fellow developers who might find it equally beneficial.</p><h3>The Need for Efficiency and Clarity 🎯</h3><p>Why focus on automating PR merges and Slack notifications? The answer lies in the desire to make our development process as smooth and conflict-free as possible. Late-day or end-of-the-week merges often lead to rushed decisions, overlooked errors, and the dreaded task of resolving conflicts that could have been avoided. By scheduling merges during optimal times and instantly notifying the team, we create a workflow that is both efficient and transparent.</p><p><strong>And here’s the kicker:</strong> there’s no longer any need to manually click on the “Merge pull request” button. When a PR is ready for merging, simply tagging it with the specified label does the trick. For a visual walkthrough on how this is achieved, check out the clip below:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQKq_As6_nWI%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQKq_As6_nWI&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ffad43375509e36d95e9442694f5521/href">https://medium.com/media/3ffad43375509e36d95e9442694f5521/href</a></iframe><p>This clip provides a step-by-step guide on setting up your GitHub Actions to automatically merge PRs once they’re labeled accordingly. It’s a game-changer, transforming the merge process from a manual checkpoint to an automated, smooth transition that keeps the development train moving without unnecessary stops.</p><h3>Implementing the Solution with GitHub Actions</h3><p>GitHub Actions is the cornerstone of our strategy, enabling us to automate workflows directly within our repository based on specific triggers. Here, we focus on two key actions: merging PRs on a defined schedule and sending notifications to Slack.</p><h3>Step 1: Scheduling PR Merges</h3><p>To get started, we create a <a href="https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions">GitHub Action</a> that triggers on a cron schedule. This ensures PRs labeled as ready-to-merge are automatically merged at the most opportune times, sidestepping potential conflicts and hasty decisions.</p><ul><li><strong>Setting Up the Workflow:</strong> In your repository, navigate to .github/workflows and create a new file named merge-on-schedule.yml.</li><li><strong>Defining the Cron Schedule:</strong> Choose when you want the merges to occur, avoiding late hours and weekends. For example, mid-week mornings can be an ideal window:</li></ul><pre>name: Auto Merge on Label<br><br>on:<br>  schedule:<br>    - cron: &#39;0 17 * * 1-4&#39;  # Triggers at 9 AM PT, Monday to Thursday<br><br>permissions:<br>  contents: write<br>  pull-requests: write</pre><ul><li><strong>Configuring the Merge Action:</strong> Utilize the GitHub CLI in the action to merge PRs tagged with ready-to-merge. The action looks something like this:</li></ul><pre>jobs:<br>  auto_merge:<br>    runs-on: ubuntu-latest<br>    steps:<br>      # Checkout the repository<br>      - name: Checkout repository<br>        uses: actions/checkout@v4<br><br>      # Setup Node.js 20<br>      - name: Setup Node.js<br>        uses: actions/setup-node@v3<br>        with:<br>          node-version: &quot;20&quot;<br><br>      # Conditionally run the next steps only if the &quot;ready-to-merge&quot; label was added<br>      - name: Check if &quot;ready-to-merge&quot; label was added<br>        if: ${{ github.event.label.name == &#39;ready-to-merge&#39; }}<br>        run: echo &quot;ready-to-merge label was added to PR.&quot;<br><br>      # Setup GitHub CLI<br>      - name: Setup GitHub CLI<br>        run: |<br>          if ! gh --version; then<br>            sudo apt-get install gh<br>          fi<br><br>      # Authenticate GitHub CLI using GITHUB_TOKEN<br>      - name: Authenticate GitHub CLI<br>        run: echo &quot;${{ secrets.GITHUB_TOKEN }}&quot; | gh auth login --with-token<br><br>      # Merge PRs labeled as &quot;ready-to-merge&quot;<br>      - name: Merge PR labeled as &quot;ready-to-merge&quot;<br>        if: ${{ github.event.label.name == &#39;ready-to-merge&#39; }}<br>        run: |<br>          PR_NUMBER=${{ github.event.pull_request.number }}<br>          PR_URL=${{ github.event.pull_request.html_url }}<br>          gh pr merge &quot;$PR_NUMBER&quot; --merge --admin<br>          echo &quot;Merged PR $PR_NUMBER: $PR_URL&quot;</pre><p>📘 <strong>Note:</strong> This script authenticates the GitHub CLI, finds open PRs with the ready-to-merge label, and merges them by scheduled time.</p><h3>Step 2: Sending Slack Notifications</h3><p>To keep the entire team informed about merged PRs, integrating Slack notifications into the workflow provides instant updates, enhancing team communication.</p><ul><li><strong>Configure a Slack Webhook:</strong> First, create an Incoming Webhook in your Slack workspace and store the URL as a <a href="https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions">GitHub secret</a> named SLACK_WEBHOOK_URL.</li><li><strong>Add the Notification Step:</strong> Modify your merge-on-schedule.yml to include a step that sends a message to Slack once a PR is merged:</li></ul><pre>  - name: Notify Slack<br>    env:<br>      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}<br>    run: |<br>      curl -X POST -H &#39;Content-type: application/json&#39; --data &#39;{&quot;text&quot;:&quot;🚀 A PR was just merged!&quot;}&#39; $SLACK_WEBHOOK_URL</pre><p>This sends a cheerful message to your designated Slack channel whenever a PR merge is successfully completed.</p><h3>Best Practices and Insights 🌟</h3><ul><li><strong>Test Your Workflow:</strong> Ensure everything works as expected by testing your workflow in a controlled environment before full implementation.</li><li><strong>Maintain Security: </strong>Keep your secrets secure and limit access to necessary personnel only.</li><li><strong>Iterate and Improve:</strong> Be open to feedback and ready to adjust your process as needed.</li></ul><h3>Wrapping Up</h3><p>As we wrap up this guide, I want to leave you with the complete merge-on-schedule.ymlfile that brings everything we’ve discussed to life. This file encapsulates the automation of PR merges and Slack notifications, acting as a blueprint for you to customize and implement within your own projects. With this setup, once a PR is ready and labeled, the rest unfolds automatically, saving time and streamlining your team’s workflow.</p><p>Here is the merge-on-schedule.ymlfile in full:</p><pre>name: Automated PR Merges &amp; Slack Notifications<br><br>on:<br>  schedule:<br>    - cron: &#39;0 17 * * 1-4&#39;  # Triggers at 9 AM PT, Monday to Thursday<br><br>permissions:<br>  contents: write<br>  pull-requests: write<br><br>jobs:<br>  auto_merge:<br>    runs-on: ubuntu-latest<br>    steps:<br>      # Checkout the repository<br>      - name: Checkout repository<br>        uses: actions/checkout@v4<br><br>      # Setup Node.js 20<br>      - name: Setup Node.js<br>        uses: actions/setup-node@v3<br>        with:<br>          node-version: &quot;20&quot;<br><br>      # Conditionally run the next steps only if the &quot;ready-to-merge&quot; label was added<br>      - name: Check if &quot;ready-to-merge&quot; label was added<br>        if: ${{ github.event.label.name == &#39;ready-to-merge&#39; }}<br>        run: echo &quot;ready-to-merge label was added to PR.&quot;<br><br>      # Setup GitHub CLI<br>      - name: Setup GitHub CLI<br>        run: |<br>          if ! gh --version; then<br>            sudo apt-get install gh<br>          fi<br><br>      # Authenticate GitHub CLI using GITHUB_TOKEN<br>      - name: Authenticate GitHub CLI<br>        run: echo &quot;${{ secrets.GITHUB_TOKEN }}&quot; | gh auth login --with-token<br><br>      # Merge PRs labeled as &quot;ready-to-merge&quot;<br>      - name: Merge PR labeled as &quot;ready-to-merge&quot;<br>        if: ${{ github.event.label.name == &#39;ready-to-merge&#39; }}<br>        run: |<br>          PR_NUMBER=${{ github.event.pull_request.number }}<br>          PR_URL=${{ github.event.pull_request.html_url }}<br>          gh pr merge &quot;$PR_NUMBER&quot; --merge --admin<br>          echo &quot;Merged PR $PR_NUMBER: $PR_URL&quot;<br><br>      # Notify Slack<br>      - name: Notify Slack<br>        env:<br>          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}<br>        run: |<br>          curl -X POST -H &#39;Content-type: application/json&#39; --data &#39;{&quot;text&quot;:&quot;🚀 A PR has just been merged automatically!&quot;}&#39; $SLACK_WEBHOOK_URL</pre><p>I hope this tutorial helps you as much as it has helped me. If you have questions, insights, or want to share your experience, feel free to reach out. Let’s make development a smoother, more enjoyable journey for everyone involved.</p><p>Happy coding!</p><p><em>A special thank you to ChatGPT for lending a hand in editing and beautifying my blog. 🤖❤️</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b6f111df0a49" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[From Copy-Paste Coder to Code Maestro: My Journey & Quest for Automated Code Excellence ]]></title>
            <link>https://medium.com/@nahrin_40746/from-copy-paste-coder-to-code-maestro-my-journey-quest-for-automated-code-excellence-bea0152b2949?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/bea0152b2949</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[best-practices]]></category>
            <category><![CDATA[peer-review]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Wed, 01 Nov 2023 06:20:35 GMT</pubDate>
            <atom:updated>2023-11-01T20:26:30.632Z</atom:updated>
            <content:encoded><![CDATA[<p>How to avoid the ‘We Don’t Code Like This’ moments in a code review…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9wK79ofsXYrTnJHn" /><figcaption>Photo by <a href="https://unsplash.com/@anniespratt?utm_source=medium&amp;utm_medium=referral">Annie Spratt</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h4>A Relatable Start</h4><p>If you had met me four years ago and asked me to pen down a line of code from scratch, I’d probably be sneaking a peek at <a href="https://developer.mozilla.org/en-US/">MDN</a> or nervously typing away on <a href="https://stackoverflow.com/">Stack Overflow</a>. The greenness was evident, the confidence wobbly. Every time I tried to fit into the existing codebase, it felt like trying on shoes several sizes too big.</p><p>During a peer review, when a more seasoned engineer pointed out my mistakes, it felt like a splash of cold water. “This is not how we code” they’d say. That night, nestled in the comfort of my home, a question haunted me — why did I transition from <a href="https://medium.com/@nahrin_40746/kid-youll-move-mountains-an-architect-s-journey-into-software-engineering-bc449eafd67">architecture to software engineering</a>? Did I want to be an engineer who just coded, or did I want to be a coder who engineered? I chose the latter, not out of defiance, but out of purpose. I wanted to be the one solving problems, not just typing them out.</p><h4>Embracing Creativity</h4><p>For those who know the whimsical twists and turns of my personality, they’ll affirm that anything devoid of creativity feels mundane to me. Borrowing code from Stack Overflow might save the day with its quick fixes, but let’s face it, it’s not the panacea for all coding ailments. Sure, I could grab a snippet from the web, slap it onto my editor, and make it run. It might save a moment, but at what cost? Efficiency? Scalability? That’s the daily puzzle that sparks my passion and keeps me on my toes each sunrise.</p><h4>From Student to Teacher</h4><p>Fast forward a few years, and I’m the one behind the reviewing screen. And boy, do I feel the weight of those four words now more than ever! As I scan through merge requests, I often catch myself thinking, “Is this how we want to code?” While I might be more diplomatic in my feedback now, the sentiment remains.</p><p>So, here’s the engineering conundrum: How do I forge a consistent code ethos across a team? We’ve got linters in place, making our code look pretty and standardized. We’ve integrated unit tests, ensuring our functions do what they’re supposed to. TypeScript’s static typing has been a godsend, catching errors way before runtime. But what about the logic? The architecture? How do I enforce <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> principles or nudge developers away from nesting ternaries like there’s no tomorrow? 🤖</p><h4>Let’s Dive Deeper!</h4><p>Let’s get curious, do you remember the game “Tic Tac Toe”? Yeah, that classic 3x3 grid game. While this might seem like a simple code challenge for many, the elegance is in the implementation. Let me take you through a code review session:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F8Dwq0ctLzCc%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D8Dwq0ctLzCc&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F8Dwq0ctLzCc%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/ef51c8dce3256350f52a23ca57d779f9/href">https://medium.com/media/ef51c8dce3256350f52a23ca57d779f9/href</a></iframe><h4>The Controller Grid</h4><p>The Controller Grid is responsible for the direction buttons: up, down, left, and right. This component is mainly responsible for allowing the user to select a direction and then update the active cell accordingly.</p><h4>The Main Grid</h4><p>The Main Grid. This is where the active cell gets highlighted based on the user’s actions. Each cell in this grid checks if it’s the currently active cell and changes its background color accordingly.</p><h4>The Game Container</h4><p>The Game Container acts as the orchestrator of our game. It manages the state of our game, particularly the current active cell, and also handles the arrow button clicks. Notice the use of the useState hook for state management. It keeps track of the current active cell.</p><pre>&#39;use client&#39;;<br><br>import { useState } from &#39;react&#39;;<br>import MainGrid from &#39;../MainGrid&#39;;<br>import ControllerGrid from &#39;../ControllerGrid&#39;;<br><br>const GameContainer = () =&gt; {<br>  const [activeRow, setActiveRow] = useState(0);<br>  const [activeCol, setActiveCol] = useState(0);<br><br>  const moveActiveCell = (direction: &#39;up&#39; | &#39;down&#39; | &#39;left&#39; | &#39;right&#39;) =&gt; {<br>    switch (direction) {<br>      case &#39;up&#39;:<br>        setActiveRow(Math.max(0, activeRow - 1));<br>        break;<br>      case &#39;down&#39;:<br>        setActiveRow(Math.min(2, activeRow + 1));<br>        break;<br>      case &#39;left&#39;:<br>        setActiveCol(Math.max(0, activeCol - 1));<br>        break;<br>      case &#39;right&#39;:<br>        setActiveCol(Math.min(2, activeCol + 1));<br>        break;<br>    }<br>  };<br><br>  const isActive1 = activeRow === 0 &amp;&amp; activeCol === 0;<br>  const isActive2 = activeRow === 0 &amp;&amp; activeCol === 1;<br>  const isActive3 = activeRow === 0 &amp;&amp; activeCol === 2;<br>  const isActive4 = activeRow === 1 &amp;&amp; activeCol === 0;<br>  const isActive5 = activeRow === 1 &amp;&amp; activeCol === 1;<br>  const isActive6 = activeRow === 1 &amp;&amp; activeCol === 2;<br>  const isActive7 = activeRow === 2 &amp;&amp; activeCol === 0;<br>  const isActive8 = activeRow === 2 &amp;&amp; activeCol === 1;<br>  const isActive9 = activeRow === 2 &amp;&amp; activeCol === 2;<br><br>  return (<br>    &lt;div className=&quot;min-h-screen flex flex-row items-center justify-center&quot;&gt;<br>      {/* MainGrid Start */}<br>      &lt;div className=&quot;bg-yellow-300 w-96 h-96 flex flex-wrap mr-10&quot;&gt;<br>        &lt;div id=&#39;1&#39; data-testid=&quot;cell-1&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive1 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;2&#39; data-testid=&quot;cell-2&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive2 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;3&#39; data-testid=&quot;cell-3&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive3 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;4&#39; data-testid=&quot;cell-4&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive4 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;5&#39; data-testid=&quot;cell-5&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive5 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;6&#39; data-testid=&quot;cell-6&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive6 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;7&#39; data-testid=&quot;cell-7&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive7 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;8&#39; data-testid=&quot;cell-8&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive8 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>        &lt;div id=&#39;9&#39; data-testid=&quot;cell-9&quot; className={`w-1/3 h-1/3 border border-slate-700 ${isActive9 ? &#39;bg-pink-300&#39; : &#39;&#39;}`} /&gt;<br>      &lt;/div&gt;<br>      {/* MainGrid End */}<br><br>      {/* ControllerGrid Start */}<br>      &lt;div className=&quot;bg-gray-300 w-48 h-48 flex flex-wrap&quot;&gt;<br>        &lt;div className=&quot;w-1/3 h-1/3&quot;&gt;&lt;/div&gt;<br>        &lt;div className=&quot;w-1/3 h-1/3 flex justify-center items-center&quot;&gt;<br>          &lt;button data-testid=&quot;up-button&quot; onClick={() =&gt; moveActiveCell(&#39;up&#39;)}&gt;⬆&lt;/button&gt;<br>        &lt;/div&gt;<br>        &lt;div className=&quot;w-1/3 h-1/3&quot;&gt;&lt;/div&gt;<br><br>        &lt;div className=&quot;w-1/3 h-1/3 flex justify-center items-center&quot;&gt;<br>          &lt;button data-testid=&quot;left-button&quot; onClick={() =&gt; moveActiveCell(&#39;left&#39;)}&gt;⬅ &lt;/button&gt;<br>        &lt;/div&gt;<br>        &lt;div className=&quot;w-1/3 h-1/3&quot;&gt;&lt;/div&gt;<br>        &lt;div className=&quot;w-1/3 h-1/3 flex justify-center items-center&quot;&gt;<br>          &lt;button data-testid=&quot;right-button&quot; onClick={() =&gt; moveActiveCell(&#39;right&#39;)} className=&#39;rotate-180&#39;&gt;⬅&lt;/button&gt;<br>        &lt;/div&gt;<br><br>        &lt;div className=&quot;w-1/3 h-1/3&quot;&gt;&lt;/div&gt;<br>        &lt;div className=&quot;w-1/3 h-1/3 flex justify-center items-center&quot;&gt;<br>          &lt;button data-testid=&quot;down-button&quot; onClick={() =&gt; moveActiveCell(&#39;down&#39;)}&gt;⬇&lt;/button&gt;<br>        &lt;/div&gt;<br>        &lt;div className=&quot;w-1/3 h-1/3&quot;&gt;&lt;/div&gt;<br>      &lt;/div&gt;<br>      {/* ControllerGrid End */}<br>    &lt;/div&gt;<br>  );<br>};<br><br>export default GameContainer;</pre><p>One might ask, why use such a brute-force method? Why not make it more efficient or robust? And those are valid questions. But remember, every engineer starts somewhere. Over time, as we encounter more challenges, learn from our mistakes, and absorb knowledge from others, our solutions become more refined.</p><h4>The Quest Continues</h4><p>However, there’s always room for improvement. What if there’s a tool out there that could scan through this code and suggest optimizations, logic refinements, and best practices? A tool that acts like that seasoned developer, who once told me, “this is not how we code.”</p><p>Curious about the complete picture? Dive into the entire codebase on my <a href="https://github.com/nahrinoda/tic-tac-toe">GitHub repository</a>.</p><h4>The Next Step: A Challenge for Us All</h4><p>In this digital age, when machine learning and automation are redefining the way we operate, why not envision a solution for code reviews too? What if we could bridge the gap between a newbie’s enthusiasm and a maestro’s wisdom? We’ve automated CI/CD pipelines, we’ve automated testing — so why not automated mentoring?</p><p>But here’s the open-ended challenge to my fellow engineers: If such a tool were to be created, what features would make it both educational and efficient? How do we ensure that while automating the review process, we’re not just enforcing rules, but fostering understanding? How do we differentiate between the strict syntax of a linter and the nuanced mentorship of a seasoned engineer? 🤔</p><p>I’m on a quest to answer these questions and to possibly build a solution. But, I need diverse insights. So, I’m tossing this challenge back to the community. Share your thoughts, your ideas, and your criticisms. Let’s engineer a tool that not only corrects but educates. After all, as we’ve seen with my journey, it’s not just about writing code — it’s about writing the future.</p><p>Your insights could be the catalyst for the next big leap in code excellence. So, are you up for the challenge? 🔍🚀</p><p><em>A special thank you to ChatGPT for lending a hand in editing and beautifying my blog. 🤖❤️</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bea0152b2949" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[“Kid, You’ll Move Mountains”: An Architect’s Journey into Software Engineering]]></title>
            <link>https://medium.com/@nahrin_40746/kid-youll-move-mountains-an-architect-s-journey-into-software-engineering-bc449eafd67?source=rss-246c7bb9e829------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc449eafd67</guid>
            <category><![CDATA[entrepreneurship]]></category>
            <category><![CDATA[career-transitions]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[personal-development]]></category>
            <category><![CDATA[writing]]></category>
            <dc:creator><![CDATA[Nahrin]]></dc:creator>
            <pubDate>Sat, 15 Jul 2023 04:35:36 GMT</pubDate>
            <atom:updated>2023-07-15T04:35:36.236Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*d0wZdx9_nnj0HtDh" /><figcaption>Photo by <a href="https://unsplash.com/@alicemoore?utm_source=medium&amp;utm_medium=referral">Elice Moore</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In this ever-evolving world, being unique is not about fitting in. This is the story of my voyage from the concrete world of architectural design to the limitless expanse of software engineering, driven by curiosity and a conviction that being unique is about standing out. With Albert Einstein’s words, ‘I have no special talent. I am only passionately curious,’ I set off on a path less traveled, teeming with unknowns, but with a steadfast determination to change the world.</p><h4>Chapter 1: The Start of Something New</h4><p>As a child, I was fascinated by the transformative power of architecture. The idea of converting an abstract thought into a tangible reality, brick by brick, was captivating. But as I grew older, the dynamic world of technology started to enthrall me. My curiosity first sparked when I wondered, “how do credit cards work?” Soon, I found myself flooded with queries about building applications and was irresistibly drawn to the limitless potential and intriguing challenges of software engineering.</p><p>Transitioning from blueprints to lines of code was akin to learning a new language — intimidating, challenging, yet incredibly fulfilling. I had to decode complex algorithms, traverse through an unfamiliar industry, and embrace the constant feeling of being on the edge. Yet, as I dug deeper, I discovered parallels between my old and new worlds. Both were about design, problem-solving, and turning concepts into reality. In architecture, you use lines and angles, while in software, you use code — like solving a complex mathematical equation.</p><h4>Chapter 2: Reengineering My Skills</h4><p>As I dove deeper into the world of software engineering, Kahlil Gibran’s words, ‘…Do not accept half a solution. Do not believe half truths. Do not dream half a dream…’ became my mantra. I began by dissecting my CV, trying to find skills from my architectural background that could transfer over to my new domain.</p><p>Math, project management, spatial reasoning, meticulous attention to detail, negotiation, and problem-solving were skills I honed as an architect and were incredibly relevant in my new field. This newfound understanding bolstered my confidence and highlighted the interconnectedness of these two seemingly disparate domains. I felt like an explorer charting a new course, ready to prove my mettle in software engineering, without the conventional experience that comes with it.</p><h4>Chapter 3: Joining a Startup and the Lessons I Learned</h4><p>Joining a startup was like stepping into a high-speed roller coaster ride. Our small team of twenty blossomed into a bustling company of a hundred. Here, I learned that growth often means stepping out of your comfort zone, embracing change, and making decisions even with incomplete information.</p><p>The tech industry, where innovations evolve every 18 months, doesn’t permit a slow-down. It’s about keeping up with trends, constantly learning, and expanding your skillset.</p><h4>Chapter 4: The last chapter of my beginning</h4><p>As I look back, I realize my journey from crafting architectural designs to coding software applications was more than a mere career switch. It was a transformative expedition that expanded my understanding of ‘architecture’ — from the physical to the virtual, from the seen to the unseen.</p><p>If you’re contemplating a similar shift or finding your way in the fast-paced world of a startup, remember Gibran’s words. It’s not about switching worlds; it’s about weaving together lessons from both domains to create a unique tapestry that sets you apart. Yes, this journey is a roller-coaster ride filled with anxiety and high-pressure moments, but just as pressure creates diamonds, these challenges have shaped me into the multifaceted professional I am today.</p><p>Today, I wear many hats. I can design a house, set up your navigation system, and connect it all with your mobile application — a one-stop solution. This journey has made me unstoppable, and now, the world is truly my oyster.”</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bc449eafd67" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>