On this page

Use it · docs/user-guide.md

User guide

For the people who work in Countersign every day: those who create and change records, those who approve them, and those who review what happened. Every screenshot shows the built-in demo (the vehicle fleet); your installation has your own record types and roles, but every screen works the same way. You can follow along in the demo: nothing you do there leaves your browser.

The screenshots are taken by a script that walks through the application from a fresh state (scripts/guide-shots.mjs), so they show what the current version really does.

The idea in one minute

  • A record (a vehicle, a depot, an option value, …) has versions. Version 1 is the first; every later change is a new version.
  • A version goes through three states: Created (a draft only its author can change), Confirmed (the author's sign-off; locked), Approved (signed by a second person; now in effect).
  • Changing an approved record does not change it. It opens the next version, which waits for approval while the approved one stays in effect.
  • Nothing is ever deleted. A record is retired (no longer counts, still shown) or removed (hidden from lists) by a new version, and every step is an entry in the audit trail.
stateDiagram-v2
  accTitle: A version goes from Created to Confirmed to Approved
  direction LR
  [*] --> Created: create
  Created --> Confirmed: confirm (the author)
  Confirmed --> Approved: approve (a second person)
  Confirmed --> Created: step back
  Approved --> Confirmed: step back
  note right of Approved
    In effect. Editing it opens
    the next version, which waits
    as Confirmed for approval.
  end note
You want to You need What happens
Add a record the right to write that record type v1, Created
Finish your draft to be its author Confirm: v1 is locked and waits
Put it into effect the right to approve that type, and not to be its author Approve: v1 is in effect
Change an approved record the right to write that type, and a reason v2, Confirmed by you, waits; v1 stays in effect
Send something back to be an approver (or, for Confirmed, the author), and a reason Step back by one state
Take a record out of use the right to write that type, a reason, and a second person Retire or remove, as a new version

Signing in

The sign-in screen of the demo

In the demo you choose a domain and a person; you can switch person at any time from the top bar, which is how you play both the author and the approver. In a production installation there is one button instead, "Sign in with Microsoft Entra ID" (or your organisation's single sign-on); who you are and which roles you hold come from there, and there is no way to switch person.

The overview

The overview

The top bar is always there: Records (the tree and this overview), Options (the catalogue of settings), Audit trail, Integrity, Configuration, and Pending my approval with the number of changes waiting for you. The status field in the middle says how many entries the trail has and whether its chain is intact.

Finding records

The tree, opened down to one vehicle class

The tree on the left follows your hierarchy; the number on the right of a line is how many records sit under it. The dot before a name is the record's state:

Dot Meaning
green approved and in effect
green with an amber ring approved, and a change is pending
amber confirmed, waiting for its first approval
grey created, a draft
hollow retired (shown only with "Show retired records")

Searching the tree

The search field finds records by name or ID.

Reading a record

A record with a pending change

Under the title are the record's ID, its summary fields and its badges: what is in effect ("Approved v1") and what is pending ("v2 Confirmed, awaiting approval"). The Details tab shows the values in effect; where the pending version differs, the new value is shown underneath in amber. The panel on the right is the signature panel: it shows the pending change, or who wrote and approved the version in effect.

Tabs: Details, Options (for records that can carry settings), Versions and Audit trail.

Options: which value applies, and why

Effective options of a vehicle

An option is defined once and can be set at any level. For this vehicle, each line shows the effective value, the source (the level and the record it comes from, or "Definition default"), the option value record and its version, what the value overrides at less specific levels, and any pending change. The order of precedence is written in the card's header: here Vehicle › Vehicle class › Depot › Region › default.

Only approved values count. A value that is still a draft or waiting for approval is shown as pending and changes nothing yet.

Four eyes: you cannot approve your own change

The author sees why he cannot approve

Bob wrote this change, so the panel shows him the checks, with the failed one marked, and no button to approve. The application never offers an action that the rules would refuse, and it says why.

The approver's inbox

The inbox of a quality assurance person

Pending my approval lists the changes you did not write and are allowed to approve, then your own drafts, then your changes waiting for someone else.

Signing

The signature panel for an approver

Before you sign you see the old and the new value, who wrote the change and when, the reason given, and the three checks. The line under the button is your signature: your name, your role, and its meaning; date and time are added when you submit. In a production installation a signature needs a recent sign-in: if yours is older than the configured limit (15 minutes unless your administrator changed it) you are asked to sign in again first.

After approval the new value is in effect

After approval the value is in effect at once, with the new version as its source.

Changing an approved record

Editing an approved record needs a reason

Edit (new version) opens the form with the current values. A reason is mandatory; the form cannot be saved without one. It goes into the new version and the audit trail.

The new version waits; the approved one stays in effect

Your edit is now v2, Confirmed by you. v1 is still what counts until someone else approves v2.

Sending a change back

Stepping back with a reason

Step back moves a version one state back: Confirmed to Created (so its author can change it), or Approved to Confirmed (revoking an approval; the previous approved version, if there is one, applies again). It always needs a reason.

Versions and the record's own audit trail

Version history

Versions lists every version with its state, the change from the version before, who wrote, confirmed and approved it, and the reason. An older approved version is shown as Superseded.

The audit trail of one record

Audit trail lists every action on this record: when, who (with their role at the time), what, old and new values, the reason, and the first characters of the entry's hash.

Creating a record

A new record

The + buttons in the tree and on a parent record ("+ Vehicle" on a depot) open the form. Fields marked * are required; the form checks the same rules the server does.

A draft

A new record is v1, Created: only you can edit it. Confirm when it is complete.

Removing a draft, retiring and removing a record

Removing a draft

A record that was never approved can be removed at once, by its author or an approver, with a reason.

A removed record

It disappears from the tree and lists; its page, versions and audit trail remain.

Retiring a record

An approved record is retired (it stops counting and is greyed out) or removed (it disappears from lists) by a new version that a second person approves. A record that others still refer to cannot be retired or removed; the message names them.

The options catalogue

All option definitions

Options lists every definition with its type, choices or range, default, and how often it is set. Definitions are records too: they have versions, four eyes and an audit trail.

A new option

People with the right to write option definitions add options: name, group, type (yes/no, number with unit and range, text, selection), default.

Choices in use are locked

A choice that values use cannot be renamed or removed, an option with values keeps its type, and a range cannot be narrowed past values in use. Change or remove those values first.

Where an option is set

On an option's page, Where it is set lists every value by level.

Setting a value

To set an option for a record, open the record's Options tab and choose "Set for this …". The value is a record of its own and goes through the same workflow.

The audit trail

The complete audit trail

Every action in the system, newest first. Filter by text, action, record type and person. Export CSV saves what the filters show; Export JSON saves the complete trail with every field and hash.

Removed records

Removed records are listed at the bottom, with who removed them and why.

Integrity

The integrity page

The page re-checks the whole trail in your browser and shows the head hash, which stands for the entire history: if it is written down somewhere outside the database, a later comparison shows whether anything was altered.

A forged entry is caught

In the demo you can tamper with your own entries to see what happens: an edited entry no longer matches its hash, and a forged entry with a recomputed hash fails when its command is re-run under the rules. A production server refuses every change while such a fault exists.

Configuration

The configuration page

Configuration shows what this installation is made of: the record types and their fields, how options are inherited, what each role may write and approve, and the history of the configuration itself. Everyone can read it. People whose role has the configure permission can change it, in two steps and with two people, as described next.

Changing the configuration

The configuration follows the same principle as the records: one person proposes, a second person approves, and nothing takes effect in between.

stateDiagram-v2
  accTitle: A configuration change is proposed by one person and approved by a second
  direction LR
  [*] --> Draft: Edit configuration
  Draft --> Proposed: propose, with a reason
  Proposed --> InEffect: approve (a second person)
  Proposed --> [*]: reject (a second person, with a reason)
  Proposed --> [*]: withdraw (the proposer)
  InEffect --> [*]
  note right of Proposed
    The configuration in effect is
    unchanged. One proposal at a time.
  end note

1. Edit a draft

The configuration editor with a problem shown next to the field that causes it

Edit configuration opens a draft of the next revision. Everything in the configuration document can be edited:

Part What you can do
Domain The name, the description and the suggested option groups. The id is fixed.
Record types Add, remove and reorder them; label, plural, id prefix, name field, description, and which fields are shown under the title.
Fields Add, remove and reorder them; label, type, required, unique, and what the type needs: the choices of a selection, the smallest and largest value of a number, the pattern of a text and its message, the help text.
Hierarchy A reference field points at a record type and is a parent (the record sits under it and inherits its options), a group (a grouping across parents) or a plain link. A parent may be optional (records can then stand at the top) and may point at its own record type (records then nest to any depth).
Roles Add, remove and reorder them; name, summary, and a table of what the role may write and approve.

The id of an existing record type or role and the key of an existing field cannot be changed: they are identities that permissions, records and the audit trail refer to. New ones choose theirs.

The draft is checked while you edit it. The bar at the top counts the problems; each problem is shown next to the record type, field or role that causes it. Two kinds of check run:

  • the rules for a configuration document (an id used twice, a selection without choices, a reference to a record type that does not exist, …), and
  • the records that exist: the same engine that decides on the server runs in your browser against the current records. In the picture, removing the choice “Petrol” is refused because four vehicles use it, and they are named.

Edit as JSON shows the same draft as a document, for pasting or for changes that are quicker in text; Load a file… replaces the draft by a configuration file. Both go through the same checks. The draft is kept in this browser tab until you propose or discard it.

2. Review and propose

The review: the changes, their effect on existing records, and the reason

At the end of the editor, Review and propose lists every change against the configuration in effect and says what it means for existing records: nothing, a refusal (to be resolved first), or a consequence that is accepted. In the picture a new required field is added: the vehicles that exist stay in effect and are marked until someone fills it in (see Records to complete). Give the reason (quote your change request) and Propose this change. That writes one audit entry and changes nothing else.

3. A second person decides

The proposal as its proposer sees it

The proposal is shown at the top of the configuration page to everyone: who proposed it, why, what it changes, and its fingerprint. Its proposer can withdraw it and is not offered the approval. While it waits, no other change can be proposed.

The proposal in the inbox of the second person

Everyone else who may configure finds it in their inbox and in the count at the top.

Approving the configuration change

Before signing, the second person sees the same list of changes and their effect on the records as they are now, and can download the proposed document. Sign and put into effect is a signature like any approval (on a server it needs a recent sign-in); from that moment the new revision is in force for every action. Reject… asks for a reason and leaves the configuration as it was. Either way the decision is an audit entry, and the history at the bottom of the page shows every proposal, approval, rejection and withdrawal.

Records to complete

A record that does not meet the configuration in effect

When a field becomes required, existing records cannot have a value for it yet. They stay in effect exactly as they were approved; each one is marked on its page, and the configuration page lists them under Records to complete. The next change to such a record has to fill the field in before it can be saved.

All other changes that existing records would contradict are refused until the records are changed first; the rules are in Configuration.

Records nested to different depths

A position five units deep, with a value inherited from the third unit up

A configuration can let a record type sit inside itself, and can make a parent optional, so the branches of the tree are as deep as the organisation they describe. The demo domain “Organisation chart” shows it: units contain units (Group › Division › Site › Department › Team in one branch, Group › Department in another), a second unit stands at the top beside the group, and positions hang off a unit at any depth.

  • The tree opens down to wherever a record is; records without a parent stand at the top of their section.
  • The path above the title lists everything the record sits under.
  • Options are inherited down every level: the nearest unit that sets a value wins, and the source column says which one. In the picture the approval limit comes from Plant Hamburg, three units up, and overrides the values of Operations and of the group.

A unit with what sits directly under it

A record's page lists what sits directly under it, with a count of everything further down, and offers to add the next record there.

Moving a unit: the units under it are not offered as its new place

To move a record, edit its parent. The list offers every possible place by its full path, and “None: at the top level” where the parent is optional. It never offers the record itself or anything under it, and the engine refuses such a move as well: a record cannot be its own ancestor. Like every change to an approved record, the move is a new version that a second person approves; until then the record stays where it is.

Records that came from another system

A migrated record

A record that was migrated shows its origin instead of an approver: the system it came from, its identifier there, the migration batch, and who approved it there as that system recorded it. From then on it behaves like any other record.

On a phone

The application on a phone

Everything works on a narrow screen; the tree is behind the Records button.

The configuration editor on a phone

Messages you may see

Message What it means What to do
Four eyes: you wrote … so someone else has to approve it. You are the author of this version. Ask a colleague with the approve right.
… is Confirmed and locked. Step it back to Created to change it. A confirmed version cannot be edited. Step it back (author or approver), change it, confirm again.
Changing an approved record needs a reason. The reason field is empty or too short. Say why the change is needed.
… still has N active records that refer to it. You are retiring or removing something others depend on. Retire or move those records first.
These choices are in use and can't be removed or renamed. Option values use the choice. Change or remove those values first.
… is under … so … can't be placed under it: a record can't be its own ancestor. You are moving a record below itself. Choose a place that is not under the record.
Does not meet the configuration in effect. A field became required after this record was approved. Edit the record and fill it in; a second person approves.
A configuration change proposed by … is waiting. Only one proposal can wait at a time. Have it approved, rejected or withdrawn first.
Four eyes: you proposed this configuration change, so someone else has to approve it. You are the proposer. Ask a second person with the configure permission.
… records hold a value for … that the new rules refuse (…). The configuration change would make approved data invalid. Change the named records first, then propose again.
A signature needs a sign-in from the last N minutes. Your sign-in is too old for a signature. Follow "Sign in again", then approve.
The audit trail failed its integrity check … Changes are refused. The server found a damaged entry. Tell your administrator; see Operations.