Xircuit Blog

Product updates, developer logs, and news from behind the scenes at Xircuit.

Finding Your Way — Navigation Gets a Foundation cover image

Finding Your Way — Navigation Gets a Foundation


Finding Your Way — Navigation Gets a Foundation

A compass on an old map as a metaphor for orientation Photo: Vintage RS · StockSnap (CC0 1.0), via Openverse

Last time, the dev-log got a home — a standalone blog engine cleanly woven into the website. This time it was the app's turn, at a place you only miss once it's missing: orientation. Xircuit is a platform spanning seven industries, and the same person can be a gym member, a studio trainer, and a practice owner all at once. Wearing that many hats, you need an answer to three questions at every moment: Where am I right now? How do I switch elsewhere? And how do I get back? This phase turned a set of separate answers, grown over time, into one coherent system — and in doing so surfaced a bug sitting exactly where nobody was looking.

A bar that knows where you are

It started with the top bar. It carried too much and said too little: several controls side by side, but no clear word on which organisation you were actually in. So I rethought it. The logo now sits centred and calm in the middle, and the bar tints itself according to the kind of the active organisation — a gym gets a different accent than a practice or a club, so the colour alone signals which world you're in. The brand name carries that belonging in plain text: "Xircuit" becomes "Xircuit | Gym", depending on context. And Settings, which used to compete for space as its own icon, moved to where you'd expect it — into the profile menu. Fewer buttons, more meaning.

One control for context

The real work sat a layer below. Over the months, two rival switchers had grown — one to change the active organisation, another to jump between member and admin views. Each solved part of the problem, neither the whole, and together they caused more confusion than clarity. In their place there is now a single control in the app bar: the Context Control. It answers the first and second questions in one move — it shows where you are, and it's also the place you switch elsewhere. Its entries are grouped by organisation, with localised headings, and every switch point is uniquely addressable — which matters so the automated tests target the one correct switch rather than accidentally a similarly named one. Two half-answers gave way to one whole.

The way back — and breadcrumbs

That leaves the third question: the way back. This is where the most embarrassing blind spot lived. Several detail pages — the view of a single member, a trainer, a patient — had simply no way back. You could get in, but not out again without a detour. I pulled the scattered, repeatedly copied "back to the app" fragments into a single, well-defined building block and gave the detail pages that. A nice by-product of the tidy-up: four icon-only buttons had no accessible name at all — mute buttons, as far as a screen reader was concerned. That's fixed too.

On the deeper pages a second layer joins in: breadcrumbs. Where routes genuinely go three levels deep — say, from a member list to a single member — a breadcrumb trail traces the path: "Gym › Members › «Name»". Each page declares its own trail, so the labels — including dynamic ones like a person's name — are correct by construction. On the phone, where a full trail would be too wide, it collapses to a single parent link — the same back button you already know. One affordance at two widths, not two rival patterns.

A person walking down a foggy road as a metaphor for the way back Photo: Image Catalog · Flickr (CC0 1.0), via Openverse

The bug beneath the navigation

While tidying the paths, I ran into the most instructive find of the whole phase — a bug sitting right beneath the navigation. The app derives which industry a path belongs to from the path's first segment. That mapping was scattered across several places and, worse, it matched without anchoring: the comparison checked whether a path begins with a segment, not whether it equals it. The effect was insidious. /gym and /gyms share the same first four characters — so a route in one industry was silently attributed to the other. Everything compiled, everything looked right, and yet you occasionally landed in the wrong context.

The fix was to pull the resolution into a single, anchored place and compare exactly rather than by prefix. The genuinely unsettling part, though, wasn't the bug but its surroundings: an entire test suite of twenty-eight cases was green while the bug ran in production. The reason is a lesson in itself — every test asked "does the correct URL work?", none asked "does a similar URL wrongly match?". A net that only walks the expected path won't catch the misstep beside it. The new tests now explicitly probe the confusability — including a deliberately negative assertion that the wrong industry does not match.

Developers who live in their own app

A move that seems to have nothing to do with navigation and yet follows the same attitude: developer organisations are now fully set up and pre-onboarded. Until now, a developer signing in got a rich fixture of organisations — one per industry and tier — only to be redirected straight into the onboarding wizard at every single one, because the join timestamp was missing. Every member-facing route led into the same welcome funnel. That's over: the fixture sets the onboarding timestamp, a backfill tightly scoped to the developer users repairs the already-existing organisations without taking onboarding away from genuine new members, and each industry gets a plausibly filled intake profile — training goal, experience, a few values — so the member-facing pages show real content instead of empty states. Live in your own app every day and you feel that friction immediately — which is exactly why you fix it.

When the security light goes on

In between, the security audit raised the alarm: a reported vulnerability in a library deep in the dependency tree — an mXSS issue in an HTML parser we use only indirectly and exclusively through a sanitizer. Xircuit handles health data, and the house rule is strict: vulnerability warnings break the build. The reflex would be to simply upgrade. Except: the latest version of the sanitizer pins exactly the affected parser version — there is simply no upward fix that would repair the source. Rather than click the warning away, I deliberately assessed and documented it: the attack path requires a specific injected element, and everywhere we reach the parser at all, the input is either trusted or defused as plain text beforehand — the vector is unreachable. The exception carries a comment with the full rationale and a mandate to remove it as soon as the sanitizer ships on a patched parser version. You may run a security light — but only with your eyes open and a written record.

Three bugs the net caught

Finally, a familiar pattern: I went through Sentry and the open tickets, and out of the noise — expected denials from the authorization layer, rate limits from third parties, gracefully handled errors — three real production bugs emerged. The first sat in the daily website-analytics rollup: run on two instances starting at the same time, both want to insert the same daily row and trip over the unique index — which aborted the entire pass. It now reconciles the conflict instead of giving up. The second was a teardown race: a notice banner still reached for an already-released resource when you navigated away mid-check. The third threw an exception when reloading the dashboard, because a render was triggered off the right thread. All three are fixed, with tests that turn the bug red before the repair — and all three share the same moral as last time: a test net proves its worth not by glowing green, but by tearing at the right spot.

What's next?

Navigation is the kind of work nobody praises when it's right and everybody feels when it's missing. The app now consistently knows where you are, offers a single place to switch, and a reliable way back — and the bug that used to quietly send you into the wrong industry is closed, together with the gap in its tests. What comes next, I don't quite know yet. But the paths are laid now, and you can build on those.


Comments

No comments yet. Be the first to share your thoughts!

Comments are closed for this post.