File
SMF·HARVEST
Received on
31.07.2026
Reviewed on
28.09.2026
Exhibits annexed
3
Questions
4

SMF·HARVEST

Can a prompt replace Harvest?

Time tracking — time tracking with invoicing

Almost Verdict recorded on 28.09.2026 · Verified on 31.07.2026
Price
$9/moSource: www.getharvest.com · Checked on July 31, 2026
Per year
$108
Build time
A weekend
Votes
0 votes
YesAlmost (checked)Not yet

Exhibit tracking slip

Exhibit A The prompt
Exhibit B What you lose
Exhibit C Why people still pay: invoicing and payment integrations
Exhibit Q Questions

Verdict

Harvest is a timer whose reason to exist is the next step: the hours become an invoice, the invoice gets paid, and neither is retyped. The tracking and the invoice document are a weekend. Getting paid is where the third parties arrive — a payment processor to accept a card, and an accounting system to reconcile it — which is why this stays a kinda rather than becoming a yes even though the code is small.

Exhibit B — What you lose

Exhibit A — The prompt

Received on31.07.2026
Build a time tracker whose output is a correct invoice, with the double-billing problem solved properly.

Stack: your choice, Postgres, one command to run.

Model: Client, Project, Task, TimeEntry, Expense, Invoice, InvoiceLine.

Billing correctness is the whole build:
- A TimeEntry has a billable flag and an `invoice_id` that is null until invoiced. Invoicing selects unbilled billable entries in a date range and sets that id inside one transaction. There is no other way for an entry to become billed.
- An invoiced entry is immutable. Editing it requires voiding the invoice or writing an adjustment entry, and the UI must explain which.
- Rates resolve by specificity — person on project, then project, then person, then default — using the rate in force **on the entry's date**. Changing a rate today must never change the value of work already logged. Test this first.
- Expenses attach to a project with a receipt file, a category, and an optional markup percentage, and flow into the invoice as their own lines.

Invoice document: number from a configurable sequence with no gaps, issue and due dates, client billing details, line items grouped by project, task or person as chosen, subtotal, a tax line with a configurable rate, and a total. Render to PDF. Store the rendered PDF rather than regenerating it — a regenerated invoice can silently differ from the one the client received.

States: draft, sent, partially paid, paid, void. Payments are recorded manually with a date, amount and method; several payments can settle one invoice. Voiding never deletes: it releases the entries back to unbilled and records who voided it and when.

Reports: unbilled hours by client, ageing of unpaid invoices in 30/60/90-day buckets, and revenue by month from invoice dates.

Write tests for the invoicing transaction being atomic, for an entry never appearing on two invoices under concurrent invoicing, for historical rate resolution, and for void releasing entries exactly once.

Do not integrate a payment processor or an accounting system. Export a CSV your accountant can import.

Opening prefills the prompt — press enter to run it.

Exhibit B — What you lose

  • B.1 accepting card payments on the invoice
  • B.2 the QuickBooks, Xero and Stripe integrations that reconcile what was paid
  • B.3 the mobile and desktop timers
  • B.4 automatic payment reminders to the client
  • B.5 team capacity and utilisation reporting

Prior art

Exhibit C — Why people still pay: invoicing and payment integrations

Because the value is in the last mile — a client clicking pay on the invoice — and that mile runs through a payment processor and an accounting system somebody has to maintain.

Questions

Why is double-billing the hard part rather than the PDF?

Because it is silent. A wrong-looking PDF gets noticed; the same three hours on two invoices does not, until a client notices for you. An `invoice_id` on the entry set inside one transaction is the whole fix, and it needs a test under concurrency.

Why store the rendered PDF instead of regenerating it?

Because your template, your address or your tax rate will change, and regenerating invoice 41 next year would produce a document the client never received. The stored file is the record.

Why must invoice numbers have no gaps?

Because in several jurisdictions a gapless sequence is a legal requirement for invoices, and in all of them a gap is the first thing an accountant asks about. Allocate the number at send, not at draft creation.

Can Harvest export everything I need?

Time entries, expenses, invoices and clients all export as CSV, and the API covers the rest. Invoice PDFs must be downloaded separately — the CSV has the numbers, not the documents you actually sent.

Receipt

Already built this yourself?