A project is a parent rollup for multi-visit jobs. Use them when one customer has several appointments, multiple invoices, change orders, and receipts on the same job. The project page shows total invoiced, materials, labor, profit, plus links to every child entity in one place.
When to use projects (and when NOT to)
- USE for a 6-week kitchen remodel: 8 visits, 12 invoices, 15 receipts, 32 labor hours.
- USE for a multi-week landscape install: 4 crews, 3 invoices for materials + labor, weekly progress visits.
- USE for any job over $5k that spans more than one visit.
- DON'T USE for a one-off service call: a single appointment + a single invoice doesn't need a parent.
- DON'T USE for recurring contracts: those have their own roll-up at /portal/contracts/[id].
Creating a project
- 1Go to /portal/projects → New project
Pick the customer, name the project (e.g. 'Master bathroom remodel'), describe scope, optionally set quoted total + start + expected completion.
- 2Address inherits from customer
Defaults to the customer's billing address. Override if the project is at a different site (rental property, second home).
- 3Save
You're now ready to link child entities. Future quotes, invoices, appointments, change orders, receipts, and time entries can be tagged with this project_id from their respective composers.
What rolls up
| Invoiced | Sum of every linked invoice's total_cents. |
| Collected | Sum of every linked invoice's amount_paid_cents. |
| Materials | Sum of every linked expense's amount_cents. |
| Labor | Sum of every linked time_entry's cost_cents. |
| Net profit | Invoiced − materials − labor. Live updated as new entities link in. |
| Quoted vs invoiced | If you set a quoted_total_cents at create time, the project page shows variance (+ or − vs quoted). |
Click 'Mark complete' on the project detail page when work wraps. The project moves to a completed state with a completed_at timestamp — useful for year-over-year reporting + 'how long did this kitchen actually take?' analysis.
v1 ships with project-tagging on the data model but the composers (quote, invoice, appointment) don't yet expose the project picker. You can backfill via API or wait for the composer wiring in a follow-up release. The project rollup only counts entities with project_id explicitly set.