Engineering decisions
Safety in shared data
One policy, three enforcement points
Permission checks scattered across every API route, the client router and the navigation would inevitably drift apart.
Define one permission policy and use it in the server middleware, the route guards and the navigation.
Adding a feature means adding one policy entry, not remembering three separate checks.
The policy becomes a critical shared module, so changes to it need care and tests.
404 for cross-client access
A 403 on another client’s resource confirms that the resource exists.
Answer cross-client requests as if the resource didn’t exist, and test that boundary deliberately.
A client portal must not reveal anything about other clients, not even their existence.
Debugging access issues is less obvious, so server logs carry the real reason.
Integer cents and transactions
Floating-point money and multi-step updates are how accounting data quietly goes wrong.
Store every amount as integer cents and run multi-record workflows in transactions.
Totals reconcile exactly, and a failed step can never leave an invoice without its line items.
Formatting and tax math have to convert explicitly at the edges.
A modular monolith
The product spans a dozen domains, but it is run by a small team on modest infrastructure.
Ship one Nuxt application on one PostgreSQL database, deployed with Docker Compose and Caddy.
Cross-domain features like reporting, search and the calendar are joins, not network calls, and it deploys in one step.
Domain boundaries are kept by code organization rather than enforced by separate services.