User Journey: Check the versions and the database

Table of Contents

This page documents a user journey: A signed-in person reads what the browser, the deployment and the database are: the client build, the server build, and the database fingerprint.

A user journey describes what one person is trying to do, before anything is built. It is a design document that outlives any sprint, so it names the screens, the entity fields each screen shows, and the operations and messages each step needs.

1. Goal

"What am I talking to?" The person reads three builds in one place: the browser's own, the deployment's, and the database under it. The journey is done when all three are stated and compared, or when the screen says which of them it cannot read and why.

2. Actor and trigger

Any signed-in person. This is the one journey in the group that is not the system administrator's: a member reporting a fault, an administrator checking a rollout, and a support engineer on a call all ask the same question, and the answer is not sensitive. The answer is built into every screen already — the footer states the client and the server — and this journey adds the screen that states all three together. Because the answer belongs to every session, the shell offers the versions screen in every mode, so a tenant administrator and a regular user open it as well as the system administrator does; the four installation screens stay out of their reach, behind the Operations area that only system administration carries.

The trigger is doubt about a build: a screen behaves like yesterday's, a release note asks for the deployment's version, or a support request asks which database the deployment stores into. The journey ends when the three values are read, and the person can say whether the build they are testing is the build they think they have.

This journey writes nothing.

3. Steps

  1. Read the footer. Every screen carries a footer with two lines: the build the browser is running and the build the deployment is running. Two versions that disagree mean the browser holds a stale bundle, and the refresh that fixes it is not a guess. The server's version is absent until the deployment answers, and the footer says so rather than inventing one.
  2. Open the versions screen. When the question needs more than the two lines — the platform, the commit, the database — the person opens the versions screen. The system shows one screen with three panels: the client, the server and the database.
  3. Read the client panel. The system states the build the browser runs. The bundle carries it from the moment it was built and never changes afterwards: the release, the short commit the bundle was cut from, and whether the checkout had uncommitted changes at that moment. A person can match those three against the release they meant to test.
  4. Read the server panel. The system states the build the deployment runs, in full: the release, the platform triplet and the build information, in the same composition the login answer stated — the answer that opened the session names the build it was opened against. The panel adds the address the browser is talking to, so a person testing two deployments keeps them apart.
  5. Read the database panel. The system states the fingerprint of the database the deployment stores into: the fingerprint of the schema it was built from, the build environment, the commit and its date, and when the database was created. The four values arrive with the login answer — the same answer that states the server build — so the panel reads them without a second request. The answer carries the row today; a database whose row could not be read is stated as unknown (The login answer does not carry the database).
  6. Compare the three. Together the values answer what no single one can: a browser older than the deployment (a stale bundle), a deployment whose build does not match the schema the database records — which every service checks at its own startup, so the deployment would not be running — or a database built from a checkout nobody claims. The client and the server strings do not share a shape, so the screen shows them side by side for a person to compare; it cannot compare them mechanically.
  7. Leave, or go on. The versions raise the next question: which instances of each service run which build, which the services screen answers per instance, and what a stale build did, which the logs answer.

4. Screens and wireframes

Two surfaces, one answer. The footer is built and rides on every screen; the versions screen is the one this journey adds, with its three panels. The screen is read-only: it creates nothing, changes nothing and destroys nothing.

wireframe_check_the_versions_and_the_database.png

Figure 1: Check the versions and the database: the client, server and database panels, with the footer.

5. Prototype

Accepted by the user on 2026-10-04. The prototype is merged into main and kept there as the record; the accepted commit names the state.

Accepted commit
285519db99, the tip of prototype/operations-journeys, merged into main
Source
doc/prototypes/operations/versions-and-database/index.html
Open
/OreStudio/doc/prototypes/operations/versions-and-database/ once the site is built, or the file directly
Design record
Task: Prototype the operations journeys

The prototype settled where the database row comes from. The panel needs no read of its own: the login answer that already states the server build states the database row beside it, and the session keeps both. A session whose answer carried no row states the database as unknown, which the prototype shows beside the settled one. The panel's shape is settled too: fingerprint, environment, commit and created, in that order, which is the question "which checkout built this database".

6. Entities composed

Entity What it contributes Model
login answer The build the answering service runs, in full, and the database row, stated when the session opens ores.iam.login_messages
bootstrap answer The same build, stated before anyone can sign in ores.iam.bootstrap_messages
service_sample Each instance's own version, for the step that follows this journey ores.telemetry.service_samples
ores_database_info_tbl The fingerprint, build environment, commit and date of the database no model: the table is deliberately not a codegen entity

The client's build is not a model at all: the bundler stamps it into the browser code at build time, and it cannot change while the tab is open. That is the point of stating it — a client that matches the server proves the bundle is current, and a client that does not says the tab is stale. The database table is the other extreme: it is declared by hand in projects/ores.sql/create/database/database_database_info_create.sql, and it owes nothing to the code generators, because it records the checkout that built the database before any service runs.

The login answer's job grows by one row. It states the deployment's build, and it states the database beside it — fingerprint, environment, commit and created — read once per login from ores_database_info_tbl. The row's only reader was each service's startup check; the login answer is its second, and no subject of its own is needed — see What is missing.

7. Operations and messages

Step Operation Subject Status
Read the client version, on every screen (no operation: the build stamps the bundle) — exists
Read the server version, before sign-in The bootstrap answer states the build the service runs iam.v1.ops.bootstrap_status exists
Read the server version, at sign-in The login answer states the same build in full iam.v1.ops.login exists
Read the server version, on every screen The session carries the build it was opened against carried by the BFF route GET /api/session exists
Read the database fingerprint The login answer states the database row iam.v1.ops.login exists
Read the per-instance versions List the latest sample of every running instance telemetry.v1.services.list exists

The server version is composed by ores.utility::version::full_version_string() as the release, the platform triplet and the build information, and the login answer carries it in full. The BFF keeps it on the session record, so the footer states it from the first read onwards without asking the service again.

The database row is written when the database is created or recreated, and exactly one row exists. Each service reads it at its own startup and compares the fingerprint with the one compiled into the code, refusing to start when they differ — so a person reading the fingerprint tells which checkout built the database, and the deployment's own startup check is the reason the values agree until somebody recreates the database under a running service. The accepted design gives the row a second reader: the login answer carries it to the session.

The versions screen needs no route of its own. The session already carries the build the login answer stated, and the database row beside it, so the screen reads the session and asks for nothing. The hand-written BFF route pattern belongs to the services screen instead, which reads the roster through GET /api/operations/services on the journey runtime — see See the running services. A session whose answer carried no row states the database as unknown.

8. What is missing

  1. The login answer carries the database row. Closed by Carry the database on the login answer: the row is read once per login and travels on the answer and the session, with no subject, permission or route of its own. The versions screen still reads it from the session rather than a read of its own, which the screens task builds. A row that could not be read is stated as unknown.
  2. The database row's audience rides the login answer. The fingerprint names the commit and build environment the database was made from — build forensics, not customer data. Riding the login answer settles the audience with the server build's: everyone who may open a session may read it. The decision to record is that the two travel together, so a future change to one audience changes both.
  3. The client and the server strings cannot be compared mechanically. The client states the release and the commit; the server adds the platform and the build information in a different composition. One shared shape would let the screen mark a mismatch instead of leaving it to the eye.
  4. The services screen cannot compare builds either. Each service reports its release string only, so the per-instance versions this journey points to cannot tell two builds of one release apart. The gap is recorded on See the running services.

9. Related journeys

10. Related knowledge

11. See also

Emacs 29.3 (Org mode 9.6.15)