Skip to main content
YourHero

Success Case

Modernizing a Legacy Education Platform Without Letting the Old CMS Define the New Product

Published
by Vahagn Karamyan
Industry
Education
Role
Product Designer
Company
Business Development Group
Views
1view
Likes

Intro

I worked on rebuilding and extending the Business Development Group education platform while preserving years of existing course content from its previous WordPress website.

The project was not simply a visual redesign.

We had to move an existing education business to a new platform while keeping old courses, translations, media and course-specific content working and at the same time give administrators the ability to create completely new courses directly inside the new system.

That created an architectural challenge that appears in many legacy migrations:

How do you preserve old content without allowing the structure of the old CMS to become the architecture of the new product?

We discovered the problem when a feature that worked perfectly for migrated courses completely disappeared on newly created ones.

Problem

One of the course-page sections was a cashback-related callout.

On courses imported from the old WordPress website, it appeared correctly.

But when an administrator created a new course directly in the new admin system, the cashback section did not appear at all.

At first, this looked like a normal frontend or admin-form bug.

The page existed.

The course itself was valid.

Other course information was displayed correctly.

There was no obvious reason why the section should behave differently depending on how the course had been created.

So we traced the feature through the system.

That investigation exposed the real problem.

The cashback section was not actually modeled as an independent feature of a course.

It was rendered inside a legacy profession course block and depended on two fields:

individual_title

and

individual_subtitle

Those fields had originally come from WordPress ACF data:

profession_block_individual_title

and

profession_block_individual_subtitle.

During migration, imported courses passed through the WordPress importer, which created the required CourseBlock records.

But manually created courses did not.

The new admin flow had no reason to create a WordPress-era profession block, so the cashback data structure simply did not exist for those courses.

The result was an accidental business rule:

Imported WordPress course → cashback section works

Course created in the new admin → cashback section disappears

Nobody had intentionally designed the product this way.

The behavior existed because the new platform had inherited an implementation detail from the old CMS.

Solution

The important realization was that this should not be fixed by adding another condition to the frontend.

The deeper issue was the product model.

We separated two concepts that had been treated as the same thing:

how the old WordPress site stored the information

and

what the information means in the new product.

The legacy profession block was an import format.

Cashback was a business capability.

Those should not have been permanently coupled.

Instead of forcing every newly created course to imitate the internal structure of an old WordPress course, we treated the cashback behavior as something that should belong to the current course experience.

Legacy courses still needed to preserve their imported data.

But new courses needed to be created using the new platform's own model.

This changed how we approached the broader migration as well.

For every inherited field or block, we started asking:

Is this part of the actual business domain, or is it only the way WordPress happened to represent the data?

If it was real business information, it should have a clear place in the new product.

If it was only migration scaffolding, it should remain an implementation detail rather than defining future functionality.

This allowed us to preserve historical content without requiring every future feature to reproduce the architecture of the previous CMS.

Lesson

The biggest lesson was that a successful data migration can still produce a poorly migrated product architecture.

It is possible to preserve every record correctly and still accidentally carry old structural assumptions into the new system.

Legacy systems contain two very different things:

business knowledge

and

implementation history.

Those need to be separated.

The business knowledge should survive the migration.

The implementation history usually should not.

Since this experience, I think about legacy modernization differently.

I no longer ask only:

“How do we migrate this field?”

I also ask:

“Why does this field exist, what business concept does it represent, and should the new product represent that concept in the same way?”

That question can prevent years of new development from being constrained by decisions made inside an old CMS.

Experience details

Context

We were rebuilding an existing education platform that had years of course content in WordPress while simultaneously introducing a new administration system for creating and managing courses directly in the new product. This meant the system had to support two realities at the same time: legacy imported content and newly created native content.

Team size:
1
Timeline:
1 week
Company stage:
Series A
Project stage:
Redesign

Constraints

  • Technical

    We could not simply discard the legacy WordPress structures because existing courses still depended on migrated fields, translations and content blocks. At the same time, requiring every new course to reproduce the internal structure of WordPress would permanently couple the new platform to the CMS we were trying to replace.

Reflection

Lesson

If I approached a similar migration again, I would classify legacy fields much earlier into two groups: Domain data - information the new product genuinely needs. Migration structure - information that exists only because of the previous system.

What I'd do differently

I would make that distinction explicit before building new admin functionality.It would reduce the risk of discovering later that seemingly normal product features still depend on invisible assumptions from the legacy platform.