Skip to content

refactor(sig): stackiq batch 2, ArchiMate import parameters and two classic import fixes - #1406

Merged
rubenvdlinde merged 7 commits into
developmentfrom
refactor/sig-stackiq-params-batch
Nov 3, 2026
Merged

rubenvdlinde merged 7 commits into
developmentfrom
refactor/sig-stackiq-params-batch

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

SIG batch for stackiq (lane SQ3): PHP unit interfacing in the ArchiMate import, plus two classic-import fixes found on the way.

Measured with the lane unit reader (lizard, PHP, lib/), development at the merge base against this branch:

PHP band development this PR 4-star limit
params >=3 18.74% (7,731 LOC) 16.95% (6,976 LOC) 15.0%
size >60 35.13% 33.98% 8.3%
McCabe >10 19.15% 18.28% 7.3%
McCabe >25 3.50% 3.29% 1.1%

With the two held REVIEW PRs of this lane (koppelingen lookup, organisation sync) params >=3 lands at 14.97% (6,158 LOC), under the 4-star limit with a margin of about 14 LOC. No unit got worse: every changed unit is listed in the commits, and each one shrank or stayed level.

1. ArchiMate import: one import scope instead of four loose parameters

What: ArchiMateImportScope (new, lib/Service/ArchiMate/) carries the model identifier, property definition map, raw section lookups, elements lookup, section and raw properties, each with a with... copy. The batch steps (bulkProcessNonViewSections, bulkTransformSection, flattenPropertiesBatch, bulkTransformViews, processViewsMaximumSpeed, buildElementsLookupFromRawData) and the classic extractSectionDataWithProperties now take at most two parameters. saveSchemaGroups, extractEssentialXmlData, extractViewNodesAndConnections, createSectionObject and the two GEMMA relationship steps also went to two or fewer. The repeated name, summary, xsi:type, slug and @self code moved into small helpers.

Units: extractSectionDataWithProperties 91 to 31 LOC, bulkTransformSection 91 to 33, flattenPropertiesBatch 87 to 57, bulkTransformViews 81 to 39, saveSchemaGroups 78 to 57, buildElementsLookupFromRawData 67 to 26, bulkProcessNonViewSections 58 to 37; all now 2 params or fewer.

Golden: ArchiMateImportGoldenTest, recorded on the old code (commit test(archimate): golden...). It runs both entry points over five fixtures (the existing sample, a new tests/data/archimate_golden.xml with property definitions, single and list properties, missing and unknown refs, organizations, nested view nodes and connections, and three tests/fixtures/archimate files) with recording doubles for the object service, progress tracker, database and logger. 16 cases, including tracked, cancelled, a failing schema save, no default organisation and no view schema. Extra check, not committed: both entry points over tests/fixtures/amef/GEMMA release.xml (13 MB, 38,437 recorded calls) hash identically before and after (188b2850... optimized, c9d2fe22... classic).

Mutants (capped, signal-safe runner, no-op control survived): 24 of 30 killed. Survivors: an xsi:type fallback the XML reader never feeds, a null check whose extra key no view reads, the save-results list nothing reads, a viewpoint child element AMEF does not have, an Object ID key the import never writes, and the GEMMA index (see finding below).

2. Fix: the classic import reads a one-item section and reports its unchanged count

What: a section holding a single element was flattened into that element's values, so extractIdentifier() received a string and importArchiMateFileFromPath died with a TypeError that its catch (Exception) did not stop (the sample file and noorg.xml both hit it). The result also read total_objects_skipped, which the statistics never have (a warning and a null); it now reports total_objects_unchanged, the key the settings page reads. Golden diff in that commit shows only the classic cases changing.

Debt fixed along the way

  • ArchiMateImportService class lacked its @spec tag (phpcs warning), added.
  • OrganisationService test stub gains ensureDefaultOrganisation, as on OpenRegister.

Findings left for a decision (not changed here)

  • processRelationshipImmediate and processStandardVersionRelationship only record a link when $standardId === true, which a string never is, so GEMMA reference components never get their recommended or mandatory standards. fixStandaardVersieUuids has the same shape ($uuid === true). These change stored data once fixed, so they need their own PR.

Verification (local green)

  • Golden recorded on the old code, plain re-run green on old and new; mutants as above.
  • Development merged in (no rebase), touched tests re-run: 77 ArchiMate tests OK.
  • Full PHPUnit unit suite under pcov with --fail-on-risky, through heavy.sh: before the last development merge 1558 tests, 0 failures, 0 errors, 0 risky, exit 0; on the final tree (this PR plus the two REVIEW PRs, development merged): 1631 tests, 0 failures, 0 errors, 0 risky, exit 0; lint 0 errors; gates 37 of 37 applicable, 0 FAIL.
  • npm run lint: 0 errors (224 inherited warnings). phpcs, phpstan, psalm and phpmd clean on the touched files.
  • Hydra gates --scope-to-diff --base origin/development: 37 of 37 applicable gates ran, 0 FAIL.

This PR was prepared with AI assistance (Claude Code).

Records every object service, progress tracker, database and logger call
and the result, recorded on the code before the parameter refactor.

Assisted-by: ClaudeCode:claude-opus-5-5
…erty map and lookups

The batch and classic import steps now take an ArchiMateImportScope (model
identifier, property definition map, section lookups, elements lookup, section
and raw properties, each with a with... copy), so every step takes at most
two parameters. The repeated name, summary, xsi:type and slug code moves into
small helpers, and the save loop aggregates through addSaveResult.

The golden fixture's propid-3 definition is renamed so its own GEMMA log branch
is exercised; the golden was re-recorded on the code before this commit.

Assisted-by: ClaudeCode:claude-opus-5-5
…the import scope

Assisted-by: ClaudeCode:claude-opus-5-5
…ts its unchanged count

A section holding a single element (or relationship, ...) was flattened into
that element's values, so extractIdentifier() got a string and the import died
with a TypeError that its catch (Exception) did not stop. The result also read
a total_objects_skipped count the statistics never have (a warning and a null);
it now reports total_objects_unchanged, the key the settings page reads.

Assisted-by: ClaudeCode:claude-opus-5-5
@rubenvdlinde
rubenvdlinde merged commit b720aaf into development Nov 3, 2026
8 checks passed
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/stackiq @ 1aeb095

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
check-vue-demi ✅
test-l10n ✅
format ❌
check-schema-l10n ❌
check-l10n-js ✅
composer ❌ ✅ 127/127
npm ❌ ✅ 807/807
app:check-code ⏭️
info.xml ✅
REUSE ❌
lockfile sync ✅
PHPUnit ❌ 1542/1548 · 24 skipped
Newman ⏭️
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ❌

Quality workflow — 2026-11-03 16:57 UTC

Download the full PDF report from the workflow artifacts.

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.

1 participant