Routes and pages, one access rule underneath.
What it is for
Every screen a customer sees, and every call the screens make to the server, is a route in the apps/ui/app tree. The routes decide which organisation is shown, which lens or review is open, and whether the reader may access the page. Session, profile and access explains identity. This page lists each route and how it handles requests.
What the app tree is
The web application uses the Next.jsNext.jsThe web framework used to build and run the NovusLens interface. It provides pages, server code and request handlers. App Router. A folder under apps/ui/app containing page.tsx defines a page. A route.ts defines a handler that returns data or files. Three files wrap every page: layout.tsx (the root layout), error.tsx (the error screen) and global-error.tsx (the fallback when the root layout itself fails).
Most pages are server componentsServer componentAn interface component prepared on the server before the resulting page is sent to the browser.. They read the signed-in viewer, load the organisation through a single load path, and render or refuse before any HTMLHTMLHypertext Markup Language: the format used to describe a web page's content and structure. is sent. Each page that reads the request’s search parameters exports dynamic = "force-dynamic", so it is rendered per request and never served from a build-time copy.
The route table
| Path | Kind | What it does | Key parameters |
|---|---|---|---|
/ | page | The twinTwinNovusLens’s model of one organisation, built from records about its teams, services and how they rely on one another. It is only as current as those records. surface. Shows one organisation’s structure, in the lens the URL names. Redirects as described below. | org, lens, view, cell, drill, tab, viewer (dev only) |
/twins | page | The index of organisations the signed-in account can access, and any organisation groups. For a signed-in viewer it opens with a Start here panel: the user-guide tutorial film from /docs and a link to the User Manual. Shows a sign-in prompt when there is no viewer. | signed_in, viewer (dev only) |
/overview | page | The selected items for review in one organisation, each with its owner, next step and source. | org, all (1 shows the omitted items), viewer (dev only) |
/evidence | page | The supporting records for one findingFindingA difference in the records that needs a decision. It includes its sources and can describe a slow handoff, disputed fact or missing owner. or one cellCellA box on the map that stands for a team, service, supplier or AI agent. It is a unit you can inspect, not necessarily a department or a person.. Shows a note when a finding has been replaced by newer findings. | org, finding, cell, view, viewer (dev only) |
/car | page | The Complexity, Agility and RecoverabilityRecoverabilityThe R in C/A/R: how well a team or service restores acceptable service after a failure. Recovery times and tested alternatives can supply evidence. assessment for each team in the organisation. | org, cell, scope, viewer (dev only) |
/brief | page | Preview of the management briefBriefThe management brief: a printable summary of the differences to review, with their sources, observation dates and limits. It is a snapshot taken when it is printed. for one organisation, with print and download actions. | org, viewer (dev only) |
/brief/status | page | Evidence check for a brief that was downloaded earlier. Says whether the tracked records have changed since the brief was generated. | org, export, viewer (dev only) |
/group | page | The consolidated view of an organisation group. Without group_id it says so and shows nothing else. | group_id, viewer (dev only) |
/audit | page | The activity log, fetched from the reasoning service and filtered by the form fields. | person, role, org, action, since, until, viewer (dev only) |
/import | page | Brings an organisation in (org chart, interview transcript or structured upload) and exports the current record. Read-only unless the account’s role is operator. | org, viewer (dev only) |
/guide | page | Redirects signed-in readers to the bundled GuideGuideThe help pages inside NovusLens. They explain the pages, input formats and tasks in the version you use. They are product instructions, not evidence about the organisation.. Unknown IDs show index and manual links. | id, viewer (dev only) |
/docs/[[...path]] | route handler | Serves the local documentation export after sign-in, including search assets, images and seekable videos. Supports GET and HEAD. | viewer (dev only) |
/login | page | The sign-in form, and the sign-out action on the same page. | error, signed_in |
/meaning | alias | Redirects to / with lens=knowledge. Every string parameter passes through except section. | any string parameter |
/search | alias | Redirects to / with lens=ask and section=search. Every string parameter passes through. | any string parameter |
/brief/download | route handler | Returns the brief as an HTML attachment and records the export. | org, viewer (dev only) |
/help-docs/[name] | route handler | Serves a Guide reference document from apps/ui/help-docs; manual names redirect to the complete local tutorials. | viewer (dev only) |
/help-images/[name] | route handler | Serves a Guide picture from apps/ui/help-images. | viewer (dev only) |
Where a page says viewer (dev only), the parameter is honoured only outside the customer profileDeployment profileA setting that selects customer or development behaviour. Customer mode refuses development credentials and uses the signed-in session as the identity., and only when no session cookieCookieA small value a browser keeps and sends back to a website. NovusLens uses a signed cookie to remember the signed-in account. is present. In the customer profile it is ignored. The rule is in resolveViewer in lib/session.ts.
How the lens works on /
The home page reads the URL and decides what to show. The steps run in this order.
- No organisation. Without
org, the page redirects to/twins. There is no default organisation. - Viewer and access. The viewer is resolved from the session, then (dev only) from
viewer, then (dev only) from thecxo-{org}convention. The organisation is then loaded throughloadTwinForPage. The access-refusal component shows signed-out, not-authorised or forgotten states. The rest of the page does not render. - Redirect to the overview. When none of
lens,view,cellordrillis present, the page redirects to/overviewwithorgandviewercarried over. Atabparameter on its own does not prevent this redirect. - The picture.
view=telemetryselects themeasuredpicture. Any other value, or none, selectstold. - Drill and cell.
drillopens the units inside a cell only when it names a cell whose parent is in the snapshot.cellselects a cell only when it exists in the snapshot. Anything else is ignored. - Lens.
lensis used when it is one of the values in theLENSESset inapp/page.tsx:twin,map,alignment,governance,domains,ask,timelineandknowledge. Any other value givestwin. Thetabvalue is passed to the view as its starting tab.
The alias routes depend on this. /meaning sets lens=knowledge, so the knowledge libraryKnowledge libraryThe organisation’s written procedures and definitions. Each entry records its source, date and who can read it. NovusLens cites these entries as supplied information. opens on the home page. /search sets lens=ask and section=search, which opens the search section of Ask and find.
Interfaces
Route handlers that serve files
/help-docs/[name] accepts only names matching lower-case letters, digits, underscores and hyphens followed by .html. Without a viewer it redirects to /login with status 303. The user and operations manual names redirect to /docs/manuals/…, retaining browser fragments. Other names read their legacy file; a missing file returns 404. File responses are private, no-store.
/help-images/[name] accepts only lower-case letters, digits and hyphens followed by .png. Without a viewer it returns 401 with a sentence asking the reader to sign in. A missing file returns 404. Responses are private, max-age=3600.
The legacy reference and picture handlers read from the help-docs and help-images folders under the application’s working directory. The route comments say those folders are copied in by scripts/guide_documents.py; the application itself does not write them.
Brief routes
/brief/download needs org, or it returns 400. It resolves the viewer, with the dev-only default, and returns 401 when there is none. In the customer profile a request with no session therefore receives 401. It builds an HTML attachment named after the organisation. It records the file hashHashA fixed-length fingerprint calculated from content. Comparing fingerprints helps detect changes and match records. and a new export identifier, and includes a /brief/status link. A refusal from the access layer returns 403.
/brief/status takes the export identifier and reports one of three outcomes: the tracked records are unchanged, they have been superseded, or current support could not be established. It states that the comparison does not certify the brief’s conclusions.
Application programming interface (API) routes
| Path | Methods | Purpose |
|---|---|---|
/api/reasoning/[...path] | GET, POST | The browser’s only route to the reasoning service. Adds the signed-in viewer and service tokenService tokenA secret value sent with requests between NovusLens services. The receiving service refuses requests with a missing or wrong value.. An unanswered call returns JSONJSONJavaScript Object Notation: a text format for data, using named fields, lists and values. Configuration files and service messages use it. 503 after 300 seconds for POST or 30 seconds for GET. Without a session in the customer profile it returns 401. |
/api/access/record | GET | Says whether the reader may now see the record a receiptReceiptA recorded acknowledgement of a request or action, with its identity, time and result. An evidence intake receipt confirms storage. It does not establish acceptance or prove that an agent acted. refers to. Returns 204 when yes, 401 when signed out or when org is missing, 403 when not now, and 503 when the entry check cannot complete. It says nothing more than that. |
/api/guide/[id] | GET | Returns one Guide page as JSON for the help drawer. Returns 401 without a viewer, 404 for an unknown identifier and 503 when the Guide cannot be loaded. |
The identity rules behind these routes, including why the reasoning proxyProxyA service that receives a request and forwards it to another service. The NovusLens web proxy adds the signed-in identity and service token. overwrites any viewer the caller names, are described in session, profile and access.
Layout and error pages
layout.tsx wraps every page. It passes the session identity to client providers. A flag enables the development viewer fallback only outside the customer profile. It also renders the account menu. The document title is “NovusLens — Live Twin”.
error.tsx is the error screen. It is a client componentClient componentAn interface component whose interactive code runs in the browser.. It shows “We can’t load your organisation right now”, a reload button and a /login link. Its support reference uses the error digest or organisation-unavailable.
global-error.tsx is the fallback when the root layout fails. It renders its own html and body and then the same content as error.tsx.
The app tree has no not-found.tsx, so an unknown path uses Next.js’s default not-found response.
Invariants and failure behaviour
- A page never defaults to an organisation or an account. Without
orgthe page goes to/twins. Without a session in the customer profile the page shows a refusal or a sign-in link. - Every organisation page takes the same path through
loadTwinForPage, so a refusal looks the same on every page. - Parameters that name a cell, a finding or a lens are checked against the data before they are used. An unknown value is ignored rather than shown.
- A failure to reach the database or the reasoning service is not a refusal. Page failures reach
error.tsxor appear as messages, as in the activity log. The contextual-help APIAPIApplication programming interface: a defined way for one program to request data or actions from another. returns JSON 503 for an unavailable Guide database. The bundled documentation remains readable. - The login form throttles attempts per account and per source address. Five failures in ten minutes lock out further attempts for that account or address. A wrong passphrase and an unknown account get the same message.