Skip to content

Release: merge development into beta - #1318

Open
github-actions[bot] wants to merge 248 commits into
betafrom
development
Open

github-actions[bot] wants to merge 248 commits into
betafrom
development

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR to sync development changes to beta for beta release.

Merging this PR will trigger the beta release workflow.

Reminder: Add a major, minor, or patch label to this PR to control the version bump. Default is patch.

WilcoLouwerse and others added 30 commits October 13, 2026 18:50
… the schemas

423 schema properties in softwarecatalogus_register.json carried null
validation keywords (minimum, maximum, multipleOf, minItems, maxItems,
minLength, maxLength). OpenRegister's validator (opis/json-schema) rejects a
null where it wants a number ("minimum must contain a valid number"), so a
schema with hardValidation, such as element, refused every object and the
E2E "Seed test data" step failed with HTTP 403.

The keys are removed (a null keyword never constrained anything), the ten
affected schemas get a patch version bump, the register goes to 2.5.8 with a
changelog entry, and RegisterNullKeywordsTest guards the register file and
its register.d fragments against the keys coming back.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The integration test README still said Guzzle 7.8+, but composer.json
require-dev has guzzlehttp/guzzle ^8.2 since the dependabot bump.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…effective version

The base bumps of catalogService, organization, usage and module went above
their register.d fragments, which broke three tests that pin the merged
usage (1.5.6) and module (0.3.8) versions. The loader keeps the highest
version per schema, so the bump belongs in the fragment that carries it:
publication-field-rules.json (catalogService 0.2.3, organization 0.5.4)
and topdesk-cmdb-import.json (usage 1.5.7, module 0.3.9). The base keeps
its own +1 bumps; the 2.5.8 changelog entry and the three pins follow.

Closes the review finding "PHPUnit red: base bumps exceed pinned fragment
versions" on #1295.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Conflicts in lib/Settings/register.d/topdesk-cmdb-import.json and
tests/Unit/Settings/TopdeskCmdbFragmentTest.php: development's archive
configuration on module is kept, with its test wording.

Both sides bumped module 0.3.8 -> 0.3.9 and usage 1.5.6 -> 1.5.7 in the
fragment that holds their effective version, and development's 0.3.9 /
1.5.7 already reached beta without the null-keyword drop. The fragment now
goes to module 0.3.10 and usage 1.5.8 so an installation at the beta
versions still imports this change; the tests expect the new versions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…schema changes

The register's info.version and the schema versions moved, but appinfo
<version> did not, so an instance already on 0.2.6 never re-imports the
register and keeps the null JSON-Schema keywords (hydra gate 120).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…0261020094847

chore(sync): carry beta back into development
…he beta build

On a Nextcloud with the 0.2.7 beta the two missing-records tests could not
pass:

- NcCheckboxRadioSwitch now puts the data-testid on the radio input itself,
  so `[data-testid=…] input` found nothing. A helper finds the input in both
  shapes, and the keep choice is made with a native click, because check()
  waits forever on the visually hidden input.
- The archive test required working modules after the later export, but
  the anonymised export holds only the two applications that test takes out.
  It now waits for the list to render, with rows or its empty state.
- It looked for the archived application by name, which a module of another
  municipality can share on an instance with other data. It now looks for
  the row of this run's module by its object id.
- Chromium does not give Playwright a multipart body that carries a file, so
  the request check of the keep choice always read an empty string. The
  outcome assertions that follow already show the choice reached the server.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…eeds

The migration-pack editor shipped in OpenRegister 2.1.41, so the docs and
the changelog name that release instead of the pull request.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…eywords

fix(register): drop null JSON-Schema keywords so the E2E seed can create elements
test(cmdb-import): pass the archive and keep e2e tests on the beta build; name OpenRegister 2.1.41 in the docs
Board SkDatakwaliteit. The usage schema declares the rules OpenRegister
scores it by (owners, application, version, status, reference components,
and a yearly freshness on lastConfirmedAt), and module gets the score
fields. GET /api/data-quality evaluates those rules over one
organisation's usages, bounded and organisation-scoped like the portfolio
report: register score, average completeness, entries not confirmed, how
many entries meet each rule, and the least complete entries with what they
miss. The organisation check moves into OrganisationReportAccess, shared
with the portfolio report. Spec landscape-completeness-score, amended to
the board.

Assisted-by: ClaudeCode:claude-opus-5-5
Board SkGemmaPlaat. GET /api/reference-component-coverage joins one
organisation's usages with the GEMMA reference components, bounded and
organisation-scoped (the shared OrganisationReportAccess check), and gives
each component a state: covered, gap (fillable when an application in use
offers it) or overlap, with a CSV variant. The GEMMA plate page groups the
components as the GEMMA model does, names the state in words next to the
colour, filters on gaps, fillable gaps and overlap, and shows a chosen
component's applications. Spec architecture-reference-component-coverage,
REQ-RCC-002 amended to the board; the map on an imported view (Task 5)
waits for architecture-views-editor.

Assisted-by: ClaudeCode:claude-opus-5-5
The data-quality fragment raises usage to 1.5.9 and module to 0.3.11. The
pins assert the versions are not lowered, which is what they guard.

