Requesting serials and multipart monographs

Requesting serials and multipart monographs

Related information

Non-functional requirements

  • Performance - creating an ECS TLR request requires complex actions within the platform backend. As a result, making such a request can take several seconds (with examples reaching up to 8 seconds). Assuming a multi-item request may contain requests for tens or hundreds of items, it is necessary to be able to process the multi-item request in a reasonable amount of time.

Assumptions

  • In FOLIO Inventory, a multi-volume (serial) is treated as one title, with all volumes and items linked to that title

  • For each volume/episode of the series, there is at least 1 inventory item (but maybe more)

  • No changes to FOLIO UI in the scope of UXPROD-5398

  • It’s okay that mod-circulation-bff and mod-requests-mediated are not a part of the FOLIO community yet (both are expected to pass TCR in Umbrellalief)

  • It's okay that the limit on the number of requests/loans per patron is taken into account while bulk multi-volume requesting - CONFIRMED (online session)

  • It's okay that for each selected item in a multi-select form, the list of allowed service points is determined separately and independently from each other - CONFIRMED and ADDRESSED ON MOCKUPS

  • It's okay that when creating a request for a stub item, library staff will have to close the original request and create a new request for the correct item for fulfillment (this is a consequence of the fact that the current implementation of ECS TLR does not support the Move action) - CONFIRMED (email)

Outstanding questions

  • What would be an appropriate limit on the number of items requested in a multi-item request? Should/can factors like performance and patron blocks be taken into account (for example, there’s no point in allowing 100+ items if patron blocks restrict the patron to no more than 20 open requests and 10 concurrent loans), as well as a general sense of practicality?
    SB: We should check with Locate on this, if that hasn’t been done already, with regard to UI usability. It seems that if a patron has a block on requesting or borrowing something, then that item wouldn’t surface in Locate, but I’m not certain.
    As for performance, in our August 26 meeting, the following action item was noted: “@Pavel Filippov & @Raman Auramau will work on finding the request limit for FOLIO, via performance or other means”.
    Let’s discuss in our meeting this week on Wednesday with the full group.
    RA: 1) Need to confirm the LoC expectations for this. 2) There should be a limit configuration on both Locate and FOLIO.

Resolved

  • Do we need to support ProxyUser functionality for multi-item requests?
    SB: This functionality is not available in Locate. We do not need to support it now, but should not discount needing to in the future.

  • How do we process Patron comments? E.g., copy them to all individual requests?
    SB: Notes in Locate already map to the patron comments field in FOLIO. Please verify with Vijay, though.
    RA: Agreed to copy patron notes to all individual circulation requests.

  • Should we implement multi-item request support for secure patrons right away (must-have), or when possible/if we have time (nice-to-have)? (~3-4 additional story points)
    SB: We need to complete all other functionality first. It should be part of this feature, but not worked on before “standard” patron functionality.
    RA: Agree to implement “standard” patron functionality first to enable integration testing, and then extend the functionality to cover “secure” patrons

  • What is the timeline for delivery of all functionality? Considering that some of it is implemented on the Locate side, some on the FOLIO side, and integration and end-to-end testing are required, we need a timeline with checkpoints.
    SB: Please review this page, particularly #20.
    The work must be as far along as possible by Oct. 24 for billing purposes, but this does not control the feature delivery timeline. Once both teams have their work planned and in tickets, we will work together first to identify blockers - which FOLIO tickets block Locate, and if there are Locate tickets that block FOLIO. Once we understand that, we can create an overall diagram of tickets with blockers, and the order in which the work needs to proceed. We will derive our timeline e2e from there. When we can deliver the work is our feature delivery timeline.
    Volaris will continue to work on their feature until it is complete.

Solution design

Working with the RTAC module

Mod-rtac allows a library user (patron) to know the location and availability/checkout status of items - more details on https://folio-org.atlassian.net/wiki/spaces/FOLIJET/pages/1384120. While still providing the required functionality, the current implementation of the module encounters issues in cases where a large number of items are linked to a single instance. The worst-case known scenario is around 30K items per instance (5-6 instances on the example of the LoC), but there can be many cases with 5-6K items per instance.

When working with such a large number of items, another concern arises - how the patron will be able to effectively interact with them and select items from the list on the UI form. A possible solution is to introduce some filters in the UI. This means the mod-rtac needs to be made searchable and filterable, and likely support pagination.

Therefore, although the design changes in the mod-rtac module are not within the scope of the current document, it is very likely that this should be investigated and addressed for the delivery of the discussed feature.

UI forms for multi-volume requesting

The discussed feature includes changes only to the Locate UI; mockups are available here - https://www.figma.com/design/MgEtfu9hierN6kg99f7INY/FY26Q1_US1385223-US1404199_Request-item-updates?node-id=3183-403&p=f&t=jfZuoInTQfGkbVb3-0

