FraudLens — Project Story

Inspiration

India loses more than ₹1,500 crore a year to cyber fraud, and a huge share of it targets people who've never been taught what a scam actually looks like from the inside — fake KYC-block SMS, "bro I'm stuck at the airport, send money" WhatsApp messages, UPI payment traps, and "digital arrest" phone calls pretending to be the CBI. Every awareness poster and news article describes these scams after the fact. Almost nothing lets you live through one — safely, with no real money and no real risk — before you meet it for real.

(This is the spot to drop your own line about what actually made you sit down and build this — a message you saw, a relative who almost fell for something, a friend who got scammed. That personal beat is what Devpost judges remember most, so worth adding in your own words.)

That gap — awareness content vs. simulated experience — is what FraudLens set out to close.

What it does

FraudLens is a full-stack, gamified scam-defense trainer with two ways to learn:

  • Immersive Simulator — step inside pixel-accurate replicas of WhatsApp, Instagram DMs, an iPhone call screen, and SMS notifications. Scenarios run as branching dialogue trees with typing indicators and realistic message delays (500ms–5000ms), and phone-call scenarios use the browser's Web Speech API to generate a real Indian-English scammer voice — no paid API keys involved. Every choice you make (send money vs. verify, answer vs. hang up) leads somewhere different, followed by a debrief that breaks down exactly which red flags were present.
  • Classic Verdict Mode — a faster loop through 24 real-pattern case files across six channels (SMS, WhatsApp, Email, Website, Call, UPI), where you stamp each one SCAM or LEGIT and get instant feedback.
  • Message Scanner — paste in any real message you received and a 17-rule detection engine flags urgency pressure, OTP/PIN requests, brand-impersonation links, leetspeak obfuscation, blackmail language, and more, with a severity-weighted risk score.
  • Academy, Dashboard, and Leaderboard — eight short lessons (OTP discipline, phishing links, UPI safety, post-scam recovery), an XP/rank/badge progression system, and a global leaderboard to make the whole thing sticky rather than a one-time read.

How we built it

The stack is Next.js 16 (App Router) with React 19 on the frontend, TypeScript throughout, and Tailwind CSS 4 for the cyberpunk-glassmorphism visual language. The backend is PostgreSQL via Drizzle ORM, exposed through dedicated API routes for cases, scans, verdicts, lesson progress, leaderboard rankings, and simulation sessions — six tables in total (learners, scams, attempts, lesson_progress, sim_scenarios, sim_sessions), with learners fanning out into the other five.

The message scanner is the technical core, so it's worth being precise about how it actually scores a message. Each of the 17 rules is tagged with a severity, each severity carries a fixed weight, and the final score is the weighted sum of every rule that fires, capped at 100:

$$\text{score}(m) = \min\left(100,\ \sum_{f \in \text{flags}(m)} w(\text{severity}(f))\right)$$

$$w(\text{critical}) = 28,\quad w(\text{high}) = 18,\quad w(\text{medium}) = 10,\quad w(\text{low}) = 5$$

A message crossing 40 is labeled high risk, 18–39 is flagged suspicious, and anything below reads as low risk — with a separate pass that catches a subtler pattern: a message naming a trusted brand (SBI, HDFC, UIDAI, PhonePe, etc.) while linking to a domain that has nothing to do with that brand, which alone is treated as a critical flag.

Challenges we ran into

The simulator logic and scanner rules came together fairly smoothly — the harder problems showed up at the production-deployment stage, which is worth being honest about since it's still fresh:

  • Static generation vs. a live database. Every route that touches Postgres (the scanner, leaderboard, case fetcher, verdict endpoint) had to be explicitly marked export const dynamic = "force-dynamic", or Next.js would try to statically render pages that need a live DB connection at build time — which fails, because there's no database available during the build step itself.
  • Local-only config leaking into "production-ready" files. The Drizzle config shipped with a hardcoded postgresql://postgres:postgres@127.0.0.1:5432/app_db string — perfectly fine for local development, completely unusable on a serverless host, since 127.0.0.1 on Vercel's servers just points back at Vercel's own machine, not any real database.
  • Reproducible builds. The repo didn't ship a lockfile, which is risky when your dependency versions are this current (Next 16.2.6, React 19.2.6) — resolving 544 packages fresh on every deploy invites version drift between builds.
  • Getting a real Postgres instance in front of the app. Vercel retired its native Postgres product in favor of Marketplace integrations (Neon being the standard path now), so "add a database" is a Marketplace install-and-redeploy step rather than a copy-pasted connection string.

Accomplishments that we're proud of

Shipping something that's actually complete, not a demo shell: eight full pages, seven-plus API routes, 24 hand-written case files, six branching simulation scenarios with full debriefs, eight academy lessons, and a six-level/eight-badge achievement system — all backed by a real relational schema instead of hardcoded JSON. And doing the audio/voice simulation entirely with browser-native Web Speech and Web Audio APIs, so the whole experience runs with zero paid third-party API keys.

What we learned

Detection-rule tuning is a genuine design problem, not just a coding one — a scanner that's too aggressive trains people to ignore warnings, and one that's too lenient misses real danger, so getting the severity weights and thresholds right mattered as much as writing the regexes. On the infrastructure side: the assumptions that hold on localhost (a database that's just there, unlimited build time, no cold starts) quietly stop holding the moment an app goes serverless, and catching that early — env vars, dynamic rendering, lockfiles — is cheaper than debugging it after a broken deploy.

What's next for FraudLens

  • Hindi and Hinglish scam detection — most real scam messages in India arrive in Hindi or code-mixed Hinglish, not English, so the 17-rule engine needs a parallel rule set for that.
  • More channels and scenario variety — voice-note scams, fake job-offer PDFs, and QR-code-in-person traps aren't covered yet.
  • A lightweight classroom/school mode — bulk leaderboard views and a teacher dashboard so a school (or a Census/civic-tech-style rollout) could run FraudLens as an actual awareness session, not just an individual tool.
  • Community-submitted patterns — a moderated pipeline for people to submit real scam messages they received, growing the case database beyond the initial 24.

Built With

Share this project:

Updates