Inspiration
Electricity bills in Pakistan are hard to read. A MEPCO bill can combine energy charges, taxes, fuel adjustments, arrears, and tariff details into one payable amount, and most households have no easy way to check it. I wanted a tool that reads the bill for you and lets you verify the numbers yourself, starting with the bills from my own region.
What it does
Bijli Bill Decoder is a proof of concept for MEPCO residential bills.
- Select a bill photo and review the preview.
- Confirm the preview. Only then is the photo sent to an AI service to read the bill's fields.
- Review the extracted fields beside your photo and correct anything that was misread.
- Reconciliation check. The app adds up the line items locally and compares them with the printed payable total. A mismatch is flagged so you can fix a field or mark the result as unverified.
The AI proposes values, and plain arithmetic does the check. The model never decides whether a bill reconciles. Tariff and slab calculations are intentionally not included yet, because the app shouldn't guess a tariff before the tariff code and rates are verified against a published source.
How we built it
- App: React Router Framework Mode, TypeScript, Tailwind CSS, and ShadCN-style UI components.
- Bill reading: a server-side route action sends the confirmed image to Cloudflare Workers AI (
@cf/meta/llama-3.2-11b-vision-instruct). API credentials stay on the server. - Validation: Zod validates the model's response before anything reaches the UI.
- Reconciliation: the line-item sum is computed locally in integer paisa to avoid floating-point errors.
- Privacy: there is no database and no accounts. The photo and extracted values aren't saved by the app, but the confirmed photo is transmitted to Cloudflare for inference.
- Process: I built it with the Devpost Learn Skill Pack (
1-start,2-scope,3-prd,4-spec,5-build), and thescope.md,prd.md, andspec.mdfiles are in the repo.
Challenges we ran into
- Real bills are messy. The layout mixes English and Urdu, with small print, arrears, and adjustments, so a vision model can misread digits. That's why every field is editable beside the photo.
- Trust over polish. It would have been easy to show a confident-looking slab insight. I chose to leave the tariff calculation out until the tariff code and rates can be verified, rather than ship numbers I couldn't stand behind.
- Scope. I cut other electricity companies, other tariff codes, accounts, and history to finish one flow.
- [Add one real bug or setup issue from your build, such as the Cloudflare model-terms step or a misread field. Specifics are what make this section land.]
Accomplishments that we're proud of
- A working flow from photo, to AI extraction, to editable review, to a reconciliation check, with the preview confirmation as the consent point.
- A clear trust boundary: the model reads, local code checks, and the user verifies.
- Honest limits stated in the app and README instead of hidden.
- Planning documents written before the code, with a project that stayed within its scope.
What we learned
- Planning with AI before building keeps a project bounded. The scope, PRD, and spec decided what not to build as much as what to build.
- Vision models are useful for reading messy documents, but their output shouldn't be trusted blindly, so validation and a human review step matter.
- Money arithmetic belongs in code, using integer units, rather than in a model.
- Saying "not yet" to a feature you can't verify is a design decision, not a failure.
What's next for Bijli Bill Decoder
- Verify the residential tariff code and a dated tariff table against a published MEPCO/NEPRA source, then add the slab insight: where your usage sits and what the next unit costs.
- A usage slider that recalculates the bill live using that deterministic calculator.
- A redacted sample bill so anyone can try the full flow without their own bill.
- More tariff codes, then other electricity companies.
- Urdu interface and explanations.
Built With
- cloudflare
- react
- react-router-framework
- shadcn
- tailwind
- typescript
Log in or sign up for Devpost to join the conversation.