Interaction between Locate and FOLIO

The interaction between OPAC/Locate and FOLIO for processing multi-item requests presents a significant challenge. The section below provides detailed information on this topic.

Multi-Item Requesting Limits

One of the logical questions related to multi-item requesting is: “Should there be a limit on the number of items in a single request, and if so, what should that limit be?”

This topic involves three key aspects to consider:

  1. Performance Limits within the FOLIO Platform - Performance of Creating Circulation Requests in a Single Tenant / ECS Context

    1. We need to assess whether we can define specific performance expectations regarding how quickly individual circulation requests are created based on a multi-item request.

    2. Currently, assuming there are no strict performance requirements (i.e., "it takes as long as it takes"), the least risky approach appears to be configuring the ParallelThreadExecutor in mod-requests-mediated, e.g., with N=2.

    3. @Raman Auramau Find the up-to-date performance metrics for the circulation domain.

      1. All the performance testing reports for the Circulation domain from the PTF team are available here - https://folio-org.atlassian.net/wiki/spaces/FOLIJET/pages/1381517

    4. @Raman Auramau Analyze if mod-circulation includes any overload protection mechanisms (e.g., back pressure) to handle spikes in request volume.

      1. No, the mod-circulation module has nothing that would help in this case. The only idea is to analyze the response time when working with the API module and balance the load depending on this.

  2. User-Specific Limits for Concurrent Requests and Loans

    1. Example Scenario: A patron makes a multi-item request for 100 items. Library staff process this request, creating 100 individual circulation requests, locating all the items, and delivering them to pick-up service points. However, during checkout, it is discovered that the patron already has open loans and is allowed to borrow only one additional item. As a result, the work done for the remaining 99 items becomes redundant.

    2. Challenge: Patron blocks and limits are highly dynamic. A single patron may have a limit on the number of concurrent loans but can manipulate their borrowing capacity by a) returning items to reduce current loans, or b) closing previous loans to free up space for new ones. This dynamic nature makes it difficult to design a system behavior that is both user-friendly and operationally efficient.

    3. @Raman Auramau Analyze whether it is possible to determine, at any given moment, how many requests/loans a specific patron has, as well as the configured limits for their concurrent requests/loans. Investigate how this information can be retrieved and used to guide multi-item requesting behavior.

      1. The platform has the following types of limits relevant to the topic under discussion:

        • Automatic patron blocks: There are six types of conditions plus limits per patron group. These are provided by the mod-patron-blocks module and configured in Settings → Users → Conditions/Limits. This module provides an endpoint to check, using the userId, whether a patron has automatic blocks (and if so, which ones). Note: This is an internal platform API and is not accessible through edge-patron.

        • Manual patron blocks.

        • Item limits: An optional parameter in circulation policies, which defines the number of loans that can be open under a specific loan policy (e.g., for particularly valuable items). This applies only at checkout.

      2. As a result, it is quite difficult to formulate requirements or expectations about how to inform patrons of potential blocks when making multi-item requests, or how to configure automatic limits.

  3. Logical Limits Based on Common Sense

    1. A clearly defined global limit may help library staff avoid these issues. This could be achieved by:

      1. Creating a global configuration at the tenant level (e.g., a virtual maximum limit enforced via mod-settings).

      2. Alternatively, establishing limits by patron group to provide more granularity in managing patron-specific needs.

Support for Congressional Loans/Secure Requests

There can be several patron groups whose requests must be processed exclusively within a dedicated Secure tenant. To enable multi-item requesting support for this tenant, additional efforts are required (compared to handling requests from regular patron groups):

  1. Implement Secure Patron Support in edge-patron - Develop new versions of the API specifically for secure patrons within the edge-patron module - 1–2 SPs.

  2. Add Secure Tenant Handling in mod-requests-mediated - Implement a condition check in mod-requests-mediated to verify “if the current tenant is secure”. If the condition is met, create individual Secure mediated requests within the same module - 2 SP.

This work can either be included in the main development process or added later as an enhancement.

Interaction between OPAC/Locate and FOLIO

The interaction between OPAC/Locate and FOLIO for processing multi-item requests presents a significant challenge. Let’s review two possible alternatives.

Splitting requests on the OPAC/Locate side ( rejected)

The simplest approach, both logically and in terms of implementation, is to iterate over all the items selected by the patron on the OPAC/Locate side and create individual circulation requests for each of them in FOLIO. This would allow for leveraging the existing edge-patron API with minimal or no modifications.

