Skip to content

feat(quant_search): Create a search page (2.3.0) - #265

Merged
stooit merged 54 commits into
2.xfrom
feat/search-page-setup
Nov 9, 2026
Merged

stooit merged 54 commits into
2.xfrom
feat/search-page-setup

Conversation

@stooit

@stooit stooit commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Part of 2.3.0. Based on #263 (feat/oauth-connect), which includes #262; merge those first.

"Create a search page": one screen makes a working Quant search page (address, content types, facets, optional search box) and publishes it.

Changes from the staging rehearsal

  • Search host from the dashboard setting. A site whose $settings['quant_api_dashboard_url'] names https://dash.<env>.quantgov.cloud now searches https://search.<env>.quantgov.cloud; before, a staging site searched production and got 401. The default host is no longer stored in config: update 8105 clears it only when it is the old default. A host set by the site still wins.
  • One search box. A second search page placed a second box in the header; the option now starts unchecked when the theme already has one. After a box is placed, the wizard links to the seed page, because the static pages show the box only after they are published again.

How it was tested

  • Staging: a site-wide search page with content type, topic and region facets; header suggestions on the static site after a reseed.
  • Unit and kernel tests for the host and update 8105; functional test for the box. Whole module suite: 193 pass, 1 skipped; phpcs clean.

stooit added 30 commits November 8, 2026 14:02
Adds quant_api.credentials (settings.php override, then the OAuth connection,
then the typed token), the platform and auth_method settings with schema, and
an update hook that sets the platform from an existing endpoint. The client,
quant_search and the seed form no longer read api_token from config.
The editor approves the site in the Quant dashboard (client drupal-quant, S256
PKCE, state bound to the session and user) and picks a project. The module
limits the token to that project, reads the project's write token and keeps
both outside config. Change project starts a new login; the old project stays
until the new choice. Cron refreshes the token with the portal's rotation
rules; a database copy never refreshes the original site's tokens. Multi-domain
sites stay on token connect. Adds drush quant:auth-status, kernel tests for the
refresh rules and a functional test against a fake dashboard.
The schema was keyed quant_search.quant_search_page.* but the entities are
named quant_search.quant_search.ID, so it never applied. Declare every
property, the facet mapping and the autocomplete block settings. Fix the
entity keys and the duplicate config_export entry, and drop the
core/jquery.once dependency that Drupal 10 removed.
Create a search page proposes the address (search), the content types, and
facets from the content type, the language and every vocabulary those types
reference. On save it creates an enabled page, extends the index when the
page needs more content types, registers the facets, publishes the page and
can place the search box. The full page form now publishes through the same
service and only when a token is set. Removes the undefined
search_page_repository service and fixes broken docs links.
An unconnected site sent requests with empty credentials, for example a
PATCH /v1/unpublish when a search page was deleted. Every call now fails
closed before any request, with one log line that says why.

(cherry picked from commit 7c2edb2)
An unconnected site sent requests with empty credentials, for example a
PATCH /v1/unpublish when a search page was deleted. Every call now fails
closed before any request, with one log line that says why.
A site with a Views page at /search was offered /search and then refused
it. The default now skips addresses that a search page or a Drupal route
already uses (search, site-search, search-2, ...).
…d endpoint, and a rotated write token recovers

- A copy of the database (fingerprint mismatch) gets no write token in
  login mode, and the settings page says to log in on the copy.
- The platform chosen for a login is saved only when the login completes,
  so a cancelled login never re-points a working token connection.
- In login mode the endpoint is the platform's own host; a custom endpoint
  (a settings.php override aside) no longer receives the hidden token.
- Cron re-reads the project write token with the login after a refresh and
  at least daily, so a token rotated in the dashboard recovers.
…rite token

- A copy (fingerprint mismatch) logs an error that names the differing
  components, shows on the status report and the settings page, and offers
  "This is the same site" (configure quant), which stores the fingerprint
  again so the site publishes. The fingerprint docblock is corrected.
- A 401 from the content API re-reads the project write token with the
  login, at most once every 15 minutes, so a token rotated in the dashboard
  recovers on the next publish.
…ver-side dashboard

- $settings['quant_api_endpoint_url'] names the content API endpoint in
  every mode (for example a stage host behind basic auth). It is never
  editable in the UI; the settings page and drush show it without its
  userinfo, and an HTTP middleware moves userinfo from any request URI into
  an Authorization header before the request is sent, so it never reaches a
  message or a log.
- $settings['quant_api_dashboard_internal_url'] is the dashboard address for
  server-to-server calls (token, refresh, projects, limit, write token); the
  browser redirect keeps quant_api_dashboard_url. Default: the same.
