Most architecture articles describe a hypothetical stack. This one describes a product we run in production every day: OneCRMApp, a CRM for insurance agents, built on Laravel 12, React and Inertia.js. It is the practical answer to the question the other articles in this cluster ask — here is what the decisions look like when real users depend on them.
The problem and the product
Insurance agents in Poland work across spreadsheets, notes and a handful of carrier portals. Policies are scattered, renewal dates are missed, and follow-up opportunities disappear. OneCRMApp puts clients, policies, reminders and commissions in one place — web and mobile.
That shaped the first architecture requirement: one team, one repository, fast iteration. No separate frontend squad, no API-first ceremony.
Why Inertia.js instead of API + SPA
At launch the web app was the only client. Building a REST API first would have meant designing and versioning a contract with a single consumer — cost without a customer. Inertia.js gave us the React SPA experience with Laravel routing, session auth and validation intact, exactly as described in Inertia.js with Laravel and React.
When the roadmap added integrations and a mobile client, we extracted REST endpoints behind Sanctum — reusing the same controllers, FormRequests and policies. The extraction took days because the seams were designed for it; the reasoning is covered in Sanctum SPA vs Inertia session auth.
- ## The hard data problem: policies that are all different
Every insurance product has its own fields and conditions. Modeling each as columns explodes the schema; modeling everything as JSON kills query performance. We use a hybrid:
- Stable fields (client, carrier, premium, dates, status) are regular indexed columns — filters and reports stay fast.
- Product-specific fields live in an EAV layer backed by PostgreSQL JSONB with GIN indexes.
- Renewal calculations run as scheduled jobs and materialized summaries, so dashboards never scan raw policies.
PostgreSQL earns its keep here — partial indexes, JSONB containment queries and window functions replaced what would otherwise be an application-side reporting layer.
Performance decisions that stuck
- Deferred props for the dashboard: counters and lists paint immediately, charts arrive in the second wave — see Inertia.js v2 features.
- Queue everything slow: carrier API calls, exports, reminder emails run in queues with Horizon.
- Redis for cache and queues; PostgreSQL tuned per query pattern, not per folklore.
- SSR on public pages — marketing and registration — while the app behind login stays client-rendered: the split we recommend in Inertia.js SSR with Laravel.
Key takeaway: The architecture bet that paid off most was deferring the API. We shipped months earlier, and when the second client appeared, nothing had to be rewritten — only extracted.
Results and what is next
Agents using OneCRMApp report saving around 5 hours a week on administration, and renewal reminders lifted renewal sales by roughly 20% in the first cohorts. The product is in active development — a mobile client and carrier integrations are the current roadmap, both riding on the extracted API.
If you are building a product in a niche where off-the-shelf tools are too generic and too heavy, this is the shape we recommend: a focused domain model, one repository, Inertia for the interface, and APIs added when a second client earns them. We do this for clients too — see Laravel development services.
FAQ
Why Inertia.js instead of API-first?
The web app was the only client at launch — Inertia avoided designing an API contract for a single consumer. Endpoints were extracted later, reusing controllers and policies.
How do you model different policy types?
- A hybrid: stable fields as indexed columns, product-specific fields in an EAV layer over PostgreSQL JSONB with GIN indexes.
Is OneCRMApp open to new users?
Yes — registration is open at onecrmapp.com, and the product is actively developed with user feedback.
👉 Building a niche SaaS or CRM? See how we approach it in Laravel development services or check the product itself at OneCRMApp.
📖 Read more: Inertia.js with Laravel and React, Inertia.js SSR with Laravel and Sanctum SPA vs Inertia session auth.