Codyware
ESEN

How we moved a platform off a vendor we didn’t control without losing a single record.

A business ran on a platform that a vendor generated and hosted. This is how we moved it out without losing a record or a feature, in parts and with tests along the way.

Illustration made of characters: Case study. How we moved a platform off a vendor we didn't control without losing a single record

Your business runs on a platform that works. It has customers, sales, inventory, a portal. So far, so good. The problem is where it lives: a vendor generates it, hosts it and keeps the database, and you have no way to take it out. There is no test environment. You don’t know what gets deployed or when. If the vendor changes its pricing or shuts down, your operation stops that same day.

That is how a wellness club in Ecuador came to us. This is the path we took, without names or business figures.

The starting point

The club sold memberships, follow-up protocols and products. Its platform covered a lot: customer records, sales and pending payments, quotes with PDFs, inventory, protocols, measurements, reports, a public site and a members’ portal. Real users worked in it every day.

What was missing was control. The application had been generated on a third-party platform that also hosted it, and that came down to five things:

  • A single environment: every change was tested in production.
  • Unconnected payments: “paid” was a box someone ticked by hand.
  • Sales that came in through chat and were typed into the system again.
  • Data in the vendor’s database, with no integrity between tables.
  • No documented way to deploy or reproduce the system.

The client’s request fit in two sentences. Get the platform out of there without losing users or data, and never again depend on a vendor to operate.

Freeze first, then touch

Why not start writing the new system on day one? Because nobody knew exactly how the old one behaved. Migrating without that safety net is migrating blind, and the differences show up when users are already inside.

We ran the legacy application in a local environment and wrote tests that capture what it does today: for each operation, what goes in and what comes out, with the validations and errors it returned. On top of that we added an automated walkthrough of the interface. That suite became the contract. The new system would be finished when it passed exactly the same tests.

Rule for the whole migration: no bug in the old system gets fixed. It is logged with its severity and left for later.

It sounds like leaving problems loose on purpose. In part, it is. We found a list of issues, some of them serious, and we left them there. If you mix fixes into the migration, you can no longer tell a regression from an intentional change. With the behavior frozen, every difference between old and new has only one possible explanation.

The audit also turned up something the system description never mentioned: a module that was supposed to be built did not exist in the code we received. It went from “migrate” to “build from scratch”, and the tests that covered it were marked as expected failures so nobody would mistake them for a problem in the new system.

Keep what works, rebuild what hurts

Not everything was redone. The interface the club’s team used worked, and they already knew it. Redoing it would have meant charging for something that didn’t hurt. It was kept and pointed at the new system, under the same data contracts. That cut the scope of the first version in half.

What did get rebuilt was the engine. A single block of code became a set of independent modules, and the document database moved to a relational one that enforces integrity between customers, sales, inventory and protocols.

ComponentDecisionWhy
User interfaceKept and reconnectedIt works and the team knows it well
Application engineRebuilt module by moduleA single block of code, hard to test and extend
DatabaseMigrated to relationalIntegrity between tables and safe transactions for money
HostingSeparate environments, sized to the businessTesting outside production and a cost that fits the size of the business

The engine was built in vertical slices: authentication and customers, catalog and inventory, protocols and measurements, quotes, sales and debt, reports, members’ portal. Each slice was checked against the contract before the next one started.

We turned down one shortcut: a set of generic responses that would have made the interface look “green” in a day. Of course it looked good. But a screen that works on fake data hides the modules that don’t exist yet. Only a few routes were left explicitly marked as pending.

No longer tied to the vendor

The second sentence of the request was solved with a platform of its own, one the club can deploy and reproduce without asking anyone for anything. Deployment is documented, there is a test environment separate from production, and keys live in a secrets manager, outside the code. None of that existed with the previous vendor: every change was tested with real users and nobody knew how to bring the system up somewhere else.

The infrastructure was chosen for a small business: a service for the engine that scales with use, a managed database and the interface served from a content delivery network, all in the same region so latency between the parts stays low. Nothing oversized, because the monthly bill has to match the size of the business.

Where it ended up

  • The parity suite passed in full, except for the cases of the module that never existed, marked as expected.
  • Within weeks of the proposal, the platform was running outside the vendor, in its own separate environments, with its real data loaded by a repeatable process.
  • On that foundation, the club later added a more complete members’ portal, a public store with card payments through a local gateway (where the server, never the browser, decides whether a payment went through) and a sales cycle with invitations and source attribution.

What can drift isn’t stored: it’s calculated. Remaining stock, a member’s status or whether an invitation is still valid are derived from facts that don’t change.

If your platform lives somewhere you don’t control, the first step is knowing, with tests, how today’s version behaves. The quote comes after that. The guide on modernizing a legacy system in stages has the full method, and what we do shows how we can help with your case.

Frequently asked questions.

How long does it take to move a platform off a vendor?

It depends on the size of the system and how much of it is worth keeping. In this case, the first version running outside the vendor, with real data, took weeks. What speeds things up most is having the current behavior documented with tests from the start.

Is data lost when you migrate from one database to another?

It shouldn't be if the migration has a contract. Here, parity tests compared the old and new systems response by response, and the real data was loaded with a repeatable process that could be run as many times as needed.

Do I have to redo the visual side too?

Not always. If the interface works and your team finds it useful, it stays and gets connected to the new system under the same contracts. Redoing it is a separate decision, with its own timing.

Can it be done without stopping operations?

Yes. The old system kept serving its users while the new one was built module by module on a copy, and the real data was loaded with a process that could be repeated. The switch happened once, when the parity suite passed in full.

What if we built it
together?

Tell us what you want to create or change. We’ll reply right away on WhatsApp or by email, with no templates or prepackaged plans.

Message us on WhatsApp
CODYWARE / YOUR NEXT STEP
NEW PRODUCT

Let’s shape
that idea.

What you tell us will be the starting point.

What best describes you?

01 / 02
CODYWARE / WHATSAPP

Done! We opened WhatsApp

Your request is registered. If WhatsApp didn’t open, you can open it here.

Open WhatsApp