Assisted-by: ClaudeCode:claude-opus-5-5
feat: Data quality page and GEMMA plate (boards SkDatakwaliteit, SkGemmaPlaat)
Board SkPubliek. The portal contribution declares the public record list
softwareCatalogue on both audiences: portaliq reads it without a session
and shows it with its public records block on the municipality site. The
list holds the published applications (publication date come, no
depublication) with supplier and licence; a record adds the website and
the reference components. The rule lives in PublicCatalogueRecords, never
in page configuration.

Assisted-by: ClaudeCode:claude-opus-5-5
…ogue

feat(portal): the published applications as a public record list (board SkPubliek)
…ys pending

Board SkPubliek, stackiq's half of the registration form. A save listener
on OpenRegister's creating event stores every organisation created with
nobody signed in as pending and unpublished, whatever the request carried:
for portaliq's form, stackiq's intake endpoint and a direct OpenRegister
call alike (the schema allows an anonymous create). Signed-in and
command-line creates keep their values. The organisation schema gets the
form's website and the registering person's name and e-mail, the contact
readable by signed-in users only.

Assisted-by: ClaudeCode:claude-opus-5-5
The organisation schema gained website (organisation-registration-through-the-portal).

Assisted-by: ClaudeCode:claude-opus-5-5
…tration

