You will build InvoiceFlow, a small invoicing app, in three parts: the feature (this page), selling it, and an AI feature. This part needs no keys at all.
The prompt
In Claude Code, in your project folder:
Add an invoices feature: a signed-in user creates invoices with a client name, an amount and a due date, sees their list, and can mark an invoice as paid. Creating an invoice costs 1 credit. Admins should see every invoice in the admin panel. A weekly cleanup job should delete paid invoices older than a year. When you are done, run /ship.
What happens
On our fresh copy it took 7.1 minutes and 54 turns ($0.95 at list price). Claude:
- ran
startfeature invoices --credits, which creates the app and wires it into settings, URLs, the sidebar and the browser tests - wrote the model, the logic in
services.py, the pages, the panel list and the weekly job - set the price, 1 credit, in the app's
costs.py - created and applied the migration
- translated 13 new strings into Arabic
- wrote 19 tests, then ran the full check suite (1,413 passed, 93.8 % coverage) and the browser tests (144 passed)
Its answer started with:
The invoices feature is built and every check passes. Nothing is committed.
And it asked us one question we had not thought about:
Decision for you: the cleanup counts a year from the date an invoice was marked paid, not the date it was created. Counting from creation would delete an invoice that is 13 months old the week after it gets paid.
That is what to expect: it builds, it checks, and it tells you the decisions that are yours.
Check four things yourself
New accounts start with 0 credits, and creating an invoice costs 1. Give yourself some first: panel, Credits, Adjust a balance, pick your user, add 10.
- The page works. Open
http://localhost:8000/invoices/, create an invoice. The credit counter at the top right goes down by 1. - Mark paid works. Mark it paid; its badge changes from Unpaid to Paid.

- Admins see everything. Panel, Invoices: every user's invoices, with search, a paid filter and a CSV export.

- The checks are green.
uv run poe checkpasses. The hook already ran it, but run it once yourself to see what it covers.
Commit it
/ship checks and summarizes. It does not commit: it hands you a commit message. Commit yourself:
git add -A
git commit -m "Invoices: create, list and mark paid; panel list; yearly cleanup"The git hook formats and lints the files as you commit.
Why that worked
- CLAUDE.md says one app per feature, logic in
services.py, and names the one helper for each job:consume_creditsfor credits,@taskandschedules.pyfor the weekly job,PanelSectionfor the panel list. startfeaturegave Claude the same starting shape every feature has, so it filled in the blanks instead of inventing a structure.- The
new-featureskill loaded by itself and listed the steps. Theshipskill ran the checks. - The tests and the 80 % coverage gate are why "every check passes" means something.
If something fails
Paste the error back into Claude Code as it is. It reads the project's own test output better than a summary.
Next: Sell It With Stripe.