Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

feat: migrate procest to JSON manifest renderer (procest-manifest-v1)#320

Merged
rubenvdlinde merged 3 commits into
developmentfrom
feature/procest-manifest-v1
May 10, 2026
Merged

feat: migrate procest to JSON manifest renderer (procest-manifest-v1)#320
rubenvdlinde merged 3 commits into
developmentfrom
feature/procest-manifest-v1

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Summary

Migrates procest to the JSON manifest renderer pattern (ADR-024) using
@conduction/nextcloud-vue@1.0.0-beta.12. Mirrors decidesk PR #160's
shape (the canonical fleet reference). After this change procest's app
shell is driven by src/manifest.json + <CnAppRoot> instead of a
hand-written router + MainMenu.vue.

Commits

SHA What
be596db Spec + manifest + validator (openspec/changes/procest-manifest-v1/, src/manifest.json, tests/validate-manifest.js)
fe2949d CnAppRoot adoption + delete 7 obsolete views + folded router/MainMenu (src/main.js, src/App.vue, src/customComponents.js, 3 sidebar-tab stubs)
a1fdd42 Bump @conduction/nextcloud-vue to ^1.0.0-beta.12, mirror l10n/en_US.{json,js}, bump appinfo/info.xml to 0.2.0, document axios pin in webpack config

Page mapping (17 pages)

Page id Original New type Notes
Dashboard hand-coded view dashboard 11 widgets + grid layout
MyWork hand-coded view custom Bespoke 4-tab filter UI
Werkvoorraad hand-coded view custom KPI-strip work queue
Cases hand-coded view index schema=case
CaseDetail hand-coded view detail schema=case + 5 sidebar tabs
Tasks hand-coded view index schema=task
TaskNew/TaskDetail hand-coded view detail schema=task
CaseMap hand-coded view custom Leaflet + WMS/WFS
Voorstellen + VoorstelDetail hand-coded view custom Parafeerroute workflow (deferred)
Doorlooptijd hand-coded view custom apexcharts (lib chart-widget gap)
Settings/CaseTypes hand-coded view custom AdminRoot multi-tab editor (lib slot gap)
PublicCase/PublicAppointment/PublicStatus (out-of-tree) custom Anonymous public routes

Verification output

$ node tests/validate-manifest.js
manifest.version: 1.0.0
pages: 17
schema.version: 1.2.0
Ajv validation: PASS (0 errors)

$ NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 npx webpack --mode production
webpack 5.105.2 compiled with 9 warnings in 71835 ms
(All 9 warnings are 244 KiB asset-size limits — no module errors.)

ESLint not run: project's flat config references eslint-plugin-import
which npm install --legacy-peer-deps does not pull in (peer-dep gap
in @nextcloud/eslint-config). Same blocker exists on decidesk's
worktree. Webpack build is the de-facto compile gate.

Custom-component registry

10 surviving entries plus 3 sidebar-tab stubs (src/customComponents.js):

  • 3 genuine UI exceptions: MyWorkView, WerkvoorraadView, CaseMapView
  • 2 lib-gap blocked: DoorlooptijdView, AdminRootView
  • 2 deferred migrations: VoorstellenView, VoorstelDetailView
  • 3 anonymous-public: PublicCaseView, PublicAppointmentPage, PublicStatusPage
  • 3 sidebar-tab stubs: CaseTasksTab, CaseDecisionsTab, CaseDocumentsTab

Deferred items

  • Sidebar tab implementations — placeholders only (procest-case-relation-tabs follow-up)
  • Voorstellen migration to index/detail — parafeerroute lifecycle filter doesn't fit (procest-voorstel-v2)
  • Doorlooptijd to dashboard — blocked on lib chart widget primitive
  • Settings to type: settings — blocked on lib custom-component slot in widgets[] rich sections
  • Dashboard widget runtime smoke test — declared optimistically; downgrade if dispatch fails

