Broadcast media replatform with SEO-safe migration and a companion mobile app
A WordPress-to-Laravel replatform for a national non-profit broadcaster: a hand-built CMS that understands the broadcast clock the organization runs on, three layers of legacy URL continuity protecting two decades of search visibility, and a companion mobile app with scheduled, preference-aware push notifications.
The organization's publishing lived on a WordPress install assembled from plugins with no shared content model and no mobile story, and none of it understood the one thing that actually mattered: 'today's episode' isn't the record dated today, it depends on air time, a post-midnight boundary, whether the show is currently live, and different weekend behaviour — logic a generic CMS simply has no concept of, so editors were compensating by hand at air time every day. Two decades of indexed URLs were riding on any replatform going right, since a broken permalink shape or a lost sitemap would destroy the search traffic that drives listenership. And there was no way to reach a supporter on a phone at all — no notification that the program was about to start, no saved content, no follow behaviour.
Put the broadcast-clock logic in one place: dedicated services resolve which episode is 'current' and which should lead the homepage, honouring air time, the post-midnight boundary, a live window, a post-air grace period and weekend behaviour, with every consumer — homepage, hero unit, notifications, archive listing — asking the same service so the rules can't drift apart between them. The services take an injectable notion of 'now', so temporal logic that's normally verified by waiting until the right hour arrives is actually testable.
Search-visibility continuity was treated as its own subsystem rather than a pre-launch task: pattern-based middleware maps whole families of legacy URL shapes onto the new structure, an administrator-managed redirect table handles the long tail case by case with click tracking, and a centralized metadata builder reproduces the structured-data shape the old site emitted closely enough that search engines read continuity rather than a new property. For the migration itself, a scanner introspects every text column in the database looking for legacy media URLs embedded in free text, rather than guessing which columns mattered, and a single merge service collision-safely re-points every favourite, save, follow, push token and pivot row from a duplicate person record onto the surviving one. The mobile app is a deliberately thin hybrid shell — native tabs around the same web experience, with native push, sharing, and a JavaScript bridge carrying login, logout and content-change events between the two layers — so there's one content model and one release cycle for content features, with native code only where native is actually required.
The organization now publishes on its own schedule, with episodes going live, leading the homepage and archiving themselves without anyone intervening at air time, and it kept the search visibility it spent two decades building because URL continuity and structured-data parity were engineered rather than checked at the end. A long-lived, messy content corpus moved intact instead of being manually cleaned up, and several plugin vendors were replaced by one coherent content model. Supporters now have a direct mobile channel — including the notification a broadcaster needs most, that the program is about to start — plus favourites, saved content and following, and editors kept the publishing habits they already had because the new CMS was built around their existing workflow rather than a framework's defaults.
Something holding you back?
New build, rebuild, or adding AI to what you already have — I'll take a look and give you an honest perspective.