01Not writing the same CRUD six times
Problem
Customers, quotes, invoices, payments, payment modes and taxes all need the same list, search, filter and paginate behaviour. Hand-writing each set of endpoints would mean six copies of the same bugs.
Approach
A generic controller factory takes a model and returns the standard handlers; entity routes are generated from it. Modules only override what is genuinely different, such as invoice totals or quote conversion.
02Money that adds up
Problem
Line items, tax rates, discounts and partial payments all interact, and a total computed in the browser can be tampered with or simply drift.
Approach
The client shows a live estimate, but subtotal, tax and total are recalculated on the server on every save. Recording a payment updates the invoice's paid amount and status in the same request, so the two cannot disagree.
03Quote to invoice without retyping
Problem
Converting a quote by hand invites copying errors and loses the link between the two documents.
Approach
A convert endpoint builds the invoice from the quote's customer and line items, assigns the next invoice number and marks the quote converted — one action, with a record of where the invoice came from.
04Branded documents on any host
Problem
PDFs have to carry the business's name, currency format and numbering prefixes, and still render on a plain container host.
Approach
Settings feed the Pug templates at render time, so a change in Settings shows up in the next PDF without a deploy. Files are written to a downloads directory and served through one route.