POST /api/v1/authorities currently offers only the heading-based
C4::AuthoritiesMarc::FindDuplicateAuthority check, and the only
escape hatch is the `x-koha-override` header.
Koha already ships configurable record matching rules (see
Administration > Record matching rules) and C4::Matcher already
supports `record_type = authority`. This patch lets an API caller
opt into one of those rules when creating an authority by sending
its numeric id in a new `x-koha-matchrule` header.
Behaviour:
* If no `x-koha-matchrule` header is sent the existing heading-based
duplicate check is used. Existing clients are unaffected.
* If `x-koha-matchrule: <id>` is sent:
* non-existent id -> 400 `matching_rule_not_found`
* matcher not record_type=authority
-> 400 `invalid_matching_rule_type`
* matcher returns matches -> 409 `duplicate`; the response
body additionally contains a
`matches: [{authid, score}, ...]`
array listing every hit returned
by the matcher
* matcher returns nothing -> record is created (201)
* `x-koha-override: any|duplicate` continues to bypass all duplicate
checks, including the matcher.
A non-integer header value is rejected by the OpenAPI schema
validator before the controller runs.
Test plan:
1) Apply the patch series.
2) Run `prove t/db_dependent/api/v1/authorities.t`
=> all subtests pass.
3) Log in to the staff interface as a user with the
'manage_matching_rules' subpermission and go to
Administration > Record matching rules > New record matching
rule:
a) Set Matching rule code e.g. `AUTH_HEADING`
b) Set Description e.g. `Authority heading match`
c) Set Record type to `authority`
d) Set Threshold to e.g. `1000`
e) Add a match point:
* Search index: `Heading-Main` (or your authorities index)
* Score: `1000`
* Tag: `110` (or the heading tag used by your
authority type)
* Subfields: `a`
f) Save. Note the numeric matching rule id in the edit URL
(`admin/matching-rules.pl?op=edit_matching_rule&matcher_id=N`).
4) Export an existing authority record as MARCXML (for example
from the authority details page). Save it as `duplicate.xml`.
5) From the command line, POST the record back to Koha using the
new header (replace <N>, credentials and host):
curl -u <user>:<pass> -X POST \
-H 'Content-Type: application/marcxml+xml' \
-H 'x-authority-type: CORPO_NAME' \
-H 'x-koha-matchrule: <N>' \
--data-binary @duplicate.xml \
http://<your-koha>/api/v1/authorities
=> Expect HTTP 409. The JSON response body contains
`error_code: "duplicate"` and a `matches` array listing the
authid(s) that were found along with their score.
6) Edit `duplicate.xml` so the main heading is something that is
not already in the catalogue. POST it again with the same
header.
=> Expect HTTP 201 and a `Location` header pointing to the new
authority.
7) Re-run the POST from step 5 but additionally send
`-H 'x-koha-override: duplicate'`.
=> Expect HTTP 201 (override bypasses the matcher).
8) Send a POST with `x-koha-matchrule: 999999`.
=> Expect HTTP 400 with `error_code: "matching_rule_not_found"`.
9) Create a second matching rule with Record type `biblio` and
note its id. POST with `x-koha-matchrule` set to that id.
=> Expect HTTP 400 with
`error_code: "invalid_matching_rule_type"`.
10) POST with `x-koha-matchrule: abc`.
=> Expect HTTP 400 from the OpenAPI schema validator.
11) POST without `x-koha-matchrule`.
=> Expect the existing heading-based duplicate check to run
exactly as before (409 for a known duplicate, 201 otherwise).
12) Sign off.
Signed-off-by: Brian J. Barr <brian.barr@churchofjesuschrist.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit cb8f1ff9d5)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>