Summary
Two scenarios in openspec/specs/gemma-faceted-search/spec.md describe
behaviour that is not implemented. Neither has been given an
@e2e exclude — an exclusion claims "a browser cannot observe this", and both
of these are perfectly observable; they simply do not happen. Excluding them
would buy a green gate-19 with a false statement, so they are being left in the
count and filed here instead.
1. A facet dimension with zero available values is NOT visibly disabled
Spec (Requirement: Facet sidebar UI on the module and dienst index pages):
THEN the applicatieservice facet section MUST indicate it has no available
values (e.g. empty state or disabled state)
AND MUST NOT be selectable
CnFacetSidebar.vue binds no :disabled on its NcSelect, and
getFilterOptions() returns [] for a dimension with no values while the
control still renders enabled. There is no empty-state branch in
src/views/FacetedCatalogIndexView.vue, src/utils/facetSchema.js, or
src/store/modules/facets.js.
Confirmed reachable on a live instance: GET /api/facets/module on a fresh
register returns
{"referentiecomponent":[],"standaard":[],"applicatieservice":[],"domein":[],"_meta":{...}}
— all four dimensions empty, and all four render as normal, selectable
pickers.
Note this control lives in @conduction/nextcloud-vue, so the fix is probably
a :disabled/empty-state prop on CnFacetSidebar there rather than in this
app.
2. The facet cache is never invalidated by a data change
Spec (Requirement: Facet aggregation results are cached):
WHEN a module's referentieComponenten, standaarden, standaardenGemma,
or related GEMMA link field is created, updated, or removed
THEN the cache for affected facet queries MUST be invalidated
AND the next facet request MUST recompute the aggregation
The cache is real (FacetService, ICacheFactory::createDistributed(prefix: 'softwarecatalog_facets'), CACHE_TTL = 1800) but expiry is TTL only.
There is no invalidation path: no registerEventListener in
lib/AppInfo/Application.php touches facets, lib/EventListener/ contains no
facet listener, and no code outside FacetService references the cache prefix.
So for up to 30 minutes after a GEMMA link changes, the facet panel serves
stale counts. This is a correctness bug with a user-visible symptom ("I edited
the module and the filter still shows the old number"), not just a spec gap.
The sibling scenario "Repeated identical facet request is served from cache"
IS satisfied and IS observable (_meta.cached is echoed in the response body).
Why these are filed rather than excluded
Both are browser-observable in principle — the first is pure DOM state, the
second is a two-request sequence around a data edit. The only reason a test
cannot pass today is that the behaviour is absent. That is a defect, not a
limit of the observation method.
Related
Found while closing gate-19 (e2e-coverage) for softwarecatalog. The five
scenarios in this spec that genuinely cannot be observed from a browser
(query-array construction, paging-vs-scanning, code-path identity, cache-key
composition, l10n key names) have been given reason-bearing @e2e exclude
markers in the same PR; these two deliberately have not.
Summary
Two scenarios in
openspec/specs/gemma-faceted-search/spec.mddescribebehaviour that is not implemented. Neither has been given an
@e2e exclude— an exclusion claims "a browser cannot observe this", and bothof these are perfectly observable; they simply do not happen. Excluding them
would buy a green gate-19 with a false statement, so they are being left in the
count and filed here instead.
1. A facet dimension with zero available values is NOT visibly disabled
Spec (
Requirement: Facet sidebar UI on the module and dienst index pages):CnFacetSidebar.vuebinds no:disabledon itsNcSelect, andgetFilterOptions()returns[]for a dimension with no values while thecontrol still renders enabled. There is no empty-state branch in
src/views/FacetedCatalogIndexView.vue,src/utils/facetSchema.js, orsrc/store/modules/facets.js.Confirmed reachable on a live instance:
GET /api/facets/moduleon a freshregister returns
{"referentiecomponent":[],"standaard":[],"applicatieservice":[],"domein":[],"_meta":{...}}— all four dimensions empty, and all four render as normal, selectable
pickers.
Note this control lives in
@conduction/nextcloud-vue, so the fix is probablya
:disabled/empty-state prop onCnFacetSidebarthere rather than in thisapp.
2. The facet cache is never invalidated by a data change
Spec (
Requirement: Facet aggregation results are cached):The cache is real (
FacetService,ICacheFactory::createDistributed(prefix: 'softwarecatalog_facets'),CACHE_TTL = 1800) but expiry is TTL only.There is no invalidation path: no
registerEventListenerinlib/AppInfo/Application.phptouches facets,lib/EventListener/contains nofacet listener, and no code outside
FacetServicereferences the cache prefix.So for up to 30 minutes after a GEMMA link changes, the facet panel serves
stale counts. This is a correctness bug with a user-visible symptom ("I edited
the module and the filter still shows the old number"), not just a spec gap.
The sibling scenario "Repeated identical facet request is served from cache"
IS satisfied and IS observable (
_meta.cachedis echoed in the response body).Why these are filed rather than excluded
Both are browser-observable in principle — the first is pure DOM state, the
second is a two-request sequence around a data edit. The only reason a test
cannot pass today is that the behaviour is absent. That is a defect, not a
limit of the observation method.
Related
Found while closing gate-19 (e2e-coverage) for softwarecatalog. The five
scenarios in this spec that genuinely cannot be observed from a browser
(query-array construction, paging-vs-scanning, code-path identity, cache-key
composition, l10n key names) have been given reason-bearing
@e2e excludemarkers in the same PR; these two deliberately have not.