Ideas Unlimited Productions · Mumbai · 2026
Seven hours, one person.
One working business.
A GST-compliant invoice system for a 35-year theatre company. Proforma to tax lifecycle, audit trail, PDF generation, WhatsApp share. Built end to end by the person who files the invoices.

Role
Solo Designer + Full-Stack Developer + User
Timeline
7 hours, end to end
Team
1 person — Janam
Scope
Full-Stack Product, Domain Architecture, AI-Assisted Build
Background
I built the software
that runs my family's business.
Ideas Unlimited Productions · Mumbai · founded 1990
113+ productions. Clients include NCPA, Reliance, Kandivali Education Society. 2–3 invoices a month. ₹34.5L+ tracked in FY 2025-26.
Manoj Shah — my father — runs the company. I'm the one who makes the invoices. I was bad at it. Wrong dates, wrong play names, wrong GST splits. The accountant charged ₹40,000/year for work that was structured, repeatable, and rule-based.
The problem
Google Sheets is not a system.
An accountant is not software.
What existed
- · Google Sheets
- · Phone calls to the accountant
- · Manual GST splits
- · Wrong dates, wrong numbers
- · Proforma + tax as two unrelated docs
- · Payment proof trapped in WhatsApp chats
- · ₹40K/year for rule-based work
What should exist
- · One source of truth
- · GST encoded as software, not human memory
- · Proforma → tax as one lifecycle, not two documents
- · Audit trail by default
- · Indian small-business sharing flow (WhatsApp first)
- · Built and owned by the person who uses it
The problem wasn't that no tool existed. It was that every tool was built for a generic small business — not for someone billing ₹14L for one performance, with a 50% advance, a 9%+9% GST split, an Indian-numbered amount-in-words, and a payment proof that lives in a WhatsApp screenshot.
The work
Five screens. The whole product.
Step 01 · Lifecycle as architecture
One invoice. Four states.
One source of truth.

Most invoicing tools treat proforma and tax invoices as separate documents. IU's actually need to evolve through advance receipt — so the schema collapses both into one entity with a status enum.
Step 02 · Description Builder
Rule-based generation.
Manual override one click away.

Pick a play, pick an advance percentage, pick a date — the description writes itself in IU's exact voice. “Edit manually” sits one click away for the exceptions.
Step 03 · Dashboard
The financial year, at a glance.

FY filter, four KPI cards, sortable invoice table with payment status. The accountant's monthly reconciliation report — replaced by the homepage.
Step 04 · PDF generation
A real Indian tax invoice,
server-rendered.

What the PDF includes
- · IDEAS UNLIMITED letterhead + logo + seal
- · Bill From / Bill To / GSTIN / SAC code
- · CGST + SGST split (9%+9%)
- · Bank details for direct transfer
- · Manoj Shah signature block
- · Indian numbering: "Eighty Eight Thousand Five Hundred"
@react-pdf/renderer, two templates (proforma and tax). Field-for-field compliant with what IU's CA already accepts.
Step 05 · Built for phones
Manoj checks invoices on his phone.
So do I.


Same lifecycle, same tracker, same actions — 430px to 1440px. Tailwind 4, no separate mobile build.
Results
Built in seven hours.
Live for a real business since.
0hours
Build time
₹0L
Tracked FY 2025-26
0invoices
This FY
0
Manual errors
₹40K/year accountant fee → ₹0.
Replaced by a system the user owns,
built in one afternoon.
Deep dive
Seven chapters,
for readers who want the why.
Decisions, architecture, what AI got right, what didn't ship.
Chapter 1 · Build vs Buy
Why I didn't pay ₹500/month
and stop typing.
Workflow fit
No SaaS supports proforma → advance → tax invoice lifecycle with play/venue/date fields and an auto-generated description that reads in IU's voice.
Cost
₹0/month vs ₹500–2,000/month for a tool that still requires manual workarounds on every single invoice.
Ownership
The invoice system is the foundation of a 14-phase production management platform. You don't build your foundation on someone else's SaaS.
What no SaaS supports
A proforma that becomes a tax invoice after advance receipt, with auto-generated descriptions in IU's voice and amount-in-words rendered in Indian numbering (Lakhs and Crores). Three things that aren't features anywhere, because the assumed user isn't this user.
This is Phase 1 of a 14-phase production management platform. The invoice system is the foundation — once the data model is right, scheduling, cast/crew, contracts, and revenue splits are additions, not rewrites.
Chapter 2 · Lifecycle as architecture
One invoice, four states.
Not two documents.
State 1
proforma
State 2
advance_received
State 3
invoice_generated
State 4
paid
Side branch
cancelled
Status enum
status: | "proforma" | "advance_received" | "invoice_generated" | "paid" | "cancelled"