At the same time, it’s important to consider the performance implications previously mentioned. If creating a single circulation request takes 3-5 seconds, and a multi-item request contains, for example, 100 items, the total processing time would be 300-500 seconds. This, understandably, would result in a poor user experience. However, if the allowed number of items in a single multi-item request is relatively small (e.g., up to 10-20 items - personal opinion), it can be quite manageable on the OPAC/Locate side. Alternatively, OPAC/Locate could handle the iteration over all items in the background. In this scenario, the responsibility for persisting the source data, managing iterations, handling errors, and other related tasks would shift entirely to the OPAC/Locate side.

Pros: A simple and straightforward approach that does not introduce new dependencies between OPAC/Locate and FOLIO and does not require synchronization of efforts.

Cons: All functional logic ends up on the OPAC/Locate side. As a result, FOLIO does not "learn" to handle multi-item requests, and each new OPAC system will be forced to implement the entire logic on its own side. And if the task of adding support for multi-item requests in the FOLIO Requests UI App arises in the future, it will require another separate implementation. Additionally, this approach is not extensible in terms of FOLIO platform capabilities.

Estimate:

  • FOLIO - 0 SP

  • Locate - TBC with the Dreamliner team likely that this should be investigated and addressed to deliver

Splitting requests on the FOLIO side ( accepted)

If the logic for splitting a multi-item request into individual circulation requests is moved to the FOLIO side, the scenario might look as follows - a new edge-patron API would be required to accept multi-item requests. This request would then need to be passed to one of FOLIO's backend modules for further processing.

Obviously, performance remains a significant issue here as well. For a multi-item request with only a few items, synchronous interaction might still be feasible.

However, even for 10-20 or more items, it would likely be necessary to introduce asynchronous interaction between OPAC/Locate and FOLIO. This complicates the design and implementation. The thing is, for asynchronous interaction, OPAC/Locate would require an additional mechanism to retrieve the processing status of the multi-item request and its results (whether all individual circulation requests were successfully created or not).

Pros: Once implemented, this approach will reduce the load on OPAC/Locate clients by centralizing the new functionality within the FOLIO platform. The approach will be reusable - other OPAC systems will also be able to work with multi-item requests through the new API. Additionally, it will be significantly easier to add this functionality to the FOLIO Requests UI App (requiring only UI changes). This will also open up possibilities for extending multi-item request capabilities in the future (e.g., certain mediation activities by library staff, batch tracking, batch notifications, etc. - though these are currently out of scope for the discussed feature).

Cons: A more complex implementation that requires introducing a new API as well as adding support for a new logical entity - the multi-item request - to the FOLIO platform.

Estimate:

Sequence diagram

New edge-patron API

Refer to https://folio-org.atlassian.net/wiki/spaces/DD/pages/1206812731 for the detailed documentation.

Action

Method, URI

Description

Example

Action

Method, URI

Description

Example

Creating a batch multi-item request

POST {{edge-base}}/patron/batch-request

Creates a new batch request and returns a batchId value. The batchId value can be provided by the client or generated by the FOLIO

