Book a 30-min call
cd ../blogs
$ cat posts/2026-04-07.mdx

From Four Tools to One Dashboard: Engineering a Solar Proposal Platform

April 7, 2026 · ImmovableTech Team

  • Full-Stack
  • Dashboard
  • Platform Integration
  • Sales Tooling

The Pain: Four Tools, One Sales Rep

The sales team at a leading solar roofing company was creating proposals using four disconnected tools: a CRM for lead management, a separate proposal builder for system sizing and pricing, a third-party calling platform for customer follow-ups, and a document generator for contracts. Every proposal required switching between all four, copying data manually, and hoping nothing fell through the cracks.

The result: proposals took 45 minutes on average, data entry errors were common, and reps spent more time wrestling with tools than talking to customers. The company was scaling fast — doubling their sales team in six months — and the fragmented workflow could not scale with them.

Discovery: Mapping the Real Workflow

We spent the first week shadowing three sales reps. Rather than asking “what tools do you use?”, we asked “walk me through your last five proposals.” The difference matters: people describe ideal workflows when you ask about tools, but reveal actual pain points when you ask about specific recent work.

Key findings from the observation sessions:

  1. The biggest time sink was not proposal creation — it was context switching. Reps spent 12 minutes per proposal just navigating between tools and re-entering data that already existed elsewhere.
  2. Calling was the surprise bottleneck. Reps made 3-4 calls per proposal (initial contact, follow-up, technical clarification, close). Switching to the calling platform, finding the contact, and logging the call back into the CRM took 8 minutes per call cycle.
  3. Pricing errors caused the most rework. When system sizing changed (which happened in 40% of proposals), reps had to manually update pricing in both the proposal builder and the contract generator. Mismatches caused 15% of proposals to require revision after client review.

Technical Architecture

The Integration Layer

Rather than building a monolithic application that replaces all four tools, we built an orchestration layer that sits on top of existing systems. Each tool exposes an API (or can be accessed via one):

  • CRM (REST API): Lead data, contact history, pipeline stage
  • Proposal Builder (REST API): System sizing, equipment catalogue, pricing engine
  • Calling Platform (Twilio): Click-to-call, call recording, automatic logging
  • Document Generator (API): Contract templates, e-signature triggers

Our dashboard queries all four APIs and presents a unified view. When a rep updates a field, the change propagates to the appropriate backend systems in real-time via webhook-triggered sync jobs.

The One-Screen Design

The core UX principle was progressive disclosure: show only what the rep needs at each stage of the proposal lifecycle.

Stage 1 — Lead Review: The rep sees the customer’s information, property details, and any previous interactions. One click imports everything from the CRM — no re-typing.

Stage 2 — System Design: The proposal builder’s sizing engine runs inside our dashboard. The rep selects panel configurations and sees pricing update live. If they change the system size, pricing and the contract draft update simultaneously.

Stage 3 — Customer Communication: A call button is embedded next to the customer’s contact info. Clicking it initiates a Twilio call, records it, and logs the summary back to the CRM automatically. The rep never leaves the dashboard.

Stage 4 — Proposal & Contract: One button generates the final proposal PDF and the contract. E-signature is triggered from the same screen. The rep can track signature status without switching to the document tool.

Real-Time Sync and Conflict Resolution

The hardest engineering problem was not the API integrations — it was handling conflicts. What happens when a rep updates the system size in our dashboard while a colleague updates the same lead’s contact info in the CRM directly?

We implemented a last-write-wins strategy for independent fields (contact info, notes) and a lock-and-notify strategy for dependent fields (system size, pricing). When a rep starts editing a proposal’s system configuration, we acquire a soft lock. If another user tries to edit the same proposal, they see a notification and can either wait or force-override with an audit trail.

Why CRDTs Were Overkill (But We’d Use Them Next Time)

Our last-write-wins + lock-and-notify approach worked for this use case because proposals are typically edited by one rep at a time. Concurrent editing was rare — maybe 3% of sessions — and when it happened, the soft lock resolved it cleanly. But on our next multi-user editing project — the enterprise collaboration suite — we used CRDTs (conflict-free replicated data types) for truly concurrent editing. CRDTs let multiple users edit the same document simultaneously without coordination, and changes merge automatically without conflicts. The tradeoff is implementation complexity: CRDT-based state management is significantly harder to reason about and debug than simple LWW. For the solar dashboard, LWW was the right call — simpler, faster to ship, and matched the actual usage pattern. For anything with true concurrent editing where multiple users are actively typing in the same document, CRDTs are worth the implementation complexity.

The Calling Integration

Twilio’s API handled outbound calling, but the real value was in the automation around it:

  • Click-to-call from any contact card in the dashboard
  • Automatic call logging: duration, timestamp, and a one-click “call summary” field that the rep fills in (average: 15 seconds vs. 3 minutes when they had to switch to the CRM)
  • Follow-up scheduling: after each call, a prompt suggests the next action based on the proposal stage, and schedules it with one click
  • Call history timeline: every interaction with a customer is visible in a single chronological feed

UX Lessons

Do not hide the complexity — sequence it. Our first prototype showed all four stages simultaneously in a tabbed layout. Reps found it overwhelming. The final design shows one stage at a time with clear “Next” progression. Completion rate went from 68% (tabs) to 94% (sequential).

Make the happy path the only path. In the old workflow, reps could create a proposal without attaching it to a CRM lead, which caused orphaned records. Our dashboard requires a lead context before any proposal work begins. This eliminated 100% of orphaned proposals.

Celebrate completion. A small animation and a “Proposal sent!” confirmation when the e-signature is triggered sounds trivial, but reps told us it was their favourite feature. It turned a tedious administrative task into something that felt like closing a deal.

Results

  • 60%+ reduction in proposal creation time (from 45 minutes to under 18 minutes on average)
  • 4 platforms unified into a single dashboard with no data re-entry
  • Zero orphaned proposals after launch (down from 15% of all proposals)
  • 92% rep adoption within the first month, with positive feedback driving the remaining 8% by week six

What Made This Work

This project succeeded not because of any single technical decision but because of the discovery phase. Shadowing reps for a week before writing any code meant we solved the right problems: context switching and calling friction, not “we need a prettier proposal builder.” The technical stack (React, Node.js, PostgreSQL, Twilio, AWS) was straightforward — the insight was in the workflow design.

The Stack in 2026 Context

If we rebuilt this today, we’d use Next.js 14 with server components for the dashboard, eliminating the separate API layer for read operations entirely. Server components collapse the API/frontend boundary — a dashboard panel that shows proposal status would fetch directly from PostgreSQL at render time instead of making a client-side API call. We’d move the Twilio webhook handling to Vercel Edge Functions, cutting callback latency by deploying the handler close to Twilio’s edge network. And we’d use CRDTs for conflict resolution from day one, since the tooling (Yjs, Automerge) has matured enough that the implementation cost is no longer a serious deterrent. The architecture would be simpler and faster — fewer moving parts, fewer round trips, and edge-deployed webhooks instead of a centralised webhook server.


This project is part of our Full-Stack Web & App Development practice. Read the full case study or talk to us about a similar challenge.