Automated Patron Blocks feature design
Purpose of this document
It needs to be decided which module "automated patron blocks" functionality has to be implemented in. There are few options:
- mod-circulation (Approach 1)
new "automated blocks" module (mod-automated-blocks)
fetching data from mod-circulation (circular dependency)
fetching data from mod-circulation-storage
consuming events published by mod-circulation
- mod-circulation requests block from mod-automated-blocks (Approach 2)
- mod-automated-blocks publishes block events
Overview
It is required for a number of modules (both BE and FE) to be able to check if a patron should be blocked from borrowing, renewing and/or requesting items and why. mod-circulation should check for these blocks every time one of these actions is performed. Also, we need to provide an endpoint (at least for UI modules, see UIU-1273) for checking patron block conditions. Each of these condition checks has a dependency on functionality implemented in various modules:
Condition | Module | Purpose |
---|---|---|
Maximum outstanding fee/fine balance | mod-feesfines | Calculate fee/fine balance |
Maximum number of items charged out | mod-circulation | Get the number of open loans |
Maximum number of lost items | mod-feesfines | Get a number of open fees/fines with item status "Aged to lost" or "Declared lost" |
Maximum number of overdue item | mod-circulation | Get overdue period (CIRC-548) |
Maximum number of overdue recalled items | mod-circulation | Get overdue period (CIRC-548) |
Maximum number of overdue days for recalled item | mod-circulation | Get overdue period (CIRC-548) |
Approach 1 (mod-circulation)
API
Even though most of the checks will be happening internally in mod-circulation, other modules (UIU-1273) will need to use this functionality to display existing patron blocks to the user, so it is proposed to add a new endpoint:
GET /automated-patron-blocks/{patronId}
Response example:
{ "automatedPatronBlocks": [ { "blockBorrowing": true, "blockRenewals": false, "blockRequests": false, "message": "Patron has reached maximum allowed number of items charged out" }, { "blockBorrowing": false, "blockRenewals": false, "blockRequests": true, "message": "Patron has reached maximum allowed outstanding fee/fine balance for his/her patron group" } ] }
Dependencies
No new dependencies are required in mod-circulation for Approach 1.
Module | Endpoint | New module dependency | Purpose |
---|---|---|---|
mod-circulation → mod-users | /patron-block-condition /patron-block-limits?query=(patronGroupId=={patronGroupId}) | No | Get conditions and limits to be checked. |
mod-circulation → mod-feesfines | /accounts?query=(userId=={patronId} AND status=="Open") | No | Check outstanding fee/fine balance and number of open fees/fines for lost items. |
mod-circulation → mod-calendar | /calendar/periods | No | Calculate the overdue period (already implemented in CIRC-548). |
Approach 2 (new module; pub-sub)
New module (mod-automated-blocks) will be created. It will receive info about circulation events and fees/fines from event subscriptions.
Publishing/subscriptions configuration
Module | Publish/subscribe | Event type | Payload |
---|---|---|---|
mod-feesfines | publish | FEE_FINE_BALANCE_CHANGED | { |
mod-circulation | publish | ITEM_CHECKED_OUT | { |
mod-circulation | publish | ITEM_CHECKED_IN | { |
mod-circulation | publish | ITEM_DECLARED_LOST | { |
mod-circulation | publish | LOAN_DUE_DATE_CHANGED | { |
mod-automatedblocks | subscribe | FEE_FINE_BALANCE_CHANGED |
DB
Using the info from events mod-automated-blocks is subscribed to, we need to maintain one object per patron in the DB:
{ "id": string, "userId": string, "outstandingFeeFineBalance": numeric, "numberOfLostItems": numeric, "openLoans": [ { "loanId": string, "dueDate": string, "returnedDate": string, "recall": boolean } ], "openFeesFines": [ { "feeFineId": string, "balance": numeric, "feeFineTypeId": string } ] }
This object allows to check each of the block conditions for a patron:
Condition | Check against |
---|---|
Maximum outstanding fee/fine balance | .outstandingFeeFineBalance |
Maximum number of items charged out | number of .openLoans objects |
Maximum number of lost items | .numberOfLostItems |
Maximum number of overdue items | number of .openLoans[dueDate < returnedDate] |
Maximum number of overdue recalled items | number of .openLoans[dueDate < returnedDate AND recall == true] |
Maximum number of overdue days for recalled item | max of .openLoans[dueDate < returnedDate AND recall == true].(returnedDate - dueDate) |
API
GET /automated-patron-blocks/{patronId}
Other modules will use this endpoint to determine if patron should be blocked from borrowing, renewing and/or requesting items and why.
Response example:
{ "automatedPatronBlocks": [ { "patronBlockConditionId": "2149fff5-a64c-4943-aa79-bb1d09511382", "blockBorrowing": true, "blockRenewals": false, "blockRequests": false, "message": "Patron has reached maximum allowed number of items charged out" }, { "patronBlockConditionId": "ac13a725-b25f-48fa-84a6-4af021d13afe", "blockBorrowing": false, "blockRenewals": false, "blockRequests": true, "message": "Patron has reached maximum allowed outstanding fee/fine balance for his/her patron group" } ] }
GET /patron-block-condition
GET /patron-block-conditions/{patronBlockConditionId}
PUT /patron-block-conditions/{patronBlockConditionId}
GET /patron-block-limits
POST /patron-block-limits
GET /patron-block-limits/{patronBlockLimitId}
PUT /patron-block-limits/{patronBlockLimitId}
DELETE /patron-block-limits/{patronBlockLimitId}
These endpoints will be moved from mod-users. This allows to avoid mod-automated-blocks dependency on mod-users.
Dependencies
Module | Endpoint | Purpose |
---|---|---|
mod-circulation → mod-automated-blocks | GET /automated-patron-blocks/{patronId} | Check if action is allowed before borrowing, renewing and/or requesting items. |
mod-automated-blocks → mod-users | GET /users/{id} | To determine which patron group a patron belongs to. |