Skip to content

Commit 2ed1e85

Browse files
rubenvdlindeConduction Release Bot
andauthored
docs(openspec): three retired capabilities still cited their deleted tests (#1931)
* docs(openspec): three retired capabilities still cited their deleted tests Fourteen exclusions across gis-integration, mobiel-inspectie-offline and supplier-portal named a PHPUnit class, a vitest spec or a Newman collection that is not in this repository. In every case the capability was migrated or removed and the named test was deleted with it, so the exclusion was doing double duty: it took the scenario out of e2e coverage and made it look handled. gis-integration lost its bespoke geo stack in bac6f70 (issue #112, ADR-022) when cases-on-map moved onto OpenRegister's maps-overview surface. GeoService, WfsService, CaseGeoController and the /api/cases/geo and /wfs/cases endpoints went with it. That spec had no status-note recording any of this while its Purpose still described the removed code as present, so it gains one. The one scenario that does still have a home in this app, the marker shaping, is repointed at tests/vitest/casesOnMap.spec.js, which asserts the coordinate order, the status colour and icon, malformed rows and non-array input. mobiel-inspectie-offline and supplier-portal lost their backends in 062d9de. Both specs already recorded that in their status-notes; only the citations were left behind. Those five and two exclusions now say the capability is gone and where it went, rather than naming a test to stand in for it. One of them also cited a Newman collection that has never existed in any commit, in an app that sets enable-newman false. Also fixes this repository's only unparseable spec front matter. The supplier-portal status-note was a plain YAML scalar containing a colon and a space, which makes the mapping invalid. It becomes a folded block scalar with byte-identical text. gate-113 goes from fourteen unresolved citations to none, and one more scenario resolves against a test that is really there. * fix(tests): eight tests execute two transition helpers without declaring them All six PHPUnit matrix cells fail with zero failures and zero errors: Tests: 3216, Assertions: 18704, Deprecations: 7, Skipped: 1, Risky: 8. Process completed with exit code 1 phpunit.xml sets beStrictAboutCoverageMetadata and failOnRisky, so a test that touches a class the docblock does not list is risky, and a risky test exits 1 while printing no failure. This is the same defect #1924 fixed for CaseResultWriter, in four more classes and for two more helpers. StatusTypeLookup and TransitionSpecReader are reached through StatusTransitionService and CaseStatusStore, which the tests do declare. The fix is five @uses lines and nothing else: a pure insertion, zero deleted lines, and php -l clean on all four files. Note that the annotations are real @uses tags, not prose mentioning them; naming an annotation inside docblock prose parses as an empty one and reddens the job by itself. --------- Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
1 parent 833c789 commit 2ed1e85

7 files changed

Lines changed: 97 additions & 15 deletions

File tree

openspec/specs/gis-integration/spec.md

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
---
22
status: done
3+
status-note: >-
4+
2026-06 (migrate-cases-on-map-to-maps-overview-leaf, ADR-022, procest#112,
5+
commit bac6f7073): the bespoke in-app geo stack is RETIRED. Removed:
6+
GeoService, WfsService, WfsExportService, WmsWfsService, LocationService,
7+
CaseGeoController and the /api/cases/geo and /wfs/cases endpoints, the
8+
Leaflet components under src/components/map, caseGeoService,
9+
coordinateService, gisProxyService and the gis store. The cases-on-map
10+
surface now consumes OpenRegister's maps-overview endpoints through
11+
src/services/casesOnMapApi.js and renders them with the shared CnMapWidget,
12+
which owns clustering and the PDOK base layer. What remains in this app is
13+
the marker shaping in src/services/mapFormatters.js, covered by
14+
tests/vitest/casesOnMap.spec.js. This spec is retained for history; the geo
15+
capability is owned by OpenRegister.
316
---
417

518
# gis-integration Specification
@@ -38,7 +51,10 @@ canonical Feature on read.
3851

3952
#### Scenario: Validate supported geometry types
4053

41-
@e2e exclude Backend GeoService unit logic; covered by GeoServiceTest (PHPUnit), no UI surface.
54+
@e2e exclude the geometry validation this describes is no longer in this app.
55+
bac6f7073 (issue #112, ADR-022) removed the bespoke geo stack when cases-on-map
56+
moved onto OpenRegister's maps-overview surface, and the PHPUnit class this
57+
reason used to name was deleted with the code. Retained for history.
4258

4359
- **GIVEN** a Point, Polygon or MultiPolygon GeoJSON geometry
4460
- **WHEN** it is validated by `GeoService::validateGeometry()`
@@ -47,7 +63,10 @@ canonical Feature on read.
4763

4864
#### Scenario: Normalise JSON-encoded stored geometry
4965

50-
@e2e exclude Backend (de)serialisation logic; covered by GeoServiceTest (PHPUnit), no UI surface.
66+
@e2e exclude the stored-geometry normalisation this describes was removed by
67+
bac6f7073 with the rest of the bespoke geo stack. OpenRegister now owns the
68+
canonical representation, and the PHPUnit class this reason used to name was
69+
deleted with the code.
5170

5271
- **GIVEN** a geometry stored JSON-encoded on a case location
5372
- **WHEN** it is read via `GeoService::normaliseGeometry()`
@@ -62,7 +81,10 @@ requesting user may read (no IDOR).
6281

6382
#### Scenario: Clustered, filtered case locations
6483

65-
@e2e exclude Server-side clustering + bbox/zaaktype/status filtering; covered by GeoServiceTest + CaseGeoControllerTest (PHPUnit) and Newman.
84+
@e2e exclude GET /api/cases/geo no longer exists here. bac6f7073 replaced it
85+
with a call to OpenRegister's maps-overview points endpoint, which does the
86+
clustering and the filtering. Both PHPUnit classes this reason used to name
87+
were deleted with the endpoint, and this app runs no Newman suite.
6688

6789
- **GIVEN** cases with locations across the Netherlands
6890
- **WHEN** the client requests `/api/cases/geo` with a zoom level and optional zaaktype/status/bounds filters
@@ -72,7 +94,10 @@ requesting user may read (no IDOR).
7294

7395
#### Scenario: Per-object access guard excludes inaccessible cases
7496

75-
@e2e exclude Authorization guard verified by CaseGeoControllerTest (PHPUnit) — asserts only readable case ids reach the response; no deterministic UI assertion.
97+
@e2e exclude the per-object access guard moved with the endpoint. OpenRegister's
98+
maps-overview points endpoint returns markers already scoped by RBAC, so the
99+
guard is enforced there and not here. The PHPUnit class this reason used to
100+
name was deleted by bac6f7073.
76101

77102
- **GIVEN** two located cases where the user may read only one
78103
- **WHEN** the user requests `/api/cases/geo`
@@ -88,15 +113,19 @@ when OpenRegister is unavailable.
88113

89114
#### Scenario: GetCapabilities advertises the case feature type
90115

91-
@e2e exclude OGC XML rendering; covered by WfsServiceTest (PHPUnit) and Newman — no UI surface.
116+
@e2e exclude the WFS endpoint was removed by bac6f7073. This app no longer
117+
serves /wfs/cases, the PHPUnit class this reason used to name was deleted with
118+
it, and this app runs no Newman suite. Retained for history.
92119

93120
- **GIVEN** an authenticated WFS client
94121
- **WHEN** it requests `GET /wfs/cases?service=WFS&request=GetCapabilities`
95122
- **THEN** a well-formed WFS 2.0.0 capabilities document MUST advertise the `dossiq:cases` feature type and the supported operations
96123

97124
#### Scenario: GetFeature returns GML members honouring BBOX
98125

99-
@e2e exclude OGC GML rendering + bbox filtering; covered by WfsServiceTest (PHPUnit) and Newman — no UI surface.
126+
@e2e exclude GetFeature went with the rest of the WFS endpoint in bac6f7073.
127+
The PHPUnit class this reason used to name was deleted with it, and this app
128+
runs no Newman suite.
100129

101130
- **GIVEN** located cases
102131
- **WHEN** a WFS client requests `GetFeature` with an optional BBOX
@@ -135,7 +164,10 @@ the backend or PDOK tiles are unavailable.
135164

136165
#### Scenario: Map data shaping is pure and testable
137166

138-
@e2e exclude Pure data-shaping helpers (toMapGeometries/buildGeoQuery/summariseGeo/toExportGeoJson); covered by caseGeoService.spec.js (vitest).
167+
@e2e exclude pure data-shaping helpers, covered by tests/vitest/casesOnMap.spec.js.
168+
After bac6f7073 the shaping is shapeMarkerFeatures in
169+
src/services/mapFormatters.js, and that vitest spec asserts the coordinate
170+
order, the status colour and icon, malformed rows and non-array input.
139171

140172
- **GIVEN** a `/api/cases/geo` FeatureCollection
141173
- **WHEN** it is shaped for the map

openspec/specs/mobiel-inspectie-offline/spec.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ The system SHALL allow inspectors to synchronize their daily schedule to local s
3535

3636
#### Scenario: Sync updates incomplete sync on connection loss
3737

38-
@e2e exclude Resumable chunked download is a Service Worker / browser-network concern; not deterministically drivable headless. Replay-ordering logic is covered by tests/vitest/syncQueueEngine.spec.js.
38+
@e2e exclude resumable chunked download is a Service Worker and browser-network
39+
concern, not deterministically drivable headless. The replay-ordering engine
40+
this reason used to name was removed by 062d9dede with the rest of the
41+
orphaned mobile-inspection backend, so nothing in this app tests it.
3942

4043
- **GIVEN** a sync download is in progress (15% complete) when network connection drops
4144
- **WHEN** the inspector taps "Dag synchroniseren" again and network is restored
@@ -235,7 +238,10 @@ The system SHALL detect when a colleague has edited the same case while the insp
235238

236239
#### Scenario: Detect conflict on sync replay
237240

238-
@e2e exclude Requires an offline-created result + a concurrent server edit to trigger a 409; not headless-deterministic. Conflict classification + record building is covered by PHPUnit (SyncControllerTest, ConflictDetectionServiceTest) and vitest (classifyConflict).
241+
@e2e exclude requires an offline-created result and a concurrent server edit to
242+
trigger a 409, which is not headless-deterministic. The conflict classification
243+
backend was removed by 062d9dede, so the two PHPUnit classes this reason used
244+
to name no longer exist here and this scenario has no coverage.
239245

240246
- **GIVEN** inspector Anja completed a checklist offline with answer "goedgekeurd" for "Keuring afgewerkt?"
241247
- **AND** while she was offline, her colleague Piet (back at the office) changed the same case's inspection status to "afgekeurd"
@@ -260,7 +266,10 @@ The system SHALL detect when a colleague has edited the same case while the insp
260266

261267
#### Scenario: Inspector resolves conflict
262268

263-
@e2e exclude Resolution flow needs a live ConflictRecord; not headless-deterministic. The resolve → re-queue / discard policy is covered by PHPUnit (SyncControllerTest client_wins/server_wins) and vitest (resolveConflictChoice).
269+
@e2e exclude the resolution flow needs a live ConflictRecord and is not
270+
headless-deterministic. The resolve, re-queue and discard policy was removed by
271+
062d9dede, so the PHPUnit class this reason used to name no longer exists here
272+
and this scenario has no coverage.
264273

265274
- **GIVEN** the merge UI is displayed
266275
- **WHEN** the inspector taps "Mijn versie gebruiken"
@@ -272,7 +281,10 @@ The system SHALL detect when a colleague has edited the same case while the insp
272281

273282
#### Scenario: Permission lost during offline work
274283

275-
@e2e exclude Requires revoking case permission while offline to force a 403 on replay; not headless-deterministic. Terminal permission_lost handling is covered by PHPUnit (SyncControllerTest) and vitest (classifyConflict/isConflictRetryable).
284+
@e2e exclude requires revoking case permission while offline to force a 403 on
285+
replay, which is not headless-deterministic. The terminal permission_lost
286+
handling went with the sync backend in 062d9dede, so the PHPUnit class this
287+
reason used to name no longer exists here.
276288

277289
- **GIVEN** an inspector worked offline on a sensitive case (e.g., social-welfare home visit)
278290
- **AND** while she was offline, a manager revoked her read permission on that case
@@ -339,7 +351,10 @@ The system SHALL record all conflict resolution decisions in an immutable audit
339351

340352
#### Scenario: Audit log entry for conflict resolution
341353

342-
@e2e exclude Immutable audit-trail persistence depends on a resolved live ConflictRecord + the OR audit log; not headless-deterministic. The conflict-resolution record (resolvedBy/resolvedAt/resolution) is built + asserted by PHPUnit (ConflictDetectionService.applyResolution, SyncControllerTest).
354+
@e2e exclude immutable audit-trail persistence depends on a resolved live
355+
ConflictRecord and the OpenRegister audit log, and is not headless-deterministic.
356+
The conflict-resolution record building was removed by 062d9dede, so the
357+
PHPUnit class this reason used to name no longer exists here.
343358

344359
- **GIVEN** inspector Anja resolves a conflict by choosing her local version
345360
- **WHEN** the resolution is processed

openspec/specs/supplier-portal/spec.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
---
22
status: done
3-
status-note: Reverse-synced 2026-06-13 from archived implemented changes. Member 09 (contract backend) completed 2026-06-13 — the previously-deferred ContractController (GET /contracts/list, GET /contracts/{id}, POST /contracts/{id}/request-renewal; supplier-scoped, 403 on cross-supplier) and the nightly ScanExpiringContractsJob (TimedJob wrapping ContractRenewalService::scanAndFlagExpiring) are now genuinely built, routed, and unit-tested. 2026-07-07 (move-portals-to-portaliq, ADR-046, procest#162): the in-app supplier portal VIEWS (src/views/leverancier/*) + nav/routes/manifest fragment are RETIRED — the supplier surface is rendered by the shared Portaliq portal as the `supplier` audience of PortalContributionProvider. The backend supplier services + /api/leverancier-portaal/* endpoints and the OpenRegister schemas remain unchanged. 2026-07-08 (procest#loose-ends): SUPERSEDED for the in-app implementation — the now-consumerless backend was removed too. Deleted: SupplierPortalController / SupplierProfileController / ContractController + all /api/leverancier-portaal/* routes, SupplierAuthMiddleware, the supplier services (Scope/Session/Dashboard/KpiAggregation/Message/MasterDataMutation/Leverancier+Tender ViewModel/TenderVisibility/InvoicePaymentForecast/Auth/UserManagement), and the ContractRenewalService + ScanExpiringContractsJob renewal chain. The OpenRegister schemas (supplierTender/Contract/Invoice/Message) are UNCHANGED and are read directly by Portaliq (field-projected), which is now the sole supplier surface. This spec is retained for history; the live supplier experience is owned by Portaliq.
3+
status-note: >-
4+
Reverse-synced 2026-06-13 from archived implemented changes. Member 09
5+
(contract backend) completed 2026-06-13 — the previously-deferred
6+
ContractController (GET /contracts/list, GET /contracts/{id}, POST
7+
/contracts/{id}/request-renewal; supplier-scoped, 403 on cross-supplier) and
8+
the nightly ScanExpiringContractsJob (TimedJob wrapping
9+
ContractRenewalService::scanAndFlagExpiring) are now genuinely built,
10+
routed, and unit-tested. 2026-07-07 (move-portals-to-portaliq, ADR-046,
11+
procest#162): the in-app supplier portal VIEWS (src/views/leverancier/*) +
12+
nav/routes/manifest fragment are RETIRED — the supplier surface is rendered
13+
by the shared Portaliq portal as the `supplier` audience of
14+
PortalContributionProvider. The backend supplier services +
15+
/api/leverancier-portaal/* endpoints and the OpenRegister schemas remain
16+
unchanged. 2026-07-08 (procest#loose-ends): SUPERSEDED for the in-app
17+
implementation — the now-consumerless backend was removed too. Deleted:
18+
SupplierPortalController / SupplierProfileController / ContractController +
19+
all /api/leverancier-portaal/* routes, SupplierAuthMiddleware, the supplier
20+
services
21+
(Scope/Session/Dashboard/KpiAggregation/Message/MasterDataMutation/Leverancier+Tender
22+
ViewModel/TenderVisibility/InvoicePaymentForecast/Auth/UserManagement), and
23+
the ContractRenewalService + ScanExpiringContractsJob renewal chain. The
24+
OpenRegister schemas (supplierTender/Contract/Invoice/Message) are UNCHANGED
25+
and are read directly by Portaliq (field-projected), which is now the sole
26+
supplier surface. This spec is retained for history; the live supplier
27+
experience is owned by Portaliq.
428
---
529
# supplier-portal Specification
630

@@ -512,7 +536,10 @@ The system SHALL flag contracts within 90 days of expiry and compute the days re
512536

513537
#### Scenario: Contract within the threshold is flagged
514538

515-
@e2e exclude Backend-only — driven by the nightly ScanExpiringContractsJob (TimedJob) with no UI surface; covered by ScanExpiringContractsJobTest + ContractRenewalServiceTest. Contract UI is chain member 10.
539+
@e2e exclude backend-only, with no UI surface in this app. The nightly job and
540+
the renewal service this reason used to name were deleted by 062d9dede when the
541+
consumerless supplier backend was removed. Portaliq is now the sole supplier
542+
surface and reads the OpenRegister Contract schema directly.
516543

517544
- GIVEN the nightly expiry-scan job runs
518545
- WHEN a contract's `endDate` is within 90 days
@@ -527,7 +554,10 @@ account manager.
527554

528555
#### Scenario: Renewal request opens a Dossiq case
529556

530-
@e2e exclude Backend REST contract — exercised via the Newman leverancier-contract-api collection + ContractControllerTest (role gate, manual-only, window, cross-supplier 403); no UI surface in this chain member. Contract renewal UI is chain member 10.
557+
@e2e exclude backend REST contract with no UI surface in this app. The
558+
controller and the /api/leverancier-portaal/* routes this reason used to name
559+
were deleted by 062d9dede, the collection it named has never existed, and this
560+
app sets enable-newman false. Portaliq now renders the supplier experience.
531561

532562
- GIVEN a contracts or admin user requests renewal of a manual-renewal contract within 90 days
533563
- WHEN the request endpoint is called

tests/Unit/Service/CmmnBpmnCoexistenceRegressionTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
* @uses \OCA\Dossiq\Service\Transitions\CaseStatusStore
5252
* @uses \OCA\Dossiq\Service\Transitions\TransitionAuthorizer
5353
* @uses \OCA\Dossiq\Service\Transitions\TransitionSpecReader
54+
* @uses \OCA\Dossiq\Service\Transitions\StatusTypeLookup
5455
*/
5556
final class CmmnBpmnCoexistenceRegressionTest extends TestCase {
5657

tests/Unit/Service/StatusTransitionServiceReplayRegressionTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function searchObjects(array $query): array;
5858
* @uses \OCA\Dossiq\Service\Transitions\CaseResultWriter
5959
* @uses \OCA\Dossiq\Service\Transitions\CaseStatusStore
6060
* @uses \OCA\Dossiq\Service\Transitions\TransitionAuthorizer
61+
* @uses \OCA\Dossiq\Service\Transitions\StatusTypeLookup
6162
*/
6263
class StatusTransitionServiceReplayRegressionTest extends TestCase {
6364

tests/Unit/Service/StatusTransitionServiceRouteSeamTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public function saveObject(array $object, mixed $register = null, mixed $schema
6464
* @uses \OCA\Dossiq\Service\Transitions\CaseResultWriter
6565
* @uses \OCA\Dossiq\Service\Transitions\CaseStatusStore
6666
* @uses \OCA\Dossiq\Service\Transitions\TransitionAuthorizer
67+
* @uses \OCA\Dossiq\Service\Transitions\StatusTypeLookup
68+
* @uses \OCA\Dossiq\Service\Transitions\TransitionSpecReader
6769
*/
6870
class StatusTransitionServiceRouteSeamTest extends TestCase {
6971

tests/Unit/Service/Transitions/CaseStatusStoreOwnershipTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
/**
4040
* @covers \OCA\Dossiq\Service\Transitions\CaseStatusStore
41+
* @uses \OCA\Dossiq\Service\Transitions\StatusTypeLookup
4142
*/
4243
class CaseStatusStoreOwnershipTest extends TestCase {
4344
/**

0 commit comments

Comments
 (0)