Page tree
Skip to end of metadata
Go to start of metadata


A requirement exits to delete users. Before deleting a user the system needs to check if the user has any open transactions. The transaction check shall include:

  • open loans,
  • open requests,
  • unpaid fees/fines,
  • unexpired proxy, or
  • manual blocks (automated block should be covered by open loans or fees/fines).

If any of the defined checks is true, the user cannot be deleted. In this case the response shall include information about the checks, so that the user can be processed by library staff members.

That means, no loans, requests, fees/fines etc. are deleted automatically by this requirement.

The functionality shall be usable via the ui.

There exists the additional requirement "As a system administrator with API access, I would like to run a transaction check (previously called dependency check) for a particular user {userId}." Hence, there needs to be an API endpoint do the checks only without deletion. THe use case for this is: "As a library, we receive exmatriculation notifications through our campus ID system. We want to deactivate exmatriculated users in Folio but do not want to delete them immediately (for report reasons and given reactivation period). But we want to make sure the user doesn't have any open transaction in the library when they leave the university. If there are open transactions, we want to notify the user based on some sort of report or logfile for a quick clearing up."

Related Jira Issues

The tickets we are working on are the following:

UXPROD-2728 - Getting issue details... STATUS

UXPROD-2388 - Getting issue details... STATUS

UXPROD-2904 - Getting issue details... STATUS

MODUSERBL-115 - Getting issue details... STATUS

MODUSERBL-116 - Getting issue details... STATUS

UIU-1971 - Getting issue details... STATUS

Proposed approach

As the requirements are not only to trigger the checks from the frontend, but also to perform transaction-checks from different systems via the API, the checks cannot be performed in the frontend only. Hence, implementing the checks into the front end is considered not as a viable approach. Instead, the checks will be implemented in mod-users-bl so that the front end and different systems may use them.

  • First, an additional endpoint needs to be implemented to check for open transactions, without deleting the user. This endpoint is needed as there is a use case for a pre-check endpoint. A different system  (e.g. a campus management system) may check if there are open transactions that need to be closed before the user leaves the university. The actual deletion may take place one year later (for instance to be able to create reports). 
    • As the transaction check spans multiple modules (e.g. checking open requests via /request-storage endpoint of mod-circulation-storage) the checks need to be done in a bl-module, namely mod-users-bl.
    • In order to check if a user has open transactions, add the endpoint /bl-users/by-id/{id}/open-transactions to mod-bl-users.
    • The proposed endpoint performs defined checks for a given user by querying the corresponding modules:
      1. Fetch open loans from mod-circulation-storage via user's id: /loan-storage/loans?query=(userId==c926be9c-a8ce-4399-a9b3-11ec0fc8d6c9 AND"Open")

      2. Fetch open requests from mod-circulation-storage via user's id: /request-storage/requests?query=(requesterId=="c926be9c-a8ce-4399-a9b3-11ec0fc8d6c9" and status=Open)   

      3. Fetch open fees/fines from mod-feesfines via user's id: /accounts?query=(userId==54f65a75-f35b-4f56-86a6-fa4a3d957e57 AND"Open")        

      4. Fetch proxy info from mod-users via user's id: /proxiesfor?query=(userId=="54f65a75-f35b-4f56-86a6-fa4a3d957e57" OR proxyUserId=="54f65a75-f35b-4f56-86a6-fa4a3d957e57")        

      5. Fetch manual blocks from mod-feesfines via user's id: /manualblocks?query=(userId==54f65a75-f35b-4f56-86a6-fa4a3d957e57)
        Hence, we need to query three modules: `mod-circulation-storage`, `mod-feesfines` and `mod-users`.

    • The endpoint /bl-users/by-id/{id}/open-transactions returns if the user has open transactions and hence the user can be deleted or not. It can be deleted if totalRecords==0 for all responses of above queries.

    • The response may look like:
                  "userID": "uuid-1234",
                  "message": "not deletable",
                                "deletable": false,
                  "loans": 1,
                  "requests": 0,
                  "fees/fines": 2,
                  "proxies": 0,
                  "blocks": 0
          Based on this we can conclude that the user has one open loan and 2 open fees/fines.

  • In order to delete a user, add a DELETE endpoint to /bl-users/by-id/{id}
    • This endpoint first calls /bl-users/by-id/{id}/open-transactions (or its implementation) to check if the user can be deleted. If this is the case, it calls DELETE on /users/{id}. If the user cannot be deleted, as some above mentioned resources are pointing to this user, the response shall clarify this.
  • When deleting a user from the ui, the frontend must call /bl-users/by-id/{id}.
  • Another approach might be that DELETE /users/{id} calls /bl-users/by-id/{id}/deletable however this would assume mod-users needs mod-users-bl which would end in a circular dependency

