Skip to content

docs(spec): public boot mode, public widget flag, and the journey runtime - #665

Merged
rubenvdlinde merged 1 commit into
developmentfrom
docs/spec-portaliq-phase-two
Aug 19, 2026
Merged

docs(spec): public boot mode, public widget flag, and the journey runtime#665
rubenvdlinde merged 1 commit into
developmentfrom
docs/spec-portaliq-phase-two

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What

Three spec-only changes for Portaliq phase two. No code in this PR.

Programme context: hydra#581 (ADR-084/085). First implementation slice: portaliq#114.

public-manifest-runtime

bootstrapCnApp() gains host: 'nextcloud' | 'public', so a manifest-v2 app can boot at a public origin.

Exactly four things differ between the two hosts — the mount element, URL resolution (generateUrl vs a configured base), transport auth (requesttoken vs bearer), and the router base. All four live in boot and cnFetch. No Cn* component takes a host prop: a component that needs to know is a component carrying a Nextcloud dependency it should not have, and the fix belongs in the component, not in a branch at the call site.

The integration test boots with OC, OCA, OCP and the requesttoken element deleted, and is first run against host: 'nextcloud' in that same environment to observe it fail. Without that control, a green public-mode test proves only that the environment supplied the globals anyway.

widget-registry-public-flag

Every dashboardWidgetRegistry entry gains public: boolean, defaulting to false, plus a markdown widget.

The registry is the fleet's single widget catalog — 40 registered types, consumed by OpenBuild and LaunchPad — and is about to gain a third consumer at a public origin. Registering a widget must not, by that act alone, make an authenticated capability anonymously mountable.

A finding carried from Portaliq's interim implementation

Portaliq implemented this same rule locally first, and got it wrong in a way worth recording. It kept an allow-list Set and a hard-coded widgetKey === 'markdown' render check — so the allow-list decided nothing. The mutation test that added files to it passed. A gate that read as real in review, and in the code, was decorative.

The fix was structural, not a stronger test: the allow-list became a key → component map, so the decision and the rendering are one thing and a mutation of it is observable.

The registry filter here must be built the same way. A public flag consulted beside an independent render condition is the same defect with a different spelling.

journey-runtime

CnJourney (in-page) and CnJourneyDialog (modal) — the one renderer for an OpenRegister journey.

  • Composes CnFormPage per form step rather than re-implementing field rendering, validation or conditional visibility.
  • Takes its step model from tilburg's con-stepper, which had it right: two levels, conditional steps, non-navigable groups.
  • Evaluates branches through the existing visibleWhen predicate and contains no second condition evaluator.
  • Route-split, measured on transferred bytes — a detail page must not pay for the journey renderer.

Also absorbs the Den Haag process-steps indicator as a library component emitting NL Design markup. @utrecht ships 95 -css packages to 17 -react ones, so pulling a React library into a Vue portal for one component is the wrong trade (ADR-072).

🤖 Generated with Claude Code

…time

Three spec-only changes for Portaliq phase two (hydra ADR-084/085). No code.

public-manifest-runtime — bootstrapCnApp gains host: 'nextcloud' | 'public'.
Exactly four things differ between the two: the mount element, URL resolution
(generateUrl vs a configured base), transport auth (requesttoken vs bearer)
and the router base. All four live in boot and cnFetch; NO Cn* component takes
a host prop, because a component that needs to know is a component carrying a
Nextcloud dependency it should not have.

The integration test boots with OC, OCA, OCP and the requesttoken element
DELETED, and is first run against host: 'nextcloud' in that same environment
to observe it fail. Without that control, a green public-mode test proves only
that the environment supplied the globals anyway.

widget-registry-public-flag — every dashboardWidgetRegistry entry gains
`public: boolean`, defaulting to FALSE. The registry is the fleet's single
widget catalog (40 types, shared with LaunchPad and OpenBuild) and is about to
gain a third consumer at a PUBLIC origin. Registering a widget must not, by
that act alone, make an authenticated capability anonymously mountable.

The proposal now carries a finding from Portaliq's interim implementation of
this same rule: it kept an allow-list Set AND a hard-coded
`widgetKey === 'markdown'` render check, so the allow-list decided nothing —
the mutation test that added `files` to it PASSED. A gate that read as real in
review was decorative. The fix was structural, not a stronger test: the
allow-list became a key→component map so the decision and the rendering are
one thing. The registry filter here must be built the same way; a `public`
flag consulted beside an independent render condition is the same defect with
a different spelling.

journey-runtime — CnJourney and CnJourneyDialog, the ONE renderer for an
OpenRegister journey, in-page and in a modal. Composes CnFormPage per form
step rather than re-implementing field rendering; takes its step model from
tilburg's con-stepper, which had it right (two levels, conditional steps,
non-navigable groups); evaluates branches through the existing visibleWhen
predicate and contains no second condition evaluator.

Also absorbs the Den Haag process-steps indicator as a library component
emitting NL Design markup — @utrecht ships 95 CSS packages to 17 React ones,
so pulling a React library into a Vue portal for one component is the wrong
trade.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/nextcloud-vue @ 34a7f6b

Check PHP Vue Security License Tests
lint ⏭️
phpcs ⏭️
phpmd ⏭️
psalm ⏭️
phpstan ⏭️
phpmetrics ⏭️
eslint
stylelint
build
test
check-build
check-docs
check-jsdoc
check-integration-parity
check-peers
check-docs-fresh
check-a11y
check-smoke
composer
npm ✅ 531/531
app:check-code ⏭️
info.xml ⏭️
REUSE
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️
Hydra gates ⏭️

Quality workflow — 2026-08-15 07:59 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 9b87186 into development Aug 19, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant