The holds placement permit and creation steps are handled by two different API calls:
open-ils.circ.title_hold.is_possible
open-ils.circ.holds.create[.override]
This means Evergreen clients have the ability to bypass the "permit" step and go straight to the holds placement step, ignoring any limits in place with the hold matrix. This problem was brought to my attention because there is apparently an "unauthorized" IOS app that some patrons are using to place holds and it's letting them place as many holds as they want without limit.
As to why/how, I believe the "is_possible" call started out as a way to answer the question, "are there any targets for this hold / should I bother placing it?". Over time, it evolved into the primary location to check for permissibility. It's time to rectify that.
My suggestion is to deprecate both of the above methods and move clients toward using open-ils.circ.holds.test_and_create[.batch]. It combines the permission check with the holds placement. Fortunately, there are few interfaces that actually call the open-ils.circ.holds.create[.override] methods, since the catalog is the only place holds are placed. TPAC is already using open-ils.circ.holds.test_and_create.batch We just need to teach JSPAC how to do the same and thoroughly document/announce the change so that 3rd-party applications can start using the correct API.
JFYI, holds can also be created with place_hold.xul (e.g. Request circ.holds. test_and_ create. batch
Items in Copy Buckets), but it's already using
open-ils.