---
title: "The Migration Ticket Was Hiding a Landing Page"
canonical: https://dxdev.com/blog/2026-04-02_migration-became-landing-page/
datePublished: 2026-04-02
---
A ticket opened as a URL redirect. Two sentences in the description. The implied work was: move a scheduling product to a new path, verify nothing breaks, close the ticket.

That framing lasted about twenty minutes.

The moment I started thinking about what someone would actually see when they arrived at the new URL, the ticket stopped being plumbing. The product is a scheduling tool that sports organizations use to manage lineups. A redirect alone would move traffic, but it would not explain the destination or help a new visitor decide what to do next.

## what the ticket actually required

By the time the ticket was done, the scope included a full landing page. SEO metadata, an FAQ accordion, feature cards describing what the product does, a demo showcase, a sitemap update, and a site index entry.

The redirect itself was a contained change. The page that made the destination useful, understandable, and maintainable took the rest of the day.

I used an AI coding assistant for the implementation. It handled the scaffolding, followed the existing template structure, and wired the accordion component. It did not independently change the product framing; that was my responsibility. The frame was the problem, not the execution.

## the hotfix merge count

I had not anticipated how many times I would need to merge this work. The landing page touched the admin layer, the public-facing marketing layer, and the sitemap generation pipeline. Each of those lives on a different branch cadence in the production app.

My hotfix discipline involves cutting from master, merging into develop, and promoting to a preview branch before anything goes live. That sequence exists for good reasons. It also means a ticket crossing three surface areas produces three or four merge passes before the work settles.

Within that branch model, the merges were part of keeping the surfaces separated and reviewed. AI tooling can speed up the mechanics of an individual merge, but it does not remove the coordination represented by the release paths.

## the last ten percent is always naming

After the landing page was live, two things remained. The product had been running under one internal name and was being renamed. That rename had to propagate through page copy, sitemap entries, FAQ content, and a set of username references at the database layer.

The username piece was the smallest part and took the longest to verify. Usernames are load-bearing. Renaming them requires checking every table where the old string appears and deciding, for each one, whether the reference is display-only or identity-keyed. I checked four tables before I was confident nothing would break.

The rename itself is not a technical problem. It is a judgment call about what the product should be called. I made the call. The agent ran the find-and-replace. That division of labor worked fine.

## why framing determines scope

For this product move, the ticket could not remain a two-sentence redirect. The destination needed a place to land, a reason to trust it, and a way to understand the product. That was not only a code requirement; it was a distribution requirement hidden inside a technical ticket.

The ticket described how the code would move. It did not describe the experience of the person arriving at the new location. Asking that question changed the real scope of the work.

## Related

- [The New Door Was Already in the Building](2026-04-02_hidden-signup-existing-rails): another case where examining an existing user flow before building a new one reduced unnecessary surface area
- [Carry Your State in the URL, Then Actually Carry It: The Dropped Query Param](url-as-state-rethread-query-params-central-builder): a related URL-design lesson about preserving the context a destination needs
