Skip to main content
Back to blog

A Self-Service Sign-In Now Decides Which Product You Meant

Riya Mittal
Riya Mittal Engineer · Zop.Dev
4 min read
A Self-Service Sign-In Now Decides Which Product You Meant

A Self-Service Sign-In Now Decides Which Product You Meant

Three products behind one login used to mean three separate bookmarks, a small self-service tax that added up every time someone forgot which one they’d saved. ZopNight now has a single shared sign-in at /zopnight/app/signin, where a user signs in once and picks the product they want: ZopNight, zopcloud, or ZopDay. The system remembers whichever one they used last and takes them straight there the next time, and each product’s own existing sign-in page still works exactly as it did before, going directly to that product without a detour through the picker.

The shared door reuses the login page that was already deployed at that path, just wearing zopdev branding instead of any one product’s identity. No new service was stood up, no ingress rule added, no environment variable introduced, and no migration run to ship it.

The Door You Arrive Through Is a Statement of Intent

The design rule underneath this is simple to state and easy to get wrong: the door a person arrives through is itself information. Signing in on ZopDay’s own login page is a stated intent to use ZopDay, so that choice is remembered and the person lands there directly, every time, without being asked again. Signing in through the shared door carries no such intent. Nothing is recorded until the person actually picks a product at the picker screen.

Architecture diagram

The full sequence for a new person is: sign in, create an organization if none exists yet, land on the picker, then land on the product they chose. The entire shared journey wears zopdev’s own branding throughout, on the page itself, the browser tab title, and the favicon, rather than flipping over to a product’s identity on the very screen where a password gets typed.

The Preference Belongs to a Person, Not a Machine

Where that remembered choice is stored matters as much as the fact that it’s remembered at all. It’s keyed to the person’s email address, not to the browser they happened to sign in from. A shared machine, a shared laptop at a desk two people use on different shifts, must never send the second person who signs in on it into the first person’s product just because the browser remembers something. Keying to email instead of browser is what prevents that.

A stored value that’s stale or has been hand-edited into something the system doesn’t recognize resolves back to the picker screen rather than attempting a redirect to a product that no longer applies. Sending someone to a broken destination is worse than asking them once more which product they meant.

A related fix in the same area made organization creation itself safe against a double click: a Redis-based fence combined with a membership lookup makes the request idempotent, so the organization automatically created during onboarding can’t end up duplicated by a retried or accidentally repeated submission.

A Reorder That Was Also a Default

A separate, smaller change reordered the picker’s three cards to read zopnight, zopcloud, zopday. On its own that sounds purely cosmetic: no copy changed, no color changed, no card’s destination changed. What actually changed underneath it is the default, because the picker pre-selects whichever product sits first in that list.

Card positionProductWhat happens if a visitor with no remembered preference does nothing else
FirstZopNightOpens automatically as the pre-selected default
SecondzopcloudRequires an active choice
ThirdZopDayRequires an active choice

Before the reorder, a visitor arriving at the picker with no history at all would have landed on whichever product sat first in the old order. After it, that same visitor lands on ZopNight instead. Reordering three cards on a screen turned out to be a product decision wearing a styling decision’s clothes.

A Passing Test That Was Checking the Wrong Thing

The reorder itself was verified the hard way, by measuring real pixel positions in an actual browser (x-coordinates 285, 604, and 924 for the three cards), specifically because the existing automated test for card order could never have caught a broken reorder here even if one had shipped. That test looked up each card by its internal test identifier through a mapped list of expected ids, which meant the first card the test checked was always whichever id the test’s own list happened to name first, not whichever card the browser actually rendered first. The test could pass forever regardless of what a real visitor saw on screen.

The fix makes the test query the rendered document directly instead of trusting its own internal list of expected identifiers. That one change moved the number of real defects this specific test suite is capable of catching from one to two, which is a small number, but it’s the difference between a test that verifies something and a test that only verifies its own assumptions about itself.

Tagged
Riya Mittal

Riya Mittal

Engineer · Zop.Dev

Riya is an AI engineer at ZopDev, working on production LLM pipelines behind the company's content and account-intelligence platforms. She works on the engineering that makes these systems reliable and repeatable, from multi-provider orchestration and structured output validation to evals, idempotent pipelines, and automated recovery. She writes about what it takes to make AI systems reliable enough to run in production.

Stop watching the waste.
Start cutting it.

See. Find. Fix. Automatic.

Connect your first cloud account in under 5 minutes. See your first remediation in under 7. No credit card required.

CDCR connect detect classify remediate
full audit every action traceable
read-only default access
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·