7b8909cb90
This patch adds support for add, edit and delete patrons via REST API. GET /api/v1/patrons Get patron list from params GET /api/v1/patrons/<borrowernumber> Get single patron POST /api/v1/patrons Create a new patron PUT /api/v1/patrons/<borrowernumber> Update data about patron DEL /api/v1/patrons/<borrowernumber> Delete a patron Revised Test plan: 1) Apply this patch 2) Run tests perl t/db_dependent/api/v1/patrons.t 3) Add a user with proper rights to use the REST API 4) play with your favourite REST client (curl/httpie, etc.): Authenticate with the user created above and get a CGISESSION id. Use the CGISESSION to add, edit and delete patrons via the API. 5) Use PUT /patrons/<borrowernumber> for a patron without borrowers flag. This should go into pending patron modification status and needs to be accepted by a librarian. Please note there is no validation of body input in PUT/POST other than branchcode,category,userid,cardnumber. Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Benjamin Rokseth <benjamin.rokseth@kul.oslo.kommune.no> Signed-off-by: Josef Moravec <josef.moravec@gmail.com> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
811 lines
22 KiB
JSON
811 lines
22 KiB
JSON
{
|
|
"/patrons": {
|
|
"get": {
|
|
"x-mojo-to": "Patron#list",
|
|
"operationId": "listPatrons",
|
|
"tags": ["patrons"],
|
|
"produces": [
|
|
"application/json"
|
|
],
|
|
"parameters": [{
|
|
"name": "borrowernumber",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on borrowernumber",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "cardnumber",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on cardnumber",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "surname",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on surname",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "firstname",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on firstname",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "title",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on title",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "othernames",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on othernames",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "initials",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on initials",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "streetnumber",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on streetnumber",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "streettype",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on streettype",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "address",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on address",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "address2",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on address2",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "city",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on city",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "state",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on state",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "zipcode",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on zipcode",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "country",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on country",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "email",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on email",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "phone",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on phone",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "mobile",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on mobile",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "fax",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on fax",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "emailpro",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on emailpro",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "phonepro",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on phonepro",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_streetnumber",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_streetnumber",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_streettype",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_streettype",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_address",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_address",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_address2",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_address2",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_city",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_city",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_state",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_state",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_zipcode",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_zipcode",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_country",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_country",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_email",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_email",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "B_phone",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on B_phone",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "dateofbirth",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on dateofbirth",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "branchcode",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on branchcode",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "categorycode",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on categorycode",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "dateenrolled",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on dateenrolled",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "dateexpiry",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on dateexpiry",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "gonenoaddress",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on gonenoaddress",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "lost",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on lost",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "debarred",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on debarred",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "debarredcomment",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on debarredcomment",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "contactname",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on contactname",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "contactfirstname",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on contactfirstname",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "contacttitle",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on contacttitle",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "guarantorid",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on guarantorid",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "borrowernotes",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on borrowernotes",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "relationship",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on relationship",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "sex",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on sex",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "password",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on password",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "flags",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on flags",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "userid",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on userid",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "opacnote",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on opacnote",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "contactnote",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on contactnote",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "sort1",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on sort1",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "sort2",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on sort2",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactfirstname",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactfirstname",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactsurname",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactsurname",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactaddress1",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactaddress1",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactaddress2",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactaddress2",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactaddress3",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactaddress3",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactstate",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactstate",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactzipcode",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactzipcode",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactcountry",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactcountry",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "altcontactphone",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on altcontactphone",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "smsalertnumber",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on smsalertnumber",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "sms_provider_id",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on sms_provider_id",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "privacy",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on privacy",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "privacy_guarantor_checkouts",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on privacy_guarantor_checkouts",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "checkprevcheckout",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on checkprevcheckout",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "updated_on",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on updated_on",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "lastseen",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on lastseen",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "lang",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on lang",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "login_attempts",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on login_attempts",
|
|
"required": false,
|
|
"type": "string"
|
|
},
|
|
{
|
|
"name": "overdrive_auth_token",
|
|
"in": "query",
|
|
"description": "Case insensetive 'starts_with' search on overdrive_auth_token",
|
|
"required": false,
|
|
"type": "string"
|
|
}],
|
|
"responses": {
|
|
"200": {
|
|
"description": "A list of patrons",
|
|
"schema": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "../definitions.json#/patron"
|
|
}
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Authentication required",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Access forbidden",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
}
|
|
},
|
|
"x-koha-authorization": {
|
|
"permissions": {
|
|
"borrowers": "1"
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"operationId": "addPatron",
|
|
"tags": ["patrons"],
|
|
"parameters": [{
|
|
"name": "body",
|
|
"in": "body",
|
|
"description": "A JSON object containing information about the new patron",
|
|
"required": true,
|
|
"schema": {
|
|
"$ref": "../definitions.json#/patron"
|
|
}
|
|
}],
|
|
"consumes": ["application/json"],
|
|
"produces": ["application/json"],
|
|
"responses": {
|
|
"201": {
|
|
"description": "A successfully created patron",
|
|
"schema": {
|
|
"items": {
|
|
"$ref": "../definitions.json#/patron"
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Bad parameter",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Authentication required",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Access forbidden",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Resource not found",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Conflict in creating resource",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Under maintenance",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
}
|
|
},
|
|
"x-koha-authorization": {
|
|
"permissions": {
|
|
"borrowers": "edit_borrowers"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/patrons/{borrowernumber}": {
|
|
"get": {
|
|
"x-mojo-to": "Patron#get",
|
|
"operationId": "getPatron",
|
|
"tags": ["patrons"],
|
|
"parameters": [{
|
|
"$ref": "../parameters.json#/borrowernumberPathParam"
|
|
}],
|
|
"produces": [
|
|
"application/json"
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "A patron",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/patron"
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Authentication required",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Access forbidden",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Patron not found",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"503": {
|
|
"description": "Under maintenance",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
}
|
|
},
|
|
"x-koha-authorization": {
|
|
"allow-owner": true,
|
|
"allow-guarantor": true,
|
|
"permissions": {
|
|
"borrowers": "edit_borrowers"
|
|
}
|
|
}
|
|
},
|
|
"put": {
|
|
"operationId": "editPatron",
|
|
"tags": ["patrons"],
|
|
"parameters": [
|
|
{
|
|
"$ref": "../parameters.json#/borrowernumberPathParam"
|
|
},
|
|
{
|
|
"name": "body",
|
|
"in": "body",
|
|
"description": "A JSON object containing new information about existing patron",
|
|
"required": true,
|
|
"schema": {
|
|
"$ref": "../definitions.json#/patron"
|
|
}
|
|
}
|
|
],
|
|
"consumes": ["application/json"],
|
|
"produces": ["application/json"],
|
|
"responses": {
|
|
"200": {
|
|
"description": "A successfully updated patron",
|
|
"schema": {
|
|
"items": {
|
|
"$ref": "../definitions.json#/patron"
|
|
}
|
|
}
|
|
},
|
|
"202": {
|
|
"description": "Accepted and waiting for librarian verification",
|
|
"schema": {
|
|
"type": "object"
|
|
}
|
|
},
|
|
"204": {
|
|
"description": "No Content",
|
|
"schema": {
|
|
"type": "object"
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Bad parameter",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Access forbidden",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Resource not found",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"409": {
|
|
"description": "Conflict in updating resource",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
}
|
|
},
|
|
"x-koha-authorization": {
|
|
"allow-owner": true,
|
|
"allow-guarantor": true,
|
|
"permissions": {
|
|
"borrowers": "1"
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"operationId": "deletePatron",
|
|
"tags": ["patrons"],
|
|
"parameters": [{
|
|
"$ref": "../parameters.json#/borrowernumberPathParam"
|
|
}],
|
|
"produces": ["application/json"],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Patron deleted successfully",
|
|
"schema": {
|
|
"type": "object"
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Patron deletion failed",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"401": {
|
|
"description": "Authentication required",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"403": {
|
|
"description": "Access forbidden",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Patron not found",
|
|
"schema": {
|
|
"$ref": "../definitions.json#/error"
|
|
}
|
|
}
|
|
},
|
|
"x-koha-authorization": {
|
|
"permissions": {
|
|
"borrowers": "1"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|