Skip to content

Eagle Search

Daniel Truong edited this page Oct 14, 2026 · 21 revisions

Eagle Search

Search and read for projects.eao.gov.bc.ca is DEMI's: digitalspace/eagle-demi wiki, Search-and-Retrieval covers how it works, ADR-011-Public-Read-Surface covers what DEMI exposes to eagle-public, and Sync-Architecture and Search-Index-Reference cover the index. The retired eagle-search repo and what remains of its Azure estate are on Eagle Search Archive.

This page covers the Angular eagle-public line (develop, tags v2.7.x), which reads everything from DEMI through /demi-search. It makes no eagle-api call. Comments are collected in ENGAGE only. eagle-admin and the React line read DEMI's native routes under /demi/api; see Architecture Overview.

Which backend answers

Two keys in the Mongo Config document (_schemaName: 'Config'), served by /demi-search/config, set the paths.

Key Empty value means Routes
SEARCH_API_PATH /demi-search every dataset listed below
DEMI_PROJECTS_PATH /demi-projects DEMI project point read (phases, short URL, EA certificate)

There is no eagle-api fallback and no kill switch.

Environment SEARCH_API_PATH Who answers
prod /demi-search rproxy location = /demi-search/search proxies to demi-api-prod; demi-api reads demi-cosmos-prod
test /demi-search rproxy location = /demi-search/search proxies to demi-api-test.azurewebsites.net; demi-api reads Cosmos

Routes eagle-public calls

Route Use
/demi-search/search?dataset=<name> lists and details
/demi-projects/<id> one project
/demi-search/config runtime config
POST /demi-search/gate test-site access gate
/demi-search/documents/<id>/download?redirect=1 document links. &inline=1 makes pdf, png, jpeg, gif and webp open in the browser; other types still download. View links send it, download actions do not

Datasets read through /demi-search/search:

  • Project
  • Document
  • DocumentChunk
  • List
  • Organization
  • RecentActivity, including the top=true home news list
  • ProjectNotification
  • CommentPeriod
  • Comment

Document download

Document links go to /demi-search/documents/<id>/download?redirect=1. From DEMI v0.133.0 the route also takes inline=1: PDF, PNG, JPEG, GIF and WebP open in the browser, and other types stay attachments. The bulk zip flow asks /demi-search/bulk-downloads for a presigned URL and navigates the browser to it directly; it never fetches the bytes itself, because the Content-Security-Policy has no blob host to hold them in-page.

The signed storage URL carries the document's file name (the document file name, else the display name, with the recorded extension), not the storage key. Without inline=1 every type is signed as an attachment.

Legacy eagle-api links

Old eagle-api document links are redirected at the Azure Front Door edge (rule set ruleseagleapi, rules legacydocumentdownload, legacydocumentdownloadfile, legacydocumentfetch, legacydocumentfetchfile), on test and prod. Each answers 302 to /demi-search/documents/<id>/download?inline=1 for GET and HEAD requests with no Authorization header. DEMI answers with the file, or 302 to the signed storage URL when it cannot stream it (Front-Door-Per-App-Split). The edge redirects these legacy paths:

  • /api/public/document/<id>/download[/<name>]
  • /api/document/<id>/fetch[/<name>]

Other methods, requests with an Authorization header, and every other /api path reach eagle-api. A #fragment on the link survives both redirects, so a PDF link ending in #page=25 opens at that page. Rule detail: eagle-edge README.md, "Legacy document links".

Unified search page (react line)

On the react line (see Eagle Public Release Lines), one /search page in eagle-public covers all four record types, chosen by a record query param: projects, documents, activities, notifications (default projects).

Common params: keywords, sortBy, currentPage, pageSize, cols (hidden columns, comma list). Documents also take scope (names or inside; inside searches document contents and is gated by the CONTENT_SEARCH config flag). Every active filter is sent as and[<id>] on /demi-search/search, one query param per filter id, using the same wire ids as the rest of this page.

The header Search link points at /search.

Old addresses redirect client-side, keywords and paging carried over:

Old address Redirects to
/projects-list /search?record=projects
/search (bare, or with document filters) /search?record=documents
/search/content /search?record=documents&scope=inside
/news /search?record=activities
/project-notifications /search?record=notifications
#/<any of the above> the path without #, then the row above

/search-help is unchanged.

/updates/:id is not a redirect. It renders the home page with that update open in a reader dialog (DEMI dataset=RecentActivity&and[_id]=<id>); closing the dialog navigates back to /. react line only.

Tab counts come from DEMI GET /search/counts. An environment where that route 404s falls back to four pageSize=1 reads, one per record type. A null count hides that pill's badge; the notifications count is null when DEMI's SEARCH_INDEX_PROJECT_NOTIFICATIONS is unset.

The old per-type page components, their table configs and the TableList shell are retired. TableTemplate has no importers left; the comments page renders its own list and the notification documents tab reuses the project DocumentsTab.

Project notification detail page (react line)

A notification row in the notifications search results links to /pn/:projId, or to /p/:associatedProjectId when the notification has been promoted to a full project. /pn/:projId reuses the project detail page shell (masthead, summary panel, tab strip) with three tabs, in order — overview, engagement, documents — and its index redirects to overview. /pn/:projId/cp/:commentPeriodId/details is a sibling route under the app shell, not a child of /pn/:projId; it renders the comment period page as its own full page, same as the project comment period route.

There is no eagle-api public endpoint for a notification; the detail page reads DEMI dataset ProjectNotification. Its documents tab reads dataset Document scoped to the notification id.

Query-shape gotchas

  • Filters are and[key]=value, not bare query params.
  • top and docIds are the exception: sent bare, not wrapped in and[].
  • docIds=a|b lookups go 50 ids per request. The Azure edge returns 404 for a query string over about 1900 characters.
  • pageSize on a filtered search caps at 500.
  • A single-record read filters on and[_id]=<id>. A bare _id=<id> is silently ignored by eagle-api's /api/search, so it only works against /demi-search.

See also

Clone this wiki locally