Skip to content

feat(brp): count the people registered at an address object, a number and nothing else - #4657

Merged
rubenvdlinde merged 1 commit into
developmentfrom
build/dep-portaliq-residents-count
Oct 15, 2026
Merged

rubenvdlinde merged 1 commit into
developmentfrom
build/dep-portaliq-residents-count

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What this does

Portaliq's "Mijn gegevens" shows a resident how many people are registered at their own address, as MijnOverheid does. Portaliq reads the BRP only through BrpPersonProvider, which could not answer that. This is the openregister half of portaliq identity-registered-details T07 (row cmp-id-residents-at-address, REQ-IRD-005), built as a dependency per decision 156.

  • BrpPersonProvider::countResidentsAtAddressObject(addressObjectId) posts ZoekMetAdresseerbaarObjectIdentificatie to /personen with one field and answers { total, meta } (the Wet-BRP audit metadata, as lookupByBsn). A malformed id (not 16 digits) answers invalid-identifier without a call. A missing or unreachable source degrades to { unavailable, cause }.
  • Behind a setting on the source. The registry is asked only when the brp-haalcentraal source carries configuration.residentCount: true (only the boolean counts), the way integriq reads BRP relations only behind configuration.relationFields: true (integriq chore(release): 1.1.5-unstable.20260821031704 #2667, decision 220). Otherwise: resident-count-not-enabled, no call.
  • Recorded without bodies. The answer carries the residents' numbers, so the call reaches integriq's CallService::call with withholdBodies: true (integriq chore(release): 1.1.5-unstable.20260821034229 #2669): the call is recorded, its bodies are not. A connector whose call has no such parameter is never called (PHP refuses the named argument before the method runs) and the answer is upstream-service-down.
  • ExternalIntegrationRouter gains sourceConfiguration(provider) and the generic withholdBodies call option. invoke and invokeWithMeta now share one dispatch.

Privacy

A count, never names: the answer holds total and meta only; no name, BSN, person object or address object id leaves the provider, and the one log line on a transport failure holds neither. Tests assert both.

OpenSpec

New change brp-residents-at-address-count, built and archived in this PR (openspec/changes/archive/2026-10-15-brp-residents-at-address-count); its two requirements are folded into openspec/specs/integration-person-lookup/spec.md, which gains a screens.md (no screen: provider API).

Tests

  • New test class BrpPersonProviderResidentCountTest (10 tests: the count, zero, four settings that do not allow it, malformed ids, missing source, unreachable registry, an unexpected failure logged without the address).
  • ExternalIntegrationRouterTest +5: sourceConfiguration answers and fails like call; withholdBodies reaches the CallService and not the request options; without the option nothing changes; a CallService without the parameter is not called.

Checks (local, changed files)

php -l 0, phpcs 0 (inherited @spec warnings on the class and its getters), phpstan 0, phpmd 0 (empty HOME), psalm --threads=1 0, phpunit 79/79 across the integration tests, openspec validate --strict 0.

Hydra gates (full tree, as CI runs them): gates 1 to 11 PASS; the remaining whole-tree gates had not finished locally when this PR opened, so CI's Hydra Gates job is the arbiter for them. composer check:strict was not run locally (disk and memory are shared and tight); CI's PHPUnit job runs the full suite.

After this lands

Portaliq's half (fills residentsAtAddress from this method, behind method_exists) follows as a portaliq PR. An administrator turns the count on with residentCount: true on the brp-haalcentraal source.

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

… and nothing else

BrpPersonProvider::countResidentsAtAddressObject() asks Haal Centraal
ZoekMetAdresseerbaarObjectIdentificatie with one field and answers
{ total, meta }. It asks only when the brp-haalcentraal source carries
configuration.residentCount: true, and the call reaches the connector with
withholdBodies so the residents' numbers are never stored. The router gains
sourceConfiguration() and the withholdBodies call option. This is the
openregister half of portaliq identity-registered-details T07.

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

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 2531b36

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-specs ✅
test-l10n ✅
test-l10n-parity ✅
format ✅
check-schema-l10n ✅
composer ✅ ✅ 173/173
npm ✅ ✅ 648/648
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 26213/26213 · 25 skipped
Newman ✅ 714/714
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-10-15 18:44 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit f3759ef into development Oct 15, 2026
48 checks passed
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