Test plan

  • Smoke test on localhost:8080 — verify all 17 manifest pages render
  • Confirm legacy $router.push({ name: ... }) calls in views/cases/components/* and views/cases/widgets/* still resolve
  • Run regression Playwright suite once green
  • Confirm Dashboard widgets fire (type: custom resolution against renderer's dashboard page)
  • Confirm CaseDetail's sidebar tabs render CnNoteCard placeholders
  • Confirm OpenRegister-missing empty state surfaces when settingsStore.hasOpenRegisters === false

Stop gate

Per project memory ("Never push to development directly"), this PR is
left open for human admin-merge. No PR-creation/merge/archive tasks
appear in tasks.md (per the no-process-tasks-in-opsx convention).

Adds the spec, manifest, and schema validator for migrating procest
to the JSON manifest renderer pattern (ADR-024) as the canonical
reference decidesk PR #160 lays out.

src/manifest.json declares 17 pages:
- 1 dashboard (/)
- 3 index (cases, tasks, [optimistic complaints folded into 'index'])
- 3 detail (case detail, task new, task detail)
- 10 custom (MyWork, Werkvoorraad, CaseMap, Voorstellen + detail,
  Doorlooptijd, Settings, CaseTypes, Public case/appointment/status)

tests/validate-manifest.js mirrors decidesk's validator. Validates
PASS against schema v1.2.0 (0 errors).

The followup commits in this branch wire CnAppRoot, delete obsolete
views, bump the lib version, and mirror en_US.json.
Replaces procest's hand-written app shell with the manifest-driven
CnAppRoot pattern from @conduction/nextcloud-vue.

main.js
-------
- Builds vue-router routes from manifest.pages[*].{id, route} via a
  routesFromManifest() helper. Catch-all '*' redirect to '/' preserved.
- Mount-survivable bootstrap (mirrors decidesk commit 50e4df7c):
  registerTranslations() wrapped in try/catch, loadTranslations()
  fire-and-forget, mount unconditionally so a /l10n/<locale>.json 404
  in standard Apache configurations doesn't kill boot.
- Shallow-clones CnPageRenderer / defaultPageTypes / customComponents
  to work around Vue.extend's _Ctor cache mutation against
  non-extensible barrel exports.

App.vue
-------
- <CnAppRoot> host receiving manifest + customComponents + pageTypes
  as props. Preserves the OpenRegister-missing empty-state branch.
- Provides objectSidebarState + sidebarState aliases via Vue.observable
  for any custom views that still inject the legacy channel.

customComponents.js
-------------------
Registers 10 surviving custom pages and 3 sidebar-tab stubs:
- MyWorkView, WerkvoorraadView, CaseMapView (genuine UI exceptions)
- DoorlooptijdView, AdminRootView (lib-gap blocked migrations)
- VoorstellenView, VoorstelDetailView (deferred migration cost)
- PublicCaseView, PublicAppointmentPage, PublicStatusPage (anonymous)
- CaseTasksTab, CaseDecisionsTab, CaseDocumentsTab (CnNoteCard stubs
  for cross-schema relation tabs; full implementation deferred to
  procest-case-relation-tabs follow-up)

Deleted views (replaced by manifest-driven page types):
- Dashboard.vue → type: dashboard
- cases/CaseList.vue, cases/CaseDetail.vue → type: index/detail
- tasks/TaskList.vue, tasks/TaskDetail.vue → type: index/detail
- complaints/ComplaintList.vue, complaints/ComplaintDetail.vue → type:
  index/detail
- router/index.js → folded into main.js
- navigation/MainMenu.vue → replaced by lib's CnAppNav
…locale alias

Bumps @conduction/nextcloud-vue from ^1.0.0-beta.6 to ^1.0.0-beta.12
to pull in the Vue.extend frozen-component fix (closes the
"Cannot add property _Ctor, object is not extensible" error that
otherwise blocks vue-router from extending lib barrel exports).

webpack.config.js
-----------------
Drops the planned @nextcloud/axios$ alias in favor of decidesk's
working setup: the existing package.json `overrides` pin to ~2.5.2
ships both `import` and `require` export conditions, so
@nextcloud/vue's CJS bundle resolves require('@nextcloud/axios')
without any alias. Leaves a comment block documenting the rationale.

l10n/en_US.{json,js}
--------------------
Mirror of l10n/en.{json,js} so users on the en_US locale don't 404
the locale fetch in standard Apache deployments. Matches decidesk's
mount-survivable bootstrap design.

appinfo/info.xml
----------------
Bumps <version> from 0.1.10 to 0.2.0 to mark the manifest migration.

Verification
------------
- node tests/validate-manifest.js: PASS (0 errors against schema v1.2.0)
- npx webpack --mode production: builds clean (9 asset-size warnings only,
  no module/import errors)
- All 17 manifest pages have unique ids and validate against the v1.2.0
  schema's closed page-type enum
@github-actions

github-actions Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/procest @ 52466ce

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-05-09 16:39 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde rubenvdlinde merged commit 5db3089 into development May 10, 2026
31 of 41 checks passed
@rubenvdlinde rubenvdlinde deleted the feature/procest-manifest-v1 branch May 10, 2026 07:08
rubenvdlinde added a commit that referenced this pull request May 11, 2026
…anifest, keep calc service (#373)

Aligns the legesberekening surface with the manifest renderer pattern
established by procest-manifest-v1 (#320) and mirrored by the
parafeerroute refactor: tariff and history CRUD is now declared in
src/manifest.json against three OpenRegister schemas, while the
domain logic in LegesCalculationService / LegesExportService and the
non-CRUD endpoints (/api/leges/calculate, /recalculate, /verrekening,
/teruggaaf, /export) remain untouched.

Schemas (lib/Settings/procest_register.json)
- legesverordening: municipal fee regulation (year, effectiveDate,
  status, isActive, globalMaximum, reference)
- legesartikel: tariff line with type vast | percentage | staffel |
  maximum | combinatie, grondslagField, brackets, subArtikelen,
  category, order, scoped by verordening
- legesberekening: per-case calculation result with breakdown,
  version history (version, previousVersion, previousTotal,
  difference, correctionReason), status concept | opgelegd |
  verrekend | teruggegeven, exportedAt + exportFormat

All three are registered on the procest register so OpenRegister
exposes the standard CRUD endpoints — no bespoke controllers needed.

Manifest pages (src/manifest.json)
- Legesverordeningen — index of regulations, columns name/year/
  effectiveDate/status/isActive
- LegesverordeningDetail — detail with sidebar tabs Overview,
  Artikelen (related-index on legesartikel filtered by verordening,
  with create/edit/delete), Audit trail
- Legesberekeningen — index of calculation history, columns case/
  verordening/total/version/status/calculatedBy/calculatedAt,
  read-only actions
- LegesberekeningDetail — detail with Overview and Audit trail
- Two new settings-section menu entries (Legesverordeningen at
  order 96, Legesberekeningen at order 97)

Preserved
- LegesController::calculate, recalculate, verrekening, teruggaaf,
  export — all five remain (domain endpoints, no CRUD proxying)
- LegesCalculationService (vast / percentage / staffel / maximum /
  combinatie rules + verrekening + teruggaaf) — untouched
- LegesExportService (CSV / XML / JSON export to financial system)
  — untouched
- /api/leges/* routes in appinfo/routes.php — all five kept

Deletions
- None required. The pre-existing controller already exposes only
  domain endpoints; no CRUD methods, routes, or Vue views for
  leges tariffs / history existed prior to this change.

Validation
- jq parses both JSON files; new schemas + register list verified
- node tests/validate-manifest.js — structural lint PASS, 21 pages
- php -l on LegesController, LegesCalculationService,
  LegesExportService, appinfo/routes.php — no syntax errors
rubenvdlinde added a commit that referenced this pull request May 21, 2026
Picks up the schema 2.7.0 + CnPageRenderer top-level field forwarding +
CnDetailPage _lockState rename + config.schema → objectType bridging
shipped in nextcloud-vue#317/#319/#320 tonight.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant