Consolidated Access to FOLIO Objects In A Consortium

This document will illustrate a pattern for allowing access to a view of objects consolidated across the consortium. With Enhanced Consortia Support(ECS) in FOLIO, multiple member libraries in a consortium require shared access to some object in FOLIO to improve collaboration and deduplication of effort. Objects like Inventory Instances is the first of such objects, and there will be more. ECS generally offers an common area(the central tenant) for communal actions to occur while still providing isolated spaces for each member library. We need a way to inform all consortium members of certain objects in each member tenant space without allowing direct access to the objects or the member space.

Design

This functionality will be supported primarily by mod-search. FOLIO objects are required to be propagated to a search index from each tenant in a FOLIO cluster for the purpose of searching. The search infrastructure will provide dual purposes; searching the consortium as a whole & retrieval of minimal data to identify FOLIO objects.

mod-search should return the ID and the “Name” for the FOLIO objects concerned. The “Name” of a FOLIO Object could differ; Call numbers for Inventory Holdings & barcodes for Inventory Items.

Exposing More Than ID and Name

mod-search should not serve as a substitute data source in place of primary data managing modules such as mod-inventory, mod-orders, and others. Limited information should be returned by mod-search to foster good habits. API clients that need to get more information about a FOLIO object can retrieve the identifier and tenant identifier from mod-search and then query other modules for the full data.

Exposing more data points means there two locations will need to be updated when modifications to the FOLIO object schema is required to have a consistent API experience.

Exposing more data also makes the bypass of the FOLIO permissions model less subtle. For example, It would go against the intent of an administrator when an affiliation is not granted to a user, but full inventory data can be read via mod-search. A balance between sharing capabilities in a consortium and security/ownership should be attained.

Backing Data Structure

Search functionality is backed by streams of information via Kafka and then saved in a intermediate table before indexed in Elasticsearch/Opensearch; https://folio-org.atlassian.net/wiki/spaces/DD/pages/1781559. For Inventory objects, there exists a table called consortium_instance ; a merged list of instances, holdings and items. This table will be used to support filtering and pagination for certain operations like obtaining holdings and items across the consortium.

For example, to get a list of holdings filtered by instance id and ordered by hrid with a limit of 100 records

select i.holdings from (select json_array_elements(consortium_instance.json -> 'holdings') as holdings from consortium_instance where instance_id = '3d676568-da49-5f58-b189-b2c5eb8fa9ff') i order by i.holdings ->> 'hrid' asc limit 100;

Similar structures can be used for upcoming objects that require consolidate access in the consortium.

Endpoints

The following endpoints on mod-search should support pagination(limit and offset). Sorting should be enabled only when at one least one filter critieria is used. Sorting over the entire consortium can have significant performance impact. HTTP requests will be sent to the central tenant only.

  • /search/consortium/instances

    • Filters

      • tenantId

    • Response

      • id

      • title

      • hrid

      • tenantId

  • /search/consortium/holdings

    • Filters

      • instanceId

      • tenantId

    • Response

      • id

      • callNumberPrefix

      • callNumber

      • hrid

      • instanceId

      • copyNumber

      • discoverySuppress

      • permanentLocationId

      • tenantId

  • /search/consortium/items

    • Filters

      • holdingsRecordId

      • instanceId REQUIRED

      • tenantId

    • Response

      • id

      • barcode

      • hrid

      • holdingsRecordId

      • instanceId

      • tenantId

  • /search/consortium/locations

    • Filters

      • tenantId

    • Response

      • id

      • name

      • code

      • tenantId

The pattern above can be used for other FOLIO objects that need similar treatment to Shared Instances in a consortium.

Use Case: Inventory UI

The Inventory UI is responsible for showing Shared Instances and also Holdings and Items of all member of the consortium that exists for any particular Shared Instance. How the inventory UI would use the consortium search endpoint is describe below:

  • Facets are selected in the left navigation to return a list of instances as normal.

  • When a Local Instance is selected, the instance detail page is populated as normal i.e querying Inventory modules.

  • When a Shared Instance is selected

    • A request is sent to Inventory to get full Instance details. The response will be used to populate appropriate instance information on the Instance detail pane.

    • Inventory UI will obtain the list of affiliations granted to the User Identity. A user might be able to access only 5 tenants in a consortium of 100 member tenants.

    • With the list of affiliated tenants in hand, it is possible to generate another list of non-affiliated tenants. This is done with the help of the full list of tenants in the consortium.

      • Affiliated Tenants: Each member tenant in this list will have the following operations performed in their scope. Requests are still routed to the central tenant.

        • A request is sent to the Inventory module to obtain full holdings data. A response is returned with a list of holdings that will populate a holdings accordion for the member tenant in the Instance detail pane of the UI.

        • A request is sent to get number of items in each holdings prior to accordion expansion. This is sent to the Inventory module as well.

        • Holdings accordion is displayed.

        • Expanding the holdings accordion to view the items will send the request to the Inventory module concerned.

        • Full item data is displayed.

      • Non-Affiliated Tenants: Each member tenant in this list will have the following operations performed in their scope. Requests are still routed to the central tenant.

        • A request is sent to /search/consortium/holdings?instanceId=<UUID>&tenantId=<UUID>&limit=1000(actual request will URL encoded). A response is returned with a list of holdings that will populate a holdings accordion for the member tenant in the instance detail pane of the UI.

        • A request is sent to /search/consortium/items?holdingsRecordId=<UUID>&limit=1000 to get the number of Items belonging to the holding.

        • Holdings accordion is displayed

        • Expanding the holdings accordion to view items will send a request to /search/consortium/items.

        • Items are displayed, but only with limited information.