{ "batchId": str | null, // optional parameter "requests": [ { "itemId": uuid, // required "pickUpLocationId": uuid // required } ] }

Retrieving the current status of a batch request

GET {{edge-base}}/patron/batch-request/{batchId}/status

Returns the processing status of the batch request.

Response example:

{ "batchId": "123456", "status": "In Progress", "submittedAt": "2023-01-01T10:00:00Z", "completedAt": null, "totalRequests": 100, "processedRequests": 50, "failedRequests": 5 }

Statuses:

  • Pending(?)

  • In Progress

  • Completed

  • Failed(?)

Retrieving detailed information about requests in a batch

GET {{edge-base}}/patron/batch-request/{batchId}/details

Returns detailed information for each request in the original batch.

Response example:

{ "batchId": "123456", "status": "Completed", "requests": [ { // Structure similar to the information for requests in the response to the account info(?) // Alternatively, a structure resembling the initial request - with only itemId, servicePointId, requestId (if present). // If `requestId` exists, it means the circulation request was successfully created and further details can be retrieved. // Otherwise, it means the request couldn't be created. }, { ...more requests... } ] }

FOLIO Back-end WBS

SP = working day (% - confidence factor)

Module

Estimate, SP

Scope of Work

Module

Estimate, SP

Scope of Work

Design a FOLIO public API to create a batch request and check the status of the batch request

2

Design a public API to create a batch multi-item request and check the status of the batch request (refine the draft API described above)

{{edge-base}}/patron/batch-request

Implement new API in edge-patron

2 (90%)

Provide a new API for multi-item requests, resolve externalSystemId or an auth token into a FOLIO patron, and pass the request to mod-patron

See https://github.com/folio-org/edge-patron/blob/master/src/main/java/org/folio/edge/patron/PatronHandler.java

Implement new API in mod-patron

2 (90%)

Allow the module to proxy a multi-item request from edge-patron to mod-circulation-bff

Implement new API in mod-circulation-bff

2 (90%)

can be potentially skipped

Allow the module to proxy a multi-item request from mod-circulation-bff to mod-requests-mediated

Implement new API in mod-requests-mediated

2 (90%)

Provide a new API for multi-item requests (service in Java code)

Add 2 new tables to the mod-requests-mediated schema and CRUD for them

3 (90%)

Table batch_request

{ "batchId": "123456", // Unique identifier for the batch "status": "In Progress", // Current processing status (e.g., Pending, In Progress, Completed, Failed) "submittedAt": "2023-01-01..", // Timestamp when the batch was created "completedAt": null, // Timestamp when the batch processing was completed "totalRequests": 100 // Total number of requests in this batch }

Table batch_request_splitted

{ "batchId": "123456", // Foreign key referencing `batch_request.batchId` "itemId": "789456", // Item ID associated with the split request "servicePointId": "SP001", // Service point ID tied to the request "status": "Pending", // Processing status of the individual request (e.g., Pending, Processed) "circulationRequestId": null, // (@Nullable) ID of the circulation request if created successfully "errorDetails": null // (@Nullable) Detailed description of an error if the request failed }

Implement the logic to split the batch multi-item request into individual circulation (ECS TLR or local) requests

2 (90%)

  • Add the logic to split the batch request into individual circulation requests

    • See org.folio.mr.service.impl.EcsRequestServiceImpl

  • It is necessary to add a new type of workflow and review the module code (refactor if necessary) for branching logic depending on the type of workflow

    • See 2024-07-29-populate-initial-mediated-workflows.sql


  • Batch Request Creation

    • Implement logic to create an entry in the batch_request table for each new batch request received

    • Insert corresponding entries in the batch_request_splitted table for each individual item in the batch

  • Filters and Search

    • Ensure that batch requests (and their individual processed items) can be filtered and searched via appropriate parameters (e.g., status, batchId, itemId, etc.)

Implement a check for the number of items in the batch request

3 (90%)

Implement a check for the number of items in the request; the limit should be configurable. If the limit is exceeded, a 413 Payload Too Large error should be returned

  • Question: Should this limit be configurable via the UI or as a static value somewhere? (mod-setting + ENV var?)

Implement the individual circulation request creation

5 (60%)

For each record in the table with a status of Pending, an individual circulation request must be created for the corresponding item

  • Status Updates (Real-Time Tracking)

    • As individual requests are processed, update the status in batch_request_splitted

    • Update aggregated fields (processedRequests, failedRequests, etc.) and status in the batch_request table to reflect processing progress

  • Error Handling

    • Ensure any issues during individual request processing are recorded in the errorDetails field of the respective record in batch_request_splitted

    • If errors exceed a predefined threshold, update the status of the batch_request table to Failed

  • Completion Handling

    • Add logic to set the completedAt timestamp in the batch_request table when all items in the batch are processed

Add a timer/controller to mod-requests-mediated to enable periodic job execution

2 (90%)

The mod-requests-mediated module needs to have a timer in order to enable execution of periodic jobs.

Add the logic to return batch request processing status and statistics

2 (80%)

When processing a request to obtain the processing status of a batch request, it is necessary to collect information about all requests associated with the specified batch_id

 

27+ SPs

 

Support for Congressional Loans/Secure Requests

3-4 SPs

edge-patron (1-2 SPs) and mod-requests-mediated (2 SPs)

Support for working with service points in the same style as with online store delivery addresses

4 SPs

2 SPs for APIs in edge-patron, mod-patron, mod-requests-mediated

2 SPs for mod-requests-mediated to implement the logic

In addition, efforts will also be required for testing, module releasing, back-porting (???), and deployment, as well as Locate integration testing ().

The "all at once" diagram

T-shirt estimates

Dependency: support for the proposed and described functionality from the LOCATE is required

Area

Estimate

Comment, assumption

Area

Estimate

Comment, assumption

Inventory & Search

0

With the assumption that each item record ….

Otherwise, M->L for search only

Support for OPAC/Discovery (LOCATE) multi-volume select UI form

0->S/M

With the assumption that either 1) some general SP for multi-volume requesting is introduced, or 2) it’s allowed to request different volumes to different SPs (e.g., prepare reference data, return general SPs)

Dependency on LOCATE UX

Processing of a multi-volume request on the FOLIO side

XL with conf. vote 60%

Assumption: Option #2 from the diagram above

Error handling on the FOLIO side

M

Assumption: async call from OPAC/Discovery (LOCATE) with trx id in response for tracking

Support major releases (S, R, T?)

S

Depends on which FOLIO flower releases are to be supported