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

Commit 75f2bee

Browse files
committed
docs(product-page): add canonical UseCases/Features/Integrations/Technical/user-guide + installation
Adds the openbuilt product-page sections so openbuilt.conduction.nl matches the 2026-05-13 fleet-wide layout (shillinq, procest, pipelinq, scholiq). OpenBuilt was missing from that batch. New top-level docs: - docs/UseCases/index.md — permit tracking, internal tooling, government compliance, citizen-led innovation + "when OpenBuilt isn't the right answer" carve-outs - docs/Features/index.md — the eight shipped features grouped by archived OpenSpec change (wizard, versioned model, promotion, ?_version= routing, detail-overview, nav, templates, page editor v1.1, MCP catalogue, export-to-real-app) - docs/Integrations/index.md — the Conduction ecosystem (OR, OC, Procest, Docudesk, NL Design, MyDash, Larping, pluggable registry) - docs/Technical/index.md — load-bearing ADRs, archived specs, test gate matrix (PHPUnit 216, Vitest 521, Hydra 14/14), MCP catalogue, schema vocabulary - docs/user-guide/index.md — user + admin tutorial pointers - docs/installation.md — prereqs, app-store path, source path, group-restriction, post-install smoke checks Pre-prod tone: no roadmap claims, no "coming soon" stubs — every section describes what's actually shipping (verified via the spec archives + test gates). Docusaurus auto-discovers the new dirs via the autogenerated sidebar; no sidebars.js update needed.
1 parent 1908044 commit 75f2bee

6 files changed

Lines changed: 462 additions & 0 deletions

File tree

