← All work Showcase migration

Moving a home energy installer off SQL Server 2012 and onto Dataverse

Kove Energy is a showcase firm with invented records, but the migration, the build and the app are real, and I ran them end to end.

Type
Legacy migration · Power Apps canvas app
Date
2026
Stack
SQL Server 2012 · Dataverse · Power Apps

An end of life legacy system holding years of data

Kove Energy installs solar, home batteries, heat pumps and EV chargers around Waikato. It has about 15 people. Around six work in the office, and contractor crews do the installs.

Jobs, customers, stock and enquiries all lived in a custom Windows desktop app. The app sat on a SQL Server 2012 Standard database, on a server in the office running Windows Server 2012 R2.

Microsoft's word for this is end of support, and both layers had reached it. SQL Server 2012 has had no security fixes since July 2022, unless you paid for extended security updates, and those ended in July 2025. Support for Windows Server 2012 R2 ended in October 2023. The app still ran. It was just running with nothing patching the holes.

The server was getting old and had to be replaced. SQL Server 2012 is not supported on Windows Server 2022 or 2025, so a new server meant the app had nowhere to go.

The bigger problem was that years of the firm's data sat in an application nobody could build on. Kove Energy wanted more from its systems: AI insights from its job history, GPS and maps for the crews, integrations with other systems, and more of the routine work automated. Before any of that, it needed a solid base.

Why Dataverse and Power Apps

Kove Energy chose Microsoft Dataverse, with a Power Apps canvas app on top. Dataverse holds related business data properly, as real tables with real links between them. Role-based access is built in, so who can see or change what is set in one place. It sits inside the Microsoft 365 the firm already uses. And it is the easiest option for the firm's IT to support, because there is no server or database engine left to patch.

What it costs to run is on the SQL Server to Dataverse page.

The rebuild: eight tables, eight screens, three roles

This was a rebuild onto Dataverse, not a lift of the old database into Azure SQL. A copy into Azure SQL would have carried the old tables across with every fault still in them. A rebuild meant each fault got fixed, or flagged, on the way in.

The data model has 8 tables. Each one keeps the old ID as an alternate key, or a stable new one where the old table had none. That means any load can be re-run without loading a row twice. I read all 8 keys back, and all 8 were Active before the load started.

The app has 8 screens: Jobs (list and panel), People, Enquiries, To do, Codes, Stats, Checks and a loading screen.

There are three roles: office manager, office staff and installer. I tested them with 18 checks, six actions for each role, and all 18 passed. Every refusal came back from Dataverse itself as a 403, so an installer cannot edit a job even by going around the app.

The database migration, measured

For this showcase I built a stand-in for the old database on SQL Server Express on my build PC, and moved it into a Dataverse environment called Kove Staging. It held 120,000 rows across 8 tables, in a 72.0 MB data file.

That is not a big database. The hard part was the quality of the data and the rebuild around it. I gave the stand-in the faults an old database usually has, and each one got a named rule and a count.

A small trial of 2,776 rows went first, into my dev environment, with 101 checks passed and 0 failed. The full run took 0.2 minutes to export, 0.1 to clean and reshape, 67.6 to load and 2.1 to verify. Dataverse sent no throttling responses (HTTP 429) during the run.

The first pass landed 119,996 rows, because 4 comments were lost to connection resets. I retried the four and the total came to 120,000. The load ran 2 more times in all, once for those comments and once after I took house numbers out of the invented addresses. Not one row was loaded twice: 0 duplicates.

Counts and a sample of rows can pass while one row has been swapped for another. So the final check compares the full key set of every table in both directions, and 145 of 145 checks pass.

MeasureValue
Rows moved120,000
Rows landed, first pass119,996
Rows landed, after retrying 4 rows120,000
Names with macrons kept203 of 203
Rows loaded twice0
Checks passed, after the retry145 of 145
Total run time, first full passabout 70 minutes
Run2026-10-31, Kove Staging, a Developer environment in Australia run as a Managed Environment, synthetic data only

Rows landed and checks passed are after the re-run that retried the 4 comments. These figures come from one dated set of test runs on invented data, not from a client. I have not measured hours saved or payback, so this page claims neither.

Feedback from a real client on work I did for them:

"I was really impressed with how the solution turned out, and the migration went a lot more smoothly than I expected."

Operations lead, NZ environmental services firm

What the new base is for: AI, maps and integrations

With the data clean and in Dataverse, the things Kove Energy wanted can be built on top instead of worked around. That means AI insights from the job history, GPS and maps for the crews, integrations with other systems, and workflows that run without someone chasing them. Each one reads from the same tables and respects the same roles, so none of them needs another migration.

The demo already has some of them built on top: a map of every job, emails and reminders that go out on their own each morning, the risks pulled out of each design report, and written trends from the job history.

How I hand it over

When I do this for a client, the solution goes into your own Microsoft tenant, not mine. I train your IT team at each milestone as we deploy, so they know it by the time it goes live. They get the runbook I write for it. From there, they support it.

Balu

Try the demo

The demo is a clickable copy of the app, on invented data. It is a React copy for browsing, not the live Dataverse app, and it makes no network calls. You can switch between the three roles and reset it whenever you like. A replay steps through the real run, from the old table to the rule applied to the Dataverse row. Try logging a web enquiry for solar plus a battery, turning it into a job, and moving it through to Signed off.

The demo is built for a laptop screen. On a phone, it asks you to turn the screen sideways.

Want this for your business?

Balu Premkumar, founder of KoveChristchurch-based. I reply within 1 working day.
Next case studyTwo years of developer time, rebuilt in six weeks