@natlibfi/melinda-record-match-validator
Version:
Validates if two records matched by melinda-record-matching can be merged and sets merge priority
535 lines (517 loc) • 19.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.comparisonTasksTable = void 0;
var _debug = _interopRequireDefault(require("debug"));
var _melindaCommons = require("@natlibfi/melinda-commons");
var _fieldSID = require("./fieldSID");
var _fieldLOW = require("./fieldLOW");
var _fieldCAT = require("./fieldCAT");
var _field = require("./field040");
var _title = require("./title");
var _field26X = require("./field26X");
var _field2 = require("./field042");
var _field33X = require("./field33X");
var _field3 = require("./field773");
var _leader = require("./leader");
var _controlFields = require("./controlFields");
var _partsAndSets = require("./partsAndSets");
var _sanityCheckAudio = require("./sanityCheckAudio");
var _sanityCheckDaisy = require("./sanityCheckDaisy");
var _sanityCheckDvd = require("./sanityCheckDvd");
var _sanityCheckIsbnQualifer = require("./sanityCheckIsbnQualifer");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/* eslint-disable max-lines */
//import {check245} from './field245';
//import {getSubfieldValues} from './collectFunctions/collectUtils';
//import {collectRecordValues} from './collectRecordValues';
//import {compareRecordValues} from './compareRecordValues';
//import {validateCompareResults} from './validateRecordCompareResults';
//import {check984} from './field984';
const debug = (0, _debug.default)('@natlibfi/melinda-record-match-validator:index');
const debugDev = debug.extend('dev');
//const debugData = debug.extend('data');
function checkExistence({
record1,
record2
}) {
if (record1 === undefined || record2 === undefined) {
return false;
}
if ((0, _melindaCommons.isDeletedRecord)(record1) || (0, _melindaCommons.isDeletedRecord)(record2)) {
return false;
}
return true;
}
function checkTestRecord({
record1,
record2
}) {
if ((0, _melindaCommons.isTestRecord)(record1) !== (0, _melindaCommons.isTestRecord)(record2)) {
return false;
}
return true;
}
function checkHostComponent({
record1,
record2
}) {
if ((0, _melindaCommons.isComponentRecord)(record1, false, ['973']) !== (0, _melindaCommons.isComponentRecord)(record2, false, ['973'])) {
return false;
}
return true;
}
// DEVELOP: move comparisonTask metadata mainly to the function files
// DEVELOP: add tag information for highlighting problematic fields / positions / subfields for human user
// DEVELOP: multilingual human readable messages
/*
name: short name for comparison task
description: longer, original description for comparison task
validation: comparison task is used for validation
preference: comparison task is used for choosing preferred record
manual: is comparison check usable in manual (internal) merge, type of fail if used [true/error/warning/false], defaults to: true/error if undefined
internal: is comparison check usable in internal merge (ie. merging two database records) [true/false], defaults to true if undefined
import: is comparison check usable in import merge (ie. merging an incoming record and a database record) [true/false], defaults to true if undefined
preference_message_fi: human readable message in Finnish for comparing record preference for merging
validation_message_fi: human readable message in Finnish for validating records for merging
DEVELOP: tags: tags to highlight fields/subfields/positions of fields and field parts that caused the matchValidation error/warning
*/
const comparisonTasks = [
// NB! These are/should be in priority order for recordImport, which checks only until first failure!
// undefined or deleted records cannot be merged (both automatic and human merge)
{
'name': 'existence',
'description': 'existence (validation only)',
'function': checkExistence,
'validation': true,
'preference': false,
'preference_message_fi': '',
'validation_message_fi': 'poistettuja tietueita ei voi yhdistää',
'tags': [{
'tag': 'STA'
}, {
'tag': 'DEL'
}, {
'tag': 'LDR',
'chars': ['5']
}]
},
// test records and non test records should not be merged
{
'name': 'test record',
'description': 'test record',
'function': checkTestRecord,
'validation': true,
'preference': false,
'import': true,
'internal': true,
'manual': 'error',
'preference_message_fi': '',
'validation_message_fi': 'testitietuetta ja normaalia tietuetta ei voi yhdistää',
'tags': [{
'tag': 'STA'
}]
},
// host and component records should not be merged
{
'name': 'host/component',
'description': 'host/component record',
'function': checkHostComponent,
'validation': true,
'preference': false,
'import': true,
'internal': true,
'manual': 'error',
'preference_message_fi': '',
'validation_message_fi': 'osakohdetta ja ei-osakohdetta ei voi yhdistää',
'tags': [{
'tag': '773'
}, {
'tag': '973'
}, {
'tag': 'LDR',
'chars': ['7']
}]
},
// checks record type LDR/06 && bibliographic level LDR/07 (validation) and LDR/17 for encoding level (preference)s
// - fail merge if LDR/006-7 are mismatch
// - preference based on encoding level and more nuanced prepublication level for prepub records
// Prioritize LDR/17 (encoding level)
{
'name': 'leader',
'description': 'leader (validation and preference)',
'function': _leader.checkLeader,
'validation': true,
'preference': true,
'manual': false,
'import': true,
'internal': true,
'validation_message_fi': 'ainestotyypiltään tai bibliografiselta tasoltaan eroavia tietueita ei voi yhdistää',
'preference_message_fi': 'suosi koodaus- ja ennakkotietotasoltaan parempaa tietuetta'
},
// Singular leader comparisons for Human/internal merge
// leader typeOfRecord LDR/006
// do not use same time as checkLeader that checks all three leader values
{
'name': 'typeOfRecord',
'description': 'leader: typeOfRecord (validation)',
'function': _leader.checkTypeOfRecord,
'validation': true,
'preference': false,
'manual': 'warning',
'import': false,
'internal': true,
'validation_message_fi': 'tarkista voiko tietueet yhdistää, ne eroavat ainestotyypiltään; yhdistettyäsi tarkista kentän 008 merkkipaikkojen arvot',
'preference_message_fi': ''
},
// leader bibliographicLevel LDR/006
// do not use same time as checkLeader that checks all three leader values
{
'name': 'bibliographicLevel',
'description': 'leader: bibliographicLevel (validation)',
'function': _leader.checkTypeOfRecord,
'validation': true,
'preference': false,
'import': false,
'internal': true,
'manual': 'error',
'validation_message_fi': 'bibliografiselta tasoltaan eroavia tietueita ei voi yhdistää',
'preference_message_fi': ''
},
// leader encodingLevel LDR/017 + f500/f594
// do not use same time as checkLeader that checks all three leader values
{
'name': 'recordLevel',
'description': 'leader + 500/594: recordLevel (preference)',
'function': _leader.checkRecordLevel,
'validation': false,
'preference': true,
'import': false,
'internal': true,
'manual': 'warning',
'validation_message_fi': '',
'preference_message_fi': 'suosi koodaus- ja ennakkotietotasoltaan parempaa tietuetta'
},
// just preference also for human merge (we like records with 264 instead of 260, they are probably more RDA-compatible)
// Bit high on the preference list, isn't it?
{
'name': 'RDA from publisher',
'description': 'publisher (264>260) (preference only)',
'function': _field26X.checkPublisher,
'validation': false,
'preference': true,
'internal': true,
'import': true,
'manual': false,
// let's not give too many preference warnings for a human user
'preference_message_fi': 'suosi tietuetta, jossa julkaisutiedot ovat kentässä 264',
'validation_message_fi': ''
},
// what are we checking here? could probably be a warning for human merge
// - fail merging online and direct using electronical resources (008/23 or 008/29 form of item)
// - fail merge if 008/06 type of date/publication status codes are a severe mismatch
// - preference from 008/06 type of date/publication status codes
// - gathers 008/39 cataloiguingSource, but does do anything with it?
{
'name': 'f008',
'description': '008 test (validation and preference)',
'function': _controlFields.check008,
'validation': true,
'preference': true,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': 'suosi tietuetta, jossa on tarkemmin ilmoitettu julkaisuajan tyyppi/julkaisun tila',
'validation_message_fi': 'tietueita, joissa on ristiriitainen julkaisuajan tyyppi/julkaisun tila ei voi yhdistää'
},
// This test checks is just for preference despite its description!
// Priority order: FIKKA > ANY > NONE
{
'name': 'LOW-for-preference',
'description': 'LOW test (preference)',
'function': _fieldLOW.checkLOW,
'validation': false,
'preference': true,
'internal': true,
'import': true,
'manual': true,
'preference_message_fi': 'suosi tietuetta, jossa on Kansalliskirjaston tietokantatunnus',
'validation_message_fi': ''
},
// database internal merge cannot merge two records with same low
{
'name': 'LOW-validation-for-internal',
'description': 'LOW test (validation for internal)',
'function': _fieldLOW.checkLOWinternal,
'validation': true,
'preference': false,
'import': false,
'internal': true,
'manual': 'error',
'preference_message_fi': '',
'validation_message_fi': 'tietueita, joissa on saman paikalliskannan tietokantatunnus, ei voi yhdistää'
},
// This test check 042 to preference
{
'name': 'f042-authentication-code',
'description': 'field 042: authentication code (preference only)',
'function': _field2.check042,
'validation': false,
'preference': true,
'internal': true,
'import': true,
'manual': true,
'preference_message_fi': 'suosi tietuetta, jossa on Kansallisbibliografian tai Kansallisdiskografian autentikaatiokoodi',
'validation_message_fi': ''
}, {
'name': 'CAT',
'description': 'CAT test (preference only)',
'function': _fieldCAT.checkCAT,
'validation': false,
'preference': true,
'internal': true,
'import': true,
'manual': false,
// let's not give too many preference warnings for a human cataloger
'preference_message_fi': 'suosi tietuetta, jolla on paremmat kuvailuhistoriatiedot',
'validation_message_fi': ''
},
// NB! I'd like to have a test for 008/06, but them specs for it are elusive?
{
'name': 'title',
'description': 'field 245 (title)',
'function': _title.checkAllTitleFeatures,
'validation': true,
'preference': false,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': '',
'validation_message_fi': 'tarkista voiko tietueet yhdistää, niiden nimeketiedot eroavat'
},
// Do not use old check f245 same time as checkAllTitleFeatures
//{'name': 'title-old', 'description': 'field 245 (title)', 'function': check245, 'validation': true, 'preference': false, 'manual': 'warning'},
// human merge: warning
{
'name': 'f336',
'description': 'field 336 (content type) test (validation and preference)',
'function': _field33X.check336,
'validation': true,
'preference': true,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': 'suosi tietuetta, jolla on tarkemmat sisältötyyppitiedot',
'validation_message_fi': 'tarkista voiko tietueet yhdistää, niiden sisältötyyppitiedot eroavat'
},
// human merge: warning
{
'name': 'f337',
'description': 'field 337 (media type) test (validation and preference)',
'function': _field33X.check337,
'validation': true,
'preference': true,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': 'suosi tietuetta, jolla on tarkemmat mediatyyppitiedot',
'validation_message_fi': 'tarkista voiko tietueet yhdistää, niiden mediatyyppitiedot eroavat'
},
// human merge: warning
{
'name': 'f338',
'description': 'field 338 (carrier type) test (validation and preference)',
'function': _field33X.check338,
'validation': true,
'preference': true,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': 'suosi tietuetta, jolla on tarkemmat tallennetyyppitiedot',
'validation_message_fi': 'tarkista voiko tietueet yhdistää, niiden tallennetyyppitiedot eroavat'
},
// human merge: warning for subfields q&g - $w actually should be different ...
{
'name': 'f773-for-internal',
'description': '773 $wgq test (validation only)',
'function': _field3.check773Internal,
'validation': true,
'preference': false,
'internal': true,
'import': false,
'manual': 'warning',
'preference_message_fi': '',
'validation_message_fi': 'tarkista voiko tietueet yhdistää, osakohteen sijaintitiedot eroavat'
}, {
'name': 'f773-for-import',
'description': '773 $wgq test (validation only)',
'function': _field3.check773,
'validation': true,
'preference': false,
'internal': false,
'import': true,
'manual': false,
'preference_message_fi': '',
'validation_message_fi': 'tarkista voiko tietueet yhdistää, osakohteen sijaintitiedot eroavat'
}, {
'name': 'f040b',
'description': '040$b (language of cataloging) (preference only)',
'function': _field.check040b,
'validation': false,
'preference': true,
'internal': true,
'import': true,
'manual': true,
'preference_message_fi': 'suosi tietuetta, jolla on soveltuvin kuvailukieli',
'validation_message_fi': ''
}, {
'name': 'f040e',
'description': '040$e (description conventions) (preference only)',
'function': _field.check040e,
'validation': false,
'preference': true,
'internal': true,
'import': true,
'manual': true,
'preference_message_fi': 'suosi tietuetta, jonka kuvailusäännöiksi on merkitty RDA',
'validation_message_fi': ''
},
// SID for import (do not use for manual database internal merge)
// - fail merge for different SIDs from same database
// set preference for record that has most commons SIDs
{
'name': 'fSID-for-import',
'description': 'SID test (validation and preference), for import only',
'function': _fieldSID.checkSID,
'validation': true,
'preference': true,
'internal': false,
'import': true,
'manual': false,
'preference_message_fi': 'suosi tietuetta, jolla on enemmän linkkejä vastintietueisiin paikalliskannoissa',
'validation_message_fi': 'tietueita, joilla on samassa paikalliskannassa eri vastintietue ei voi yhdistää'
},
// preference for record that's updated more recently
{
'name': 'f005',
'description': '005 timestamp test (preference)',
'function': _controlFields.check005,
'validation': false,
'preference': true,
'internal': true,
'import': true,
'manual': false,
// let's not give too many preference warnings for a human cataloger
'preference_message_fi': 'suosi tietuetta, jota on päivitetty viimeksi',
'validation_message_fi': ''
},
// human merge: warning
// - fail merge, for CD vs LP record
{
'name': 'audio-sanity',
'description': 'audio sanity check (validation only)',
'function': _sanityCheckAudio.performAudioSanityCheck,
'validation': true,
'preference': false,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': '',
'validation_message_fi': 'tietueissa on kuvailtu CD- ja LP-levy, tarkista voiko ne yhdistää'
},
// human merge: warning
// - fail merge, for daisy-audiobook vs generic audiobook
{
'name': 'daisy-sanity',
'description': 'Daisy sanity check (validation only)',
'function': _sanityCheckDaisy.performDaisySanityCheck,
'validation': true,
'preference': false,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': '',
'validation_message_fi': 'tietueissa on kuvailtu yleinen ja Daisy-äänikirja, tarkista voiko ne yhdistää'
},
// human merge: warning
// - fail merge, for DVD vs Blueray video discs
{
'name': 'dvd-blueray-sanity',
'description': 'DVD vs Blu-Ray sanity check (validation only)',
'function': _sanityCheckDvd.performDvdSanityCheck,
'validation': true,
'preference': false,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': '',
'validation_message_fi': 'tietueissa on kuvailtu DVD- ja Bluray-levy, tarkista voiko ne yhdistää'
},
// human merge: warning
// - fail merge, for mismatching ISBN qualifiers
{
'name': 'isbn-qualifier',
'description': 'ISBN qualifier sanity check (validation only)',
'function': _sanityCheckIsbnQualifer.performIsbnQualifierCheck,
'validation': true,
'preference': false,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': '',
'validation_message_fi': 'tietueissa on eroava ISBN-tarkenne, tarkista voiko ne yhdistää'
},
// human merge: warning
// - fail merge, part of a multipart monograph vs whole set of multipart monographs
{
'name': 'parts-sets',
'description': 'Parts vs sets test (validation)',
'function': _partsAndSets.compareRecordsPartSetFeatures,
'validation': true,
'preference': false,
'internal': true,
'import': true,
'manual': 'warning',
'preference_message_fi': '',
'validation_message_fi': 'tietueissa on kuvailtu yksittäinen moniosaisen monografian osa ja moniosainen monografia kokonaisuutena, tarkista voiko ne yhdistää'
}];
const comparisonTasksTable = exports.comparisonTasksTable = {
recordImport: [...comparisonTasks].filter(isUsableForImport),
// merge two records existing in database together, checked by human user in UI
humanMerge: [...comparisonTasks.filter(isUsableForInternal).filter(isUsableForManual)]
};
debugDev(`------------ RECORD IMPORT --------`);
debugDev(`comparisonTasksTable.recordImport has ${comparisonTasksTable.recordImport.length} comparison tasks:`);
debugDev(`${comparisonTasksTable.recordImport.map(task => task.description).join('\n')}`);
debugDev(`------------ HUMAN MERGE --------`);
debugDev(`comparisonTasksTable.humanMerge has ${comparisonTasksTable.humanMerge.length} comparison tasks:`);
debugDev(`${comparisonTasksTable.humanMerge.map(task => task.description).join('\n')}`);
// Manual merge: merge done manually in an UI
function isUsableForManual(task) {
if (task.manual !== undefined && task.manual === false) {
debugDev(`${task.name} has manual: ${task.manual}`);
return false;
}
debugDev(`${task.name} has manual: ${task.manual}`);
return true;
}
// Internal merge: merging two records in the database together
function isUsableForInternal(task) {
if (task.internal !== undefined && task.internal === false) {
debugDev(`${task.name} has internal: ${task.internal}`);
return false;
}
debugDev(`${task.name} has internal: ${task.internal}`);
return true;
}
// Import merge: merging incoming record and database record together
function isUsableForImport(task) {
if (task.import !== undefined && task.import === false) {
debugDev(`${task.name} has import: ${task.import}`);
return false;
}
debugDev(`${task.name} has import: ${task.import}`);
return true;
}
//# sourceMappingURL=comparisonTasks.js.map