Inspiration
Every prepaid mobile user in Nepal has the same story: you buy a data pack, get an "80% used" warning SMS, and then...silence. No warning. No "pack expired" message on time. Just a surprise: your main balance has been drained from Rs 50 to Rs 0.03. You can't call, can't text, can't recharge. You're stranded. I was stuck outside the gate of my PG in the same situation a month ago.
I was inspired by airtelblack.com from India. It is a viral site that turned individual telecom frustrations into a collective public record aka public wall of shame. Nepal has the same problem with NTC and NCELL, but nobody's collecting the receipts. The new government regulation asks these companies to improve, but they'll never promote transparency the way they promote "1 GB ma 1 GB data free" offers. So we built Kati Lutne, a place where the stories speak for themselves.
What it does
Kati Lutne ("How much more will you loot?") is a public wall of shame for prepaid telecom users in Nepal. Users sign in with a passwordless magic link, write their story about data deductions or balance drainage, and submit it. The story is verified in real-time by Google's Gemini AI, which checks if it's a relevant telecom complaint (not spam, harassment, or personal data). Verified stories are published instantly on the Wall of Shame. Rejected submissions are blocked from the database entirely. Borderline stories are saved for manual review.
How I built it
- Next.js (App Router): server components for the wall pages, client components for auth and submission
- Supabase: Postgres database with Row-Level Security for storing complaints, and magic-link email authentication (no passwords)
- Google Gemini API (gemini-flash-latest): AI verification that classifies complaints into categories (SilentDeduction, DataRemainingUnknown, StrandedNoCall) and returns a publish/pending/reject verdict with a confidence score
- Tailwind CSS: psychology-driven design with a warm parchment background, red accent for urgency, and editorial serif typography for the brand
- Vercel: deployment target for instant global access
Challenges I ran into
- Gemini model deprecation: The gemini-1.5-flash models were retired without warning, returning 404 errors. I had to query the live model list API to discover that gemini-flash-latest (resolving to gemini-3-flash-preview) was the working model, and built a fallback chain with retry logic for 429/503 errors.
- Thinking tokens eating the budget: The new Gemini model uses internal "thinking" tokens that counted against maxOutputTokens. A 240-token limit meant the actual JSON response was truncated. We fixed it by disabling thinking (thinkingBudget: 0) and increasing the output limit.
- Supabase RLS blocking rejected inserts: The Row-Level Security policy correctly prevented rejected complaints from being saved, but the app was trying to insert them anyway. We restructured the flow so rejected submissions never touch the database.
- Next.js hydration issues: useSearchParams() in the auth callback caused server-side rendering errors. I had to split it into a server component with a Suspense boundary wrapping the client logic.
Accomplishments that I'm proud of
I tried a lot of new things today: Gemini API, Supabase auth and database, and also good UI generation with Cursor. Most importantly, I was thinking of this problem for long. Today I built it.
What I learned
Major thing I learned today is optimization. All kinds of optimizations. Such as the token optimization, time optimization for the hackahton, and the UI optimization as well.
What's next for Kati Lutne
- Screenshot uploads: let users attach screenshots of their SMS warnings and balance statements as visual proof alongside their stories
- Nepali language AI: fine-tune the verification to better understand complaints written in Devanagari and mixed Nepali-English
- Share-to-social: one-click sharing of wall stories to Twitter/X and Facebook to amplify pressure on providers
- Figure out a way to make these companies responsible when we subscribe data package after the electricity blackout and they don't work when power is out. That's bad... kati luteko
Built With
- gemini
- next
- supabase
Log in or sign up for Devpost to join the conversation.