Koha-clms/api/v1/swagger/paths
Martin Renvoize 52c16d61c3
Bug 41901: Allow duplicate check when adding authority via API
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>
2026-05-24 13:42:22 +01:00
..
acquisitions_baskets.yaml Bug 29668: Add API route to add a basket 2026-02-16 14:45:29 +00:00
acquisitions_edifiles.yaml Bug 40541: Add missing new line at the end of files when missing 2025-07-31 12:42:09 -06:00
acquisitions_funds.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
acquisitions_orders.yaml Bug 39816: (QA follow-up) Rename 'late_since_days' to 'days_late' 2025-10-22 07:42:55 -06:00
acquisitions_vendor_issues.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
acquisitions_vendors.yaml Bug 41594: Add Cypress tests 2026-04-02 18:31:10 +01:00
acquisitions_vendors_config.yaml Bug 40684: Adjust permissions for vendors 2025-09-24 09:25:04 -06:00
additional_contents.yaml Bug 39900: (follow-up) Add a newline to end of additional_contents.yaml 2025-08-15 09:52:29 -06:00
advancededitormacros.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
article_requests.yaml Bug 40541: Add missing new line at the end of files when missing 2025-07-31 12:42:09 -06:00
auth.yaml Bug 36561: Make /auth/password/validation use new permission 2025-07-24 17:04:05 -06:00
authorised_value_categories.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
authorised_values.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
authorities.yaml Bug 41901: Allow duplicate check when adding authority via API 2026-05-24 13:42:22 +01:00
biblios.yaml Bug 35380: Make updateBiblio-API respect Record overlay rules 2026-05-24 13:42:13 +01:00
biblios_item_groups.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
biblios_merge.yaml Bug 37791: Fix 'Biblio not found' messages on the API 2024-10-11 12:21:29 +02:00
bookings.yaml Bug 33736: (follow-up) Remove top-level embed in bookings.yaml 2024-10-25 11:09:57 +02:00
cash_registers.yaml Bug 39091: Add cash registers list REST API endpoint 2025-07-23 16:36:40 -06:00
checkouts.yaml Bug 40665: API spec changes 2025-09-05 15:10:36 -06:00
circulation_rules.yaml Bug 40541: Add missing new line at the end of files when missing 2025-07-31 12:42:09 -06:00
cities.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
clubs.yaml Bug 25787: Update club holds to only require place_holds permission 2025-05-06 18:48:23 +02:00
config_file_transports.yaml Bug 39190: Rename API from sftp_servers to file_transports 2025-09-19 13:23:25 -06:00
config_smtp_servers.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
deleted_biblios.yaml Bug 37791: Fix 'Biblio not found' messages on the API 2024-10-11 12:21:29 +02:00
erm_agreements.yaml Bug 37576: Add additional fields for ERM agreements 2024-11-08 16:09:17 +01:00
erm_config.yaml Bug 34387: Improve API docs naming consistency 2023-08-15 11:25:35 +03:00
erm_counter_files.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_counter_logs.yaml Bug 36627: Rename embed method to patron 2024-12-23 13:36:14 +01:00
erm_counter_registries.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_custom_reports.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_default_usage_reports.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_documents.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_eholdings_packages.yaml Bug 37577: Add additional fields for ERM packages 2024-11-08 16:09:19 +01:00
erm_eholdings_packages_resources.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_eholdings_resources.yaml Bug 38201: Add missing newlines at end of file 2025-10-02 09:40:32 -06:00
erm_eholdings_titles.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_eholdings_titles_resources.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_extended_attribute_types.yaml Bug 38446: Add a dedicated route to retrieve ERM-related additional fields 2025-11-17 15:15:38 -07:00
erm_licenses.yaml Bug 35287: REST API - Add additional fields support to ERM Licenses 2024-10-24 13:38:19 +02:00
erm_sushi_services.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_usage_data_providers.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_usage_databases.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_usage_items.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_usage_platforms.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_usage_titles.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
erm_users.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
extended_attribute_types.yaml Bug 37577: Add additional fields for ERM packages 2024-11-08 16:09:19 +01:00
holds.yaml Bug 23269: (follow-up) Rename to item_level_holds_count and add tests 2026-05-24 13:42:11 +01:00
ill_backends.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
ill_batches.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
ill_batchstatuses.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
ill_requests.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
import_batch_profiles.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
import_batches.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
item_types.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
items.yaml Bug 40154: prevent deletion of items with holds 2026-03-23 12:32:24 +00:00
jobs.yaml Revert "Bug 36217: Fix background jobs page's include_last_hour filter" 2024-10-18 14:26:01 +02:00
libraries.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
lists.yaml Bug 28965: Add /public/lists 2024-11-08 16:09:21 +01:00
oauth.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
patron_categories.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
patrons.yaml Bug 41733: Honor EmailPatronRegistrations in the API 2026-05-24 13:42:18 +01:00
patrons_account.yaml Bug 38931: Add endpoints for individual credits and debits 2025-10-14 14:51:59 -06:00
patrons_checkouts.yaml Bug 40665: API spec changes 2025-09-05 15:10:36 -06:00
patrons_extended_attributes.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
patrons_hold_groups.yaml Bug 41849: Add cancel hold_group REST API endpoint 2026-05-24 13:42:16 +01:00
patrons_holds.yaml Bug 40543: Remove pickup_library.branchname embed 2025-08-14 16:06:00 -06:00
patrons_password.yaml Bug 29926: (QA follow-up) Date format missing in spec 2022-05-06 10:33:10 -10:00
patrons_recalls.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
preservation_config.yaml Bug 36565: Preservation module API docs fixes (bug 30708 follow-up) 2024-04-29 09:35:36 +02:00
preservation_processings.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
preservation_trains.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
preservation_waiting_list.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
public_oauth.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
public_patrons.yaml Bug 39600: Fix spec to include invalid query handling 2025-04-29 17:19:34 +02:00
quotes.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
record_sources.yaml Bug 35380: Change record sources to by systemdefined 2026-05-24 13:42:13 +01:00
return_claims.yaml Bug 33292: Add logic to handle refunding a lost fee 2024-10-24 13:38:15 +02:00
rotas.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
search_filters.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
sip2_accounts.yaml Bug 37893: Add sip2 module permission 2025-11-18 11:21:05 -07:00
sip2_institutions.yaml Bug 37893: Add sip2 module permission 2025-11-18 11:21:05 -07:00
sip2_system_preference_overrides.yaml Bug 37893: Add sip2 module permission 2025-11-18 11:21:05 -07:00
suggestions.yaml Bug 33430: Update API specs to include required embeds 2025-05-19 18:54:20 +02:00
tickets.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00
transfer_limits.yaml Bug 37018: Add 400 response definition to all routes 2024-08-01 17:26:44 +02:00