docs/Features/index.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
sidebar_position: 2
3+
title: Features
4+
description: What ships in OpenBuilt today — the citizen-developer app builder for Nextcloud.
5+
---
6+
7+
# Features
8+
9+
OpenBuilt is a citizen-developer app builder for Nextcloud. Every feature below is shipped and verified by the spec gate (PHPUnit + Vitest + Newman + Playwright + Hydra mechanical gates — see [Technical](../Technical/) for the matrix).
10+
11+
## App creation wizard
12+
13+
A three-step modal that creates the parent Application, an admin-defined version chain (development → staging → production by default), and one per-version OpenRegister register per tier. The wizard is atomic: a failure at any step rolls back every resource it provisioned so the org-wide unique slug isn't squatted.
14+
15+
Highlights:
16+
17+
- **Identity step** — slug + name + description with live duplicate-slug detection.
18+
- **Versions step** — pick a preset (`single`, `dev-prod`, `dev-staging-prod`) or hand-design the chain. The wizard enforces ADR-002's linear-chain rule (no fan-out, no cycles, exactly one terminal `production` tier).
19+
- **Permissions step** — owners / editors / viewers, with the caller pre-filled into `owners`. Group `group:*` means "all signed-in users" (REQ-OBRBAC-004).
20+
21+
Spec: [`openbuilt-app-creation-wizard`](https://github.com/ConductionNL/openbuilt/tree/main/openspec/changes/archive/2026-05-17-openbuilt-app-creation-wizard).
22+
23+
## Versioned app deployment
24+
25+
Per ADR-002, every Application carries N ApplicationVersion rows on a linear `promotesTo` chain. Each version owns:
26+
27+
- a per-version OpenRegister register (`openbuilt-{appSlug}-{versionSlug}`) so dev data, staging data, and production data are physically isolated;
28+
- its own manifest (the page + menu + widget declaration);
29+
- its own semver — auto-bumped when the manifest changes meaningfully, untouched on metadata-only edits (the no-op-detect rule).
30+
31+
The `Application.productionVersion` pointer decides which version answers at `/apps/openbuilt/{slug}`. Switching `productionVersion` is a single OR write — rollback is instant, no redeploy.
32+
33+
Spec: [`openbuilt-versioning-model`](https://github.com/ConductionNL/openbuilt/tree/main/openspec/changes/archive/2026-05-17-openbuilt-versioning-model).
34+
35+
## Version promotion (dev → staging → prod)
36+
37+
Three strategies for moving one version forward into the next:
38+
39+
- **`migrate-existing-data`** — schema-import the source version's columns onto the target's existing rows (default when target IS the production version; preserves production data).
40+
- **`start-with-source-data`** — wipe target rows, copy source rows over (default for mid-chain targets; reproducible from-source build).
41+
- **`empty-start`** — wipe target rows entirely and start clean. Gated by a type-the-slug confirmation in the UI.
42+
43+
Failure handling: target flips to `archived`, OR lock releases, response carries `code: "promotion_failed"`. Source register is read-only throughout — a failed promotion never mutates the source.
44+
45+
Spec: [`openbuilt-version-promotion`](https://github.com/ConductionNL/openbuilt/tree/main/openspec/changes/archive/2026-05-17-openbuilt-version-promotion).
46+
47+
## `?_version=` URL routing (bookmarkable preview)
48+
49+
Every builder URL accepts an optional `?_version=<slug>` query that pins the rendered manifest to a specific ApplicationVersion. The leading underscore (`_version`, not `version`) is OpenBuilt's system-reserved namespace so citizen developers can ship their own `?version=` query params without collision.
50+
51+
- Without the param: the production manifest answers — accessible to everyone in the org.
52+
- With the param + production slug: also accessible to everyone.
53+
- With the param + non-production slug: only callers in `permissions.editors ∪ permissions.owners` see it. Viewers / non-members get a security-shaped 404 (no existence leak).
54+
55+
Spec: [`openbuilt-version-routing`](https://github.com/ConductionNL/openbuilt/tree/main/openspec/changes/archive/2026-05-17-openbuilt-version-routing).
56+
57+
## Application detail overview (maintainer dashboard)
58+
59+
The detail page for each Application packs the maintainer's daily working surface into one screen:
60+
61+
- **Hero strip** — icon, name, description, status, your role badge, productionVersion semver.
62+
- **Version pill strip** — one pill per version (most-upstream first), with `*` marking production. Click a pill to switch the rest of the page to that version.
63+
- **Window toggle (7d / 30d / 90d)** — drives the KPI + activity calls.
64+
- **KPI grid** — Active users, Object count, Files, Audit events for the selected (version, window).
65+
- **Activity graph** — daily event counts; empty-state when the window has no traffic.
66+
- **Structural widgets** — Register, Schemas, Pages, Menu cards with deep-links into OpenRegister, Schema Designer, Page Designer.
67+
68+
Spec: [`openbuilt-app-detail-overview`](https://github.com/ConductionNL/openbuilt/tree/main/openspec/changes/archive/2026-05-17-openbuilt-app-detail-overview).
69+
70+
## Nextcloud nav integration (one top-bar entry per published app)
71+
72+
Every published Application gets its own top-bar entry alongside Files, Mail, Talk etc. The entry's icon is served by `GET /apps/openbuilt/icons/{slug}.svg` (light) / `{slug}-dark.svg` (dark) and falls back to the app icon when the OR-attached file is missing.
73+
74+
Visibility is per-app: only callers who hold any role on the Application (or are listed via `group:*` wildcard) see the entry. Draft and archived apps stay hidden.
75+
76+
Spec: [`openbuilt-nextcloud-nav`](https://github.com/ConductionNL/openbuilt/tree/main/openspec/changes/archive/2026-05-17-openbuilt-nextcloud-nav).
77+
78+
## Templates marketplace
79+
80+
The "New from template" path clones a marked Application + its companion schemas into the caller's namespace. The same-user-same-slug case returns `slug_collision` 409 so the caller can pick a fresh slug; the cross-user case provisions an owner-namespaced register (`openbuilt-{ownerUid}-{slug}`) so two users can clone the same template without colliding on OR's organisation-wide unique constraint.
81+
82+
## Schema designer
83+
84+
A visual editor for the per-version schema set. Field types, lifecycle states + transitions, RBAC, relations to other schemas, widgets, aggregations, calculations and notifications all live in the schema's declarative annotations (ADR-031) — readable by humans, executable by OpenRegister at runtime.
85+
86+
## Page editor v1.1
87+
88+
JSON-driven page declaration with type-aware sub-editors per page type (`index`, `detail`, `form`, `dashboard`, `chat`, `logs`, `settings`, `files`, `custom`). Inline validator marks paint the offending field on save; an undo/redo stack covers the in-flight manifest; the Raw JSON tab is the integrator fallback for shapes the Design tab can't yet author.
89+
90+
## MCP authoring surface (for AI assistants)
91+
92+
OpenBuilt registers eight tools on the OpenRegister MCP bus so an LLM can author apps directly: `listApps`, `getAppManifest`, `createApp`, `promoteVersion`, `upsertSchema`, `upsertPage`, `addWidget`, `upsertMenuItem`. Each tool carries the per-app RBAC gate; an LLM acting on behalf of a user can only modify apps where that user holds owner or editor role.
93+
94+
## Export to a real Nextcloud app (Phase 2)
95+
96+
A built app is *virtual* by default — it lives as a record in OpenBuilt's register and is rendered inside the OpenBuilt shell at `/apps/openbuilt/{slug}`. Phase 2 export bakes the manifest, register, and schemas into a standalone Nextcloud app you can install on any Nextcloud instance — no OpenBuilt dependency at runtime.

docs/Integrations/index.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
sidebar_position: 3
3+
title: Integrations
4+
description: The Conduction ecosystem OpenBuilt composes from — registers, connectors, workflows, documents, dashboards.
5+
---
6+
7+
# Integrations
8+
9+
OpenBuilt is the composition layer of the Conduction ecosystem. Each built app reuses the same supporting services every other Conduction app uses — there's no second data layer, no second connector framework, no second document engine.
10+
11+
## OpenRegister — the data layer
12+
13+
Every OpenBuilt app's data lives in [OpenRegister](https://openregister.conduction.nl). Specifically:
14+
15+
- the parent **Application** record and its **ApplicationVersion** rows live in the shared `openbuilt` register;
16+
- each ApplicationVersion gets its **own per-version register** (`openbuilt-{appSlug}-{versionSlug}`) seeded with the version's schemas and rows;
17+
- the **BuiltAppRoute** index (slug → applicationUuid) gives `/apps/openbuilt/{slug}` its O(1) lookup.
18+
19+
OpenRegister contributes the audit trail (every mutation logged), object time travel (rewind any record to its state at time T), declarative state machines (ADR-031), per-record RBAC, organisation-wide multi-tenancy, and the schema validator.
20+
21+
Schemas you author in OpenBuilt are first-class OpenRegister schemas — they show up in the OpenRegister UI, validate against the same OAS-shape contract, and benefit from the same MCP tools.
22+
23+
## OpenConnector — system integration
24+
25+
When an OpenBuilt app needs to talk to a system outside Nextcloud — pull supplier data from G2, post a closed record into your ERP, fetch a TenderNed listing — it does so via [OpenConnector](https://openconnector.conduction.nl). OpenConnector handles HTTP, OAuth, REST, SOAP, SFTP, and the mapping between external payloads and OpenRegister schemas.
26+
27+
A built app declares its integrations in the manifest; the connector source rows live in OpenConnector. When the manifest points at `integrations.xwiki`, OpenConnector exposes the matching live XWiki space through OpenBuilt's integration sidebar.
28+
29+
## Procest — business workflows
30+
31+
Decisions, intakes, multi-step approvals — the state machine *between* the data lives in [Procest](https://procest.conduction.nl). OpenBuilt + Procest is the pattern for permit-tracking style apps: OpenBuilt owns the application form and the manifest; Procest owns the *how* of moving an application from intake through decision.
32+
33+
The two are loosely coupled — Procest reacts to OpenRegister `ObjectTransitionedEvent`s, so any OpenBuilt-authored state transition can fire a Procest workflow without OpenBuilt knowing.
34+
35+
## Docudesk — document generation
36+
37+
Turn an OpenBuilt record into a PDF, DOCX or signed document via [Docudesk](https://docudesk.conduction.nl). Common patterns:
38+
39+
- intake confirmation PDF emailed on form submission;
40+
- agenda + meeting minutes printable export from a Decidesk-style virtual app;
41+
- signed decision letter for permit approvals.
42+
43+
Docudesk reads the schema (templates bind to schema property paths) and the record (data) and emits the file. OpenBuilt apps reference Docudesk templates by slug in their manifest's `actions[]` declarations.
44+
45+
## NL Design System — government theming
46+
47+
OpenBuilt apps inherit the [NL Design System](https://nldesignsystem.nl) tokens via the [nldesign](https://github.com/ConductionNL/nldesign) Nextcloud theme. When `nldesign` is enabled, OpenBuilt's UI — buttons, inputs, modals, headings, colours — automatically conforms to the Dutch government's design standards, ensuring WCAG AA compliance and visual consistency with the rest of your municipal estate.
48+
49+
No app-side opt-in: it's a Nextcloud theme. Switch it on, every OpenBuilt app + every sibling Conduction app re-themes.
50+
51+
## MyDash — dashboards across apps
52+
53+
When stakeholders need a cross-app view — "today's open intakes across every municipality department" — [MyDash](https://mydash.conduction.nl) reads the OpenRegister GraphQL surface and renders widgets. OpenBuilt apps expose their data as registers, so MyDash widgets work against an OpenBuilt app the same way they work against any sibling app.
54+
55+
## Larping App — gamification + onboarding
56+
57+
[Larping App](https://larpingapp.conduction.nl) provides onboarding flows, skill-tree progression, and gamified citizen-developer training inside Nextcloud. The "build your first OpenBuilt app" tutorial lives there; OpenBuilt opens its hello-world preset directly from the Larping tour.
58+
59+
## Pluggable integration registry
60+
61+
OpenBuilt's pluggable integration registry (per nc-vue #202..#218 + openregister #1490 / #1493) means any future ecosystem app can publish a sidebar provider for OpenBuilt's detail page. When DeskDesk, Decidesk, Pipelinq etc. add a provider, the OpenBuilt app shell exposes their UI inline — no per-app patch.

docs/Technical/index.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
sidebar_position: 4
3+
title: Technical
4+
description: ADRs, test gates, MCP catalogue, schema vocabulary — the contracts OpenBuilt ships against.
5+
---
6+
7+
# Technical
8+
9+
OpenBuilt is built declaratively. The contracts below — ADRs, schema annotations, test gates — are the load-bearing surfaces an integrator or auditor reads first.
10+
11+
## Architecture decisions (ADRs)
12+
13+
OpenBuilt and its sibling Conduction apps share a single set of architectural decision records in the [hydra](https://github.com/ConductionNL/hydra) repo. The directly load-bearing ADRs for OpenBuilt:
14+
15+
| ADR | Title | What it means for OpenBuilt |
16+
|---|---|---|
17+
| **ADR-001** | App assets via OpenRegister files | Icons + future blobs are stored as files attached to the Application record, referenced by `{ref: "name"}` in the manifest |
18+
| **ADR-002** | Versioned app deployment model | Per-version registers + linear promotion chain + Application.productionVersion pointer |
19+
| **ADR-004** | Modal isolation | Every dialog lives in its own `src/dialogs/*.vue` file |
20+
| **ADR-007** | i18n | Apps support nl + en at minimum; keys live in `l10n/{nl,en}.json` |
21+
| **ADR-022** | Consume OR abstractions | No app-local DB access; every persistence path goes through OpenRegister |
22+
| **ADR-024** | App manifest | Every built app is rendered at runtime by mounting `CnAppRoot` with the app's manifest |
23+
| **ADR-031** | Schema-declarative business logic | State machines, aggregations, calculations, notifications declared as schema metadata, not service code |
24+
| **ADR-032** | Spec sizing | Single-purpose specs; thin-glue controllers; tests come bundled in the spec change |
25+
26+
The full ADR set lives at [hydra/openspec/architecture](https://github.com/ConductionNL/hydra/tree/main/openspec/architecture).
27+
28+
## Specs shipped today
29+
30+
Six OpenSpec changes archived 2026-05-17:
31+
32+
- `2026-05-17-openbuilt-nextcloud-nav` — top-bar nav entry + icon endpoints
33+
- `2026-05-17-openbuilt-app-creation-wizard` — three-step wizard + atomic provisioning
34+
- `2026-05-17-openbuilt-version-routing``?_version=` resolver + RBAC gate
35+
- `2026-05-17-openbuilt-app-detail-overview` — maintainer dashboard with KPIs + activity + structural widgets
36+
- `2026-05-17-openbuilt-versioning-model` — per-version registers + promotesTo chain + auto-bump semver
37+
- `2026-05-17-openbuilt-version-promotion` — three strategies + lock-contention 409 + on-failure archive
38+
39+
Each archive carries its `tasks.md` (every requirement crossed off with verification evidence), `proposal.md` (intent + design), and the spec delta(s) merged into `openspec/specs/`.
40+
41+
## Test gate matrix
42+
43+
OpenBuilt's CI gate is the same matrix every Conduction app ships against:
44+
45+
| Gate | Tool | Current state |
46+
|---|---|---|
47+
| PHP lint | `composer lint` | ✓ clean |
48+
| PHPCS | `composer phpcs` (PHPCS + custom sniffs) | ✓ 0 errors |
49+
| Psalm | `composer psalm` | ✓ 88% inferred |
50+
| PHPUnit | `composer test:unit` | ✓ 216/216 |
51+
| Vitest | `npm test` | ✓ 521/521 |
52+
| Newman | `npm run test:newman` (12 collections) | ✓ main + version-routing pass |
53+
| Playwright | `npm run test:e2e` | ✓ infra clean; per-spec content assertions tracked separately |
54+
| ADR-024 schema | `npm run check:manifest` | ✓ shell + wizard seed PASS |
55+
| Hydra gates (14) | `bash run-hydra-gates.sh` | ✓ ALL 14 GREEN |
56+
57+
Each green is reproducible from a clean checkout. The gates run in CI on every PR.
58+
59+
## MCP tool catalogue
60+
61+
OpenBuilt registers eight tools on the OpenRegister MCP bus so an LLM acting on behalf of a user can author apps directly:
62+
63+
| Tool ID | Purpose |
64+
|---|---|
65+
| `openbuilt.listApps` | Enumerate Applications visible to the caller |
66+
| `openbuilt.getAppManifest` | Read the resolved manifest for `(slug, version)` |
67+
| `openbuilt.createApp` | Atomic wizard-equivalent: app + N versions + N registers |
68+
| `openbuilt.promoteVersion` | Run a promotion strategy on a version edge |
69+
| `openbuilt.upsertSchema` | Create or update a per-version schema |
70+
| `openbuilt.upsertPage` | Add/edit a manifest page entry |
71+
| `openbuilt.addWidget` | Add a widget to a dashboard page's config |
72+
| `openbuilt.upsertMenuItem` | Add/edit a manifest menu entry |
73+
74+
Every write tool re-checks the per-app RBAC gate (owner or editor required) before mutating.
75+
76+
## Schema vocabulary
77+
78+
OpenBuilt-owned schema annotations live under the `x-openregister-*` namespace and pass through OR's vocabulary whitelist (`lib/Db/Schema.php`):
79+
80+
- `x-openregister-lifecycle` — state machine declaration (states, initial state, transitions). Used by OpenBuilt's ApplicationVersion schema for the `draft → published → archived → draft` cycle.
81+
- `x-openregister-validation` — assertion list on the schema (e.g. "promotesTo cannot equal own UUID" — the self-loop guard).
82+
- `x-openregister-aggregations`, `x-openregister-calculations`, `x-openregister-notifications`, `x-openregister-widgets` — same pattern, declarative metadata read at runtime.
83+
84+
Unknown `x-openregister-*` keys are dropped at save time and the dropped slug is logged so typos surface immediately.
85+
86+
## Source
87+
88+
- App repo: [`ConductionNL/openbuilt`](https://github.com/ConductionNL/openbuilt)
89+
- Foundation: [`ConductionNL/openregister`](https://github.com/ConductionNL/openregister) (OpenBuilt depends on OR ≥ 0.2.10)
90+
- Docusaurus preset: [`@conduction/docusaurus-preset`](https://www.npmjs.com/package/@conduction/docusaurus-preset) (this docs site)
91+
- nc-vue shared lib: [`@conduction/nextcloud-vue`](https://www.npmjs.com/package/@conduction/nextcloud-vue) (CnAppRoot, page-type registry, widget pool)
92+
93+
All code EUPL-1.2 — free to copy, modify and redistribute across the public sector.

0 commit comments

Comments
 (0)