feat(registration): an organisation registered without an account stays pending (board SkPubliek)
Bumps [nextcloud/ocp](https://github.com/nextcloud-deps/ocp) from 35.0.1 to 35.0.2.
- [Commits](nextcloud-deps/ocp@v35.0.1...v35.0.2)

---
updated-dependencies:
- dependency-name: nextcloud/ocp
  dependency-version: 35.0.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

guzzlehttp/guzzle ^8.2 sat in require-dev, so every dev install put
Guzzle 8 in vendor/. When stackiq's autoloader registered first, the
server's IClientService got Guzzle 8's Client, which rejects the
CURLOPT_HTTP_VERSION option Nextcloud passes, and every outgoing HTTP
request on the instance failed.

Guzzle was only used by the KoppelingenGebruik integration test. Port
that test to symfony/http-client (already a runtime dependency) and drop
guzzlehttp/guzzle (and its psr7/promises) from the lock. Add a unit
guard that fails if composer.lock or the generated autoloader ever
contains guzzlehttp/* or GuzzleHttp\ again.

Assisted-by: ClaudeCode:claude-opus-5-5
#1335)

One requirement per property, each naming who provides it and how stackiq
inherits it. The lifecycle threshold and the Webhooks section drawn on
SkInstellingenUitwisseling get build tasks; both rows move to building.
rubenvdlinde and others added 30 commits November 3, 2026 15:13
…-export

refactor(store): split the settings store save, export and register selection into small steps
…chema-config

refactor(store): split the plugin's object save and schema config lookup into small steps
…es-table

refactor(theme): read the theme variables from one name list
…json-configuration

refactor(settings): drop the uncalled compactToJsonConfiguration
… it behaves today

Creating an organisation escapes with an Error on both paths: the signed-in
path calls OrganisationMapper::createWithUuid, which OpenRegister does not
have, and the anonymous path saves and then reads the absent user.

Assisted-by: ClaudeCode:claude-opus-5-5
…actories

refactor(store): build the initial store states and statistics rows from tables
test(settings): render the CMDB import info panel against its section (stackiq batch 2)
…m the OpenRegister create and update steps

Neither createOrganisationInOpenRegisterInternal nor updateOrganisationInOpenRegister
reads the OrganisationService it was handed. The public create wrapper still
fetches it first, so a missing OpenRegister fails at the same point. The golden
masks mock and anonymous class names, which depend on test order; it was
re-recorded on the code before this commit.

Assisted-by: ClaudeCode:claude-opus-5-5
…s-batch

refactor(sig): stackiq batch 2, ArchiMate import parameters and two classic import fixes
- composer.lock: symfony/mime 7.4.12 -> 7.4.22 (CVE-2026-45070, gate 4).
- manifest: the Reports menu entry sits in the footer section (gates 104, 107).
- @SPEC tags point at the renamed REQ-RCC-002 heading (gate 46).
- prettier on the seven files format --check rejected.
- Test stubs: ObjectEntity::jsonSerialize() returns array like OpenRegister's
  (the one PHPUnit deprecation), and a UserProfileUpdatedEvent copy so its
  four listener tests run under the unit bootstrap.

Assisted-by: ClaudeCode:claude-opus-5-5
…ions

The import recorded a GEMMA link only when `$standardId === true`, which a
string identifier never is, so no reference component ever got its
recommended, mandatory or combined standards and no standard version got its
standard. The post-save fix had the same `$uuid === true` pattern and updated
the `standaard` column, which is `standard` since the catalog rename. The
classic import also never matched, because its sections are plural.

The linking moves out of ArchiMateImportService into GemmaStandardLinker (with
GemmaObjectReader), which references a linked object by its uuid id, or by its
slug when it has none. `occ stackiq:gemma:link-standards` back-fills the links
for earlier imports: it patches only link properties that differ, so a second
run writes nothing, and `--dry-run` reports without writing. ObjectPages is the
paged reader both occ commands now share.

Assisted-by: ClaudeCode:claude-opus-5-5
…contacts' and 'origin/refactor/sig-koppelingen-gebruik-params' into fix/stackiq-organisation-creation
…ationService

StackiqService created a signed-in user's organisation with
OrganisationMapper::createWithUuid(), which OpenRegister does not have, and
an anonymous one by saving an admin-owned entity and then calling getUID() on
the null user. Both ended in an Error that escaped catch (\Exception), so
creation never returned an organisation.

A signed-in creation now goes through OrganisationService::createOrganisation()
with addCurrentUser, so the creator becomes owner and member, and the
organisation's contact persons are added with addUserToOrganisation(). Without
a signed-in user nothing is created: the specs do not say who would own it.

ContactpersoonService passed orgObject: to ensureOrganisationEntityPublic(),
whose parameter is organisationObject, so its backup entity creation always
failed with an Error.

Tests: golden cases recorded on the old code for the anonymous, forged owner
and member, creator-as-contact and missing-service paths (the Organisation
stub answers magic accessors like the Entity does, so the anonymous case
reaches the save it really makes); the backfill sends no mail and
processSpecificOrganization mails on create; the koppelingen lookup cases for
a forged owner filter, owner lookalikes and forged @self/isAmbtenaar options.

Assisted-by: ClaudeCode:claude-opus-5-5
fix(stackiq): clear the reds the development run found
…leVersie lookup

importForModuleVersie (82 lines) keeps the order of every call; starting and
completing the progress, the log line and the summary move into helpers. The
moduleVersie lookup that importForModuleVersie, resolveParentModuleUuid and
getStatus each repeated is one findModuleVersion().

Golden: every object service, progress and logger call over nine imports
(both formats, VEX, empty, unsupported, missing version, 50 and 60
components), recorded on the old code.

Assisted-by: ClaudeCode:claude-opus-5-5
… CI bootstrap

#1400 put the Doctrine and HeaderUtils stubs one directory below tests/Stubs.
tests/bootstrap.php, the bootstrap CI runs, loads every file that deep before
Nextcloud boots, so the stub ExpressionBuilder (without eq()) replaced
Doctrine's. The server then could not finish booting, OpenRegister never
loaded, and every PHPUnit cell failed on its missing event classes.

The stubs move to tests/Stubs/Standalone/, out of that glob's reach, and
tests/bootstrap-stubs.php loads each one only when the real class is absent.
bootstrap-unit.php requires it as before; bootstrap.php requires it after the
boot, so a run without a server still finds them.

Assisted-by: ClaudeCode:claude-opus-5-5
handleObjectCreated (92 lines), handleObjectUpdated (203) and
handleObjectDeleted (137) took the event plus three services. They now take
the event and one services array, read the object facts once
(objectContext), look the catalog schemas up lazily in the same order
(firstMatchingSchema), and hand each matched type to a small method. The
contact person and contactgegevens update and deletion branches share
runContactAction with their log lines in a table. Every call and log line
keeps its order and text.

Golden: 37 cases over handle() for created, updated and deleted events of
every catalog type, with sync, refetch and contact failures, recorded on the
old code.

Assisted-by: ClaudeCode:claude-opus-5-5
fix(tests): keep the standalone Doctrine and Symfony stubs out of the CI bootstrap
…sync and creation

Nothing calls StackiqService::handleNewOrganization, handleOrganizationUpdate,
syncOrganizationWithOpenRegister or createOrganisationInOpenRegister: the
background job creates organisations through OrganisatieService, and no class
in lib/, src/ or appinfo/ references StackiqService at all. The 20 methods only
those reach (1,800 lines) go, and with them the never-read OrganizationHandler,
SymfonyEmailService, IUserSession, IUserManager and IGroupManager
dependencies.

That removes the creation path that called OpenRegister's createOrganisation()
without a slug check, which would have handed an existing organisation with the
same name to the caller, instead of fixing a path nothing uses. The golden test
for that path, its stub additions and the stale tests/OrganizationSyncTest.php
(outside every suite, against the old constructor) go too.

Assisted-by: ClaudeCode:claude-opus-5-5
…op the stale skipped test

Two golden cases from review, recorded on the old code: an Error from the
contact person service escapes handle() (catch (\Exception) does not catch it),
and an organisation update with schema id "01" matches schema 1.

StackiqEventListenerTest skipped all 12 of its cases in setUp(): they were
written against a constructor and service calls the listener no longer has.
The golden test covers the current dispatch, so the stale file goes.

Assisted-by: ClaudeCode:claude-opus-5-5
fix(archimate): link GEMMA standards, back-fill command, and split the SBOM import
…reation

refactor(organisations): delete StackiqService's unused organisation sync, fix the contact backup entity (REVIEW)
…-listener

refactor(listener): split the three object event handlers (REVIEW)

This branch has not been deployed

No deployments
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.

2 participants