The schema decision
advance_amount, advance_date, advance_proof_url all live on the invoices table. There is no proformas table. There is no payments table. There is one row that grows.
Chapter 3 · Domain encoded as software
GST splits. Lakhs and Crores.
Advance percentages I actually use.
GST auto-detection
Reads the first two digits of the client's GSTIN, compares to the seller's state code, picks the right tax split.
Indian numbering
Amount-in-words rendered in Lakhs and Crores, the way an Indian CA expects to read it.
✓ “One Lakh Twenty Thousand”
✗ “One Hundred Twenty Thousand”
Advance presets
25 / 40 / 50 / 75 + Custom. These are IU's actual percentages — known from doing the calculations manually for years.
SAC code 998596
Hard-coded in business settings. Indian tax invoices need a service accounting code that matches the work performed — for performing arts, that's 998596.

Each of these is a fact about IU's actual workflow. None of them are configurable. That's the point.
Chapter 4 · No context breaks
Same principle as
SBI's inline OTP.


→ See SBI Redesign for the same principle applied to OTP entry
Why it matters
Modal-less. The form expands inline below the picker, the user fills it, saves, and the picker auto-selects the new client. Zero context loss. Same shape applied to plays, venues, and the Description Builder.
Chapter 5 · The trust system
Audit ≠ auth.
Both matter.

Audit
- · Invoice created
- · Advance received (with proof URL)
- · Converted to tax invoice
- · Shared via WhatsApp / Email
- · Final payment received
- · Cancelled (with reason)
Each entry stamped with device info + timestamp. Survives the user.
Auth
- · Email OTP, no passwords
- · Phone allowlist (1–2 users)
- · Two-step confirmation for writes


Right-sized auth
A 1–2 user family tool doesn't need OAuth or SSO. It needs a 6-digit code, an allowlist, and an audit log that survives the user.
Chapter 6 · The Claude Code loop
Seven hours, one named principle,
three honest overrides.
[Claude] generated supabase/migrations/001_initial.sql[Janam] rejected — Claude wants two tables (proformas, tax_invoices)> revise: single entity, status enum, lifecycle as state machine[Claude] regenerated with single table + state transitions# next: invoice CRUD form (hour 2)Hour 1
Architecture
7 Supabase migrations. Data model: clients ↔ plays ↔ invoices ↔ activity_log ↔ business_settings ↔ whatsapp_sessions. Status enum, audit trail, GST split logic.
Hours 2–3
Invoice CRUD
Create, edit, lifecycle state machine. Description Builder. GST auto-detection from client state code. Advance percentage presets.
Hours 4–5
PDF + Sharing
@react-pdf/renderer, two templates (proforma, tax). IU letterhead, tax breakdown, bank details, signature. WhatsApp + Email share flows.
Hours 5–6
Dashboard + Management
Financial dashboard with FY filtering. Client + play management with inline creation. Payment proof upload.
Hours 6–7
Polish + Audit
Activity log with device fingerprint. Settings page (company, bank, SAC). Mobile pass. Email OTP + phone allowlist.
Named principle
Architect for fast feedback. Schema first, UI last. Hour 1 was 7 Supabase migrations and an ER diagram in my head. After that the UI was just a view layer over decisions already made.
Three overrides
Schema
Claude
Two tables — proformas + tax_invoices.
Me
One entity, status enum, fewer joins, simpler audit trail.
Why
Proformas become tax invoices. They aren't separate documents.
Voice
Claude
Generic template: "Payment for the play..."
Me
Rewrote in IU’s voice: “Towards 50% of total fees to be paid as advance for the play ‘Adbhut’ on the 6th of May 2026.”
Why
Generic doesn't pass the accountant. Specific does.
Auth
Claude
Full auth flow — OAuth, password + reset, 2FA.
Me
Email OTP + phone allowlist. User count is 1–2.
Why
A family tool doesn't need enterprise auth.
Chapter 7 · What didn't ship (yet)
The chatbot. The platform.
The boundary.
Pages
- /login
- /clients
- /plays
- /settings
- /invoices
- /invoices/new
- /invoices/[id]
API + Lib
- /api/* (server actions)
- /lib/pdf (@react-pdf)
Phase 2
- /api/whatsapp
- /lib/whatsapp (Anthropic SDK)
Supabase (Postgres)
- clients
- invoices
- plays
- venues
- invoice_activity_log
- business_settings
- whatsapp_sessions
Block A · The WhatsApp chatbot, in design
The architecture exists: Meta Cloud API webhook, Anthropic SDK for Hindi/Hinglish parsing, a whatsapp_sessions table for confirmation state (migration 007), and a route scaffolded at /api/whatsapp. Not deployed. Phase 2.
Block B · The 14-phase platform
Invoicing is Phase 1. The plan, not the promise:
- · Production scheduling
- · Cast + crew management
- · Venue contracts
- · Revenue split with collaborators
- · … plus 9 more
The 7 hours bought a working invoice system.
The architecture bought the next 7 phases.
Closing
The fastest way to ship the right thing
is to be the user who needs it.
What this project made me
Seven hours of build is only credible because the seven months before it were spent filing invoices badly. The speed is downstream of the domain. AI compiled the code; I compiled the requirements every time I sent a wrong invoice.
Phase 2 is the WhatsApp chatbot — designed, schema migrated, not yet deployed. Phase 3 onward is the rest of the production management platform: scheduling, cast/crew, contracts, revenue splits.