Repairwala: a voice-first job book for small repair shops, with local AI A developer built Repairwala, a Hindi-first Android app that lets small repair-shop owners record jobs by speaking them aloud, with speech recognition (whisper.cpp) and a Gemma 4 model running in Ollama on an on-premise shop laptop rather than in the cloud. The Flutter phone app captures photos of machines and rating plates and sends audio over the shop's Wi-Fi to a Node.js/Fastify server backed by node:sqlite, which fills in job cards and generates a UPI QR code; only the customer's "it's ready" WhatsApp message and Hindi voice note leave the shop, via ElevenLabs. The developer, whose father runs an electrical repair shop, said the app is aimed at one-person shops in small-town India that currently keep no records, with a proposed price of a one-time setup fee or ₹99 a month. This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 2 https://dev.to/challenges/hacktoberfest-week2-2026-10-12 My father is an electrician. He runs a repair shop from our home, and people bring him whatever has stopped working: water pumps, submersibles, ceiling fans, coolers, ACs, cutters, mixer-grinders, induction cooktops, room heaters, kettles. There are two kinds of jobs: Nothing else gets written down. No slip for the customer, no photo of the machine, no history. When a pump comes back three months later, the only record is his memory. When someone says "this isn't my motor" or "you said 1,200, not 1,500" , it's his word against theirs. Repairwala रिपेयरवाला is the record book the shop never had. It's an Android app in Hindi, with big buttons, built for one user: my father. Type a customer's phone number and their earlier jobs show up: same pump, what was replaced last time, what they paid. | A job card | Filling it in | Dark mode | |---|---|---| The screenshots use made-up customers. Not my father first. The person who pays is every repair shop like his. Small towns and villages in India are full of one-person shops: electricians, motor-winding shops, mobile repairers, tailors, cycle mechanics. They take in other people's things every day, and almost none of them keep records. What they would pay for is fewer arguments and more repeat customers: The running cost matters as much as the price. A shop that charges ₹150 to change a fan capacitor can't pay per-job fees to a cloud speech API and a cloud LLM. Here the speech recognition and the model run on a laptop the shop already owns, so the only per-job cost is the ElevenLabs voice note for the "it's ready" message: a few seconds of audio. My guess at a price is a small one-time setup fee, or ₹99 a month. The next step is a few weeks of real jobs at his counter, then showing it to the shops nearby. 97 seconds: the job list, saying a job in Hindi, the job card and the rating plate, and the "it's fixed" WhatsApp message with its voice note. Made-up customers and a ₹1 test amount. The record book my father's repair shop never had. People bring water pumps, submersibles, fans, coolers, mixer-grinders and heaters to his electrical repair shop at home. Until now nothing was written down: no slip, no photo, no history. Repairwala is a Hindi-first Android app for him: he takes a photo of the machine, says the job out loud in Hindi , and a local open-weight model fills in the job card. When it's fixed, the customer gets a WhatsApp message with a Hindi voice note and a UPI QR for the exact amount. Speech-to-text whisper.cpp and the language model Gemma 4 in Ollama run on the shop laptop , so customers' names, numbers and photos never leave the shop. Built for DEV's Hacktoberfest Open-Source AI Challenge, Week 2: Side Hustle https://dev.to/challenges/hacktoberfest-week2-2026-10-12 . ▶ Watch the 97-second demo video https://youtu.be/9ohNuEXWs7g A Flutter app for the phone, and a small Node.js server for the shop laptop: Fastify, built-in node:sqlite , whisper.cpp, Gemma 4 in Ollama, ElevenLabs and a UPI QR generator. There's no account and no cloud database. A 7.5B model and Whisper won't run well on a ₹15,000 Android phone. They do run on the i7 laptop already in the house, with no GPU. So the phone app is the eyes and ears, and the laptop on the shop Wi-Fi does the heavy work: Shop phone Flutter, Hindi ── shop Wi-Fi ── Shop laptop Node server camera: machine, plate, customer SQLite + photos folder mic: says the job in Hindi ────────── whisper.cpp Hindi speech - text job list, history by phone Gemma 4 in Ollama text - job card, "repaired" - WhatsApp plate photo - details UPI QR with the exact amount only the message - ElevenLabs Hindi voice note The app records 16 kHz mono WAV and sends it to a whisper-server from whisper.cpp , running the large-v3-turbo model quantised to 5 bits 574 MB . For my test sentences, a 10-second clip took about 12 seconds and came back nearly word-perfect, in Devanagari: रामेश्वर महतो, पिठोरिया से, सबमर्सिबल मोटर नहीं चल रहा, वाइंडिंग जल गई है, पंदरह सौ लगेगा, परसों ले जाना. The only differences were spellings: पंदरह for पंद्रह, कैपिसिटर for कैपेसिटर, रुपए for रुपये. English shop words like winding and capacitor come out in Devanagari, the way he says them. One honest failure: Whisper invents words for silence. Three seconds of nothing came back as "प्रफ्राइब प्रफ्राइब" . So the app always shows what it heard, under "आपने बोला सुधार सकते हैं " "you said; you can correct it" , with a button to understand it again. One rule shaped the whole design: the model understands, plain code decides. Gemma 4 gemma4:e4b in Ollama gets the transcript and a JSON schema. It fills in the name, village, machine type, complaint, fault and amount, and the pickup words exactly as said . It never sees a calendar. The server turns आज today , कल tomorrow , परसों day after tomorrow , बुधवार को on Wednesday or 25 तारीख़ को on the 25th into a date itself. That split matters for Hindi. कल means both yesterday and tomorrow, but a pickup date is always in the future, so in this app it's always tomorrow. The prompt also teaches the number words a shop actually uses: डेढ़ सौ is 150, ढाई सौ is 250, साढ़े तीन सौ is 350, पंद्रह सौ is 1,500. Code then rejects any amount outside ₹10 to ₹2,00,000. I tested it on nine sentences, including one with no amount, one with Devanagari digits ३५० रुपये , one with a weekday and one with a date. All nine came out right, in 5 to 25 seconds each. Every pump and motor has a metal plate with its brand, model, power and serial number. Copying that by hand is exactly what my father would never do, so the same Gemma model reads it from the photo. The prompt is strict: copy only what's printed on the plate, and return nothing rather than guess a brand from how the machine looks. On a Kirloskar pump photographed at the shop, it read KIRLOSKAR BROTHERS LIMITED, CPBS 73624-V, 750 W / 1.0 HP . It takes 40 to 60 seconds on the CPU, so it runs in the background while he keeps talking. The details appear when they're ready, and anything he typed himself is never overwritten. When he taps ठीक हो गया repaired and enters the final amount, the server: eleven multilingual v2 , a warm Indian Hindi voice to say a shorter version. Amounts are spoken in Hindi words, so ₹1,450 is read as upi://pay?...&am=1450.00 , so the customer scans it from the gallery in GPay or PhonePe and doesn't type anything. Then the app hands all three to WhatsApp and opens the customer's own chat, even if the number isn't saved in his contacts. Fully automatic sending would need the WhatsApp Business API, Meta verification and approved templates. One tap on Send is fine. NoSuchMethodError inside shared preferences . That plugin now calls its Kotlin code from Dart through JNI, and R8 had renamed kotlin.coroutines.Continuation , which appears in that method's signature. Keeping the plugin classes wasn't enough; turning off obfuscation -dontobfuscate , with shrinking still on fixed it. If I hadn't installed the release build on the phone, the first GitHub release would have been broken. .env OLLAMA MODEL , VISION MODEL , and so is changing the Whisper size or the voice. Any other shop can copy the repo and run it on their own laptop. I built this with Claude Code as my pair: from the first message describing my father's shop, through the server and the app, testing on his phone over USB, and the bugs above. At runtime the app uses no closed-model AI. Whisper and Gemma run locally; only the voice note uses ElevenLabs. The session is curated: small style tweaks and housekeeping turns are removed, and secrets, real phone numbers and customer details are replaced. my father is an electrician. people come to our home shop with their faulty - water pumps, submersible, fans, ac, cooler, electric cutters, mixy grinders , Induction Cooktops, room heaters, Electric Kettles, and others. - they explain the problem to my father and if repairable it gets repaired within that day, they pay and take the repaired one. == problem: here we do not keep any track and history - if not repairable, my father checks and inspects the machine and tells them the expected problem and expected repair cost, expected date of take away. we take the name, phone no, village name from them. problem: we should take photo of machine, photo of customer. I want to create this week project based on this one. is it right $ {"command": "cd \"~/.claude/projects/c--Users-rahul-Desktop-Hacktober-Fest-side-hustle/72aaa0c8-0b07-4917-8c75-bcdc7537a6fb/tool-results\" && PYTHONIOENCODING=utf-8 python -c \"\nimport json,glob\nids={}\nfor f in glob.glob 'mcp-devrelay-gateway-get articles- .txt' :\n for x in json.loads open f,encoding='utf-8' .read 'Ok' : ids x 'id' =x\nks= 'repair','electrician','job card','job sheet','technician','mechanic','service centre','service center','workshop' \nfor x in ids.values :\n t= … 477 more characters trimmed I Built a Private AI Spreadsheet Repair Tool That Runs on Windows, No Cloud API Required | https://dev.to/shade555/i-built-a-private-ai-spreadsheet-repair-tool-that-runs-on-windows-no-cloud-api-required-29ke hits 'repair' Kintsugi : A Side Hustle Repair Assistant for Technicians Who Can't Afford a Wrong Answer | https://dev.to/lakshay deol 3f21b00bccca/kintsugi-a-side-hustle-repair-assistant-for-technicians-who-cant-afford-a-wrong-answer-g39 hits 'repair', 'technician' FlipCheck: Helping an Electronics Repairer Find Deals with Local AI | https://dev.to/quangvinhlee/flipcheck-helping-an-electronics-repairer-find-deals-with-local-ai-23o6 hits 'repair' … 271 more characters trimmed $ {"command": "cd \"~/.claude/projects/c--Users-rahul-Desktop-Hacktober-Fest-side-hustle/72aaa0c8-0b07-4917-8c75-bcdc7537a6fb/tool-results\" && PYTHONIOENCODING=utf-8 python -c \"\nimport json,glob\nids={}\nfor f in glob.glob 'mcp-devrelay-gateway-get articles- .txt' :\n for x in json.loads open f,encoding='utf-8' .read 'Ok' : ids x 'id' =x\nfor x in ids.values :\n if any k in x 'title' for k in 'Kintsugi','ReTrace','FlipCheck' :\n print ' ',x 'title' ; print x.get 'descript … 134 more characters trimmed Kintsugi : A Side Hustle Repair Assistant for Technicians Who Can't Afford a Wrong Answer This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle ... '' FlipCheck: Helping an Electronics Repairer Find Deals with Local AI This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle. ... '' I Built ReTrace to Help Generator Technicians Remember Every Repair This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle ... '' Shell cwd was reset to ~\Desktop\Hacktober Fest\side-hustle { "query": "select:mcp devrelay-gateway get article by path", "max results": 1 } { "path": "/sniperchief/i-built-retrace-to-help-generator-technicians-remember-every-repair-1aeh" } {"Ok":{"id":4871486,"title":"I Built ReTrace to Help Generator Technicians Remember Every Repair","description":"This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle ...","tag list": "devchallenge","hf26challenge" ,"user":{"name":"Samuel Aniodo","username":"sniperchief"},"body markdown":" This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle https://dev.to/challenges/hacktoberfest-week2-2026-10-12 \n\n Image description https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/hawm9damhc8nxriaceun.png \n\n What I Built\n\nI built ReTrace , a voice-first repair-history assistant for independent … 8331 more characters trimmed { "path": "/lakshay deol 3f21b00bccca/kintsugi-a-side-hustle-repair-assistant-for-technicians-who-cant-afford-a-wrong-answer-g39" } {"Ok":{"id":4869131,"title":"Kintsugi : A Side Hustle Repair Assistant for Technicians Who Can't Afford a Wrong Answer","description":"This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle ...","tag list": "devchallenge","hf26challenge","repair","electrical" ,"user":{"name":"Lakshay Deol","username":"lakshay deol 3f21b00bccca"},"body markdown":" This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle https://dev.to/challenges/hacktoberfest-week2-2026-10-12 \n\n What I Built\n Kintsugi 金継ぎ is a manual-grounded AI appliance repair assistant for technicians, repair shops, and repair-café volunteers. A technician … 6876 more characters trimmed Yes, build this. Of everything we've looked at, it's the strongest option. Why it's strong: - A real user today. Your father's shop has real customers and real machines. For the first-user bonus, he can use it on real jobs tomorrow morning, well before the 12:29 PM IST deadline. Most of the 300 entries have no user at all. - Someone would pay. Small repair shops in every town and village run this way, with no records. A lost machine, an argument over the price, or "this isn't my fan" costs real money. - It fits your posts. This one is for your father. Judges weight writing most heavily, and that's your strength. Similar entries, and how yours differs: - ReTrace: generator technicians in Nigeria. A voice note is turned into a repair record using Whisper and Gemma. Its "first user" quote is hypothetical; they say they still need to validate it with a real technician. - Kintsugi: answers repair questions from service manuals. That's a different problem. Yours stands apart because it covers the full intake at the counter, in Hindi, with photos and real customers. What to watch: the open-source AI has to be the core, not a plain database app with AI added on top. Judges check that. Here's where it fits naturally: Scope for about 13 hours: - One page with two flows: a same-day repair quick log and an intake full job card with photos . - A job list sorted by pickup date. - Search by phone number or village. - Reuse the Fastify, Ollama and ElevenLabs code from your earlier projects. No login and no cloud. Two questions before I scaffold it: we will use wisper also if possible. we will also send the details on whatsapp along with voice note, when it is repaired. let us also create a qr code with the amount so when they scan the qr the exact amount they will be asked to pay. The features are clear. One technical limit shapes the design: Gemma and Whisper are too heavy to run on the phone itself, so the laptop in the shop has to do the AI work. Plan: Father's phone app, Hindi, big buttons ──shop Wi-Fi── Laptop in shop camera: machine, rating plate, customer Fastify server + SQLite + photos folder mic: says problem in Hindi whisper.cpp Hindi speech → text, local job list, search by phone/village Gemma 4 in Ollama text → job card, reads rating plate "repaired" → share to WhatsApp ElevenLabs Hindi voice note: only message text leaves UPI QR with exact amount generated locally Flows: 1. New job: take photos, then your father speaks the problem, estimate and date. Whisper turns that into text, and Gemma fills the job card: appliance, fault, estimate, pickup date, plus brand and model read from the rating plate. He checks it and saves. Numbers are kept exactly as he said them; code never guesses them. 2. Same-day repair: a quick log of the problem, the amount and "paid". Every job builds history. 3. Job list: pending jobs sorted by pickup date, and a customer's history found by phone number. 4. Repaired: he enters the final amount. The app generates a Hindi message, a voice note and a UPI QR for that exact amount. Then one share button sends the text, the voice note and the QR image to WhatsApp, and he taps the customer's name and Send. Limits: - WhatsApp can't be fully automatic. Automatic sending needs the WhatsApp Business API, which requires Meta business verification and approved templates. That can't be done in 13 hours. The share sheet is one tap plus choosing the customer. - The customer pays from the QR image. They can't scan their own screen, but GPay and PhonePe can scan a QR from the gallery. Test with ₹1 first, because some apps restrict amounts on personal UPI IDs. - The phone needs HTTPS for the camera, mic and file sharing. I'll make a local certificate and install it on the phone once. Order of work: first the server, database and photo upload. Then Whisper, then Gemma, then the app screens, then the WhatsApp share, voice note and QR. Then test on your father's phone, then write the post. If Whisper's Hindi is too weak or slow on your laptop's CPU, fallback: he types, and Gemma still structures the job card. A few decisions are yours before I start: {"questions": {"question": "What kind of mobile app?", "header": "App type", "multiSelect": false, "options": {"label": "Web app Recommended ", "description": "Installs to the home screen like an app. Plain HTML/JS like your last two projects, no build step, fastest to finish in 13h. Needs a one-time certificate install on the phone."}, {"label": "Expo React Native", "description": "A real native app, run via the Expo Go app on his phone. Camera, mic and sharing work without HTTPS. More setup … 917 more characters trimmed The user answered: "What kind of mobile app?"="i already have flutter setup in my system, lets use flutter, what do you say?", "Which UPI ID should the payment QR use?"="Personal UPI ID", "Which Whisper model?"="I already have installed super wisper on my windows 11 system, https://superwhisper.com/ ". Read the answers carefully — they may request clarification, changes, or that you not proceed — and follow what they actually say. $ {"command": "flutter --version 2 &1 | head -5; echo ---; flutter doctor 2 &1 | head -30", "description": "Check Flutter version and toolchain", "timeout": 180000} ┌─────────────────────────────────────────────────────────┐ │ A new version of Flutter is available │ │ │ │ To update to the latest version, run "flutter upgrade". │ --- Doctor summary to see all details, run flutter doctor -v : √ Flutter Channel stable, 3.44.1, on Microsoft Windows Version 10.0.26200.9457 , locale en-US √ Windows Version Windows 11 or higher, 25H2, 2009 Android toolchain - develop for Android devices Android SDK version 35.0.0 X cmdline-tools component is missing. Try installing or updating Android Studio. Alternatively, download the tools from https://developer.android … 778 more characters trimmed $ {"command": "node --version; echo ---; ollama list 2 &1; echo ---; adb devices 2 &1; echo ---; where whisper-server whisper-cli main 2 &1 | head", "description": "Check Node, Ollama models, phone connection, whisper"} v22.12.0 --- time=2026-10-18T23:43:54.468+05:30 level=INFO source=app windows.go:281 msg="starting Ollama" app=~\AppData\Local\Programs\Ollama version=0.40.4 OS=Windows/10.0.26200 time=2026-10-18T23:43:54.470+05:30 level=INFO source=app.go:238 msg="initialized tools registry" tool count=0 time=2026-10-18T23:43:54.475+05:30 level=INFO source=app.go:253 msg="starting ollama server" time=2026-10-18T23:43:54.478+05:30 level=INFO source=app.go:285 msg="starting ui server" port=61677 time=2026-10-18T23:43:57.479+05:30 level=INFO source=updater.go:373 msg="beginning update checker" interval=1h0m0s time=2026-10-18T23:43:59.094+05:30 level=INFO source=updater.go:133 msg="New update available at http … 343 more characters trimmed $ {"command": "for d in \"$LOCALAPPDATA\" \"$APPDATA\" \"$USERPROFILE/.superwhisper\" \"$USERPROFILE/Documents\"; do find \"$d\" -maxdepth 4 -iname \" superwhisper \" 2 /dev/null; done | head; echo ---; find \"$LOCALAPPDATA\" \"$APPDATA\" \"$USERPROFILE\" -maxdepth 6 \\ -iname \"ggml- .bin\" -o -iname \" whisper .bin\" -o -iname \" .gguf\" \\ 2 /dev/null | grep -iv ollama | head -20", "description": "Look for Superwhisper's Whisper model files", "timeout": 120000} ~\AppData\Local/com.superwhisper.app ~\AppData\Local/com.superwhisper.app/database/superwhisper.sqlite ~\AppData\Local/com.superwhisper.app/database/superwhisper.sqlite-shm ~\AppData\Local/com.superwhisper.app/database/superwhisper.sqlite-wal ~\AppData\Local/superwhisper ~\AppData\Local/superwhisper/Superwhisper.exe ~\AppData\Local/Temp/superwhisper-1.6.8-updater-t5mtjr ~\AppData\Local/Temp/superwhisper-1.6.8-updater-t5mtjr/superwhisper-1.6.8-installer.exe ~\AppData\Roaming/com.superwhisper.app --- ~\AppData\Local/com.superwhisper.app/models/cohere-transcribe-03-2026-Q4 K M.gguf ~/AppData/Local/com.superwhisper.app/models/cohere-transcribe-03-2026-Q4 K M.gguf $ {"command": "flutter devices 2 &1 | tail -8; echo ---; flutter config --list 2 &1 | grep -i android; echo \"ANDROID HOME=$ANDROID HOME\"; ls \"$LOCALAPPDATA/Android/Sdk\" 2 &1; ls \"$LOCALAPPDATA/Android/Sdk/build-tools\" \"$LOCALAPPDATA/Android/Sdk/platforms\" 2 &1", "description": "List Flutter devices and Android SDK contents", "timeout": 120000} Found 3 connected devices: Windows desktop • windows • windows-x64 • Microsoft Windows Version 10.0.26200.9457 Chrome web • chrome • web-javascript • Google Chrome 155.0.8059.80 Edge web • edge • web-javascript • Microsoft Edge 150.0.4078.105 Run "flutter emulators" to list and start any available device emulators. If you expected another device to be detected, please run "flutter doctor" to diagnose potential issues. You may also try increasing the time to wait for connected devices with the "--device-timeout" flag. Visit https://flutter.dev/setup/ for troubleshooting tips. --- enable-android: Not set ANDROID HOME= build-tools cmake emulator extras fon … 216 more characters trimmed $ {"command": "curl -s https://api.github.com/repos/ggml-org/whisper.cpp/releases/latest | python -c \"import json,sys; d=json.load sys.stdin ; print d 'tag name' , d 'published at' ; print a 'name' , a 'size' , a 'browser download url' for a in d 'assets' \"", "description": "Check latest whisper.cpp release assets"} v1.9.5 2026-10-06T17:39:17Z $ {"command": "curl -s \"https://api.github.com/repos/ggml-org/whisper.cpp/releases?per page=6\" | python -c \"\nimport json,sys\nfor r in json.load sys.stdin :\n print r 'tag name' , r 'published at' , len r 'assets' \n for a in r 'assets' :\n if 'win' in a 'name' .lower or 'x64' in a 'name' .lower : print ' ',a 'name' , a 'size' , a 'browser download url' \n\"", "description": "List recent whisper.cpp releases with Windows binaries"} v1.9.5 2026-10-06T17:39:17Z 0 b5454 2026-10-06T16:51:27Z 12 whisper-bin-ubuntu-x64.tar.gz 10364195 https://github.com/ggml-org/whisper.cpp/releases/download/b5454/whisper-bin-ubuntu-x64.tar.gz whisper-bin-win-cpu-arm64.zip 4371193 https://github.com/ggml-org/whisper.cpp/releases/download/b5454/whisper-bin-win-cpu-arm64.zip whisper-bin-win-cuda-11.8.0-x64.zip 284761231 https://github.com/ggml-org/whisper.cpp/releases/download/b5454/whisper-bin-win-cuda-11.8.0-x64.zip whisper-bin-win-cuda-12.4.0-x64.zip 684913404 https://github.com/ggml-org/whisper.cpp/releases/download/b5454/whisper-bin-win-cuda-12.4.0-x64.zip whisper-bin-win-cuda-13.4-arm64.zip 291157544 https://git … 3619 more characters trimmed $ {"command": "mkdir -p \"~/tools/whisper.cpp\" \"~/tools/whisper-models\" && cd \"~/tools/whisper.cpp\" && curl -sL -o whisper-blas-bin-x64.zip https://github.com/ggml-org/whisper.cpp/releases/download/b5130/whisper-blas-bin-x64.zip && unzip -oq whisper-blas-bin-x64.zip && ls -R | head -30 && cd ../whisper-models && curl -sL -o ggml-large-v3-turbo-q5 0.bin https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo-q5 0.bin && ls -la", "description": "Download whisper.cpp v1.9.4 … 54 more characters trimmed Command running in background with ID: bpyddht24. Output is being written to: