Skip to content

Implement extend-schemas-in-register-service: honour _extend on RegisterService end-to-end (#1428)#1430

Open
rjzondervan wants to merge 1 commit intodevelopmentfrom
feat/1428/extend-schemas-register-service
Open

Implement extend-schemas-in-register-service: honour _extend on RegisterService end-to-end (#1428)#1430
rjzondervan wants to merge 1 commit intodevelopmentfrom
feat/1428/extend-schemas-register-service

Conversation

@rjzondervan
Copy link
Copy Markdown
Member

Summary

Honours _extend on RegisterService end-to-end so DI consumers (DocuDesk, OpenCatalogi, softwarecatalog) receive the same expanded schemas as the HTTP GET /api/registers?_extend=schemas endpoint. Schema expansion + per-schema @self.stats move from RegistersController::index() into a new RegisterSerializer in a new lib/Service/Serializer/ namespace.

Closes #1428.

What changed

New code

  • lib/Service/Serializer/RegisterSerializer.php — entity serializer with serialize() + serializeMany(). Recognises schemas and @self.stats. Preserves orphan schema IDs in their original position (deliberate divergence from the pre-refactor controller, documented in the proposal/design/spec). Preserves properties on expanded schemas; consumer-side stripping stays in the consumer (e.g. DocuDesk).
  • RegisterService::findSerialized() and RegisterService::findAllSerialized() — DI-accessible methods that orchestrate the stats fetch and delegate to the serializer.

Refactored

  • RegistersController::index() now calls findAllSerialized for the schema-expansion path. Inline expansion + per-schema stats loops removed. Register-level @self.stats (object/log/file counts on the register itself) stays in the controller — out of scope for the serializer.
  • RegisterMapper::find() / ::findAll() drop the unused _extend parameter; the @SuppressWarnings(PHPMD.UnusedFormalParameter) pragmas are removed. Service-level find() / findAll() keep _extend as a documented no-op placeholder for signature compatibility.
  • SchemaMapper's @method find(...) annotation extended so PHPStan sees the full signature (was previously find(int|string $id) only).

Tests + docs

  • RegisterSerializerTest — 10 unit tests covering all spec scenarios (no extend, schemas, orphan-ID retention, type preservation, stats with/without orphans, unknown-key tolerance, entity-contract preservation, plus a serializeMany per-register stats routing test).
  • RegisterSerializerIntegrationTest — 4 integration tests against a live DB (DI parity, orphan retention, stats attachment, no-extend baseline).
  • RegisterServiceTest and RegistersControllerTest updated for the new constructor + delegation pattern. Caught a pre-existing constructor-arg-count drift in the controller test (IGroupManager mock was missing) and fixed that too.
  • New doc: docs/development/Services/serializers.md.
  • CHANGELOG.md Added + Breaking entries.

Wire-format breaking change (orphan IDs)

When a register references a schema that has been deleted, the response's schemas field is now a heterogeneous array of objects + bare IDs (in original order) instead of silently dropping the orphan. JSON consumers in statically-typed clients (Go, Java, Kotlin) that decode schemas as []Schema need a discriminated decoder. The DocuDesk frontend already filters via typeof schema === 'object' and is unaffected. Documented under Risks in design.md and called out in the changelog.

Quality

Tool Status
PHPCS ✅ 0 errors
PHPMD ✅ no new warnings on touched files (3 introduced suppressed with @SuppressWarnings + reasons; pre-existing warnings on unrelated code left as-is)
Psalm ✅ 0 errors on touched files
PHPStan ✅ 0 errors on touched files (3 fixed)
PHPUnit (targeted) ✅ 120/120 (RegisterServiceTest 21, RegistersControllerTest 87, RegisterMapperTest 2, RegisterSerializerTest 10)
PHPUnit integration ✅ 4/4 (RegisterSerializerIntegrationTest)

Test plan

  • CI quality runs green
  • Manual: GET /api/registers?_extend=schemas against a register with all schemas resolvable — response is byte-equivalent to the pre-refactor happy path
  • Manual: GET /api/registers?_extend=schemas against a register with at least one deleted schema — orphan ID is retained in its original position, log warning is emitted
  • Manual: GET /api/registers?_extend=schemas&_extend=@self.stats — each expanded schema has stats.objects.total; the register has stats.objects/logs/files
  • Manual: confirm DocuDesk's admin-settings dropdown still empty (DocuDesk follow-up issue Switch RegisterDiscoveryService to RegisterService::findAllSerialized (depends on openregister#1428) docudesk#120 ships the consumer change)

Cross-repo follow-ups

🤖 Generated with Claude Code

Honour `_extend` on `RegisterService` end-to-end so DI consumers receive
the same expanded schemas as HTTP callers. Schema expansion + per-schema
`@self.stats` move from the controller into a new `RegisterSerializer`.

What changed
- New `OCA\OpenRegister\Service\Serializer\RegisterSerializer` (197 lines)
  with `serialize()` + `serializeMany()`. Recognises `schemas` and
  `@self.stats`. Preserves orphan schema IDs in original position
  (deliberate divergence from the pre-refactor controller, documented
  in proposal/design/spec). Preserves `properties` on expanded schemas;
  consumer-side stripping stays in the consumer (e.g. DocuDesk).
- `RegisterService::findSerialized()` and `findAllSerialized()` —
  DI-accessible methods that orchestrate the stats fetch and delegate
  to the serializer.
- `RegistersController::index()` now calls `findAllSerialized` and the
  inline expansion + per-schema stats blocks are gone. Register-level
  `@self.stats` (object/log/file counts) stays in the controller — out
  of scope for the serializer.
- `RegisterMapper::find()` and `::findAll()` drop the unused `_extend`
  parameter; the `@SuppressWarnings(PHPMD.UnusedFormalParameter)`
  pragmas are removed. Service-level signatures keep `_extend` as a
  documented no-op placeholder for compatibility.
- `SchemaMapper`'s `@method find(...)` annotation extended so PHPStan
  sees the full signature.
- `RegisterSerializerTest` (10 unit tests) and
  `RegisterSerializerIntegrationTest` (4 integration tests) cover all
  spec scenarios. `RegisterServiceTest` and `RegistersControllerTest`
  updated for the new constructor + delegation pattern.
- Docs: new `docs/development/Services/serializers.md`, CHANGELOG entry
  (Added + Breaking).

Quality
- PHPCS / Psalm / PHPStan clean on all touched files
- Unit suite for affected files: 120/120 green inside the dev container
- Integration tests: 4/4 green

Follow-up
- DocuDesk follow-up issue filed at ConductionNL/docudesk#120 — opens
  once openregister cuts a release containing this change.

Closes openregister#1428
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Quality Report — ConductionNL/openregister @ 5f386d0

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 147/147
npm ✅ 598/598
PHPUnit
Newman
Playwright ⏭️

Quality workflow — 2026-05-05 18:37 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