Xircuit Blog

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

Organizations Get a Face: Contact Data and Profile Pages cover image

Organizations Get a Face: Contact Data and Profile Pages


Organizations Get a Face: Contact Data and Profile Pages

Contact data symbolizing organization profiles Photo: Breather · StockSnap (CC0 1.0), via Openverse

Until now, an organization in Xircuit was surprisingly anonymous. It had a name, an owner, a handful of members — but nobody could say where it was actually located, what phone number to reach it at, or which address an invoice should go to. For the first few weeks that wasn't a problem, because I deliberately kept the data models lean. But the closer we get to billing, public-facing presences, and legally sound emails, the clearer it became: without reliable master data, all of that stands on sand.

So this week I gave organizations a face. It sounds unspectacular — a few fields for contact and address, a page for editing them. But behind that facade is a decision that shapes the whole path ahead: how do you model data that has to work for seven very different industries at once, without building it seven times?

Why Master Data Has to Come First

There's a sequencing that keeps asserting itself in systems like this: before you can do anything with data, the data has to exist and be reliable. Billing needs an invoice address and a legal point of contact. Support needs a phone number and an email people can reach. And the marketing pages we want to roll out later need exactly the details an organization wants to present to the outside world.

All of these functions ultimately draw on the same source. If that source is inconsistent — the address spelled one way here and another way there, the contact email maintained three separate times in three separate places — the error multiplies with every feature built on top of it. That's why I deliberately decided against scattering contact details as loose text fields somewhere. Instead, organizations get structured contact and address fields as clean master data: separate fields for street, postal code, city, country, for phone and email, for the website. Structure instead of free text, because structure can later be queried, validated, and reused.

One Data Model, Seven Industries

Xircuit serves seven industries, and each speaks its own language. What's a "studio" in one is a "practice," a "club," or a "location" in another. The obvious but wrong reaction would be to build a separate data model for every industry. That would have given us sevenfold maintenance, sevenfold migrations, and sevenfold sources of error.

The path I chose cleanly separates what's technically identical from what only differs on the surface. The Organization entity gets the new contact and address fields exactly once. Underneath sits exactly one schema, one table, one truth. The industries differ only in vocabulary — in labels, in tone, in help texts. Technically, it's the same structure everywhere. This separation is the real core of the week: it makes it possible to build a feature once and still give seven different audiences the feeling that it was made for them.

The Profile Editor at /admin/org/

The new fields need a place where they can be maintained. I implemented that place as a dedicated profile editor page, accessible at /admin/org/{id}/profile. It bundles an organization's contact and address data in a single spot, instead of spreading it across various settings dialogs. Whoever manages the organization finds everything here that makes up its public and legal face.

The page is a Blazor component that loads the matching entity via the organization ID, binds the fields into a form, and validates changes server-side before they're saved. It was important to me that it works consistently across all seven industries. There aren't seven editors — there's one, which draws its vocabulary from the industry context. A fitness chain sees different terms than a physiotherapy practice, but both work with the same form, the same validation rules, and the same save path.

A map with a location pin Photo: Rawpixel (CC0 1.0), via Openverse

Vocabulary on the Surface, One Technology Underneath

How do you concretely solve the problem of the same page speaking differently depending on the industry? The trick lies in not hard-coding the labels into the component, but resolving them through the industry context instead. The surface follows the industry-dependent vocabulary while staying technically the same underneath. A field is internally just called AddressLine — what label the user actually reads is decided by the respective organization's industry.

That has a pleasant side effect for maintenance. If I later extend the contact model, say with a field for a second phone number or a VAT ID, that happens in exactly one place. All seven industries inherit the change automatically; I only need to add the respective vocabulary. That's the kind of decision that barely makes itself felt in the first few weeks and leaves you grateful to your earlier self half a year later.

What Builds on This Data

The real value of this week only shows up later, once other building blocks dock onto it. The contact data will feed several functions at once going forward: an organization's public-facing presence, outgoing emails, and legal disclosures. When we send a confirmation email, the footer can carry the organization's real address and real point of contact instead of a generic placeholder. When an organization gets a public page, it will pull its details from these same fields. And when it comes to legally required disclosures, there's finally a canonical source for them.

That's exactly why it mattered to me to lay the foundation cleanly before building on it. Consistent master data is the quiet prerequisite for billing, support, and marketing pages alike. None of these three functions is particularly spectacular at the moment you create the contact fields — but each of them would have become needlessly error-prone had the data stayed scattered and unstructured. So I see this week less as a feature in its own right and more as an investment that will pay off multiple times over the coming weeks.

A Deliberately Unassuming Building Block

Not every week in a product brings a visible new screen or a feature people immediately talk about. This one belongs to the quiet kind — and that's exactly why I like it. A data model that carries seven industries at once, an editor that works the same way everywhere and still sounds right everywhere, and master data that's finally reliable enough to build on. This is the kind of work you no longer see later, because everything built on it simply works.

What's Next?

Next week: observability for seven workers — Sentry in every background service, each with its own DSN.


Comments

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

Leave a Comment