Mount read-only inspector screens
Some bundled features ship read-only inspector screens over their internal read-models: a list (and detail) view an operator can open to see what is going on, GDPR export jobs, invalid download attempts, and so on. The screens live in the feature; your app only opts in by navigating them. No per-app screen code, no custom queries.
Prerequisites
Section titled “Prerequisites”- The bundled feature whose screens you want is mounted in your app (see the table below for which features ship them).
- You’ve read Features and composition so
r.requiresand qualified cross-feature names are familiar.
The code
Section titled “The code”The screens are registered but inert, they appear nowhere until your app navs
them. Add one r.nav per screen in any of your app features. They are
SystemAdmin-gated, so they surface only for platform operators:
defineFeature("my-app", (r) => { r.requires("user-data-rights");
r.nav({ id: "gdpr-export-jobs", label: "GDPR · Export Jobs", // qualified screen name: <feature>:screen:<id> screen: "user-data-rights:screen:export-job-list", access: { roles: ["SystemAdmin"] }, order: 90, });});That is the entire wiring. The list, the detail and their query handlers all
live in the feature, your app references the screen by its qualified name. The
nav resolves cross-feature with no import or coupling, and validateBoot fails
loudly if the screen name is wrong.
Which features ship inspector screens
Section titled “Which features ship inspector screens”| Feature | Screens | Shows | Gating |
|---|---|---|---|
user-data-rights | export-job-list, export-job-detail, download-attempt-list | GDPR Art. 20 export requests (user, status, requested / completed, expires) and invalid download attempts (result, IP, attempt time), DPO brute-force triage | SystemAdmin |
This table grows as more features expose inspector screens.
Inspector screens use the entityList / entityEdit machinery, which binds to
an event-sourced r.entity read-model (rebuild-safe). Features whose read-model
is a direct-write store (jobs, sessions, billing-foundation) cannot use
this pattern, registering those as entities would wipe the live table on the
next projection rebuild. A separate query-bound read-only primitive for those is
tracked as a follow-up.
Common gotchas
Section titled “Common gotchas”- No
r.nav, no screen. The feature registers its inspector screens either way; without a nav entry they are reachable by nobody and it looks like the feature never shipped them. - The screen name is qualified.
<feature>:screen:<id>, not the bare id,validateBootfails loudly on a wrong name, so a typo shows up at boot rather than as an empty menu. r.requires("<feature>")is mandatory. Without it the boot validator fails with a clear message, instead of the nav silently pointing at nothing once the feature leaves your feature list.- SystemAdmin gating is not optional trim. These screens expose raw
operator data across tenants; widening
access.rolesto hand a support role “just the list” hands it the whole read-model.
See also
Section titled “See also”- Bundled features, what each feature stores.
- Restrict a field to specific roles : narrowing what an operator screen shows, at the field.
- UI widgets, for the case where an inspector screen is not enough and you do build a screen.