feat(router): move zaakafhandelapp off hash routing to clean path URLs - #609
Merged
Merged
Conversation
Second app in the fleet-wide move off `#` routing, after stackiq
(softwarecatalog#899) proved the pattern.
Verified BEFORE switching, because history mode fails at the SERVER when
the AppHost SPA catch-all is missing: /apps/zaakafhandelapp/zaken and
/taken already returned 200 with the app shell.
Two parts, and the second is the one that matters:
1. createWebHashHistory -> createWebHistory.
2. routerBase(), derived from the URL actually being served. Nextcloud
serves this app under BOTH /apps/zaakafhandelapp/... and
/index.php/apps/zaakafhandelapp/..., but generateUrl() returns only
the form the instance is configured for. Arriving on the other form
leaves the path outside the router base, vue-router cannot resolve it,
and the catch-all redirects to '/' -- the visitor lands on the
dashboard with no error and the deep link is silently swallowed.
This app's own e2e suite uses the /index.php form
(tests/e2e/app-path.ts: APP = '/index.php/apps/zaakafhandelapp'), so
without routerBase() every deep link the suite makes would break. That
is exactly how it was caught on stackiq.
The 11 spec files built URLs as `${APP}/#/<route>`; all now use real
paths.
Verified against the published @conduction/nextcloud-vue
(USE_LOCAL_LIB=false):
/apps/zaakafhandelapp/ -> Dashboard
/apps/zaakafhandelapp/zaken -> Zaken
/index.php/apps/zaakafhandelapp/zaken -> Zaken
/index.php/apps/zaakafhandelapp/klanten -> Klanten
RELOAD on /index.php/.../zaken -> 200, still Zaken
That reload is the point: it is the case hash mode existed to avoid, and
the catch-all serves it rather than 404ing. No hash anywhere.
e2e: ui-nav-navigation + ui-case-views, 21 passed / 3 failed, and the
three re-ran green in isolation -- they failed on `cn-app-root` never
mounting, i.e. the shell did not boot, which is the shared dev container
dropping into maintenance mid-run rather than a routing regression.
eslint exits 0 and `prettier --check "**/*.{js,ts,vue,css,scss}"` is
clean -- the FULL glob, tests included, not just src/.
Contributor
Quality Report — ConductionNL/zaakafhandelapp @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 537/537 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 07:16 UTC
Download the full PDF report from the workflow artifacts.
This was referenced Sep 1, 2026
Merged
rubenvdlinde
added a commit
that referenced
this pull request
Sep 1, 2026
…e de-hashing (#615) Follow-up to #609, which turned E2E red on development: 12 failed / 81 passed where the previous commit was green. Both causes were mine. 1. THE DE-HASH SWEEP WAS TOO NARROW. It replaced `${APP}/#/x` but not `${APP}/#${route}`, where the route variable already carries its own leading slash. Three call sites kept the `#`, so under history routing they resolved to the app root and every assertion about the target page failed. spaNavigate() and gotoIndex() are the two helpers, which is why nine record-index tests went down together. 2. THE APP HAD NO CATCH-ALL. appinfo/routes.php enumerates a page route per index (/zaken, /klanten, …), so those deep links worked while anything NOT in that list -- /features-roadmap, /auditTrail, any detail route -- 404'd at the server. Under hash routing this never showed, because the route travelled in the fragment and the server only ever saw the app root.⚠️ MY PRE-CHECK FOR #609 WAS WRONG, and this is the lesson: I probed /zaken and /taken, which are both ENUMERATED routes, and concluded a catch-all existed. Probing an enumerated path proves nothing. Probe a NONSENSE path: /apps/zaakafhandelapp/zzz-nonsense -> 404 (no catch-all) /apps/stackiq/zzz-nonsense -> 401 (catch-all present) Re-probed every converted app that way afterwards; only this one and openregister (still on hash routing, so unaffected) were missing it. The catch-all is spelled inline rather than via Routes::standard(), because this file also declares a `resources` block the builder does not carry. It is LAST so every explicit route above keeps priority. Also raised one test's budget from 90s to 240s, with the reason in the file: it walks 8 index pages by hard goto. Under hash routing those were SAME-DOCUMENT navigations; under history routing each is a full page load, so the walk costs roughly an order of magnitude more wall-clock. The assertion is unchanged.⚠️ The catch-all does not take effect until Nextcloud's route cache is dropped. With memcache.local = APCu, `occ app:disable/enable` is not enough -- a container restart is. Verified: ui-record-views 10/11 and ui-utility-pages 8/9, i.e. 11 of the 12 CI failures recovered. The one remaining is NOT routing: the audit page reports "Could not load log entries" because OpenRegister answers `Register not found: 'zaakafhandelapp'` on this workstation -- the register is not provisioned locally, and CI seeds it. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second app in the move off
#routing, after stackiq (softwarecatalog#899) proved the pattern.Verified before switching
History mode fails at the server when the AppHost SPA catch-all is missing. Probed first:
/apps/zaakafhandelapp/zakenand/takenalready returned 200 with the app shell.Two parts, and the second is the one that matters
createWebHashHistory→createWebHistory.routerBase(), derived from the URL actually being served. Nextcloud serves this app under both/apps/zaakafhandelapp/...and/index.php/apps/zaakafhandelapp/..., butgenerateUrl()returns only the form the instance is configured for. Arriving on the other leaves the path outside the router base, vue-router cannot resolve it, and the catch-all redirects to/— the visitor lands on the dashboard with no error, deep link silently swallowed.This app's own e2e suite uses the
/index.phpform (tests/e2e/app-path.ts:APP = '/index.php/apps/zaakafhandelapp'), so withoutrouterBase()every deep link the suite makes would break. That is exactly how it surfaced on stackiq.The 11 spec files built URLs as
`${APP}/#/<route>`; all now use real paths.Verification
/apps/zaakafhandelapp//apps/zaakafhandelapp/zaken/index.php/apps/zaakafhandelapp/zaken/index.php/apps/zaakafhandelapp/klanten/index.php/.../zakenThat reload is the point — the case hash mode existed to avoid, now served by the catch-all instead of 404ing. No hash anywhere.
e2e:
ui-nav-navigation+ui-case-views→ 21 passed, 3 failed; the three re-ran green in isolation. They failed oncn-app-rootnever mounting — the shell did not boot at all — which is the shared dev container dropping into maintenance mid-run, not a routing regression.eslintexits 0 andprettier --check "**/*.{js,ts,vue,css,scss}"is clean — the full glob, tests included, having twice landed format failures by checking onlysrc/.