← Back to Work

K-12 Job Spot

K-12 Migration Redesign

The account migration that lost its best idea two days before launch.


What I did

Reframed a failing account migration and designed an email-first flow that let the system detect each user's account type, instead of making people self-diagnose it before they could sign in.

Why I did it

Only about half the users moving from the old K-12 Job Spot to the new one finished the process. Migration was the single biggest threat to the launch — nothing else mattered if people couldn't get in.

What broke

Two days before the final sprint, engineering found the identity platform couldn't build the real-time detection the whole model depended on. The version I wanted was gone, with almost no time left to replace it.

What changed

We shipped a blunter, date-based fallback in the time we had. Migration completion went from 50% to 88%, and the flow dropped from eight-to-ten screens down to two-to-four.

Abstract flow diagram showing a tangled multi-step branching flow resolving into a short, direct flow

Context

Launching the new K-12 Job Spot meant moving every existing user off a legacy identity system and onto a new one owned by our platform team. Early adopter numbers were bad: only about half of the users who started the migration finished it. Everything else about the launch rode on people actually reaching the product, so this was the piece most likely to sink it.

Problem

The existing flow asked users to sort themselves before signing in — new account, legacy account, or no account yet. Every choice opened another branch of screens and confirmations, and a user could pass through eight to ten of them before getting in. Legacy users had it worse: right after signing in, they were asked to review and confirm their migrated profile data, which dumped work onto the exact moment they were trying to reach the product.

A few constraints made this harder than a normal login redesign:

  • The legacy and modern databases couldn't talk to each other freely.
  • A separate platform team owned authentication, not us.
  • We couldn't customize the platform-owned login screens.
  • Legacy passwords didn't always clear the new security requirements.
Abstract flow map of the original migration flow, with several self-selection branch points highlighted
Original flow map — 8–10 screens, self-selection branch points highlighted

Cutting a requirement nobody had questioned

Before touching the flow, I went after an assumption baked into it: that we had to carry every user's legacy profile data across. It had been in the plan long enough to stop being a decision and become a given. When I raised cutting it, Product pushed back — their worry was reasonable, that users would be upset to find old data gone.

So I didn't argue it on principle. I asked the PM to pull three numbers: how many profiles had been created in the past year, how many edited in the past year, and how many of those held anything beyond a bare name and email. About 80,000 had been created or updated, and fewer than half had more than the basics. I also pointed out that the new system didn't use the same fields as the old one, so a clean migration was never possible — we'd lose some data regardless. The only real question was how much of an already-partial transfer was worth delaying the launch to preserve.

Once Product saw the numbers, they came around, and were relieved to let it go. They added a line to the migration announcement email telling users who wanted their old data to retrieve it first, since it wouldn't carry over — which handled the exact worry they'd started with. With profile migration off the table, the redesign narrowed to a single job: get the user signed in.

The idea: let the system sort it out

Instead of making users identify their own account type, I flipped it. The user enters an email; the system checks whether it belongs to a new account, an existing Frontline identity, or a legacy account, and routes them to the right screen. One thing to do on the user's side, all the branching handled behind it. I worked through the routing logic with the PM and tech lead, checking each path against what the identity platform could actually support.

Abstract diagram of an email-first routing model, with one user input and system-side branching to three destinations
Email-first routing model — one input, system-side branching

The pivot

Two days before the final sprint, engineering came back with a problem: the identity platform team couldn't build the real-time account detection the whole model rested on. Two reasons. First, they were underwater — buried in requests and firefighting a backend that kept going down, with no room to take on more. Second, and harder to design around: their identity system is shared across every Frontline product. Checking for legacy accounts couldn't be scoped to K-12 Job Spot alone — switch it on for us and you switch it on everywhere, for every product on the platform. A migration convenience for one product wasn't worth that blast radius.

Either way, the version I wanted was gone, and we had two days to replace it with something that could ship.

What shipped instead

We went with a blunter, date-based rule. If someone hadn't created or used their account since April 2026, we told them to make a new one. Two buttons: sign in, or create an account. Guess wrong and the system caught it — try to create an account you already have and it sends you to sign-in; try to sign in without one and it sends you to create. The most likely mistake, someone typing old legacy credentials that were technically still valid, got a plain-language message telling them to make a new account instead of a dead-end error.

It didn't do the work for the user the way the email-first version would have. But it held onto the same rule: give people the fewest choices possible, and cover the edge cases with clear guidance instead of extra screens. Sign-in came out to two screens, account creation three, and even a wrong first guess topped out around four — down from eight to ten.

Abstract diagram of the shipped flow, showing a two-screen sign-in path and a three-screen creation path with a wrong-guess redirect between them
Shipped flow — 2/3/4 screens with the wrong-guess redirect path

Outcome

Migration completion went from 50% to 88%. Both figures come from Pendo, measured over comparable two-week windows — the first once we had enough volume to be confident the original flow was failing, the second in the two weeks after the new version deployed.

What I'd do differently

The expensive part of this project wasn't the design — it was learning about the platform constraint two days before the sprint. We'd agreed on the ideal solution, assumed it was buildable, and only hit the wall once there was no time left to react. A five-minute capacity check with the identity team's lead early on might have gotten the real version built, or at least bought us more than two days to plan the fallback. That's the change I'd make: pull the dependency team in before committing to a design that leans entirely on them, not after.

The part that held up better than I expected was the fallback itself. It worked because everything in the redesign traced back to one goal — cut the number of decisions between a user and their account. The email-first model was the sharper way to get there; the date-based model got there with a duller tool. Because the goal was right, the project survived losing the version I actually wanted to build.