Open questions

  • Is it the correct approach to add a DELETE endpoint to /bl-users/by-id/{id}, and calling DELETE on /users/{id} from there?
  • Is it okay to call DELETE on /bl-users/by-id/{id} from ui-users?

  • No labels


  1. This sort of thing makes me think that we maybe should have maintained reference lists in the user space.  The problem then becomes keeping that information consistent with that in the other modules, but it flips the script on dependencies... instead of users-bl having dependencies on circ-storage, feesfines, etc. those would have dependencies on users, which they likely already do.  Then implementing a GET /bl-users/by-id/{id}/references endpoint would only require a call to the appropriate API in mod-users.

    Unfortunately, I don't think it would be an easy task to work this in now as it would require work in at least the 5 places you mention above - loans, requests, feesfines, proxies, blocks, in addition to the new API in bl-users and corresponding API/storage in mod-users.  Anyway food for thought.

    1. This sort of thing makes me think that we maybe should have maintained reference lists in the user space

      I believe this is one of the options that might be included in the decision proposal for how to manage references during deletion that the Technical Leads asked Zak_Burke to write.

  2. In other areas of the system, it was decided that these checks would be done in the front end, in order to limit the expansion of dependencies to only the front end and not the back end of the system. Why was it decided to perform these checks in the back end in this case?

    1. We need to perform the checks in the backend as there is the requirement to perform user-deletions with references-check via mod-users-import ( MODUIMP-33 - Getting issue details... STATUS ). Hence, the references check needs to be called from another backend module and cannot be done in the front end only.

      1. We need to perform the checks in the backend as there is the requirement to perform user-deletions with references-check via mod-users-import

        I think it could help the reader of this document understand why this approach was taken if that was included in the description of the situation. And maybe explain why having the checks in both the UI and the import was considered not a viable approach.

  3. Whilst I think all of the listed references (loans, requests, fees/fines, proxy relationships, patron blocks) in this document are included in Platform Core, I think it might be worth referring to UITEN-128 - Getting issue details... STATUS for a discussion of some of the challenges with this approach to reference checking.

    I believe that issue outlines a challenge with using optional interface dependencies and permission sets that include permissions from the implementation of that interface.

    As I understand it, in order for mod-users-bl  to use these interfaces, the module permissions for this endpoint would need to include the permissions from the implementations, meaning in practice these dependencies cannot be optional. As mod-users-bl provides the interface for users to log into the system, in effect, a basic system that allows for a login would need to rely on mod-circulation-storage , mod-feesfines  and mod-patron-blocks .

    That is unless we intend for the users to have the permissions to perform these checks.

    Craig McNally Zak_BurkePlease correct me if I've garbled my understanding of this situation from that issue (and other recent conversations about unique permissions).

    Much like Craig McNally comment above. I think it is unlikely that this challenge can be easily circumvented and as such is more for future reference and context than a critique of this proposal.

    1. Marc Johnson Thanks for your feedback!
      I see it similar to you. This proposal will rely on mod-circulation-storage and mod-feefines as non-optional dependencies. 
      Note, that it will not depend on mod-patron-blocks, as automated blocks should be covered by open loans or fees/fines, as stated in UXPROD-2728.

      I see that this is a drawback of this proposal, even if mod-circulation-storage and mod-feefines are part of folio-core.
      But I hope it is still a workable solution.

      1. I hope it is still a workable solution.

        Similarly to Craig McNallycomments, I don't think there is an alternative available at this time, rather these comments are there more to link this proposal to some other contexts which have encountered challenges.

      2. Note, that it will not depend on mod-patron-blocks, as automated blocks should be covered by open loans or fees/fines, as stated in UXPROD-2728.

        Interesting. How does that work for blocks that not dependent upon fees / fines, e.g. item (borrowing) limits?

        1. I checked internally: We need to check for a defined set of open transactions. This set is defined in  UXPROD-2904 - Getting issue details... STATUS .
          It does not list automated blocks from mod-patron-blocks. This has been agreed with Annika Schröer . Hence, we do not need to include mod-patron-blocks as a dependency.