docs(integration-registry): developer guide + leaf scaffold + tracking sync (umbrella PR 10b/N)#1490
Conversation
…g sync (umbrella PR 10b) The openregister-side companion to the nextcloud-vue PRs (#202/#204/ #209/#210/#211). No production-code change here — docs, a scaffold script, and the umbrella's task-tracking sync. - docs/Integrations/pluggable-integration-registry.md (new) — "How to add an integration": the five built-ins table, storage strategies, the scaffold quickstart, a worked walkthrough (PHP provider → JS tab+widget → registration → surfaces light up → admin/health), and a reference section - scripts/scaffold-integration.sh (new) — `scaffold-integration.sh <id> [<Label>]` generates `openspec/changes/integration-<id>/` with proposal.md, tasks.md (within the ADR-028 cap), hydra.json (depends_on: pluggable-integration-registry), a PHP provider stub and a JS registration stub. Validates the id is kebab-case; derives the PascalCase class name; refuses to overwrite. - README.md — "Integrations" section now leads with the pluggable integration registry, pointing at the developer guide - openspec/changes/pluggable-integration-registry/{tasks.md, plan.json} — mark tasks 6.x / 7.x / 8.x / 9.x / 10.x / 12.1-12.2- 12.4 / 13.x / 14.x / 15.x done, with the cross-repo PR references inline; documents the spec deviations (listByGroup → inline filter; check-integration-parity.js not .sh; parity step folded into code-quality.yml not a separate workflow); flags the two explicitly-deferred items (hydra quality-gate hook 12.3, ADR-019 authoring — both separate hydra-repo PRs) Implements tasks 13.1-13.2 and 14.2-14.3 of the umbrella, and syncs the tracking for everything landed in the nextcloud-vue PRs. Smoke-tested: `scaffold-integration.sh scaffoldtest "Scaffold Test"` generates the expected tree; plan.json stays valid JSON.
There was a problem hiding this comment.
[CONCERN] Generated PHP stub lacks SPDX / @copyright / @license header
The PHP provider stub written to stubs/${PASCAL}Provider.php has no SPDX-License-Identifier line, no @copyright, and no @license doc-block. Every other PHP file in the repo carries these headers. Downstream consumers who move the stub into production without noticing will fail the SPDX gate. Add a # SPDX-License-Identifier: AGPL-3.0-or-later line (or the repo-standard copyright block) to the heredoc before declare(strict_types=1);.
There was a problem hiding this comment.
[CONCERN] Generated JS stub lacks SPDX / @license comment
The JS stub written to stubs/${ID}.js has no // SPDX-License-Identifier: AGPL-3.0-or-later or /* @license … */ comment. The repo's hydra-gate-spdx check will flag any file that ships to production without one. Add the SPDX comment as the first line of the JS heredoc.
There was a problem hiding this comment.
[CONCERN] Bash parameter substitution inside double-quoted heredoc is fragile
Lines 532 and 546 use ${ID//-/} (strip hyphens) inside the JS heredoc. The substitution is performed at generation time which is the desired behaviour, but if someone later quotes the heredoc delimiter ('EOF') to prevent other expansions, these substitutions will break silently. Consider computing CAMEL="${ID//-/}" near the top alongside PASCAL and using $CAMEL explicitly in the heredoc for clarity and robustness.
|
|
||
| ```bash | ||
| # from the openregister repo root | ||
| scripts/scaffold-integration.sh contacts |
There was a problem hiding this comment.
[CONCERN] Link to normative contract (design.md) points to a file not present in this PR
Line 23 links to ../../openspec/changes/pluggable-integration-registry/design.md. That file does not appear in the diff. Verify the file exists on the base branch (feature/1307/admin-ui-for-auth), or update the link to the correct existing artefact (e.g. the tasks.md or plan.json).
| icon: 'AccountBox', | ||
| requiredApp: 'contacts', | ||
| order: 10, | ||
| group: 'comms', |
There was a problem hiding this comment.
[CONCERN] Docs reference an incomplete contract surface — canHandle() / declare() / getCapability() absent
Per the umbrella PR series the normative interface includes declare(), canHandle(), get(), list(), getCapability(). The developer guide shows only getId(), getLabel(), getIcon(), getGroup(), getRequiredApp(), getStorageStrategy(), isEnabled(), list(), plus a mention of get/create/update/delete. If canHandle(), declare(), and getCapability() are required by the IntegrationProvider interface, omitting them here will cause implementors to produce incomplete providers.
There was a problem hiding this comment.
[CONCERN] PHP stub hardcodes namespace OCA\OpenRegister\Service\Integration\BuiltinProviders
The scaffold is intended for third-party / consuming-app providers, not just OpenRegister built-ins. Placing an external app's provider in OCA\OpenRegister\… is incorrect. The comment says "Move this into the appropriate location" but the namespace declaration will be wrong after the move. The stub should either use a placeholder namespace (e.g. OCA\YourApp\Service\Integration) with a clear TODO, or accept a namespace argument.
WilcoLouwerse
left a comment
There was a problem hiding this comment.
Review
🟡 Concerns (6)
- Generated PHP stub lacks SPDX / @copyright / @license header —
scripts/scaffold-integration.sh:519 - Generated JS stub lacks SPDX / @license comment —
scripts/scaffold-integration.sh:519 - Bash parameter substitution inside double-quoted heredoc is fragile —
scripts/scaffold-integration.sh:532 - Link to normative contract (
design.md) points to a file not present in this PR —docs/Integrations/pluggable-integration-registry.md:23 - Docs reference an incomplete contract surface —
canHandle()/declare()/getCapability()absent —docs/Integrations/pluggable-integration-registry.md:83 - PHP stub hardcodes namespace
OCA\OpenRegister\Service\Integration\BuiltinProviders—scripts/scaffold-integration.sh:451
🟢 Minor (2)
- AD reference inconsistency: AD-22 vs AD-19 for storage strategies (
docs/Integrations/pluggable-integration-registry.md:35)
Line 35 attributes storage strategies to(AD-22). Lines 85–86 and 286 of tasks.md referenceAD-19for surface fallback. Verify the correct AD number — some umbrella PRs renumber ADs as they land. - Scaffold output references
openspec validatecommand that may not exist (scripts/scaffold-integration.sh:553)
Line 553–554 printsopenspec validate integration-$ID --strictas the suggested next step. Ifopenspecis not a real CLI available in the dev environment, this will mislead developers. Replace with the actual validation command or remove the hint.
Reviewed by WilcoLouwerse via automated batch review.
WilcoLouwerse
left a comment
There was a problem hiding this comment.
Review
(Inline comments already posted above — this is the summary verdict.)
🟡 Concerns (6)
- Generated PHP stub lacks SPDX / @copyright / @license header (
scripts/scaffold-integration.sh:519) - Generated JS stub lacks SPDX / @license comment (
scripts/scaffold-integration.sh:519) - Bash parameter substitution inside double-quoted heredoc is fragile (
scripts/scaffold-integration.sh:532) - Link to normative contract (
design.md) points to a file not present in this PR (docs/Integrations/pluggable-integration-registry.md:23) - Docs reference an incomplete contract surface —
canHandle()/declare()/getCapability()absent (docs/Integrations/pluggable-integration-registry.md:83) - PHP stub hardcodes namespace
OCA\OpenRegister\Service\Integration\BuiltinProviders(scripts/scaffold-integration.sh:451)
🟢 Minor (2)
- AD reference inconsistency: AD-22 vs AD-19 for storage strategies (
docs/Integrations/pluggable-integration-registry.md:35) - Scaffold output references
openspec validatecommand that may not exist (scripts/scaffold-integration.sh:553)
Reviewed by WilcoLouwerse via automated batch review.
WilcoLouwerse: generated stubs lacked SPDX/@license headers — apps using the scaffold would fail composer license CI on every new integration. Add inline SPDX-License-Identifier + SPDX-FileCopyrightText inside the heredoc'd stubs. Other review concerns surveyed: - design.md link target exists at openspec/changes/pluggable-integration-registry/design.md (not stale) - 'openspec validate <item-name>' is the correct CLI form (verified working) - Heredoc parameter substitution is intentional (bash expands ${PASCAL}/$ID/$LABEL — double-backslashed for PHP namespace separators is correct output) Docs concerns (canHandle/declare/getCapability not surfaced in guide) left for follow-up PR — additive doc work, not a blocker.
Part of #1307. Stacked on #1475 (admin UI) → … →
development. No production-code change — docs, the leaf-scaffold script, and the umbrella's task-tracking sync. Companion to the nextcloud-vue PRs (#202 / #204 / #209 / #210 / #211).What's in this PR
docs/Integrations/pluggable-integration-registry.md(new) — "How to add an integration": the five built-ins table, storage strategies (AD-22), the scaffold quickstart, a worked walkthrough (PHP provider → JS tab+widget → registration → surfaces light up → admin/health), reference links.scripts/scaffold-integration.sh(new) —scaffold-integration.sh <id> [<Label>]generatesopenspec/changes/integration-<id>/withproposal.md,tasks.md(within the ADR-028 cap),hydra.json(depends_on: ["pluggable-integration-registry"]), a PHP provider stub, and a JS registration stub. Validates the id is kebab-case; derives the PascalCase class name; refuses to overwrite.README.md— the Integrations section now leads with the pluggable integration registry, pointing at the developer guide.openspec/changes/pluggable-integration-registry/{tasks.md,plan.json}— marks tasks 6.x / 7.x / 8.x / 9.x / 10.x / 12.1-12.2-12.4 / 13.x / 14.x / 15.x done with the cross-repo PR references inline; documents the spec deviations; flags the two explicitly-deferred items (the hydra quality-gate hook 12.3 and ADR-019 authoring — both separate hydra-repo PRs).Implements tasks 13.1–13.2 and 14.2–14.3; syncs tracking for everything landed in the nextcloud-vue PRs.
Test plan
scaffold-integration.sh scaffoldtest "Scaffold Test"generates the expected tree (proposal/tasks/hydra/stubs); validates the id; refuses to overwrite an existing change dirplan.jsonstays valid JSON; the diff is a clean per-line status flip (no reformat)