The dashboard token response names the user but not the organisations, so a
real login found no projects. The test dashboard now answers like the real
one. A dashboard fixed in settings.php also sets the starting platform.
Without the Redirect module, a changed alias (for example Pathauto after a
title change) left a 404 at the old URL on the static site. The old alias
now gets a 301 to the new one, for published nodes and terms only. With the
Redirect module on, its own redirect entity is pushed as before.
Installing the module failed strict config schema checks for
views.view.quant_metadata_node.
…leted

A deleted published node or term sent its internal-path redirect again,
because the entity is still published during delete. /node/N kept a 301
to a page that no longer exists. Deleted content now unpublishes its
internal paths (the prefixed one only, for one deleted translation).
The file_link formatter settings of views.view.quant_metadata_file carried
a copy of Views UI options, which fails strict config schema checks.
Log out deleted the token only in Drupal, so it stayed valid on the portal
until it expired. The module now calls POST /api/oauth/revoke first (best
effort: an older dashboard or a failed call is logged, and the local
connection is deleted in every case).
After Quant refused a refresh (for example a revoked login), the settings
page still showed "Connected" and the reconnect note sat below it. The
page message is now the warning, and the status report shows "The Quant
login needs renewing". After a project pick the page shows one success
message, not two. The status is built on a page view only: built during a
submit, it showed stale after the redirect (for example the copied-site
error right after "This is the same site").
…n needs renewing

The warning asked the editor to log in again, but the only button was
"Change project".
…ettings page

Guzzle's ConnectException is not a RequestException, so ping(), project()
and search() let it through and the Quant API settings page failed with an
error page. They now catch every Guzzle error. The editor sees a fixed
message instead of the exception text, which names the endpoint URL and can
carry credentials; the log keeps the cause with URL user information
removed. The settings page shows one error, not two.
…tting

A site that sets $settings['quant_api_dashboard_url'] to
https://dash.<env>.quantgov.cloud now searches search.<env>.quantgov.cloud
without a second setting. The default host is no longer stored in config
(update 8105 clears it when it is the old default), so production keeps
search.quantgov.cloud and a host set by the site still wins.
…ite gets it

A second search page placed a second search box in the header. The wizard
now leaves the box unticked when the theme already has one. After it places
a box, it says the static pages show it after they are published again and
links to the Seed page.
stooit added 10 commits November 9, 2026 09:15
The core schema fixes from fix/content-paths make the shipped views valid.
…s; review fixes

From the release review:
- Log out (or a token save) on a copy of another site's database revoked the
  original site's login. A copy now only forgets the login locally.
- Change project and a failed project pick now end the login they replace
  or discard, instead of leaving it valid at the dashboard.
- An expired access token with a refresh token stored no longer shows
  "The Quant login needs renewing": the next request renews it.
- The settings page decides on its success and error messages from a session
  flag and the client's own unreachable flag, not from other queued
  messages, so a token save shows "Connected" again.
- The endpoint override warning no longer shows credentials in the URL.
stooit added 14 commits November 9, 2026 14:10
With a dashboard override outside quantgov.cloud (for example a local
QuantGov dashboard), the platform radio defaulted to QuantCDN while the
saved platform was QuantGov, so saving the settings form for another reason
logged the site out.
Pushes run after the response is sent (and from the queue on cron), so a
failed push was only in the log. Each failure is now kept for the site, with
a short reason and never the error text, until a later push of the same page
succeeds. Editors (configure quant or access content overview) see a warning
on their next page view, and the status report lists the pages. Also: a
blank or invalid pagination selector no longer raises PHP warnings.
From review: a cached editor page did not show a new failure (the list now
has a cache tag, invalidated when it changes); a file that Quant already had
(MD5 matches) never cleared its failure; concurrent queue workers could lose
entries (the list changes under a lock); the message pointed editors without
access to the status report.
…ts in CI

CI (Drupal 11.1) failed: config/install/quant.settings.yml held 0/1 for keys
the schema types as boolean. Drupal 11.1 installs module config as trusted
data, without casting it, so the strict schema check saw integers. Drupal
11.4 casts on save, which is why a local 11.4 run passed. The install config
now holds true/false, and update 9009 casts integers that existing sites
stored.

CI now starts a PHP web server and sets SIMPLETEST_BASE_URL, so the
functional tests run instead of failing on the missing base URL.
CI (Drupal 11.1, which installs module config without casting it) still
failed on quant.token_settings. A new kernel test checks every config/install
and config/optional file of quant and its submodules against its schema, as
the files are on disk, and lists every mismatch in one run. It found:
- quant.token_settings disable/strict and the Quant Search entity settings
  stored 0/1 for booleans: now true/false; update 9009 casts them on
  existing sites.
- The quant_metadata Views field option kept 0 for each unticked key (from
  checkboxes), against its list-of-strings schema: the shipped views keep
  only the ticked keys, the field drops unticked keys on save, and update
  9010 filters saved views.
CI also installs drupal/webform, so the Quant Forms tests can run.
@stooit
stooit merged commit 13f1933 into 2.x Nov 9, 2026
2 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