Skip to content

refactor(api): pass ApiController its collaborators as four bundles - #576

Open
rubenvdlinde wants to merge 1 commit into
developmentfrom
refactor/api-controller-bundles
Open

rubenvdlinde wants to merge 1 commit into
developmentfrom
refactor/api-controller-bundles

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What (REVIEW: the bundles carry the auth, PAT and install collaborators)

ApiController took 25 constructor parameters. It now takes the app name, the request and four bundles:

bundle holds
AccessCollaborators ApiCaller (session, group manager, clock), PatServices (mapper, manager, validator, expiry evaluator), the deeplink builder, the optional connection report
InstallCollaborators installer, server version, app manager, artifact cache
AutoUpdateStores policies, pins, auto-update settings, attempt ledger (from #575)
ReportCollaborators ReportStores (advisory snapshot and settings, pending-updates snapshot, instance settings), discovery, audit log

Every bundle holds at most 4 collaborators (gate 122 flags new constructors with 5 or more). They live in lib/Service/Api/, outside lib/Controller, so route and OpenAPI scanning do not see them.

What to review:

  • isAdmin() reads $this->access->caller->userSession and ->groupManager; the guard itself is unchanged and runs first in every endpoint, as before.
  • The attempt ledger used to be an optional constructor argument read with ?->. The container always provided it, so it is now a plain field of AutoUpdateStores and the two reads are plain calls. Nothing else changes behaviour.

Stacked on #575 (and #574); the diff shows their commits until they merge.

SIG (gate 122 five-star report, PHP)

#575 this PR development
params >=7 2.87% 2.53% 3.31%
params >=5 6.23% 5.99% 6.54%
params >=3 21.18% 21.37% 21.12%
duplication 244 lines 235 lines (2.31%) 244 lines (2.42%)
size >15 48.68% 49.25%

params >=3 rises 0.19 points: the bundles are new 3 and 4 parameter units. That band is far from its limit (15%) either way; the >=7 and >=5 bands are the ones this work targets.

How it was verified

  • The four controller test files build the controller by parameter name (BuildsByParameterName from refactor(advisory): bundle the collaborators of AdvisoryService and AdvisoryRefreshJob #574), so they ran unchanged on the old and the new constructor: 88 controller tests green on both.
  • New ApiReadEndpointsGoldenTest (14 cases), recorded on the old code: response plus every collaborator call for apps, advisories, advisory interval, PAT list, discovery, deeplinks, cache clearing, pin and policy timestamps and the update channel. These were the accesses a first mutant round showed no test checked (9 survivors on the old code).
  • Capped mutants (prlimit 1.5 GB, timeout 120), one per rewired collaborator plus the admin check: 29/29 killed on the old and on the new code; admin check pinned to the acting user (literal 'admin' mutant killed, no-user-allowed killed); no-op control survived on both.
  • Full unit suite once on the final tree under pcov with --fail-on-risky: 1007 tests OK, rc 0.
  • php -l, php-cs-fixer and psalm clean on the touched files; hydra gates --scope-to-diff --base origin/development: 33 of 33 applicable gates pass (gate 7 checks 0 NoAdminRequired methods in this controller on both refs); gate 122 ratchet 0 findings; gate 119 0.

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

ApiController took 25 constructor parameters. It now takes the app name,
the request and four bundles:

- AccessCollaborators: ApiCaller (session, group manager, clock),
  PatServices (mapper, manager, validator, expiry), the deeplink builder
  and the optional connection report
- InstallCollaborators: installer, server version, app manager, cache
- AutoUpdateStores: policies, pins, auto-update settings, attempt ledger
- ReportCollaborators: ReportStores (advisory snapshot and settings,
  pending-updates snapshot, instance settings), discovery, audit log

Every bundle holds at most 4 collaborators. The attempt ledger is now
always present (the container always provided it), so the two nullsafe
reads of it became plain reads. Behaviour is otherwise unchanged.

The controller tests build it by parameter name, so they ran unchanged on
the old and the new constructor. ApiReadEndpointsGoldenTest, recorded on
the old code, pins the endpoints whose collaborator answer the existing
tests never checked: apps, advisories, advisory interval, PAT list,
discovery, deeplinks, cache clearing, pin and policy timestamps and the
update channel.

Assisted-by: ClaudeCode:claude-opus-5-5
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/versioniq @ b35fff0

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
composer ✅ ✅ 32/32
npm ❌ ✅ 302/302
app:check-code ⏭️
info.xml ✅
REUSE ❌
lockfile sync ✅
PHPUnit ❌ 999/1000 · 7 skipped (8 legs)
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 02:05 UTC

Download the full PDF report from the workflow artifacts.

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.

1 participant