Add new slots and classes for enhanced documentation and availability tracking

- Introduced `is_or_was_created_through` slot to indicate content creation methods, replacing previous boolean flags.
- Added `is_or_was_required` slot for generic temporal boolean requirements, aligning with Schema.org.
- Created `AutoGeneration` class to represent automatic content generation, capturing methods and provenance.
- Established `AvailabilityStatus` class to model resource availability with temporal validity.
- Developed `Documentation` class for structured documentation resources, replacing domain-specific slots.
- Implemented `Taxon` class for biological classification in natural history collections.
- Archived previous slots related to API availability and documentation, ensuring a clean schema.
- Enhanced existing slots with detailed descriptions and examples for clarity and usability.
This commit is contained in:
kempersc 2026-01-14 13:09:31 +01:00
parent b13674400f
commit 60e66d60f9
90 changed files with 2626 additions and 621 deletions

View file

@ -1,12 +1,12 @@
{
"generated": "2026-01-14T10:31:53.486Z",
"generated": "2026-01-14T11:51:09.964Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": 2896,
"totalFiles": 2884,
"categoryCounts": {
"main": 4,
"class": 671,
"class": 675,
"enum": 147,
"slot": 2070,
"slot": 2054,
"module": 4
},
"categories": [
@ -290,6 +290,11 @@
"path": "modules/classes/AudiovisualArchiveRecordSetTypes.yaml",
"category": "class"
},
{
"name": "AutoGeneration",
"path": "modules/classes/AutoGeneration.yaml",
"category": "class"
},
{
"name": "AuxiliaryDigitalPlatform",
"path": "modules/classes/AuxiliaryDigitalPlatform.yaml",
@ -300,6 +305,11 @@
"path": "modules/classes/AuxiliaryPlace.yaml",
"category": "class"
},
{
"name": "AvailabilityStatus",
"path": "modules/classes/AvailabilityStatus.yaml",
"category": "class"
},
{
"name": "BackupStatus",
"path": "modules/classes/BackupStatus.yaml",
@ -965,6 +975,11 @@
"path": "modules/classes/Division.yaml",
"category": "class"
},
{
"name": "Documentation",
"path": "modules/classes/Documentation.yaml",
"category": "class"
},
{
"name": "DocumentationCentre",
"path": "modules/classes/DocumentationCentre.yaml",
@ -2535,6 +2550,11 @@
"path": "modules/classes/ReligiousArchiveRecordSetTypes.yaml",
"category": "class"
},
{
"name": "RequirementStatus",
"path": "modules/classes/RequirementStatus.yaml",
"category": "class"
},
{
"name": "RequirementType",
"path": "modules/classes/RequirementType.yaml",
@ -4182,31 +4202,11 @@
"path": "modules/slots/annual_participants.yaml",
"category": "slot"
},
{
"name": "api_available",
"path": "modules/slots/api_available.yaml",
"category": "slot"
},
{
"name": "api_documentation",
"path": "modules/slots/api_documentation.yaml",
"category": "slot"
},
{
"name": "applicable_countries",
"path": "modules/slots/applicable_countries.yaml",
"category": "slot"
},
{
"name": "applies_to_call",
"path": "modules/slots/applies_to_call.yaml",
"category": "slot"
},
{
"name": "appointment_required",
"path": "modules/slots/appointment_required.yaml",
"category": "slot"
},
{
"name": "approved_by",
"path": "modules/slots/approved_by.yaml",
@ -4237,11 +4237,6 @@
"path": "modules/slots/asserted_by.yaml",
"category": "slot"
},
{
"name": "associated_encompassing_bodies",
"path": "modules/slots/associated_encompassing_bodies.yaml",
"category": "slot"
},
{
"name": "associated_taxa",
"path": "modules/slots/associated_taxa.yaml",
@ -4252,11 +4247,6 @@
"path": "modules/slots/audio_event_segments.yaml",
"category": "slot"
},
{
"name": "authentication_required",
"path": "modules/slots/authentication_required.yaml",
"category": "slot"
},
{
"name": "authors",
"path": "modules/slots/authors.yaml",
@ -4282,11 +4272,6 @@
"path": "modules/slots/available_caption_languages.yaml",
"category": "slot"
},
{
"name": "backup_status",
"path": "modules/slots/backup_status.yaml",
"category": "slot"
},
{
"name": "base_surname",
"path": "modules/slots/base_surname.yaml",
@ -4317,21 +4302,6 @@
"path": "modules/slots/benefit.yaml",
"category": "slot"
},
{
"name": "bibframe_equivalent",
"path": "modules/slots/bibframe_equivalent.yaml",
"category": "slot"
},
{
"name": "binding",
"path": "modules/slots/binding.yaml",
"category": "slot"
},
{
"name": "binding_description",
"path": "modules/slots/binding_description.yaml",
"category": "slot"
},
{
"name": "bio_custodian_subtype",
"path": "modules/slots/bio_custodian_subtype.yaml",
@ -4357,11 +4327,6 @@
"path": "modules/slots/bold_id.yaml",
"category": "slot"
},
{
"name": "booking_required",
"path": "modules/slots/booking_required.yaml",
"category": "slot"
},
{
"name": "bookplate",
"path": "modules/slots/bookplate.yaml",
@ -4387,11 +4352,6 @@
"path": "modules/slots/box_number.yaml",
"category": "slot"
},
{
"name": "branch_description",
"path": "modules/slots/branch_description.yaml",
"category": "slot"
},
{
"name": "branch_head",
"path": "modules/slots/branch_head.yaml",
@ -4407,41 +4367,11 @@
"path": "modules/slots/branch_staff_count.yaml",
"category": "slot"
},
{
"name": "broader_concept",
"path": "modules/slots/broader_concept.yaml",
"category": "slot"
},
{
"name": "broader_concept_label",
"path": "modules/slots/broader_concept_label.yaml",
"category": "slot"
},
{
"name": "broader_type",
"path": "modules/slots/broader_type.yaml",
"category": "slot"
},
{
"name": "budget",
"path": "modules/slots/budget.yaml",
"category": "slot"
},
{
"name": "budget_currency",
"path": "modules/slots/budget_currency.yaml",
"category": "slot"
},
{
"name": "budget_description",
"path": "modules/slots/budget_description.yaml",
"category": "slot"
},
{
"name": "budget_name",
"path": "modules/slots/budget_name.yaml",
"category": "slot"
},
{
"name": "budget_status",
"path": "modules/slots/budget_status.yaml",
@ -7547,16 +7477,6 @@
"path": "modules/slots/has_annotation_type.yaml",
"category": "slot"
},
{
"name": "has_api_available_flag",
"path": "modules/slots/has_api_available_flag.yaml",
"category": "slot"
},
{
"name": "has_api_documentation_url",
"path": "modules/slots/has_api_documentation_url.yaml",
"category": "slot"
},
{
"name": "has_api_version",
"path": "modules/slots/has_api_version.yaml",
@ -7592,11 +7512,6 @@
"path": "modules/slots/has_application_opening_date.yaml",
"category": "slot"
},
{
"name": "has_appointment_required_flag",
"path": "modules/slots/has_appointment_required_flag.yaml",
"category": "slot"
},
{
"name": "has_appraisal_note",
"path": "modules/slots/has_appraisal_note.yaml",
@ -8232,11 +8147,6 @@
"path": "modules/slots/has_or_had_associated_digital_platform.yaml",
"category": "slot"
},
{
"name": "has_or_had_associated_encompassing_body",
"path": "modules/slots/has_or_had_associated_encompassing_body.yaml",
"category": "slot"
},
{
"name": "has_or_had_audience_size",
"path": "modules/slots/has_or_had_audience_size.yaml",
@ -8372,6 +8282,11 @@
"path": "modules/slots/has_or_had_digital_platform.yaml",
"category": "slot"
},
{
"name": "has_or_had_documentation",
"path": "modules/slots/has_or_had_documentation.yaml",
"category": "slot"
},
{
"name": "has_or_had_documentation_source",
"path": "modules/slots/has_or_had_documentation_source.yaml",
@ -9572,6 +9487,11 @@
"path": "modules/slots/is_or_was_aggregated_by.yaml",
"category": "slot"
},
{
"name": "is_or_was_allocated_budget",
"path": "modules/slots/is_or_was_allocated_budget.yaml",
"category": "slot"
},
{
"name": "is_or_was_allocated_by",
"path": "modules/slots/is_or_was_allocated_by.yaml",
@ -9592,11 +9512,26 @@
"path": "modules/slots/is_or_was_archived_in.yaml",
"category": "slot"
},
{
"name": "is_or_was_associated_with",
"path": "modules/slots/is_or_was_associated_with.yaml",
"category": "slot"
},
{
"name": "is_or_was_available",
"path": "modules/slots/is_or_was_available.yaml",
"category": "slot"
},
{
"name": "is_or_was_collection_of",
"path": "modules/slots/is_or_was_collection_of.yaml",
"category": "slot"
},
{
"name": "is_or_was_created_through",
"path": "modules/slots/is_or_was_created_through.yaml",
"category": "slot"
},
{
"name": "is_or_was_encompassed_by",
"path": "modules/slots/is_or_was_encompassed_by.yaml",
@ -9622,6 +9557,11 @@
"path": "modules/slots/is_or_was_related_to.yaml",
"category": "slot"
},
{
"name": "is_or_was_required",
"path": "modules/slots/is_or_was_required.yaml",
"category": "slot"
},
{
"name": "is_or_was_sub_collection_of",
"path": "modules/slots/is_or_was_sub_collection_of.yaml",

View file

@ -16,8 +16,9 @@ imports:
- ../slots/has_or_had_holds_record_set_type
- ../slots/has_or_had_custodian_type
- ../slots/dual_class_link
- ../slots/broader_concept
- ../slots/broader_concept_label
# broader_concept REMOVED - migrated to has_or_had_hypernym (Rule 53)
- ../slots/has_or_had_hypernym
- ../slots/has_or_had_label
- ../slots/specificity_annotation
- ../slots/template_specificity
- ../slots/wikidata_alignment
@ -35,8 +36,9 @@ classes:
- has_or_had_custodian_type
- dual_class_link
- has_or_had_holds_record_set_type
- broader_concept
- broader_concept_label
# broader_concept REMOVED - migrated to has_or_had_hypernym (Rule 53)
- has_or_had_hypernym
- has_or_had_label
- specificity_annotation
- template_specificity
- wikidata_alignment
@ -82,9 +84,16 @@ classes:
wikidata_alignment:
range: WikidataAlignment
inlined: true
broader_concept:
has_or_had_hypernym:
description: >-
MIGRATED from broader_concept (Rule 53).
SKOS broader (parent) concept in the archive type hierarchy.
equals_expression: '["wd:Q166118"]'
broader_concept_label:
has_or_had_label:
description: >-
Human-readable label for the broader concept.
Stored for display to avoid repeated lookups.
MIGRATED from broader_concept_label (2026-01-15) per Rule 53.
equals_string: archive
dual_class_link:
range: DualClassLink

View file

@ -21,7 +21,9 @@ imports:
- ../slots/policy_name
- ../slots/has_or_had_access_description
- ../slots/has_or_had_access_level
- ../slots/appointment_required
# REMOVED 2026-01-15: ../slots/appointment_required - migrated to is_or_was_required
# REMOVED 2026-01-15: ../slots/has_appointment_required_flag - consolidated to is_or_was_required
- ../slots/is_or_was_required
- ../slots/condition
- ../slots/credentials_required
- ../slots/cultural_protocol_url
@ -37,7 +39,6 @@ imports:
- ../slots/template_specificity
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../slots/has_appointment_required_flag
classes:
AccessPolicy:
class_uri: premis:RightsStatus
@ -64,7 +65,7 @@ classes:
Valid ID required for registration\"\n ```\n\n2. **Restricted Research Materials**:\n ```yaml\n AccessPolicy:\n\
\ policy_id: \"hc:access-policy/university-special-collections\"\n access_level: \"RESEARCHERS_ONLY\"\n \
\ access_description: \"Academic researchers with institutional affiliation\"\n conditions: \"Letter of introduction\
\ required from supervising institution\"\n appointment_required: true\n ```\n\n3. **Embargoed Collection**:\n\
\ required from supervising institution\"\n is_or_was_required: true\n ```\n\n3. **Embargoed Collection**:\n\
\ ```yaml\n AccessPolicy:\n policy_id: \"hc:access-policy/donor-embargo-2050\"\n access_level: \"EMBARGOED\"\
\n access_description: \"Closed until 2050 per donor agreement\"\n embargo_end_date: \"2050-01-01\"\n embargo_reason:\
\ \"Donor privacy restrictions\"\n ```\n\n4. **Culturally Sensitive**:\n ```yaml\n AccessPolicy:\n policy_id:\
@ -85,7 +86,8 @@ classes:
slots:
- has_or_had_access_description
- has_or_had_access_level
- appointment_required
# REMOVED 2026-01-15: appointment_required - migrated to is_or_was_required
- is_or_was_required
- condition
- contact_email
- credentials_required
@ -160,8 +162,12 @@ classes:
description: In Copyright
- value: http://rightsstatements.org/vocab/NoC-US/1.0/
description: No Copyright - United States
has_appointment_required_flag:
is_or_was_required:
range: boolean
description: |
Whether an appointment is required for access.
MIGRATED 2026-01-15: Replaces appointment_required and has_appointment_required_flag per Rule 53.
Consolidated to generic is_or_was_required slot.
examples:
- value: true
description: Appointment required
@ -251,7 +257,7 @@ classes:
- Registration form must be completed
- Original materials handled with gloves
registration_required: true
appointment_required: false
is_or_was_required: false # MIGRATED 2026-01-15: was appointment_required
fee_required: false
contact_email: studiezaal@nationaalarchief.nl
description: Standard archive public access policy
@ -273,7 +279,7 @@ classes:
condition:
- Awaiting processing and cataloging
- Access may be arranged for urgent research needs
appointment_required: true
is_or_was_required: true # MIGRATED 2026-01-15: was appointment_required
credentials_required: PROFESSIONAL
contact_email: preservation@archive.org
description: Dark archive / DIM access policy

View file

@ -0,0 +1,83 @@
id: https://nde.nl/ontology/hc/class/AutoGeneration
name: auto_generation_class
title: AutoGeneration Class
imports:
- linkml:types
- ../slots/has_or_had_label
- ../slots/has_or_had_description
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
prov: http://www.w3.org/ns/prov#
dcterms: http://purl.org/dc/terms/
default_prefix: hc
classes:
AutoGeneration:
class_uri: prov:Activity
description: >-
Represents automatic generation or creation of content by a system or algorithm.
**DEFINITION**:
AutoGeneration models the automatic creation of content such as subtitles,
chapters, transcripts, or metadata by AI/ML systems, platform algorithms,
or automated processes. This replaces simple boolean flags like `auto_generated`
with a structured class that can capture the generation method and provenance.
**ONTOLOGY ALIGNMENT**:
- PROV-O: `prov:Activity` - an activity that generates entities
- PROV-O: `prov:wasGeneratedBy` - links to generating activity
- Schema.org: `schema:CreateAction` - creation action
**GENERATION METHODS**:
- ASR (Automatic Speech Recognition): Speech-to-text for subtitles
- Scene Detection: AI-based video chapter generation
- NLP: Natural language processing for metadata extraction
- OCR: Optical character recognition for text extraction
**USE CASES**:
1. **Auto-Subtitles**: YouTube auto-generated captions
2. **Auto-Chapters**: AI-detected video chapters
3. **Auto-Transcripts**: ASR-generated transcripts
4. **Auto-Metadata**: ML-extracted metadata
exact_mappings:
- prov:Activity
close_mappings:
- schema:CreateAction
related_mappings:
- prov:wasGeneratedBy
slots:
- has_or_had_label
- has_or_had_description
slot_usage:
has_or_had_label:
range: string
examples:
- value: "YouTube Auto-Caption"
description: Platform auto-generated captions
- value: "ASR Transcription"
description: Automatic speech recognition
has_or_had_description:
range: string
examples:
- value: "Automatically generated by YouTube's speech recognition system"
description: Platform-provided auto-generation
- value: "Generated using Whisper ASR model"
description: Specific ASR model used
comments:
- Generic auto-generation class replacing domain-specific boolean flags
- Captures generation method and provenance
- Aligns with PROV-O Activity for provenance tracking
see_also:
- https://www.w3.org/TR/prov-o/#Activity
- https://schema.org/CreateAction
examples:
- value:
has_or_had_label: "YouTube Auto-Caption"
has_or_had_description: "Automatically generated by YouTube's speech recognition"
description: YouTube auto-generated subtitles

View file

@ -23,7 +23,7 @@ imports:
- ../slots/archived_at
- ../slots/serves_finding_aid
- ../slots/has_or_had_data_service_endpoint
- ../slots/api_documentation
- ../slots/has_or_had_documentation # MIGRATED: was ../slots/api_documentation (2026-01-15)
- ../slots/has_or_had_archival_status
- ../slots/has_or_had_identifier
- ../slots/has_auxiliary_platform_type
@ -49,7 +49,8 @@ imports:
- ../slots/was_generated_by
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../slots/has_api_documentation_url
- ./Documentation # Added for has_or_had_documentation migration (2026-01-15)
# REMOVED: ../slots/has_api_documentation_url - migrated to has_or_had_documentation (2026-01-15)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
@ -110,7 +111,7 @@ classes:
- schema:isRelatedTo
- dcat:servesDataset
slots:
- api_documentation
- has_or_had_documentation # MIGRATED: was api_documentation (2026-01-15)
- has_or_had_archival_status
- archived_at
- has_or_had_identifier
@ -188,8 +189,10 @@ classes:
- value: Rijksstudio allows users to create personal collections from the Rijksmuseum's digitized artworks, download
high-resolution images, and share curated sets with others.
description: Detailed platform description
has_api_documentation_url:
has_or_had_documentation: # MIGRATED: was has_api_documentation_url (2026-01-15)
description: Documentation resources for this auxiliary platform (API docs, user guides, etc.)
range: uri
multivalued: true
examples:
- value: https://data.rijksmuseum.nl/object-metadata/api/
description: API documentation URL
@ -369,7 +372,7 @@ classes:
auxiliary_platform_type: APIEndpoint
platform_url: https://data.rijksmuseum.nl/
platform_purpose: Developer access to collection metadata and images
api_documentation: https://data.rijksmuseum.nl/object-metadata/api/
has_or_had_documentation: https://data.rijksmuseum.nl/object-metadata/api/
technology_stack:
- REST
- JSON

View file

@ -0,0 +1,96 @@
id: https://nde.nl/ontology/hc/class/AvailabilityStatus
name: availability_status_class
title: AvailabilityStatus Class
imports:
- linkml:types
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/valid_from
- ../slots/valid_to
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcat: http://www.w3.org/ns/dcat#
dcterms: http://purl.org/dc/terms/
default_prefix: hc
classes:
AvailabilityStatus:
class_uri: schema:Availability
description: >-
Represents the availability state of a resource, service, or feature.
**DEFINITION**:
AvailabilityStatus models whether something (API, service, feature, resource)
is currently available for use. This replaces domain-specific boolean flags
like `api_available` with a structured class that can capture temporal
validity and descriptive context.
**ONTOLOGY ALIGNMENT**:
- Schema.org: `schema:Availability` - availability of a product/service
- DCAT: `dcat:DataService` availability patterns
- DCTERMS: `dcterms:available` - date resource became available
**USE CASES**:
1. **API Availability**: Whether a CMS provides API access
2. **Service Availability**: Whether a digital platform is operational
3. **Feature Availability**: Whether specific features are enabled
**TEMPORAL VALIDITY**:
Availability can change over time:
- API available from 2015-01-01 to 2020-12-31 (deprecated)
- Service temporarily unavailable during maintenance
exact_mappings:
- schema:Availability
close_mappings:
- dcat:DataService
related_mappings:
- dcterms:available
slots:
- has_or_had_label
- has_or_had_description
- valid_from
- valid_to
slot_usage:
has_or_had_label:
range: string
required: false
examples:
- value: "API Available"
description: Indicates API is available
- value: "Service Unavailable"
description: Indicates service is down
has_or_had_description:
range: string
examples:
- value: "REST API available with JSON responses"
description: Details about API availability
valid_from:
range: date
examples:
- value: "2015-01-01"
description: API available since 2015
valid_to:
range: date
examples:
- value: null
description: Still available (no end date)
comments:
- Generic availability status class replacing domain-specific boolean flags
- Supports temporal validity for tracking when availability changed
- Aligns with Schema.org Availability enumeration pattern
see_also:
- https://schema.org/Availability
- https://www.w3.org/TR/vocab-dcat-2/#Class:DataService
examples:
- value:
has_or_had_label: "API Available"
has_or_had_description: "REST API with JSON responses available for collection metadata access"
valid_from: "2015-06-01"
valid_to: null
description: CMS API availability status

View file

@ -14,8 +14,8 @@ imports:
- ../slots/has_or_had_acquisition_budget
- ../slots/approved_by
- ../slots/budget_currency
- ../slots/budget_description
- ../slots/budget_name
- ../slots/has_or_had_description
- ../slots/has_or_had_label
- ../slots/budget_status
- ../slots/has_or_had_type
- ../slots/capital_budget
@ -94,8 +94,8 @@ classes:
- has_approval_date
- approved_by
- budget_currency
- budget_description
- budget_name
- has_or_had_description
- has_or_had_label
- budget_status
- has_or_had_type
- capital_budget
@ -129,9 +129,39 @@ classes:
budget_name:
range: string
required: true
description: >-
DEPRECATED: Use has_or_had_label instead.
MIGRATION: 2026-01-15 - Replaced by has_or_had_label slot per Rule 53.
deprecated: "Use has_or_had_label instead"
has_or_had_label:
range: string
required: true
description: >-
Name/title for this budget document.
MIGRATED from budget_name (2026-01-15) per Rule 53.
Maps to dcterms:title as a formal title for a financial planning resource.
examples:
- value: Rijksmuseum Operating Budget FY2024
description: Major museum annual budget
- value: Noord-Hollands Archief Annual Budget 2024-2025
description: Provincial archive budget
budget_description:
range: string
required: false
description: >-
DEPRECATED: Use has_or_had_description instead.
MIGRATION: 2026-01-15 - Replaced by has_or_had_description slot per Rule 53.
deprecated: "Use has_or_had_description instead"
has_or_had_description:
range: string
required: false
description: >-
Narrative description of this budget document's scope and purpose.
MIGRATED from budget_description (2026-01-15) per Rule 53.
Maps to dcterms:description for financial planning documentation.
examples:
- value: Annual operating budget for fiscal year 2024, including major exhibition initiatives and digitization expansion.
description: Comprehensive budget description
budget_type:
range: string
multivalued: true
@ -265,8 +295,8 @@ classes:
examples:
- value:
id: https://nde.nl/ontology/hc/budget/rm/fy2024
budget_name: Rijksmuseum Operating Budget FY2024
budget_description: Annual operating budget for fiscal year 2024, including major exhibition initiatives and digitization
has_or_had_label: Rijksmuseum Operating Budget FY2024
has_or_had_description: Annual operating budget for fiscal year 2024, including major exhibition initiatives and digitization
expansion.
budget_type:
- OPERATING
@ -292,8 +322,8 @@ classes:
description: Major museum annual operating budget
- value:
id: https://nde.nl/ontology/hc/budget/nha/fy2024-2025
budget_name: Noord-Hollands Archief Annual Budget 2024-2025
budget_description: Provincial archive annual budget aligned with government fiscal year.
has_or_had_label: Noord-Hollands Archief Annual Budget 2024-2025
has_or_had_description: Provincial archive annual budget aligned with government fiscal year.
budget_type:
- OPERATING
- CONSOLIDATED

View file

@ -11,7 +11,7 @@ imports:
- ./TimeSpan
- ../slots/documentation_url
- ./ReconstructedEntity
- ../slots/api_available
- ../slots/is_or_was_available # MIGRATED: was ../slots/api_available (2026-01-15)
- ../slots/cms_category
- ../slots/cms_id
- ../slots/cms_product_name
@ -38,7 +38,8 @@ imports:
- ../slots/was_generated_by
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../slots/has_api_available_flag
- ./AvailabilityStatus # Added for is_or_was_available migration (2026-01-15)
# REMOVED: ../slots/has_api_available_flag - migrated to is_or_was_available (2026-01-15)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
@ -99,7 +100,7 @@ classes:
- doap:repository
- rico:Activity
slots:
- api_available
- is_or_was_available # MIGRATED: was api_available (2026-01-15)
- cms_category
- cms_id
- cms_product_name
@ -225,7 +226,8 @@ classes:
examples:
- value: true
description: Supports LOD export
has_api_available_flag:
is_or_was_available: # MIGRATED: was has_api_available_flag (2026-01-15)
description: Whether this CMS provides API access (REST, GraphQL, OAI-PMH, SPARQL, SRU/SRW)
range: boolean
examples:
- value: true
@ -303,7 +305,7 @@ classes:
- LIDO
iiif_compatible: true
linked_data_export: true
api_available: true
is_or_was_available: true
powers_platform:
- https://nde.nl/ontology/hc/platform/rijksmuseum-website
manages_collection:
@ -332,7 +334,7 @@ classes:
- LIDO
iiif_compatible: true
linked_data_export: true
api_available: true
is_or_was_available: true
refers_to_custodian: https://nde.nl/ontology/hc/example-museum
description: Open-source CollectiveAccess deployment
- value:
@ -349,7 +351,7 @@ classes:
- MDTO
iiif_compatible: false
linked_data_export: false
api_available: true
is_or_was_available: true
manages_collection:
- https://nde.nl/ontology/hc/collection/na-government-records
refers_to_custodian: https://nde.nl/ontology/hc/nl-na

View file

@ -13,7 +13,7 @@ default_prefix: hc
imports:
- linkml:types
- ../slots/record_equivalent
- ../slots/bibframe_equivalent
# REMOVED: ../slots/bibframe_equivalent - Use LinkML close_mappings instead (2026-01-15)
- ../slots/collection_broader_type
- ../slots/has_or_had_collection_narrower_type
- ../slots/collection_type_description
@ -49,10 +49,10 @@ classes:
\ | rico:Fonds | Provenance-based archival unit |\n| SERIES | rico:Series | Subdivision of fonds |\n| FILE | rico:File\
\ | Individual file/dossier |\n| ITEM | rico:Item | Single record |\n| ARTIFICIAL_COLLECTION | rico:Collection | Non-provenance\
\ assemblage |\n\n**USE CASES**:\n\n1. **Archival Classification**:\n ```yaml\n CollectionType:\n type_id: \"\
hc:collection-type/fonds\"\n type_name: \"Fonds\"\n record_equivalent: \"rico:Fonds\"\n description: \"\
hc:collection-type/fonds\"\n type_name: \"Fonds\"\n record_equivalent: \"rico:Fonds\"\n description: \"\
Provenance-based archival unit\"\n ```\n\n2. **Library Special Collection**:\n ```yaml\n CollectionType:\n \
\ type_id: \"hc:collection-type/special-collection\"\n type_name: \"Special Collection\"\n bibframe_equivalent:\
\ \"bf:Collection\"\n description: \"Named library special collection\"\n ```\n\n3. **Museum Named Collection**:\n\
\ type_id: \"hc:collection-type/special-collection\"\n type_name: \"Special Collection\"\n # BIBFRAME mapping at class level via close_mappings: [bf:CollectionType]\n description:\
\ \"Named library special collection\"\n ```\n\n3. **Museum Named Collection**:\n\
\ ```yaml\n CollectionType:\n type_id: \"hc:collection-type/named-collection\"\n type_name: \"Named Collection\"\
\n description: \"Collection named for donor or subject\"\n ```\n"
exact_mappings:
@ -62,7 +62,7 @@ classes:
- bf:CollectionType
- dcterms:DCMIType
slots:
- bibframe_equivalent
# REMOVED: bibframe_equivalent - Use LinkML close_mappings instead (2026-01-15)
- collection_broader_type
- has_or_had_collection_narrower_type
- collection_type_description
@ -107,13 +107,8 @@ classes:
description: RiC-O Series
- value: rico:Collection
description: RiC-O Collection (assembled)
bibframe_equivalent:
range: uriorcurie
examples:
- value: bf:Collection
description: BIBFRAME Collection
- value: bf:Archival
description: BIBFRAME Archival
# REMOVED: bibframe_equivalent slot_usage - Use LinkML close_mappings instead (2026-01-15)
# BIBFRAME mappings are now at class level: close_mappings: [bf:CollectionType]
wikidata_equivalent:
range: string
pattern: ^Q[0-9]+$
@ -173,6 +168,6 @@ classes:
collection_type_name: Special Collection
collection_type_description: A named special collection within a library, often focusing on a particular subject,
format, or provenance.
bibframe_equivalent: bf:Collection
# BIBFRAME mapping at class level via close_mappings: [bf:CollectionType]
domain_context: LIBRARY
description: Library special collection type

View file

@ -9,7 +9,7 @@
# Keeps curation-specific slots:
# - curated_holding, objects_affected, objects_added, objects_removed
# - responsible_actor, responsible_department, spectrum_procedure
# - budget, funding_source, deliverable, documentation_produced
# - is_or_was_allocated_budget (MIGRATED 2026-01-15: was budget), funding_source, deliverable, documentation_produced
#
# Rule compliance: 38, 39, 42, 43, 48
@ -38,7 +38,8 @@ imports:
- ./ExhibitedObject
- ./PersonObservation
- ../enums/CurationActivityTypeEnum
- ../slots/budget
# REMOVED 2026-01-15: ../slots/budget - migrated to is_or_was_allocated_budget
- ../slots/is_or_was_allocated_budget
- ../slots/curated_holding
- ../slots/deliverable
- ../slots/documentation_produced
@ -168,7 +169,8 @@ classes:
# Curation-specific slots (in addition to inherited Activity slots)
slots:
- budget
# REMOVED 2026-01-15: budget - migrated to is_or_was_allocated_budget
- is_or_was_allocated_budget
- curated_holding
- has_or_had_custodian_type
- deliverable
@ -323,9 +325,12 @@ classes:
- value: Friends of the Museum donation
description: Donor-funded
budget:
is_or_was_allocated_budget:
range: string
description: Budget allocated for this activity.
description: |
Budget allocated for this activity.
MIGRATED 2026-01-15: Replaces budget slot per Rule 53.
For structured budget information, override range to Budget class.
examples:
- value: EUR 125,000
description: Digitization project budget
@ -439,7 +444,7 @@ classes:
deliverable:
- https://www.nationaalarchief.nl/onderzoeken/archief/1.04.02/digital
funding_source: Metamorfoze National Digitization Programme
budget: EUR 850,000
is_or_was_allocated_budget: EUR 850,000 # MIGRATED 2026-01-15: was budget
status: IN_PROGRESS
priority: HIGH
spectrum_procedure: documentation
@ -466,7 +471,7 @@ classes:
- Before/after condition photographs
- Updated location records in CMS
funding_source: Andrew W. Mellon Foundation Grant
budget: EUR 95,000
is_or_was_allocated_budget: EUR 95,000 # MIGRATED 2026-01-15: was budget
status: PLANNED
priority: HIGH
spectrum_procedure: object-storage

View file

@ -14,7 +14,7 @@ imports:
- ../slots/has_or_had_access_control
- ../slots/has_administration_description
- ../slots/has_administration_name
- ../slots/backup_status
# REMOVED 2026-01-15: ../slots/backup_status - migrated to has_or_had_status with BackupStatus
- ../slots/has_or_had_status
- ./BackupStatus
- ../slots/business_criticality
@ -107,7 +107,7 @@ classes:
- is_or_was_active_since
- has_administration_description
- has_administration_name
- backup_status
# REMOVED 2026-01-15: backup_status - migrated to has_or_had_status with BackupStatus
- has_or_had_status
- business_criticality
- creating_function
@ -303,7 +303,11 @@ classes:
data_sensitivity: CONFIDENTIAL
gdpr_relevant: true
business_criticality: HIGH
backup_status: Daily backup to Azure, replicated to secondary site
has_or_had_status:
has_or_had_type:
- has_or_had_short_code: DAILY_AUTOMATED
- has_or_had_short_code: CLOUD_AZURE
has_or_had_description: Daily backup to Azure, replicated to secondary site
access_control: 'AD Group: RM-Directors-Staff'
refers_to_custodian: https://nde.nl/ontology/hc/nl-nh-ams-m-rm-q190804
description: Active director's correspondence system
@ -327,7 +331,11 @@ classes:
data_sensitivity: SPECIAL_CATEGORY - Personnel data
gdpr_relevant: true
business_criticality: CRITICAL
backup_status: Real-time replication, encrypted at rest
has_or_had_status:
has_or_had_type:
- has_or_had_short_code: REALTIME_REPLICATION
- has_or_had_short_code: ENCRYPTED_AT_REST
has_or_had_description: Real-time replication, encrypted at rest
access_control: HR Department only, individual file permissions
refers_to_custodian: https://nde.nl/ontology/hc/nl-nh-ams-m-rm-q190804
description: Active HR personnel records system
@ -353,6 +361,10 @@ classes:
data_sensitivity: INTERNAL
gdpr_relevant: false
business_criticality: HIGH
backup_status: Daily backup, 10-year retention, linked to object records
has_or_had_status:
has_or_had_type:
- has_or_had_short_code: DAILY_AUTOMATED
- has_or_had_short_code: LONG_RETENTION
has_or_had_description: Daily backup, 10-year retention, linked to object records
refers_to_custodian: https://nde.nl/ontology/hc/nl-nh-ams-m-rm-q190804
description: Active conservation treatment documentation

View file

@ -8,7 +8,7 @@ imports:
- ../slots/created
- ../slots/modified
- ../slots/wikidata_entity
- ../slots/applicable_countries
# - ../slots/applicable_countries # MIGRATED 2026-01-15: replaced by has_applicable_country
- ../slots/glamorcubesfixphdnt_code
- ../slots/specificity_annotation
- ../slots/template_specificity
@ -66,7 +66,8 @@ classes:
- org:classification
- schema:additionalType
slots:
- applicable_countries
# - applicable_countries # MIGRATED 2026-01-15: replaced by has_applicable_country
- has_applicable_country
- created
- custodian_type_broader
- custodian_type_narrower
@ -112,6 +113,7 @@ classes:
multivalued: true
required: false
has_applicable_country:
description: "ISO 3166-1 alpha-2 country codes where this type applies. Empty = worldwide. (MIGRATED 2026-01-15: was applicable_countries)"
range: string
multivalued: true
required: false

View file

@ -15,7 +15,8 @@ imports:
- ./DataServiceEndpointType
- ../slots/protocol
- ../slots/response_format
- ../slots/authentication_required
# REMOVED 2026-01-15: ../slots/authentication_required - migrated to is_or_was_required
- ../slots/is_or_was_required
- ../slots/specificity_annotation
- ../slots/template_specificity
- ./SpecificityAnnotation
@ -28,7 +29,8 @@ classes:
abstract: true
class_uri: dcat:DataService
slots:
- authentication_required
# REMOVED 2026-01-15: authentication_required - migrated to is_or_was_required
- is_or_was_required
- protocol
- response_format
- specificity_annotation
@ -136,7 +138,7 @@ classes:
range: uri
authentication_method:
slot_uri: schema:potentialAction
description: 'Authentication method required (if authentication_required is true).
description: 'Authentication method required (if is_or_was_required is true).
Values from AuthenticationMethodEnum:
@ -289,7 +291,7 @@ classes:
\nThis slot links an INSTANCE (DataServiceEndpoint) to its TYPE classification\n(DataServiceEndpointType), following\
\ the same architectural pattern as\nCustodian/CustodianType.\n\n```\nDataServiceEndpoint (INSTANCE) DataServiceEndpointType\
\ (TYPE)\n├── endpoint_url ├── protocol_name\n├── status ├── protocol_version\n\
├── authentication_required ├── specification_url\n└── endpoint_type ────────────────►└── typical_response_formats\n\
├── is_or_was_required ├── specification_url\n└── endpoint_type ────────────────►└── typical_response_formats\n\
```\n\n**Why Both `protocol` and `endpoint_type`?**\n\n- `protocol` (enum): Simple string classification for quick\
\ filtering\n- `endpoint_type` (class reference): Rich type metadata with SKOS hierarchy,\n specification URLs,\
\ and semantic relationships\n\n**Example:**\n\n```yaml\ndata_service_endpoint:\n endpoint_id: \"https://nde.nl/hc/endpoint/na-oai-pmh\"\

View file

@ -30,7 +30,7 @@ classes:
\ Properties**: Define protocol specifications, capabilities,\n and standards at the TYPE level (shared across all\
\ instances)\n2. **Instance-Level Properties**: Keep URL, status, authentication at the\n INSTANCE level (unique per\
\ deployment)\n\n**Architecture:**\n\n```\nDataServiceEndpoint (instance)\n │\n ├── endpoint_url: \"https://example.org/oai\"\
\n ├── status: ACTIVE\n ├── authentication_required: false\n │\n └── endpoint_type ──→ DataServiceEndpointType\
\n ├── status: ACTIVE\n ├── is_or_was_required: false\n │\n └── endpoint_type ──→ DataServiceEndpointType\
\ (classification)\n │\n └── OAIPMHEndpointType\n \
\ ├── protocol_name: \"OAI-PMH\"\n ├── protocol_version: \"\
2.0\"\n └── specification_url: \"http://...\"\n```\n\n**Subclasses (Endpoint Type Taxonomy):**\n\

View file

@ -0,0 +1,100 @@
id: https://nde.nl/ontology/hc/class/Documentation
name: documentation_class
title: Documentation Class
imports:
- linkml:types
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/has_or_had_identifier
- ../slots/valid_from
- ../slots/valid_to
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcterms: http://purl.org/dc/terms/
foaf: http://xmlns.com/foaf/0.1/
doap: http://usefulinc.com/ns/doap#
default_prefix: hc
classes:
Documentation:
class_uri: schema:TechArticle
description: >-
Documentation resource for a service, API, platform, or system.
**DEFINITION**:
Documentation represents technical documentation resources such as
API documentation, user guides, developer references, or system manuals.
This replaces domain-specific slots like `api_documentation` with a
structured class that can capture multiple documentation resources
with different types and purposes.
**ONTOLOGY ALIGNMENT**:
- Schema.org: `schema:TechArticle` - technical documentation
- DOAP: `doap:homepage`, `doap:wiki` - project documentation
- FOAF: `foaf:Document` - generic document
- DCTERMS: `dcterms:references` - documentation references
**DOCUMENTATION TYPES**:
- API Reference: Endpoint specifications, parameters, responses
- User Guide: End-user instructions and tutorials
- Developer Guide: Integration and development instructions
- System Manual: Technical specifications and architecture
**USE CASES**:
1. **API Documentation**: Link to REST API reference docs
2. **Integration Guides**: How to integrate with the platform
3. **User Manuals**: End-user documentation for staff
exact_mappings:
- schema:TechArticle
close_mappings:
- foaf:Document
- doap:homepage
related_mappings:
- dcterms:references
- doap:wiki
slots:
- has_or_had_label
- has_or_had_description
- has_or_had_identifier
- valid_from
- valid_to
slot_usage:
has_or_had_identifier:
range: uri
required: true
identifier: true
examples:
- value: "https://data.rijksmuseum.nl/object-metadata/api/"
description: Rijksmuseum API documentation URL
has_or_had_label:
range: string
examples:
- value: "API Reference Documentation"
description: Label for API docs
- value: "Developer Integration Guide"
description: Label for integration guide
has_or_had_description:
range: string
examples:
- value: "Complete REST API reference with endpoint specifications, authentication, and response formats."
description: Description of API documentation content
comments:
- Generic documentation class replacing domain-specific documentation slots
- Supports multiple documentation types (API, user, developer, system)
- URL stored in has_or_had_identifier as the primary identifier
- Aligns with Schema.org TechArticle for technical documentation
see_also:
- https://schema.org/TechArticle
- http://usefulinc.com/ns/doap#
examples:
- value:
has_or_had_identifier: "https://data.rijksmuseum.nl/object-metadata/api/"
has_or_had_label: "Rijksmuseum Collection API"
has_or_had_description: "REST API documentation for accessing collection metadata and images"
description: Rijksmuseum API documentation

View file

@ -9,7 +9,8 @@ imports:
- ../enums/EducationProviderTypeEnum
- ../slots/has_or_had_accessibility_feature
- ../slots/annual_participants
- ../slots/booking_required
# REMOVED 2026-01-15: ../slots/booking_required - migrated to is_or_was_required
- ../slots/is_or_was_required
- ../slots/classroom_count
- ../slots/has_or_had_custodian_type
- ../slots/education_center_description
@ -79,7 +80,8 @@ classes:
slots:
- has_or_had_accessibility_feature
- annual_participants
- booking_required
# REMOVED 2026-01-15: booking_required - migrated to is_or_was_required
- is_or_was_required
- classroom_count
- has_or_had_custodian_type
- education_center_description
@ -197,11 +199,14 @@ classes:
examples:
- value: 8
description: Education team size
booking_required:
is_or_was_required:
range: boolean
description: |
Whether advance booking is required for education programs.
MIGRATED 2026-01-15: Replaces booking_required slot.
examples:
- value: true
description: Booking required
description: Booking required for programs
education_contact_email:
range: string
examples:
@ -252,7 +257,7 @@ classes:
- Hearing loop
annual_participants: 75000
staff_count: 12
booking_required: true
is_or_was_required: true
education_contact_email: educatie@rijksmuseum.nl
description: Major museum education center
- value:
@ -272,5 +277,5 @@ classes:
classroom_count: 2
max_group_size: 20
has_av_equipment: true
booking_required: true
is_or_was_required: true
description: Archive learning center

View file

@ -21,7 +21,9 @@ imports:
- ../slots/language
- ../slots/price
- ../slots/authors
- ../slots/binding
# REMOVED: ../slots/binding - Use has_or_had_type with BindingType instead (2026-01-15)
- ../slots/has_or_had_type
- ./BindingType
- ../slots/catalog_description
- ../slots/catalog_entries_count
- ../slots/catalog_for
@ -79,7 +81,8 @@ classes:
- bibo:Book
slots:
- authors
- binding
# REMOVED: binding - Use has_or_had_type with BindingType instead (2026-01-15)
- has_or_had_type
- catalog_description
- catalog_entries_count
- catalog_for
@ -217,12 +220,24 @@ classes:
examples:
- value: 280 color illustrations
- value: 150 color plates, 50 b/w figures
binding:
# DEPRECATED: binding slot - Use has_or_had_type with BindingType instead (2026-01-15)
# binding:
# required: false
# range: string
# deprecated: "Use has_or_had_type with BindingType instead"
has_or_had_type:
required: false
range: string
range: BindingType
description: >-
The binding type of the catalog (hardcover, paperback, etc.).
MIGRATED from binding slot (2026-01-15) per Rule 53.
Uses BindingType class hierarchy for structured binding classification.
examples:
- value: hardcover
- value: paperback
- value: hc:HardcoverBinding
description: Hardcover binding type
- value: hc:PaperbackBinding
description: Paperback binding type
language:
required: false
range: string
@ -336,7 +351,7 @@ classes:
isbn_13: '9789491714962'
pages: 320
illustrations: 280 color illustrations
binding: hardcover
has_or_had_type: hc:HardcoverBinding # Migrated from binding: hardcover
language:
- en
catalog_url: https://www.rijksmuseum.nl/nl/webshop/catalogus-vermeer
@ -365,7 +380,7 @@ classes:
isbn_13: '9780870709159'
pages: 298
illustrations: 230 illustrations
binding: hardcover
has_or_had_type: hc:HardcoverBinding # Migrated from binding: hardcover
language:
- en
price: $60.00

View file

@ -14,7 +14,7 @@ imports:
- ../metadata
- ./DataServiceEndpoint
- ../slots/protocol
- ../slots/authentication_required
# REMOVED 2026-01-15: ../slots/authentication_required - migrated to is_or_was_required (inherited from DataServiceEndpoint)
- ../slots/specificity_annotation
- ../slots/template_specificity
- ./SpecificityAnnotation

View file

@ -26,7 +26,8 @@ imports:
- ../slots/wikidata_id
- ../slots/record_equivalent
- ../slots/typical_domain
- ../slots/broader_type
# broader_type REMOVED - migrated to has_or_had_hypernym (Rule 53)
- ../slots/has_or_had_hypernym
- ../slots/finding_aid_type_definition
- ../slots/finding_aid_type_id
- ../slots/finding_aid_type_name
@ -74,7 +75,8 @@ classes:
- schema:CreativeWork
- crm:E31_Document
slots:
- broader_type
# broader_type REMOVED - migrated to has_or_had_hypernym (Rule 53)
- has_or_had_hypernym
- finding_aid_type_definition
- finding_aid_type_id
- finding_aid_type_name
@ -99,7 +101,10 @@ classes:
pattern: ^Q[0-9]+$
record_equivalent:
range: uriorcurie
broader_type:
has_or_had_hypernym:
description: >-
MIGRATED from broader_type (Rule 53).
For finding aid subtypes, links to parent type in hierarchy.
range: FindingAidType
narrower_type:
range: FindingAidType

View file

@ -23,7 +23,7 @@ imports:
- ../slots/has_annotation_by
- ../slots/has_archival_reference
- ../slots/has_arrangement_level
- ../slots/binding_description
- ../slots/has_or_had_description
- ../slots/has_or_had_provenance
- ../slots/has_or_had_type
- ../slots/bookplate
@ -109,7 +109,7 @@ classes:
- has_annotation_by
- archival_reference
- arrangement_level
- binding_description
- has_or_had_description
- has_or_had_provenance
- has_or_had_type
- bookplate
@ -220,9 +220,27 @@ classes:
binding_description:
required: false
range: string
description: >-
DEPRECATED: Use has_or_had_description instead for binding descriptions.
MIGRATION: 2026-01-15 - Replaced by has_or_had_description slot per Rule 53.
deprecated: "Use has_or_had_description instead"
examples:
- value: "Contemporary blind-stamped pigskin over wooden boards, \nwith brass clasps and corner pieces. Spine with\
\ five raised bands.\n"
has_or_had_description:
required: false
range: string
description: >-
Detailed description of the physical binding of this information carrier.
MIGRATED from binding_description (2026-01-15) per Rule 53.
Describes binding style, materials, decorative elements, and condition.
For carriers like codices, bound manuscripts, and books.
examples:
- value: "Contemporary blind-stamped pigskin over wooden boards, with brass clasps and corner pieces. Spine with five raised bands."
description: Medieval manuscript binding
- value: "Rebound in the 18th century in red morocco with gold tooling."
description: Later rebinding of early printed book
cover_material:
required: false
range: string
@ -470,7 +488,7 @@ classes:
- Paper (handmade, watermarked)
folio_count: 641
binding_type: 18th-century full leather
binding_description: 'Rebound in the 18th century in red morocco with gold tooling.
has_or_had_description: 'Rebound in the 18th century in red morocco with gold tooling.
Five raised bands on spine with gilt lettering.

View file

@ -12,7 +12,7 @@ imports:
- ./ReconstructedEntity
- ./BranchType
- ../slots/located_at
- ../slots/branch_description
- ../slots/has_or_had_description
- ../slots/branch_head
- ../slots/has_or_had_identifier
- ../slots/has_or_had_label
@ -84,7 +84,7 @@ classes:
- schema:branchOf
- schema:department
slots:
- branch_description
- has_or_had_description
- branch_head
- has_or_had_identifier
- has_or_had_label
@ -156,9 +156,26 @@ classes:
description: Conservation facility type
branch_description:
range: string
description: >-
DEPRECATED: Use has_or_had_description instead.
MIGRATION: 2026-01-15 - Replaced by has_or_had_description slot per Rule 53.
deprecated: "Use has_or_had_description instead"
examples:
- value: Small exhibition space at Schiphol Airport featuring rotating highlights from the Rijksmuseum collection.
description: Branch purpose description
has_or_had_description:
range: string
description: >-
Narrative description of the branch's purpose, role, and activities.
MIGRATED from branch_description (2026-01-15) per Rule 53.
Describes what this branch does, its scope of operations,
and its relationship to the parent organization.
examples:
- value: Small exhibition space at Schiphol Airport featuring rotating highlights from the Rijksmuseum collection.
description: Exhibition branch description
- value: Off-site collection storage facility managing overflow objects and art storage.
description: Storage operations branch
located_at:
range: AuxiliaryPlace
multivalued: true
@ -252,7 +269,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/branch/rm-schiphol
has_or_had_label: Rijksmuseum Schiphol
branch_type: EXHIBITION_SPACE
branch_description: Small exhibition space at Schiphol Airport featuring rotating highlights from the collection.
has_or_had_description: Small exhibition space at Schiphol Airport featuring rotating highlights from the collection.
located_at:
- https://nde.nl/ontology/hc/aux-place/rijksmuseum-schiphol
has_operational_unit:
@ -269,7 +286,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/branch/rm-depot-operations
has_or_had_label: Collection Storage Operations - Amersfoort
branch_type: STORAGE_MANAGEMENT
branch_description: Off-site collection storage facility managing overflow objects and art storage.
has_or_had_description: Off-site collection storage facility managing overflow objects and art storage.
located_at:
- https://nde.nl/ontology/hc/aux-place/rijksmuseum-depot-amersfoort
has_operational_unit:
@ -286,7 +303,7 @@ classes:
has_or_had_identifier: https://nde.nl/ontology/hc/branch/na-rhc-nh
has_or_had_label: Regionaal Historisch Centrum Noord-Holland
branch_type: REGIONAL_OFFICE
branch_description: Regional archives center serving Noord-Holland province, providing reading room services and archival
has_or_had_description: Regional archives center serving Noord-Holland province, providing reading room services and archival
research support.
is_branch_of: https://nde.nl/ontology/hc/nl-na
staff_count: 25

View file

@ -0,0 +1,207 @@
# RequirementStatus - Status class for structured requirement information
#
# Following the BackupStatus pattern:
# This is a STATUS class that represents the current state of a requirement,
# with structured type classification via RequirementType.
#
# Generation date: 2026-01-15 (created for booking_required migration)
# Rule compliance: 37 (specificity scores), 38 (slot centralization), 39 (RiC-O naming)
#
# ONTOLOGY ALIGNMENT: PROV-O prov:Entity for status with provenance
id: https://nde.nl/ontology/hc/class/RequirementStatus
name: requirement_status_class
title: Requirement Status Class
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
prov: http://www.w3.org/ns/prov#
skos: http://www.w3.org/2004/02/skos/core#
schema: http://schema.org/
default_prefix: hc
imports:
- linkml:types
# Shared slots (centralized)
- ../slots/has_or_had_identifier
- ../slots/has_or_had_type
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/has_or_had_note
- ../slots/is_or_was_required
- ../slots/begin_of_the_begin
- ../slots/end_of_the_end
# Import the RequirementType for type references
- ./RequirementType
classes:
RequirementStatus:
class_uri: prov:Entity
description: |
Represents the status of a requirement (e.g., booking, registration, appointment).
**DEFINITION**:
RequirementStatus captures structured requirement information including:
- Whether the requirement is active (is_or_was_required boolean)
- The type(s) of requirement (via has_or_had_type → RequirementType)
- Status description (free text details)
- Temporal validity (when this requirement was in effect)
**ONTOLOGY ALIGNMENT**:
| Ontology | Class/Property | Notes |
|----------|----------------|-------|
| **PROV-O** | `prov:Entity` | Primary - entity with provenance |
| **Schema.org** | `schema:isRequired` | Boolean requirement |
| **SKOS** | `skos:Concept` | For type classification |
**RELATIONSHIP TO OTHER CLASSES**:
```
EducationCenter / ReadingRoom / etc.
└── has_or_had_status → RequirementStatus (THIS CLASS)
├── is_or_was_required (boolean - is booking required?)
├── has_or_had_type → RequirementType (what kind of requirement)
├── has_or_had_description (free text details)
└── begin_of_the_begin / end_of_the_end (validity period)
```
**SLOT MIGRATION** (2026-01-15):
This class replaces domain-specific boolean slots:
- booking_required (boolean) → has_or_had_status: RequirementStatus
- appointment_required (boolean) → has_or_had_status: RequirementStatus
- registration_required (boolean) → has_or_had_status: RequirementStatus
**SIMPLE VS STRUCTURED USAGE**:
For simple boolean requirement (just true/false):
```yaml
is_or_was_required: true
```
For structured requirement with details:
```yaml
has_or_had_status:
is_or_was_required: true
has_or_had_type:
- has_or_had_short_code: ADVANCE_BOOKING
has_or_had_description: "Advance booking required for groups of 10+"
```
exact_mappings:
- prov:Entity
close_mappings:
- schema:Action
slots:
- has_or_had_identifier
- is_or_was_required
- has_or_had_type
- has_or_had_label
- has_or_had_description
- has_or_had_note
- begin_of_the_begin
- end_of_the_end
slot_usage:
has_or_had_identifier:
range: uriorcurie
identifier: true
pattern: "^https://nde\\.nl/ontology/hc/requirement-status/[a-z0-9-]+$"
is_or_was_required:
range: boolean
required: true
description: "Whether this requirement is active/mandatory."
examples:
- value: true
description: Booking is required
- value: false
description: Booking is optional (walk-ins welcome)
has_or_had_type:
range: RequirementType
multivalued: true
inlined_as_list: true
description: "The type(s) of requirement (advance booking, group booking, etc.)."
examples:
- value:
- has_or_had_short_code: ADVANCE_BOOKING
description: Advance booking required
has_or_had_description:
range: string
description: "Free text description of the requirement details."
examples:
- value: "Advance booking required for groups of 10 or more. Individual visitors welcome without booking."
has_or_had_note:
range: string
multivalued: true
description: "Additional notes about the requirement."
examples:
- value: "Online booking available at www.museum.nl/book"
- value: "Phone bookings: +31 20 123 4567"
begin_of_the_begin:
range: datetime
description: "When this requirement came into effect."
end_of_the_end:
range: datetime
description: "When this requirement ended (if no longer in effect)."
annotations:
specificity_score: "0.55"
specificity_rationale: "Requirement status applicable to many heritage contexts (education, reading rooms, visits)."
template_specificity: '{"collection_discovery": 0.60, "location_browse": 0.75, "general_heritage": 0.50}'
slot_migration: |
2026-01-15: Created to replace domain-specific requirement boolean slots
- booking_required (boolean) → has_or_had_status (RequirementStatus)
- appointment_required (boolean) → has_or_had_status (RequirementStatus)
comments:
- "RequirementStatus represents structured requirement information"
- "Linked to RequirementType for type classification"
- "Supports temporal validity tracking"
- "CREATED 2026-01-15: Enables migration from domain-specific boolean slots"
examples:
- value:
has_or_had_identifier: https://nde.nl/ontology/hc/requirement-status/rijksmuseum-edu-booking
is_or_was_required: true
has_or_had_type:
- has_or_had_short_code: ADVANCE_BOOKING
has_or_had_label:
- Booking required for education programs@en
- Reservering verplicht voor educatieprogramma's@nl
has_or_had_description: |
Advance booking required for all school groups and educational programs.
Minimum 2 weeks advance booking for groups of 20+.
has_or_had_note:
- "Online booking: educatie@rijksmuseum.nl"
begin_of_the_begin: "2020-01-01T00:00:00Z"
description: Example booking requirement for museum education center
- value:
has_or_had_identifier: https://nde.nl/ontology/hc/requirement-status/archive-reading-room
is_or_was_required: true
has_or_had_type:
- has_or_had_short_code: APPOINTMENT_REQUIRED
has_or_had_description: |
Appointment required for reading room access.
Walk-in visits not possible due to limited seating.
description: Appointment requirement for archive reading room
- value:
has_or_had_identifier: https://nde.nl/ontology/hc/requirement-status/library-open-access
is_or_was_required: false
has_or_had_description: "No booking required. Open access during public hours."
description: No requirement (open access)

View file

@ -11,7 +11,7 @@ imports:
- ../slots/includes_music_description
- ../slots/includes_sound_description
- ../slots/includes_speaker_identification
- ../slots/is_auto_generated
- ../slots/is_or_was_created_through # MIGRATED: was ../slots/is_auto_generated (2026-01-15)
- ../slots/is_closed_caption
- ../slots/is_sdh
- ../slots/raw_subtitle_content
@ -22,6 +22,7 @@ imports:
- ../slots/track_name
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ./AutoGeneration # Added for is_or_was_created_through migration (2026-01-15)
- ../enums/SubtitlePositionEnum
- ../enums/SubtitleFormatEnum
prefixes:
@ -206,7 +207,7 @@ classes:
- `content_language`: From track language code
- `is_auto_generated`: YouTube auto-caption flag
- `is_or_was_created_through`: YouTube auto-caption flag
**SEGMENTS ARE REQUIRED**:
@ -232,7 +233,7 @@ classes:
- includes_music_description
- includes_sound_description
- includes_speaker_identification
- is_auto_generated
- is_or_was_created_through # MIGRATED: was is_auto_generated (2026-01-15)
- is_closed_caption
- is_sdh
- raw_subtitle_content
@ -302,7 +303,8 @@ classes:
examples:
- value: true
description: Subtitle text includes speaker labels
is_auto_generated:
is_or_was_created_through: # MIGRATED: was is_auto_generated (2026-01-15)
description: Whether this subtitle was auto-generated (e.g., YouTube ASR)
range: boolean
required: false
ifabsent: 'false'

View file

@ -31,7 +31,8 @@ imports:
- ../slots/has_or_had_data_service_endpoint
- ../slots/is_or_was_aggregated_by
# aggregates_from REMOVED - migrated to aggregates_or_aggregated_from (Rule 53)
- ../slots/associated_encompassing_bodies
# associated_encompassing_bodies REMOVED - migrated to is_or_was_associated_with (Rule 53)
- ../slots/is_or_was_associated_with
- ../slots/created_by_project
- ../slots/implements_auxiliary_platform
- ../slots/implements_digital_platform
@ -57,7 +58,7 @@ imports:
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../slots/aggregates_or_aggregated_from
- ../slots/has_or_had_associated_encompassing_body
# has_or_had_associated_encompassing_body REMOVED - replaced by generic is_or_was_associated_with (Rule 53)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
@ -134,7 +135,8 @@ classes:
# aggregates_from REMOVED - use aggregates_or_aggregated_from (Rule 53)
- aggregates_or_aggregated_from
- has_or_had_api_endpoint
- associated_encompassing_bodies
# associated_encompassing_bodies REMOVED - use is_or_was_associated_with (Rule 53)
- is_or_was_associated_with
- created_by_project
- data_license_policy
- has_or_had_data_service_endpoint
@ -343,7 +345,11 @@ classes:
examples:
- value: https://nde.nl/ontology/hc/project/nde/nde-portal-development-2023
description: NDE Portal Development project that created this portal
has_or_had_associated_encompassing_body:
is_or_was_associated_with:
description: >-
MIGRATED from associated_encompassing_bodies and has_or_had_associated_encompassing_body (Rule 53).
EncompassingBody organizations associated with this portal beyond the operator.
Range narrowed to uriorcurie for EncompassingBody references.
range: uriorcurie
multivalued: true
inlined_as_list: true
@ -400,7 +406,7 @@ classes:
- Track lifecycle with portal_status and successor_portal
- 'NEW: data_license_policy links to portal''s licensing stance (CC0, CC-BY, etc.)'
- 'NEW: created_by_project links to Project that built the portal'
- 'NEW: associated_encompassing_bodies for organizational relationships beyond operator'
- 'NEW: is_or_was_associated_with for organizational relationships beyond operator (migrated from associated_encompassing_bodies)'
- 'NEW: implements_digital_platform links to aggregated DigitalPlatform instances'
- 'NEW: implements_auxiliary_platform links to subordinate AuxiliaryDigitalPlatform instances'
- 'FUNDING: For funding relationships, link FundingOrganisation → Project → WebPortal (not direct)'
@ -502,7 +508,7 @@ classes:
project_period:
begin_of_the_begin: '2015-01-01'
end_of_the_end: '2025-12-31'
has_or_had_associated_encompassing_body:
is_or_was_associated_with:
- https://nde.nl/ontology/hc/encompassing-body/government/european-commission
- https://nde.nl/ontology/hc/encompassing-body/network/europeana-foundation
- https://nde.nl/ontology/hc/encompassing-body/consortium/europeana-network-association

View file

@ -0,0 +1,50 @@
id: https://nde.nl/ontology/hc/slot/has_or_had_documentation
name: has_or_had_documentation_slot
title: Has Or Had Documentation Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcterms: http://purl.org/dc/terms/
doap: http://usefulinc.com/ns/doap#
imports:
- linkml:types
default_prefix: hc
slots:
has_or_had_documentation:
description: >-
Links to documentation resources for a service, API, platform, or system.
**SEMANTIC PATTERN**:
This slot follows the RiC-O temporal predicate pattern (has_or_had_*)
to indicate that documentation may change over time (versioned docs,
deprecated documentation, etc.).
**REPLACES**:
- `api_documentation` - URL to API documentation
- Other domain-specific documentation URL slots
**RANGE OPTIONS**:
- uri: Simple URL to documentation
- Documentation: Structured documentation with metadata
Classes should use slot_usage to specify appropriate range.
slot_uri: schema:documentation
range: uri
multivalued: true
exact_mappings:
- schema:documentation
close_mappings:
- doap:homepage
- dcterms:references
related_mappings:
- doap:wiki
examples:
- value: "https://data.rijksmuseum.nl/object-metadata/api/"
description: API documentation URL
- value: "https://manual.collectiveaccess.org/"
description: CMS documentation URL

View file

@ -0,0 +1,61 @@
# is_or_was_allocated_budget - Generic temporal budget allocation slot
#
# Following RiC-O style naming convention (Rule 39):
# - is_or_was_* indicates temporal relationship
#
# ONTOLOGY ALIGNMENT: Schema.org schema:funding for budget allocation
#
# Created: 2026-01-15 to support budget slot migration in CurationActivity
id: https://nde.nl/ontology/hc/slot/is_or_was_allocated_budget
name: is_or_was_allocated_budget_slot
title: Is Or Was Allocated Budget Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
org: http://www.w3.org/ns/org#
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_allocated_budget:
slot_uri: schema:funding
range: string
description: |
Budget allocated to an entity or activity.
**ONTOLOGY ALIGNMENT**:
| Ontology | Property | Notes |
|----------|----------|-------|
| **Schema.org** | `schema:funding` | Primary - monetary allocation |
| **W3C Org** | `org:Organization` | Related - organizational budget |
**USAGE NOTE**:
For simple string budget (e.g., "€50,000"), use this slot directly.
For structured budget information with types, quantities, and temporal validity,
override the range to point to Budget class in slot_usage.
**MIGRATION NOTE**:
Replaces domain-specific budget slots:
- budget → is_or_was_allocated_budget
- digitization_budget → is_or_was_allocated_budget (with BudgetType)
- preservation_budget → is_or_was_allocated_budget (with BudgetType)
exact_mappings:
- schema:funding
close_mappings:
- schema:price
- schema:totalPrice
examples:
- value: "€50,000"
description: Simple budget amount with currency
- value: "USD 100,000 annually"
description: Annual budget allocation

View file

@ -0,0 +1,47 @@
id: https://nde.nl/ontology/hc/slot/is_or_was_associated_with
name: is_or_was_associated_with_slot
title: Is Or Was Associated With Slot
prefixes:
hc: https://nde.nl/ontology/hc/
linkml: https://w3id.org/linkml/
org: http://www.w3.org/ns/org#
prov: http://www.w3.org/ns/prov#
schema: http://schema.org/
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_associated_with:
description: >-
Generic slot expressing a temporal association relationship between entities.
This is a GENERIC slot following RiC-O naming conventions (Rule 39).
The range should be narrowed via slot_usage in class definitions to
the specific entity type being associated (EncompassingBody, Taxon, etc.).
**ONTOLOGY ALIGNMENT**:
- W3C Org: `org:linkedTo` - organizational linkage
- PROV-O: `prov:wasAssociatedWith` - activity/agent association
- Schema.org: `schema:memberOf` - membership relationships
**TEMPORAL SEMANTICS**:
The "is_or_was" pattern indicates this association may be:
- Current (is associated with)
- Historical (was associated with)
- Both (relationship changed over time)
Use slot_usage to narrow range and add temporal tracking if needed.
range: string
multivalued: true
slot_uri: org:linkedTo
exact_mappings:
- org:linkedTo
close_mappings:
- prov:wasAssociatedWith
- schema:memberOf
annotations:
custodian_types: '["*"]'
custodian_types_rationale: Generic association slot applicable to all heritage custodian types.
custodian_types_primary: M
specificity_score: 0.3
specificity_rationale: Generic relational slot - broadly applicable across many contexts.

View file

@ -0,0 +1,46 @@
id: https://nde.nl/ontology/hc/slot/is_or_was_available
name: is_or_was_available_slot
title: Is Or Was Available Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcat: http://www.w3.org/ns/dcat#
dcterms: http://purl.org/dc/terms/
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_available:
description: >-
Indicates whether a resource, service, or feature is or was available.
**SEMANTIC PATTERN**:
This slot follows the RiC-O temporal predicate pattern (is_or_was_*)
to indicate that availability may change over time.
**REPLACES**:
- `api_available` - Whether a CMS has API access available
- Other domain-specific availability boolean flags
**RANGE OPTIONS**:
- boolean: Simple true/false availability
- AvailabilityStatus: Structured availability with temporal validity
Classes should use slot_usage to specify appropriate range.
slot_uri: schema:availability
range: boolean
exact_mappings:
- schema:availability
close_mappings:
- dcterms:available
- dcat:servesDataset
examples:
- value: true
description: API is available
- value: false
description: API is not available

View file

@ -0,0 +1,54 @@
id: https://nde.nl/ontology/hc/slot/is_or_was_created_through
name: is_or_was_created_through_slot
title: Is Or Was Created Through Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
prov: http://www.w3.org/ns/prov#
schema: http://schema.org/
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_created_through:
description: >-
Indicates how content was created - manually or through automatic generation.
**SEMANTIC PATTERN**:
This slot follows the RiC-O temporal predicate pattern (is_or_was_*)
to indicate that creation method is a historical fact that may be
relevant for provenance and quality assessment.
**REPLACES**:
- `auto_generated` - Boolean flag for automatic generation
- `is_auto_generated` - Similar boolean flag
**RANGE OPTIONS**:
- boolean: Simple true/false for auto-generated (backwards compatible)
- AutoGeneration: Structured generation method with provenance
Classes should use slot_usage to specify appropriate range.
**PROVENANCE CONTEXT**:
Auto-generated content often has different quality characteristics:
- ASR subtitles may have transcription errors
- AI chapters may have generic titles
- ML metadata may require human review
slot_uri: prov:wasGeneratedBy
range: boolean
exact_mappings:
- prov:wasGeneratedBy
close_mappings:
- schema:creator
related_mappings:
- prov:Activity
examples:
- value: true
description: Content was auto-generated
- value: false
description: Content was manually created

View file

@ -0,0 +1,55 @@
# is_or_was_required - Generic temporal boolean requirement slot
#
# Following RiC-O style naming convention (Rule 39):
# - is_or_was_* indicates temporal boolean state
#
# ONTOLOGY ALIGNMENT: Schema.org schema:isRequired for boolean requirement
#
# Created: 2026-01-15 to support booking_required migration
id: https://nde.nl/ontology/hc/slot/is_or_was_required
name: is_or_was_required_slot
title: Is Or Was Required Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_required:
slot_uri: schema:isRequired
range: boolean
description: |
Whether something is or was required (boolean).
**ONTOLOGY ALIGNMENT**:
| Ontology | Property | Notes |
|----------|----------|-------|
| **Schema.org** | `schema:isRequired` | Primary - boolean requirement |
**USAGE NOTE**:
This is a simple boolean slot. For structured requirement information
with types and temporal validity, use has_or_had_status with RequirementStatus.
**MIGRATION NOTE**:
Replaces domain-specific boolean slots like:
- booking_required → is_or_was_required
- appointment_required → is_or_was_required
- registration_required → is_or_was_required
exact_mappings:
- schema:isRequired
examples:
- value: true
description: Requirement is mandatory
- value: false
description: Requirement is optional

View file

@ -13,9 +13,7 @@
"annual_participants.yaml",
"api_available.yaml",
"api_documentation.yaml",
"applicable_countries.yaml",
"applies_to_call.yaml",
"appointment_required.yaml",
"approved_by.yaml",
"approximate.yaml",
"archive_branches.yaml",
@ -24,10 +22,8 @@
"area_hectares.yaml",
"arrangement_notes.yaml",
"asserted_by.yaml",
"associated_encompassing_bodies.yaml",
"associated_taxa.yaml",
"audio_event_segments.yaml",
"authentication_required.yaml",
"authors.yaml",
"auto_generated.yaml",
"auxiliary_places.yaml",
@ -65,10 +61,7 @@
"branch_office_name.yaml",
"branch_service_area.yaml",
"branch_staff_count.yaml",
"broader_concept.yaml",
"broader_concept_label.yaml",
"broader_type.yaml",
"budget.yaml",
"budget_currency.yaml",
"budget_description.yaml",
"budget_name.yaml",
@ -708,7 +701,6 @@
"has_applicable_country.yaml",
"has_application_deadline.yaml",
"has_application_opening_date.yaml",
"has_appointment_required_flag.yaml",
"has_appraisal_note.yaml",
"has_approval_date.yaml",
"has_archdiocese_name.yaml",
@ -743,7 +735,6 @@
"has_audit_date.yaml",
"has_audit_opinion.yaml",
"has_auditor_name.yaml",
"has_authentication_required_flag.yaml",
"has_author.yaml",
"has_authority_file_abbreviation.yaml",
"has_authority_file_name.yaml",
@ -837,7 +828,6 @@
"has_or_had_associated_auxiliary_platform.yaml",
"has_or_had_associated_custodian.yaml",
"has_or_had_associated_digital_platform.yaml",
"has_or_had_associated_encompassing_body.yaml",
"has_or_had_audience_size.yaml",
"has_or_had_audit_status.yaml",
"has_or_had_based_on_observation.yaml",
@ -1097,6 +1087,7 @@
"is_or_was_also_allocation_agency.yaml",
"is_or_was_archive_department_of.yaml",
"is_or_was_archived_in.yaml",
"is_or_was_associated_with.yaml",
"is_or_was_collection_of.yaml",
"is_or_was_encompassed_by.yaml",
"is_or_was_member_of.yaml",

View file

@ -30,34 +30,28 @@ fixes:
status: true
timestamp: '2026-01-14T16:00:00Z'
session: "session-2026-01-14-type-migration"
notes: "FULLY MIGRATED: TemporaryLocation - actual_end REMOVED. Use temporal_extent (range: TimeSpan) which contains end_of_the_end. CIDOC-CRM pattern: P4_has_time-span → E52_Time-Span → P82b_end_of_the_end"
notes: "FULLY MIGRATED: TemporaryLocation - actual_end REMOVED, using temporal_extent with TimeSpan.end_of_the_end (Rule 53)"
revision:
- label: temporal_extent
type: slot
description: "Slot with range TimeSpan (crm:P4_has_time-span)"
type: slot
- label: TimeSpan
type: class
description: "Class containing begin_of_the_begin, end_of_the_begin, begin_of_the_end, end_of_the_end slots"
- label: end_of_the_end
type: slot
description: "Nested within TimeSpan - latest possible end time (crm:P82b_end_of_the_end)"
- original_slot_id: https://nde.nl/ontology/hc/slot/actual_start
processed:
status: true
timestamp: '2026-01-14T16:00:00Z'
session: "session-2026-01-14-type-migration"
notes: "FULLY MIGRATED: TemporaryLocation - actual_start REMOVED. Use temporal_extent (range: TimeSpan) which contains begin_of_the_begin. CIDOC-CRM pattern: P4_has_time-span → E52_Time-Span → P82a_begin_of_the_begin"
notes: "FULLY MIGRATED: TemporaryLocation - actual_start REMOVED, using temporal_extent with TimeSpan.begin_of_the_begin (Rule 53)"
revision:
- label: temporal_extent
type: slot
description: "Slot with range TimeSpan (crm:P4_has_time-span)"
- label: TimeSpan
type: class
description: "Class containing begin_of_the_begin, end_of_the_begin, begin_of_the_end, end_of_the_end slots"
- label: begin_of_the_begin
type: slot
description: "Nested within TimeSpan - earliest possible start time (crm:P82a_begin_of_the_begin)"
- original_slot_id: https://nde.nl/ontology/hc/slot/address_formatted
processed:
@ -379,15 +373,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/applicable_countries
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Country class"
status: true
timestamp: "2026-01-15T00:00:00Z"
session: "slot-migration-session-20260115"
notes: "Migrated to has_applicable_country in CustodianType.yaml. Slot uses schema:areaServed URI. Archived applicable_countries.yaml."
revision:
- label: is_or_was_applicable_in
- label: has_applicable_country
type: slot
- label: Country
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/applies_to_call
processed:
@ -407,15 +399,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/appointment_required
processed:
status: false
timestamp: null
session: null
notes: "Requires RequirementStatus class creation"
status: true
timestamp: "2026-01-15T00:00:00Z"
session: "slot-migration-session-20260115"
notes: "Migrated to is_or_was_required in AccessPolicy.yaml. Archived appointment_required.yaml and has_appointment_required_flag.yaml."
revision:
- label: is_or_was_required
type: slot
- label: RequirementStatus
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/appraisal_notes
processed:
@ -523,10 +513,15 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/associated_encompassing_bodies
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing EncompassingBody class"
status: true
timestamp: '2026-01-14T22:00:00Z'
session: "session-2026-01-14-association-migration"
notes: >-
FULLY MIGRATED: WebPortal - associated_encompassing_bodies REMOVED.
Created generic is_or_was_associated_with slot per slot_fixes.yaml revision.
Also archived bespoke has_or_had_associated_encompassing_body slot that
was incorrectly created previously. WebPortal now uses is_or_was_associated_with
with range narrowed to uriorcurie via slot_usage (Rule 53).
revision:
- label: is_or_was_associated_with
type: slot
@ -559,10 +554,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/authentication_required
processed:
status: false
timestamp: null
session: null
notes: "Maps to RequirementStatus class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to is_or_was_required. DataServiceEndpoint.yaml updated with new import and slot. FileAPI.yaml import removed (inherits from DataServiceEndpoint). DataServiceEndpointType.yaml example updated. Slot archived to modules/slots/archive/authentication_required_archived_20260115.yaml."
revision:
- label: is_or_was_required
type: slot
@ -756,10 +751,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/binding_description
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Description class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_description. Binding.yaml updated with slot_usage. Slot archived to modules/slots/archive/binding_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -769,15 +764,9 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/binding_provenance
processed:
status: true
timestamp: '2026-01-15T00:20:00Z'
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: >-
FULLY MIGRATED: binding_provenance REMOVED and archived.
InformationCarrier.yaml updated to use has_or_had_provenance slot.
Updated imports, slots list, and slot_usage with migration note.
Note: This slot described physical binding provenance (e.g., royal presentation bindings),
which is semantically different from data extraction provenance.
Archived: binding_provenance.yaml to archive/ folder per Rule 53.
notes: "COMPLETE: Migrated to has_or_had_provenance. Binding.yaml updated with slot_usage. Slot archived to modules/slots/archive/binding_provenance_archived_20260115.yaml."
revision:
- label: has_or_had_provenance
type: slot
@ -950,10 +939,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_description
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Description class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_description. OrganizationBranch.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -975,12 +964,9 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_id
processed:
status: true
timestamp: '2026-01-14T23:45:00Z'
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: >-
FULLY MIGRATED: branch_id REMOVED and archived.
OrganizationBranch.yaml updated to use has_or_had_identifier slot.
Archived: branch_id.yaml to archive/ folder per Rule 53.
notes: "COMPLETE: Migrated to has_or_had_identifier. OrganizationBranch.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_id_archived_20260115.yaml."
revision:
- label: has_or_had_identifier
type: slot
@ -990,13 +976,9 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_name
processed:
status: true
timestamp: '2026-01-15T00:10:00Z'
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: >-
FULLY MIGRATED: branch_name REMOVED and archived.
OrganizationBranch.yaml updated to use has_or_had_label slot.
AuxiliaryPlace.yaml examples updated (hosts_branch references).
Archived: branch_name.yaml to archive/ folder per Rule 53.
notes: "COMPLETE: Migrated to has_or_had_label. OrganizationBranch.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_name_archived_20260115.yaml."
revision:
- label: has_or_had_label
type: slot
@ -1006,13 +988,9 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_office_description
processed:
status: true
timestamp: '2026-01-15T00:15:00Z'
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: >-
FULLY MIGRATED: branch_office_description REMOVED and archived.
BranchOffice.yaml updated to use has_or_had_description slot.
Updated imports, slots list, slot_usage, class description example, and 2 class examples.
Archived: branch_office_description.yaml to archive/ folder per Rule 53.
notes: "COMPLETE: Migrated to has_or_had_description. BranchOffice.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_office_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -1022,12 +1000,9 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_office_id
processed:
status: true
timestamp: '2026-01-14T23:50:00Z'
timestamp: '2026-01-14T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: >-
FULLY MIGRATED: branch_office_id REMOVED and archived.
BranchOffice.yaml updated to use has_or_had_identifier slot.
Archived: branch_office_id.yaml to archive/ folder per Rule 53.
notes: "COMPLETE: Migrated to has_or_had_identifier. BranchOffice.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_office_id_archived_20260114.yaml."
revision:
- label: has_or_had_identifier
type: slot
@ -1037,13 +1012,9 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_office_name
processed:
status: true
timestamp: '2026-01-15T00:00:00Z'
timestamp: '2026-01-14T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: >-
FULLY MIGRATED: branch_office_name REMOVED and archived.
BranchOffice.yaml updated to use has_or_had_label slot.
Updated imports, slots list, slot_usage, class description example, and 2 class examples.
Archived: branch_office_name.yaml to archive/ folder per Rule 53.
notes: "COMPLETE: Migrated to has_or_had_label. BranchOffice.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_office_name_archived_20260114.yaml."
revision:
- label: has_or_had_label
type: slot
@ -1092,10 +1063,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/broader_concept
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Hypernym/has_or_had_hypernym slot"
status: true
timestamp: '2026-01-14T22:30:00Z'
session: "session-2026-01-14-hypernym-migration"
notes: >-
FULLY MIGRATED: AcademicArchive - broader_concept REMOVED.
Replaced with existing has_or_had_hypernym slot (Rule 53).
Slot archived to modules/slots/archive/broader_concept_archived_20260114.yaml.
revision:
- label: has_or_had_hypernym
type: slot
@ -1104,10 +1078,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/broader_concept_label
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Label class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_label. AcademicArchive.yaml updated with slot_usage. Slot archived to modules/slots/archive/broader_concept_label_archived_20260115.yaml."
revision:
- label: has_or_had_label
type: slot
@ -1116,10 +1090,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/broader_type
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Hypernym/has_or_had_hypernym slot"
status: true
timestamp: '2026-01-14T22:30:00Z'
session: "session-2026-01-14-hypernym-migration"
notes: >-
FULLY MIGRATED: FindingAidType - broader_type REMOVED.
Replaced with existing has_or_had_hypernym slot (Rule 53).
Slot archived to modules/slots/archive/broader_type_archived_20260114.yaml.
revision:
- label: has_or_had_hypernym
type: slot
@ -1164,10 +1141,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/budget_description
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Description class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_description. Budget.yaml updated with slot_usage. Slot archived to modules/slots/archive/budget_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -1176,10 +1153,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/budget_name
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Label class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_label. Budget.yaml updated with slot_usage. Slot archived to modules/slots/archive/budget_name_archived_20260115.yaml."
revision:
- label: has_or_had_label
type: slot
@ -1273,16 +1250,57 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/cadastral_id
processed:
status: true
timestamp: '2026-01-14T23:55:00Z'
timestamp: '2026-01-14T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: >-
FULLY MIGRATED: cadastral_id REMOVED and archived.
GeoSpatialPlace.yaml updated to use has_or_had_identifier slot.
Use Identifier with identifier_scheme='cadastral' for parcel IDs.
Archived: cadastral_id.yaml to archive/ folder per Rule 53.
notes: "COMPLETE: Migrated to has_or_had_identifier. CadastralProperty.yaml updated with slot_usage. Slot archived to modules/slots/archive/cadastral_id_archived_20260114.yaml."
revision:
- label: has_or_had_identifier
type: slot
- label: Identifier
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/accepts_or_accepted_external_work
revision:
- label: accepts_or_accepted
type: slot
- label: ExternalWork
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/accepts_or_accepted_payment_method
revision:
- label: accepts_or_accepted
type: slot
- label: PaymentMethod
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/accepts_or_accepted_visiting_scholar
revision:
- label: accepts_or_accepted
type: slot
- label: VisitingScholar
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/zone_name
revision:
- label: has_or_had_label
type: slot
- label: Label
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/zone_id
revision:
- label: has_or_had_identifier
type: slot
- label: Identifier
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/zone_description
revision:
- label: has_or_had_description
type: slot
- label: Description
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/years_restricted
revision:
- label: has_or_had_restriction
type: slot
- label: Restriction
type: class
- label: temporal_extent
type: slot
- label: TimeSpan
type: class

View file

@ -244,6 +244,31 @@ export interface ClassDependencyCounts {
exportCount: number; // Total reverse dependencies
}
/**
* Information about how a slot is used/referenced by classes.
* This represents the "reverse dependencies" - what classes use this slot.
*/
export interface SlotExportInfo {
slotName: string;
/** Classes that include this slot in their slots array */
classesUsingSlot: string[];
/** Classes that have slot_usage overrides for this slot */
classesWithSlotUsage: Array<{
className: string;
/** Properties overridden in slot_usage (e.g., 'range', 'description', 'required') */
overrides: string[];
}>;
/** The range type if it's a class or enum (for navigation) */
rangeType?: {
name: string;
isClass: boolean;
isEnum: boolean;
};
}
const SCHEMA_BASE_PATH = '/schemas/20251121/linkml';
/**
@ -1463,6 +1488,79 @@ class LinkMLSchemaService {
return exportInfo;
}
/**
* Get export/usage information for a slot.
* This finds all classes that use or customize this slot.
*
* Analyzes:
* - Classes that include this slot in their slots array
* - Classes that have slot_usage overrides for this slot
* - The range type (for navigation to class/enum)
*/
async getSlotExportInfo(slotName: string): Promise<SlotExportInfo> {
await this.initialize();
const exportInfo: SlotExportInfo = {
slotName,
classesUsingSlot: [],
classesWithSlotUsage: [],
rangeType: undefined,
};
// Get the slot definition for range info
const slotDef = this.slotSchemas.get(slotName);
if (slotDef?.range) {
const isClass = this.classSchemas.has(slotDef.range);
const isEnum = this.enumSchemas.has(slotDef.range);
if (isClass || isEnum) {
exportInfo.rangeType = {
name: slotDef.range,
isClass,
isEnum,
};
}
}
// Scan all classes for references to this slot
for (const [className, schema] of this.classSchemas.entries()) {
const classDef = schema.classes?.[className];
if (!classDef) continue;
// Check if class uses this slot directly
if (classDef.slots?.includes(slotName)) {
exportInfo.classesUsingSlot.push(className);
}
// Check if class has slot_usage for this slot
if (classDef.slot_usage?.[slotName]) {
const slotUsage = classDef.slot_usage[slotName];
const overrides: string[] = [];
// Detect which properties are overridden
if (slotUsage.range !== undefined) overrides.push('range');
if (slotUsage.description !== undefined) overrides.push('description');
if (slotUsage.required !== undefined) overrides.push('required');
if (slotUsage.multivalued !== undefined) overrides.push('multivalued');
if (slotUsage.pattern !== undefined) overrides.push('pattern');
if (slotUsage.slot_uri !== undefined) overrides.push('slot_uri');
if (slotUsage.identifier !== undefined) overrides.push('identifier');
if (slotUsage.examples !== undefined) overrides.push('examples');
exportInfo.classesWithSlotUsage.push({
className,
overrides,
});
}
}
// Sort for consistent display
exportInfo.classesUsingSlot.sort();
exportInfo.classesWithSlotUsage.sort((a, b) => a.className.localeCompare(b.className));
return exportInfo;
}
/**
* Get import/dependency information for a class.
* This finds what a class depends ON (forward dependencies).

View file

@ -27,7 +27,7 @@ import {
extractSlots,
extractEnums,
} from '../lib/linkml/schema-loader';
import { linkmlSchemaService, type ClassExportInfo, type ClassImportInfo, type ClassDependencyCounts, type SlotDefinition } from '../lib/linkml/linkml-schema-service';
import { linkmlSchemaService, type ClassExportInfo, type ClassImportInfo, type ClassDependencyCounts, type SlotDefinition, type SlotExportInfo } from '../lib/linkml/linkml-schema-service';
import { useLanguage } from '../contexts/LanguageContext';
import { useSchemaLoadingProgress } from '../hooks/useSchemaLoadingProgress';
import { CustodianTypeBadge } from '../components/uml/CustodianTypeIndicator';
@ -1036,6 +1036,11 @@ const TEXT = {
searchModeContent: { nl: 'Inhoud', en: 'Content' },
noSearchResults: { nl: 'Geen resultaten voor zoekopdracht', en: 'No results for search' },
clearSearch: { nl: 'Zoekopdracht wissen', en: 'Clear search' },
// Slot exports (classes using this slot)
exports: { nl: 'Exports', en: 'Exports' },
classesUsingSlot: { nl: 'Klassen die deze slot gebruiken:', en: 'Classes using this slot:' },
classesWithSlotUsage: { nl: 'Klassen met slot_usage overschrijvingen:', en: 'Classes with slot_usage overrides:' },
noClassesUsingSlot: { nl: 'Geen klassen gebruiken deze slot.', en: 'No classes use this slot.' },
};
// Dynamically discover schema files from the modules directory
@ -1120,6 +1125,11 @@ const LinkMLViewerPage: React.FC = () => {
const [classImports, setClassImports] = useState<Record<string, ClassImportInfo>>({});
const [loadingImports, setLoadingImports] = useState<Set<string>>(new Set());
// State for expandable Exports section in slot details (which classes use this slot)
const [expandedSlotExports, setExpandedSlotExports] = useState<Set<string>>(new Set());
const [slotExports, setSlotExports] = useState<Record<string, SlotExportInfo>>({});
const [loadingSlotExports, setLoadingSlotExports] = useState<Set<string>>(new Set());
// State for expandable UML diagram section in class details
const [expandedUML, setExpandedUML] = useState<Set<string>>(new Set());
@ -1368,6 +1378,37 @@ const LinkMLViewerPage: React.FC = () => {
}
}, [classImports, loadingImports, isSchemaServiceComplete]);
// Toggle exports section for a slot and load export data on demand
const toggleSlotExports = useCallback(async (slotName: string) => {
// Toggle expansion state
setExpandedSlotExports(prev => {
const next = new Set(prev);
if (next.has(slotName)) {
next.delete(slotName);
} else {
next.add(slotName);
}
return next;
});
// Load export data if not already loaded and schema service is ready
if (!slotExports[slotName] && !loadingSlotExports.has(slotName) && isSchemaServiceComplete) {
setLoadingSlotExports(prev => new Set(prev).add(slotName));
try {
const exportInfo = await linkmlSchemaService.getSlotExportInfo(slotName);
setSlotExports(prev => ({ ...prev, [slotName]: exportInfo }));
} catch (error) {
console.error(`Error loading export info for slot ${slotName}:`, error);
} finally {
setLoadingSlotExports(prev => {
const next = new Set(prev);
next.delete(slotName);
return next;
});
}
}
}, [slotExports, loadingSlotExports, isSchemaServiceComplete]);
// Toggle UML diagram section for a class
// Loads both exports AND imports data since UML diagram can show both directions
const toggleUML = useCallback(async (className: string) => {
@ -3072,6 +3113,112 @@ const LinkMLViewerPage: React.FC = () => {
</div>
)}
{/* Exports section - Only show for standalone slots (not within class context) */}
{!className && (
<div className="linkml-viewer__accordion">
<button
className={`linkml-viewer__accordion-header ${expandedSlotExports.has(slot.name) ? 'linkml-viewer__accordion-header--expanded' : ''}`}
onClick={() => toggleSlotExports(slot.name)}
>
<span className="linkml-viewer__accordion-icon">
{expandedSlotExports.has(slot.name) ? '▼' : '▶'}
</span>
{t('exports')}
{slotExports[slot.name] && (
<span className="linkml-viewer__accordion-count">
({slotExports[slot.name].classesUsingSlot.length + slotExports[slot.name].classesWithSlotUsage.length})
</span>
)}
{loadingSlotExports.has(slot.name) && (
<span className="linkml-viewer__accordion-loading">...</span>
)}
</button>
{expandedSlotExports.has(slot.name) && (
<div className="linkml-viewer__accordion-content">
{loadingSlotExports.has(slot.name) ? (
<div className="linkml-viewer__loading-text">{t('loading')}...</div>
) : slotExports[slot.name] ? (
<>
{/* Range Type - Navigation to class/enum */}
{slotExports[slot.name].rangeType && (
<div className="linkml-viewer__export-section">
<span className="linkml-viewer__label">{t('range')}</span>
<button
className="linkml-viewer__link-button"
onClick={() => {
const range = slotExports[slot.name].rangeType!;
if (range.isClass) {
navigateToClass(range.name);
} else if (range.isEnum) {
navigateToEnum(range.name);
}
}}
title={`Navigate to ${slotExports[slot.name].rangeType!.isClass ? 'class' : 'enum'}: ${slotExports[slot.name].rangeType!.name}`}
>
<code>{slotExports[slot.name].rangeType!.name}</code>
<span className="linkml-viewer__badge linkml-viewer__badge--small">
{slotExports[slot.name].rangeType!.isClass ? 'class' : 'enum'}
</span>
</button>
</div>
)}
{/* Classes that use this slot */}
{slotExports[slot.name].classesUsingSlot.length > 0 && (
<div className="linkml-viewer__export-section">
<span className="linkml-viewer__label">{t('classesUsingSlot')}</span>
<div className="linkml-viewer__export-list">
{slotExports[slot.name].classesUsingSlot.map(cls => (
<button
key={cls}
className="linkml-viewer__link-button"
onClick={() => navigateToClass(cls)}
title={`Navigate to class: ${cls}`}
>
{cls}
</button>
))}
</div>
</div>
)}
{/* Classes with slot_usage overrides */}
{slotExports[slot.name].classesWithSlotUsage.length > 0 && (
<div className="linkml-viewer__export-section">
<span className="linkml-viewer__label">{t('classesWithSlotUsage')}</span>
<div className="linkml-viewer__export-list">
{slotExports[slot.name].classesWithSlotUsage.map(({ className: cls, overrides }) => (
<button
key={cls}
className="linkml-viewer__link-button linkml-viewer__link-button--with-meta"
onClick={() => navigateToClass(cls)}
title={`Navigate to class: ${cls}\nOverrides: ${overrides.join(', ')}`}
>
{cls}
<span className="linkml-viewer__badge linkml-viewer__badge--usage linkml-viewer__badge--small">
{overrides.length} {overrides.length === 1 ? 'override' : 'overrides'}
</span>
</button>
))}
</div>
</div>
)}
{/* Empty state */}
{slotExports[slot.name].classesUsingSlot.length === 0 &&
slotExports[slot.name].classesWithSlotUsage.length === 0 && (
<div className="linkml-viewer__export-empty">
{t('noClassesUsingSlot')}
</div>
)}
</>
) : null}
</div>
)}
</div>
)}
{/* Side-by-side comparison view - only shown when expanded */}
{showComparison && hasSlotUsageOverrides && genericSlot && (
<div className="linkml-viewer__slot-comparison">

View file

@ -1,12 +1,12 @@
{
"generated": "2026-01-14T11:14:08.309Z",
"generated": "2026-01-14T12:09:32.173Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": 2896,
"totalFiles": 2884,
"categoryCounts": {
"main": 4,
"class": 671,
"class": 675,
"enum": 147,
"slot": 2070,
"slot": 2054,
"module": 4
},
"categories": [
@ -290,6 +290,11 @@
"path": "modules/classes/AudiovisualArchiveRecordSetTypes.yaml",
"category": "class"
},
{
"name": "AutoGeneration",
"path": "modules/classes/AutoGeneration.yaml",
"category": "class"
},
{
"name": "AuxiliaryDigitalPlatform",
"path": "modules/classes/AuxiliaryDigitalPlatform.yaml",
@ -300,6 +305,11 @@
"path": "modules/classes/AuxiliaryPlace.yaml",
"category": "class"
},
{
"name": "AvailabilityStatus",
"path": "modules/classes/AvailabilityStatus.yaml",
"category": "class"
},
{
"name": "BackupStatus",
"path": "modules/classes/BackupStatus.yaml",
@ -965,6 +975,11 @@
"path": "modules/classes/Division.yaml",
"category": "class"
},
{
"name": "Documentation",
"path": "modules/classes/Documentation.yaml",
"category": "class"
},
{
"name": "DocumentationCentre",
"path": "modules/classes/DocumentationCentre.yaml",
@ -2535,6 +2550,11 @@
"path": "modules/classes/ReligiousArchiveRecordSetTypes.yaml",
"category": "class"
},
{
"name": "RequirementStatus",
"path": "modules/classes/RequirementStatus.yaml",
"category": "class"
},
{
"name": "RequirementType",
"path": "modules/classes/RequirementType.yaml",
@ -4182,31 +4202,11 @@
"path": "modules/slots/annual_participants.yaml",
"category": "slot"
},
{
"name": "api_available",
"path": "modules/slots/api_available.yaml",
"category": "slot"
},
{
"name": "api_documentation",
"path": "modules/slots/api_documentation.yaml",
"category": "slot"
},
{
"name": "applicable_countries",
"path": "modules/slots/applicable_countries.yaml",
"category": "slot"
},
{
"name": "applies_to_call",
"path": "modules/slots/applies_to_call.yaml",
"category": "slot"
},
{
"name": "appointment_required",
"path": "modules/slots/appointment_required.yaml",
"category": "slot"
},
{
"name": "approved_by",
"path": "modules/slots/approved_by.yaml",
@ -4237,11 +4237,6 @@
"path": "modules/slots/asserted_by.yaml",
"category": "slot"
},
{
"name": "associated_encompassing_bodies",
"path": "modules/slots/associated_encompassing_bodies.yaml",
"category": "slot"
},
{
"name": "associated_taxa",
"path": "modules/slots/associated_taxa.yaml",
@ -4252,11 +4247,6 @@
"path": "modules/slots/audio_event_segments.yaml",
"category": "slot"
},
{
"name": "authentication_required",
"path": "modules/slots/authentication_required.yaml",
"category": "slot"
},
{
"name": "authors",
"path": "modules/slots/authors.yaml",
@ -4282,11 +4272,6 @@
"path": "modules/slots/available_caption_languages.yaml",
"category": "slot"
},
{
"name": "backup_status",
"path": "modules/slots/backup_status.yaml",
"category": "slot"
},
{
"name": "base_surname",
"path": "modules/slots/base_surname.yaml",
@ -4317,21 +4302,6 @@
"path": "modules/slots/benefit.yaml",
"category": "slot"
},
{
"name": "bibframe_equivalent",
"path": "modules/slots/bibframe_equivalent.yaml",
"category": "slot"
},
{
"name": "binding",
"path": "modules/slots/binding.yaml",
"category": "slot"
},
{
"name": "binding_description",
"path": "modules/slots/binding_description.yaml",
"category": "slot"
},
{
"name": "bio_custodian_subtype",
"path": "modules/slots/bio_custodian_subtype.yaml",
@ -4357,11 +4327,6 @@
"path": "modules/slots/bold_id.yaml",
"category": "slot"
},
{
"name": "booking_required",
"path": "modules/slots/booking_required.yaml",
"category": "slot"
},
{
"name": "bookplate",
"path": "modules/slots/bookplate.yaml",
@ -4387,11 +4352,6 @@
"path": "modules/slots/box_number.yaml",
"category": "slot"
},
{
"name": "branch_description",
"path": "modules/slots/branch_description.yaml",
"category": "slot"
},
{
"name": "branch_head",
"path": "modules/slots/branch_head.yaml",
@ -4407,41 +4367,11 @@
"path": "modules/slots/branch_staff_count.yaml",
"category": "slot"
},
{
"name": "broader_concept",
"path": "modules/slots/broader_concept.yaml",
"category": "slot"
},
{
"name": "broader_concept_label",
"path": "modules/slots/broader_concept_label.yaml",
"category": "slot"
},
{
"name": "broader_type",
"path": "modules/slots/broader_type.yaml",
"category": "slot"
},
{
"name": "budget",
"path": "modules/slots/budget.yaml",
"category": "slot"
},
{
"name": "budget_currency",
"path": "modules/slots/budget_currency.yaml",
"category": "slot"
},
{
"name": "budget_description",
"path": "modules/slots/budget_description.yaml",
"category": "slot"
},
{
"name": "budget_name",
"path": "modules/slots/budget_name.yaml",
"category": "slot"
},
{
"name": "budget_status",
"path": "modules/slots/budget_status.yaml",
@ -7547,16 +7477,6 @@
"path": "modules/slots/has_annotation_type.yaml",
"category": "slot"
},
{
"name": "has_api_available_flag",
"path": "modules/slots/has_api_available_flag.yaml",
"category": "slot"
},
{
"name": "has_api_documentation_url",
"path": "modules/slots/has_api_documentation_url.yaml",
"category": "slot"
},
{
"name": "has_api_version",
"path": "modules/slots/has_api_version.yaml",
@ -7592,11 +7512,6 @@
"path": "modules/slots/has_application_opening_date.yaml",
"category": "slot"
},
{
"name": "has_appointment_required_flag",
"path": "modules/slots/has_appointment_required_flag.yaml",
"category": "slot"
},
{
"name": "has_appraisal_note",
"path": "modules/slots/has_appraisal_note.yaml",
@ -8232,11 +8147,6 @@
"path": "modules/slots/has_or_had_associated_digital_platform.yaml",
"category": "slot"
},
{
"name": "has_or_had_associated_encompassing_body",
"path": "modules/slots/has_or_had_associated_encompassing_body.yaml",
"category": "slot"
},
{
"name": "has_or_had_audience_size",
"path": "modules/slots/has_or_had_audience_size.yaml",
@ -8372,6 +8282,11 @@
"path": "modules/slots/has_or_had_digital_platform.yaml",
"category": "slot"
},
{
"name": "has_or_had_documentation",
"path": "modules/slots/has_or_had_documentation.yaml",
"category": "slot"
},
{
"name": "has_or_had_documentation_source",
"path": "modules/slots/has_or_had_documentation_source.yaml",
@ -9572,6 +9487,11 @@
"path": "modules/slots/is_or_was_aggregated_by.yaml",
"category": "slot"
},
{
"name": "is_or_was_allocated_budget",
"path": "modules/slots/is_or_was_allocated_budget.yaml",
"category": "slot"
},
{
"name": "is_or_was_allocated_by",
"path": "modules/slots/is_or_was_allocated_by.yaml",
@ -9592,11 +9512,26 @@
"path": "modules/slots/is_or_was_archived_in.yaml",
"category": "slot"
},
{
"name": "is_or_was_associated_with",
"path": "modules/slots/is_or_was_associated_with.yaml",
"category": "slot"
},
{
"name": "is_or_was_available",
"path": "modules/slots/is_or_was_available.yaml",
"category": "slot"
},
{
"name": "is_or_was_collection_of",
"path": "modules/slots/is_or_was_collection_of.yaml",
"category": "slot"
},
{
"name": "is_or_was_created_through",
"path": "modules/slots/is_or_was_created_through.yaml",
"category": "slot"
},
{
"name": "is_or_was_encompassed_by",
"path": "modules/slots/is_or_was_encompassed_by.yaml",
@ -9622,6 +9557,11 @@
"path": "modules/slots/is_or_was_related_to.yaml",
"category": "slot"
},
{
"name": "is_or_was_required",
"path": "modules/slots/is_or_was_required.yaml",
"category": "slot"
},
{
"name": "is_or_was_sub_collection_of",
"path": "modules/slots/is_or_was_sub_collection_of.yaml",

View file

@ -16,7 +16,8 @@ imports:
- ../slots/has_or_had_holds_record_set_type
- ../slots/has_or_had_custodian_type
- ../slots/dual_class_link
- ../slots/broader_concept
# broader_concept REMOVED - migrated to has_or_had_hypernym (Rule 53)
- ../slots/has_or_had_hypernym
- ../slots/has_or_had_label
- ../slots/specificity_annotation
- ../slots/template_specificity
@ -35,7 +36,8 @@ classes:
- has_or_had_custodian_type
- dual_class_link
- has_or_had_holds_record_set_type
- broader_concept
# broader_concept REMOVED - migrated to has_or_had_hypernym (Rule 53)
- has_or_had_hypernym
- has_or_had_label
- specificity_annotation
- template_specificity
@ -82,7 +84,10 @@ classes:
wikidata_alignment:
range: WikidataAlignment
inlined: true
broader_concept:
has_or_had_hypernym:
description: >-
MIGRATED from broader_concept (Rule 53).
SKOS broader (parent) concept in the archive type hierarchy.
equals_expression: '["wd:Q166118"]'
has_or_had_label:
description: >-

View file

@ -0,0 +1,83 @@
id: https://nde.nl/ontology/hc/class/AutoGeneration
name: auto_generation_class
title: AutoGeneration Class
imports:
- linkml:types
- ../slots/has_or_had_label
- ../slots/has_or_had_description
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
prov: http://www.w3.org/ns/prov#
dcterms: http://purl.org/dc/terms/
default_prefix: hc
classes:
AutoGeneration:
class_uri: prov:Activity
description: >-
Represents automatic generation or creation of content by a system or algorithm.
**DEFINITION**:
AutoGeneration models the automatic creation of content such as subtitles,
chapters, transcripts, or metadata by AI/ML systems, platform algorithms,
or automated processes. This replaces simple boolean flags like `auto_generated`
with a structured class that can capture the generation method and provenance.
**ONTOLOGY ALIGNMENT**:
- PROV-O: `prov:Activity` - an activity that generates entities
- PROV-O: `prov:wasGeneratedBy` - links to generating activity
- Schema.org: `schema:CreateAction` - creation action
**GENERATION METHODS**:
- ASR (Automatic Speech Recognition): Speech-to-text for subtitles
- Scene Detection: AI-based video chapter generation
- NLP: Natural language processing for metadata extraction
- OCR: Optical character recognition for text extraction
**USE CASES**:
1. **Auto-Subtitles**: YouTube auto-generated captions
2. **Auto-Chapters**: AI-detected video chapters
3. **Auto-Transcripts**: ASR-generated transcripts
4. **Auto-Metadata**: ML-extracted metadata
exact_mappings:
- prov:Activity
close_mappings:
- schema:CreateAction
related_mappings:
- prov:wasGeneratedBy
slots:
- has_or_had_label
- has_or_had_description
slot_usage:
has_or_had_label:
range: string
examples:
- value: "YouTube Auto-Caption"
description: Platform auto-generated captions
- value: "ASR Transcription"
description: Automatic speech recognition
has_or_had_description:
range: string
examples:
- value: "Automatically generated by YouTube's speech recognition system"
description: Platform-provided auto-generation
- value: "Generated using Whisper ASR model"
description: Specific ASR model used
comments:
- Generic auto-generation class replacing domain-specific boolean flags
- Captures generation method and provenance
- Aligns with PROV-O Activity for provenance tracking
see_also:
- https://www.w3.org/TR/prov-o/#Activity
- https://schema.org/CreateAction
examples:
- value:
has_or_had_label: "YouTube Auto-Caption"
has_or_had_description: "Automatically generated by YouTube's speech recognition"
description: YouTube auto-generated subtitles

View file

@ -23,7 +23,7 @@ imports:
- ../slots/archived_at
- ../slots/serves_finding_aid
- ../slots/has_or_had_data_service_endpoint
- ../slots/api_documentation
- ../slots/has_or_had_documentation # MIGRATED: was ../slots/api_documentation (2026-01-15)
- ../slots/has_or_had_archival_status
- ../slots/has_or_had_identifier
- ../slots/has_auxiliary_platform_type
@ -49,7 +49,8 @@ imports:
- ../slots/was_generated_by
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../slots/has_api_documentation_url
- ./Documentation # Added for has_or_had_documentation migration (2026-01-15)
# REMOVED: ../slots/has_api_documentation_url - migrated to has_or_had_documentation (2026-01-15)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
@ -110,7 +111,7 @@ classes:
- schema:isRelatedTo
- dcat:servesDataset
slots:
- api_documentation
- has_or_had_documentation # MIGRATED: was api_documentation (2026-01-15)
- has_or_had_archival_status
- archived_at
- has_or_had_identifier
@ -188,8 +189,10 @@ classes:
- value: Rijksstudio allows users to create personal collections from the Rijksmuseum's digitized artworks, download
high-resolution images, and share curated sets with others.
description: Detailed platform description
has_api_documentation_url:
has_or_had_documentation: # MIGRATED: was has_api_documentation_url (2026-01-15)
description: Documentation resources for this auxiliary platform (API docs, user guides, etc.)
range: uri
multivalued: true
examples:
- value: https://data.rijksmuseum.nl/object-metadata/api/
description: API documentation URL
@ -369,7 +372,7 @@ classes:
auxiliary_platform_type: APIEndpoint
platform_url: https://data.rijksmuseum.nl/
platform_purpose: Developer access to collection metadata and images
api_documentation: https://data.rijksmuseum.nl/object-metadata/api/
has_or_had_documentation: https://data.rijksmuseum.nl/object-metadata/api/
technology_stack:
- REST
- JSON

View file

@ -0,0 +1,96 @@
id: https://nde.nl/ontology/hc/class/AvailabilityStatus
name: availability_status_class
title: AvailabilityStatus Class
imports:
- linkml:types
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/valid_from
- ../slots/valid_to
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcat: http://www.w3.org/ns/dcat#
dcterms: http://purl.org/dc/terms/
default_prefix: hc
classes:
AvailabilityStatus:
class_uri: schema:Availability
description: >-
Represents the availability state of a resource, service, or feature.
**DEFINITION**:
AvailabilityStatus models whether something (API, service, feature, resource)
is currently available for use. This replaces domain-specific boolean flags
like `api_available` with a structured class that can capture temporal
validity and descriptive context.
**ONTOLOGY ALIGNMENT**:
- Schema.org: `schema:Availability` - availability of a product/service
- DCAT: `dcat:DataService` availability patterns
- DCTERMS: `dcterms:available` - date resource became available
**USE CASES**:
1. **API Availability**: Whether a CMS provides API access
2. **Service Availability**: Whether a digital platform is operational
3. **Feature Availability**: Whether specific features are enabled
**TEMPORAL VALIDITY**:
Availability can change over time:
- API available from 2015-01-01 to 2020-12-31 (deprecated)
- Service temporarily unavailable during maintenance
exact_mappings:
- schema:Availability
close_mappings:
- dcat:DataService
related_mappings:
- dcterms:available
slots:
- has_or_had_label
- has_or_had_description
- valid_from
- valid_to
slot_usage:
has_or_had_label:
range: string
required: false
examples:
- value: "API Available"
description: Indicates API is available
- value: "Service Unavailable"
description: Indicates service is down
has_or_had_description:
range: string
examples:
- value: "REST API available with JSON responses"
description: Details about API availability
valid_from:
range: date
examples:
- value: "2015-01-01"
description: API available since 2015
valid_to:
range: date
examples:
- value: null
description: Still available (no end date)
comments:
- Generic availability status class replacing domain-specific boolean flags
- Supports temporal validity for tracking when availability changed
- Aligns with Schema.org Availability enumeration pattern
see_also:
- https://schema.org/Availability
- https://www.w3.org/TR/vocab-dcat-2/#Class:DataService
examples:
- value:
has_or_had_label: "API Available"
has_or_had_description: "REST API with JSON responses available for collection metadata access"
valid_from: "2015-06-01"
valid_to: null
description: CMS API availability status

View file

@ -18,7 +18,9 @@ imports:
- ./CustodianPlace
- ../enums/PreservationMethodEnum
- ../slots/wikidata_id
- ../slots/associated_taxa
# associated_taxa REMOVED - migrated to is_or_was_associated_with (Rule 53)
- ../slots/is_or_was_associated_with
- ./Taxon
- ../slots/bold_id
- ../slots/cites_appendix
- ../slots/collection_date
@ -100,7 +102,8 @@ classes:
- gbif:Specimen
is_a: ExhibitedObject
slots:
- associated_taxa
# associated_taxa REMOVED - migrated to is_or_was_associated_with (Rule 53)
- is_or_was_associated_with
- bold_id
- cites_appendix
- collection_date
@ -138,6 +141,17 @@ classes:
- template_specificity
- type_status
slot_usage:
is_or_was_associated_with:
description: >-
MIGRATED from associated_taxa (Rule 53).
Links biological object to associated taxa.
Range narrowed to Taxon class.
range: Taxon
multivalued: true
inlined_as_list: true
examples:
- value: https://nde.nl/ontology/hc/taxon/raphus-cucullatus
description: Associated with Dodo taxon
taxon_name:
required: true
range: string

View file

@ -11,7 +11,7 @@ imports:
- ./TimeSpan
- ../slots/documentation_url
- ./ReconstructedEntity
- ../slots/api_available
- ../slots/is_or_was_available # MIGRATED: was ../slots/api_available (2026-01-15)
- ../slots/cms_category
- ../slots/cms_id
- ../slots/cms_product_name
@ -38,7 +38,8 @@ imports:
- ../slots/was_generated_by
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../slots/has_api_available_flag
- ./AvailabilityStatus # Added for is_or_was_available migration (2026-01-15)
# REMOVED: ../slots/has_api_available_flag - migrated to is_or_was_available (2026-01-15)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
@ -99,7 +100,7 @@ classes:
- doap:repository
- rico:Activity
slots:
- api_available
- is_or_was_available # MIGRATED: was api_available (2026-01-15)
- cms_category
- cms_id
- cms_product_name
@ -225,7 +226,8 @@ classes:
examples:
- value: true
description: Supports LOD export
has_api_available_flag:
is_or_was_available: # MIGRATED: was has_api_available_flag (2026-01-15)
description: Whether this CMS provides API access (REST, GraphQL, OAI-PMH, SPARQL, SRU/SRW)
range: boolean
examples:
- value: true
@ -303,7 +305,7 @@ classes:
- LIDO
iiif_compatible: true
linked_data_export: true
api_available: true
is_or_was_available: true
powers_platform:
- https://nde.nl/ontology/hc/platform/rijksmuseum-website
manages_collection:
@ -332,7 +334,7 @@ classes:
- LIDO
iiif_compatible: true
linked_data_export: true
api_available: true
is_or_was_available: true
refers_to_custodian: https://nde.nl/ontology/hc/example-museum
description: Open-source CollectiveAccess deployment
- value:
@ -349,7 +351,7 @@ classes:
- MDTO
iiif_compatible: false
linked_data_export: false
api_available: true
is_or_was_available: true
manages_collection:
- https://nde.nl/ontology/hc/collection/na-government-records
refers_to_custodian: https://nde.nl/ontology/hc/nl-na

View file

@ -30,7 +30,7 @@ classes:
\ Properties**: Define protocol specifications, capabilities,\n and standards at the TYPE level (shared across all\
\ instances)\n2. **Instance-Level Properties**: Keep URL, status, authentication at the\n INSTANCE level (unique per\
\ deployment)\n\n**Architecture:**\n\n```\nDataServiceEndpoint (instance)\n │\n ├── endpoint_url: \"https://example.org/oai\"\
\n ├── status: ACTIVE\n ├── authentication_required: false\n │\n └── endpoint_type ──→ DataServiceEndpointType\
\n ├── status: ACTIVE\n ├── is_or_was_required: false\n │\n └── endpoint_type ──→ DataServiceEndpointType\
\ (classification)\n │\n └── OAIPMHEndpointType\n \
\ ├── protocol_name: \"OAI-PMH\"\n ├── protocol_version: \"\
2.0\"\n └── specification_url: \"http://...\"\n```\n\n**Subclasses (Endpoint Type Taxonomy):**\n\

View file

@ -0,0 +1,100 @@
id: https://nde.nl/ontology/hc/class/Documentation
name: documentation_class
title: Documentation Class
imports:
- linkml:types
- ../slots/has_or_had_label
- ../slots/has_or_had_description
- ../slots/has_or_had_identifier
- ../slots/valid_from
- ../slots/valid_to
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcterms: http://purl.org/dc/terms/
foaf: http://xmlns.com/foaf/0.1/
doap: http://usefulinc.com/ns/doap#
default_prefix: hc
classes:
Documentation:
class_uri: schema:TechArticle
description: >-
Documentation resource for a service, API, platform, or system.
**DEFINITION**:
Documentation represents technical documentation resources such as
API documentation, user guides, developer references, or system manuals.
This replaces domain-specific slots like `api_documentation` with a
structured class that can capture multiple documentation resources
with different types and purposes.
**ONTOLOGY ALIGNMENT**:
- Schema.org: `schema:TechArticle` - technical documentation
- DOAP: `doap:homepage`, `doap:wiki` - project documentation
- FOAF: `foaf:Document` - generic document
- DCTERMS: `dcterms:references` - documentation references
**DOCUMENTATION TYPES**:
- API Reference: Endpoint specifications, parameters, responses
- User Guide: End-user instructions and tutorials
- Developer Guide: Integration and development instructions
- System Manual: Technical specifications and architecture
**USE CASES**:
1. **API Documentation**: Link to REST API reference docs
2. **Integration Guides**: How to integrate with the platform
3. **User Manuals**: End-user documentation for staff
exact_mappings:
- schema:TechArticle
close_mappings:
- foaf:Document
- doap:homepage
related_mappings:
- dcterms:references
- doap:wiki
slots:
- has_or_had_label
- has_or_had_description
- has_or_had_identifier
- valid_from
- valid_to
slot_usage:
has_or_had_identifier:
range: uri
required: true
identifier: true
examples:
- value: "https://data.rijksmuseum.nl/object-metadata/api/"
description: Rijksmuseum API documentation URL
has_or_had_label:
range: string
examples:
- value: "API Reference Documentation"
description: Label for API docs
- value: "Developer Integration Guide"
description: Label for integration guide
has_or_had_description:
range: string
examples:
- value: "Complete REST API reference with endpoint specifications, authentication, and response formats."
description: Description of API documentation content
comments:
- Generic documentation class replacing domain-specific documentation slots
- Supports multiple documentation types (API, user, developer, system)
- URL stored in has_or_had_identifier as the primary identifier
- Aligns with Schema.org TechArticle for technical documentation
see_also:
- https://schema.org/TechArticle
- http://usefulinc.com/ns/doap#
examples:
- value:
has_or_had_identifier: "https://data.rijksmuseum.nl/object-metadata/api/"
has_or_had_label: "Rijksmuseum Collection API"
has_or_had_description: "REST API documentation for accessing collection metadata and images"
description: Rijksmuseum API documentation

View file

@ -14,7 +14,7 @@ imports:
- ../metadata
- ./DataServiceEndpoint
- ../slots/protocol
- ../slots/authentication_required
# REMOVED 2026-01-15: ../slots/authentication_required - migrated to is_or_was_required (inherited from DataServiceEndpoint)
- ../slots/specificity_annotation
- ../slots/template_specificity
- ./SpecificityAnnotation

View file

@ -26,7 +26,8 @@ imports:
- ../slots/wikidata_id
- ../slots/record_equivalent
- ../slots/typical_domain
- ../slots/broader_type
# broader_type REMOVED - migrated to has_or_had_hypernym (Rule 53)
- ../slots/has_or_had_hypernym
- ../slots/finding_aid_type_definition
- ../slots/finding_aid_type_id
- ../slots/finding_aid_type_name
@ -74,7 +75,8 @@ classes:
- schema:CreativeWork
- crm:E31_Document
slots:
- broader_type
# broader_type REMOVED - migrated to has_or_had_hypernym (Rule 53)
- has_or_had_hypernym
- finding_aid_type_definition
- finding_aid_type_id
- finding_aid_type_name
@ -99,7 +101,10 @@ classes:
pattern: ^Q[0-9]+$
record_equivalent:
range: uriorcurie
broader_type:
has_or_had_hypernym:
description: >-
MIGRATED from broader_type (Rule 53).
For finding aid subtypes, links to parent type in hierarchy.
range: FindingAidType
narrower_type:
range: FindingAidType

View file

@ -0,0 +1,106 @@
id: https://nde.nl/ontology/hc/class/Taxon
name: taxon_class
title: Taxon Class
description: >-
Biological taxon (species, genus, family, etc.) associated with heritage objects.
Follows Schema.org Taxon pattern for biological classification.
Used primarily for natural history collections.
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dwc: http://rs.tdwg.org/dwc/terms/
skos: http://www.w3.org/2004/02/skos/core#
default_prefix: hc
imports:
- linkml:types
- ../slots/id
- ../slots/has_or_had_label
- ../slots/description
- ../slots/specificity_annotation
- ../slots/template_specificity
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
classes:
Taxon:
class_uri: schema:Taxon
description: >-
A biological taxon (species, genus, family, order, etc.) that can be
associated with heritage objects in natural history collections.
**USE CASES**:
1. **Specimen Classification**: Link BiologicalObject to its taxonomic identification
2. **Collection Scope**: Define taxa covered by a natural history collection
3. **Research Context**: Document species studied in research archives
**DARWIN CORE ALIGNMENT**:
Uses Darwin Core terms for taxonomic data:
- dwc:scientificName - Full scientific name
- dwc:taxonRank - Level in hierarchy (species, genus, etc.)
- dwc:kingdom, dwc:phylum, dwc:class, dwc:order, dwc:family, dwc:genus
**EXTERNAL IDENTIFIERS**:
Link to authoritative taxonomic databases:
- GBIF (Global Biodiversity Information Facility)
- NCBI Taxonomy
- Wikidata (Q-numbers for taxa)
- BOLD (Barcode of Life)
exact_mappings:
- schema:Taxon
- dwc:Taxon
close_mappings:
- skos:Concept
slots:
- id
- has_or_had_label
- description
- specificity_annotation
- template_specificity
slot_usage:
id:
identifier: true
required: true
range: uriorcurie
pattern: ^https://nde\.nl/ontology/hc/taxon/[a-z0-9-]+$
examples:
- value: https://nde.nl/ontology/hc/taxon/raphus-cucullatus
description: Dodo (extinct species)
has_or_had_label:
description: Scientific name of the taxon.
range: string
required: true
examples:
- value: Raphus cucullatus
description: Dodo scientific name
- value: Homo sapiens
description: Human scientific name
description:
range: string
examples:
- value: Extinct flightless bird endemic to Mauritius
comments:
- Used for taxonomic associations in natural history collections
- Link to GBIF, NCBI, or Wikidata for authoritative identifiers
- Range should be narrowed via slot_usage when used
examples:
- value:
id: https://nde.nl/ontology/hc/taxon/raphus-cucullatus
has_or_had_label: Raphus cucullatus
description: >-
Dodo - an extinct flightless bird that was endemic to the island
of Mauritius. Last confirmed sighting in 1662.
description: Dodo taxon for natural history specimen

View file

@ -8,8 +8,9 @@ imports:
- ./SpecificityAnnotation
- ../slots/template_specificity
- ./TemplateSpecificityScores
- ./AutoGeneration # Added for is_or_was_created_through migration (2026-01-15)
- ../enums/ChapterSourceEnum
- ../slots/auto_generated
- ../slots/is_or_was_created_through # MIGRATED: was ../slots/auto_generated (2026-01-15)
- ../slots/chapter_description
- ../slots/chapter_end_seconds
- ../slots/chapter_end_time
@ -67,7 +68,7 @@ classes:
related_mappings:
- wikidata:Q1454986
slots:
- auto_generated
- is_or_was_created_through # MIGRATED: was auto_generated (2026-01-15)
- chapter_description
- chapter_end_seconds
- chapter_end_time
@ -147,7 +148,8 @@ classes:
examples:
- value: PT5M0S
description: 5 minutes
is_auto_generated:
is_or_was_created_through: # MIGRATED: was is_auto_generated (2026-01-15)
description: Whether this chapter was auto-generated by AI/platform algorithms
range: boolean
required: false
examples:

View file

@ -11,7 +11,7 @@ imports:
- ../slots/includes_music_description
- ../slots/includes_sound_description
- ../slots/includes_speaker_identification
- ../slots/is_auto_generated
- ../slots/is_or_was_created_through # MIGRATED: was ../slots/is_auto_generated (2026-01-15)
- ../slots/is_closed_caption
- ../slots/is_sdh
- ../slots/raw_subtitle_content
@ -22,6 +22,7 @@ imports:
- ../slots/track_name
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ./AutoGeneration # Added for is_or_was_created_through migration (2026-01-15)
- ../enums/SubtitlePositionEnum
- ../enums/SubtitleFormatEnum
prefixes:
@ -206,7 +207,7 @@ classes:
- `content_language`: From track language code
- `is_auto_generated`: YouTube auto-caption flag
- `is_or_was_created_through`: YouTube auto-caption flag
**SEGMENTS ARE REQUIRED**:
@ -232,7 +233,7 @@ classes:
- includes_music_description
- includes_sound_description
- includes_speaker_identification
- is_auto_generated
- is_or_was_created_through # MIGRATED: was is_auto_generated (2026-01-15)
- is_closed_caption
- is_sdh
- raw_subtitle_content
@ -302,7 +303,8 @@ classes:
examples:
- value: true
description: Subtitle text includes speaker labels
is_auto_generated:
is_or_was_created_through: # MIGRATED: was is_auto_generated (2026-01-15)
description: Whether this subtitle was auto-generated (e.g., YouTube ASR)
range: boolean
required: false
ifabsent: 'false'

View file

@ -31,7 +31,8 @@ imports:
- ../slots/has_or_had_data_service_endpoint
- ../slots/is_or_was_aggregated_by
# aggregates_from REMOVED - migrated to aggregates_or_aggregated_from (Rule 53)
- ../slots/associated_encompassing_bodies
# associated_encompassing_bodies REMOVED - migrated to is_or_was_associated_with (Rule 53)
- ../slots/is_or_was_associated_with
- ../slots/created_by_project
- ../slots/implements_auxiliary_platform
- ../slots/implements_digital_platform
@ -57,7 +58,7 @@ imports:
- ./SpecificityAnnotation
- ./TemplateSpecificityScores
- ../slots/aggregates_or_aggregated_from
- ../slots/has_or_had_associated_encompassing_body
# has_or_had_associated_encompassing_body REMOVED - replaced by generic is_or_was_associated_with (Rule 53)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
@ -134,7 +135,8 @@ classes:
# aggregates_from REMOVED - use aggregates_or_aggregated_from (Rule 53)
- aggregates_or_aggregated_from
- has_or_had_api_endpoint
- associated_encompassing_bodies
# associated_encompassing_bodies REMOVED - use is_or_was_associated_with (Rule 53)
- is_or_was_associated_with
- created_by_project
- data_license_policy
- has_or_had_data_service_endpoint
@ -343,7 +345,11 @@ classes:
examples:
- value: https://nde.nl/ontology/hc/project/nde/nde-portal-development-2023
description: NDE Portal Development project that created this portal
has_or_had_associated_encompassing_body:
is_or_was_associated_with:
description: >-
MIGRATED from associated_encompassing_bodies and has_or_had_associated_encompassing_body (Rule 53).
EncompassingBody organizations associated with this portal beyond the operator.
Range narrowed to uriorcurie for EncompassingBody references.
range: uriorcurie
multivalued: true
inlined_as_list: true
@ -400,7 +406,7 @@ classes:
- Track lifecycle with portal_status and successor_portal
- 'NEW: data_license_policy links to portal''s licensing stance (CC0, CC-BY, etc.)'
- 'NEW: created_by_project links to Project that built the portal'
- 'NEW: associated_encompassing_bodies for organizational relationships beyond operator'
- 'NEW: is_or_was_associated_with for organizational relationships beyond operator (migrated from associated_encompassing_bodies)'
- 'NEW: implements_digital_platform links to aggregated DigitalPlatform instances'
- 'NEW: implements_auxiliary_platform links to subordinate AuxiliaryDigitalPlatform instances'
- 'FUNDING: For funding relationships, link FundingOrganisation → Project → WebPortal (not direct)'
@ -502,7 +508,7 @@ classes:
project_period:
begin_of_the_begin: '2015-01-01'
end_of_the_end: '2025-12-31'
has_or_had_associated_encompassing_body:
is_or_was_associated_with:
- https://nde.nl/ontology/hc/encompassing-body/government/european-commission
- https://nde.nl/ontology/hc/encompassing-body/network/europeana-foundation
- https://nde.nl/ontology/hc/encompassing-body/consortium/europeana-network-association

View file

@ -0,0 +1,50 @@
id: https://nde.nl/ontology/hc/slot/has_or_had_documentation
name: has_or_had_documentation_slot
title: Has Or Had Documentation Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcterms: http://purl.org/dc/terms/
doap: http://usefulinc.com/ns/doap#
imports:
- linkml:types
default_prefix: hc
slots:
has_or_had_documentation:
description: >-
Links to documentation resources for a service, API, platform, or system.
**SEMANTIC PATTERN**:
This slot follows the RiC-O temporal predicate pattern (has_or_had_*)
to indicate that documentation may change over time (versioned docs,
deprecated documentation, etc.).
**REPLACES**:
- `api_documentation` - URL to API documentation
- Other domain-specific documentation URL slots
**RANGE OPTIONS**:
- uri: Simple URL to documentation
- Documentation: Structured documentation with metadata
Classes should use slot_usage to specify appropriate range.
slot_uri: schema:documentation
range: uri
multivalued: true
exact_mappings:
- schema:documentation
close_mappings:
- doap:homepage
- dcterms:references
related_mappings:
- doap:wiki
examples:
- value: "https://data.rijksmuseum.nl/object-metadata/api/"
description: API documentation URL
- value: "https://manual.collectiveaccess.org/"
description: CMS documentation URL

View file

@ -0,0 +1,47 @@
id: https://nde.nl/ontology/hc/slot/is_or_was_associated_with
name: is_or_was_associated_with_slot
title: Is Or Was Associated With Slot
prefixes:
hc: https://nde.nl/ontology/hc/
linkml: https://w3id.org/linkml/
org: http://www.w3.org/ns/org#
prov: http://www.w3.org/ns/prov#
schema: http://schema.org/
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_associated_with:
description: >-
Generic slot expressing a temporal association relationship between entities.
This is a GENERIC slot following RiC-O naming conventions (Rule 39).
The range should be narrowed via slot_usage in class definitions to
the specific entity type being associated (EncompassingBody, Taxon, etc.).
**ONTOLOGY ALIGNMENT**:
- W3C Org: `org:linkedTo` - organizational linkage
- PROV-O: `prov:wasAssociatedWith` - activity/agent association
- Schema.org: `schema:memberOf` - membership relationships
**TEMPORAL SEMANTICS**:
The "is_or_was" pattern indicates this association may be:
- Current (is associated with)
- Historical (was associated with)
- Both (relationship changed over time)
Use slot_usage to narrow range and add temporal tracking if needed.
range: string
multivalued: true
slot_uri: org:linkedTo
exact_mappings:
- org:linkedTo
close_mappings:
- prov:wasAssociatedWith
- schema:memberOf
annotations:
custodian_types: '["*"]'
custodian_types_rationale: Generic association slot applicable to all heritage custodian types.
custodian_types_primary: M
specificity_score: 0.3
specificity_rationale: Generic relational slot - broadly applicable across many contexts.

View file

@ -0,0 +1,46 @@
id: https://nde.nl/ontology/hc/slot/is_or_was_available
name: is_or_was_available_slot
title: Is Or Was Available Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
dcat: http://www.w3.org/ns/dcat#
dcterms: http://purl.org/dc/terms/
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_available:
description: >-
Indicates whether a resource, service, or feature is or was available.
**SEMANTIC PATTERN**:
This slot follows the RiC-O temporal predicate pattern (is_or_was_*)
to indicate that availability may change over time.
**REPLACES**:
- `api_available` - Whether a CMS has API access available
- Other domain-specific availability boolean flags
**RANGE OPTIONS**:
- boolean: Simple true/false availability
- AvailabilityStatus: Structured availability with temporal validity
Classes should use slot_usage to specify appropriate range.
slot_uri: schema:availability
range: boolean
exact_mappings:
- schema:availability
close_mappings:
- dcterms:available
- dcat:servesDataset
examples:
- value: true
description: API is available
- value: false
description: API is not available

View file

@ -0,0 +1,54 @@
id: https://nde.nl/ontology/hc/slot/is_or_was_created_through
name: is_or_was_created_through_slot
title: Is Or Was Created Through Slot
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
prov: http://www.w3.org/ns/prov#
schema: http://schema.org/
imports:
- linkml:types
default_prefix: hc
slots:
is_or_was_created_through:
description: >-
Indicates how content was created - manually or through automatic generation.
**SEMANTIC PATTERN**:
This slot follows the RiC-O temporal predicate pattern (is_or_was_*)
to indicate that creation method is a historical fact that may be
relevant for provenance and quality assessment.
**REPLACES**:
- `auto_generated` - Boolean flag for automatic generation
- `is_auto_generated` - Similar boolean flag
**RANGE OPTIONS**:
- boolean: Simple true/false for auto-generated (backwards compatible)
- AutoGeneration: Structured generation method with provenance
Classes should use slot_usage to specify appropriate range.
**PROVENANCE CONTEXT**:
Auto-generated content often has different quality characteristics:
- ASR subtitles may have transcription errors
- AI chapters may have generic titles
- ML metadata may require human review
slot_uri: prov:wasGeneratedBy
range: boolean
exact_mappings:
- prov:wasGeneratedBy
close_mappings:
- schema:creator
related_mappings:
- prov:Activity
examples:
- value: true
description: Content was auto-generated
- value: false
description: Content was manually created

View file

@ -14,7 +14,6 @@
"api_available.yaml",
"api_documentation.yaml",
"applies_to_call.yaml",
"appointment_required.yaml",
"approved_by.yaml",
"approximate.yaml",
"archive_branches.yaml",
@ -23,10 +22,7 @@
"area_hectares.yaml",
"arrangement_notes.yaml",
"asserted_by.yaml",
"associated_encompassing_bodies.yaml",
"associated_taxa.yaml",
"audio_event_segments.yaml",
"authentication_required.yaml",
"authors.yaml",
"auto_generated.yaml",
"auxiliary_places.yaml",
@ -64,9 +60,7 @@
"branch_office_name.yaml",
"branch_service_area.yaml",
"branch_staff_count.yaml",
"broader_concept.yaml",
"broader_concept_label.yaml",
"broader_type.yaml",
"budget_currency.yaml",
"budget_description.yaml",
"budget_name.yaml",
@ -706,7 +700,6 @@
"has_applicable_country.yaml",
"has_application_deadline.yaml",
"has_application_opening_date.yaml",
"has_appointment_required_flag.yaml",
"has_appraisal_note.yaml",
"has_approval_date.yaml",
"has_archdiocese_name.yaml",
@ -741,7 +734,6 @@
"has_audit_date.yaml",
"has_audit_opinion.yaml",
"has_auditor_name.yaml",
"has_authentication_required_flag.yaml",
"has_author.yaml",
"has_authority_file_abbreviation.yaml",
"has_authority_file_name.yaml",
@ -835,7 +827,6 @@
"has_or_had_associated_auxiliary_platform.yaml",
"has_or_had_associated_custodian.yaml",
"has_or_had_associated_digital_platform.yaml",
"has_or_had_associated_encompassing_body.yaml",
"has_or_had_audience_size.yaml",
"has_or_had_audit_status.yaml",
"has_or_had_based_on_observation.yaml",
@ -1095,6 +1086,7 @@
"is_or_was_also_allocation_agency.yaml",
"is_or_was_archive_department_of.yaml",
"is_or_was_archived_in.yaml",
"is_or_was_associated_with.yaml",
"is_or_was_collection_of.yaml",
"is_or_was_encompassed_by.yaml",
"is_or_was_member_of.yaml",

View file

@ -349,10 +349,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/api_available
processed:
status: false
timestamp: null
session: null
notes: "Requires AvailabilityStatus class creation"
status: true
timestamp: '2026-01-15T12:00:00Z'
session: "session-2026-01-15-availability-migration"
notes: "FULLY MIGRATED: CollectionManagementSystem - api_available and has_api_available_flag REMOVED, using is_or_was_available. Created AvailabilityStatus class. Both slots archived to archive/."
revision:
- label: is_or_was_available
type: slot
@ -361,10 +361,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/api_documentation
processed:
status: false
timestamp: null
session: null
notes: "Requires Documentation class creation"
status: true
timestamp: '2026-01-15T12:15:00Z'
session: "session-2026-01-15-documentation-migration"
notes: "FULLY MIGRATED: AuxiliaryDigitalPlatform - api_documentation and has_api_documentation_url REMOVED, using has_or_had_documentation. Created Documentation class. Both slots archived to archive/."
revision:
- label: has_or_had_documentation
type: slot
@ -373,15 +373,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/applicable_countries
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Country class"
status: true
timestamp: "2026-01-15T00:00:00Z"
session: "slot-migration-session-20260115"
notes: "Migrated to has_applicable_country in CustodianType.yaml. Slot uses schema:areaServed URI. Archived applicable_countries.yaml."
revision:
- label: is_or_was_applicable_in
- label: has_applicable_country
type: slot
- label: Country
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/applies_to_call
processed:
@ -401,15 +399,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/appointment_required
processed:
status: false
timestamp: null
session: null
notes: "Requires RequirementStatus class creation"
status: true
timestamp: "2026-01-15T00:00:00Z"
session: "slot-migration-session-20260115"
notes: "Migrated to is_or_was_required in AccessPolicy.yaml. Archived appointment_required.yaml and has_appointment_required_flag.yaml."
revision:
- label: is_or_was_required
type: slot
- label: RequirementStatus
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/appraisal_notes
processed:
@ -517,10 +513,15 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/associated_encompassing_bodies
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing EncompassingBody class"
status: true
timestamp: '2026-01-14T22:00:00Z'
session: "session-2026-01-14-association-migration"
notes: >-
FULLY MIGRATED: WebPortal - associated_encompassing_bodies REMOVED.
Created generic is_or_was_associated_with slot per slot_fixes.yaml revision.
Also archived bespoke has_or_had_associated_encompassing_body slot that
was incorrectly created previously. WebPortal now uses is_or_was_associated_with
with range narrowed to uriorcurie via slot_usage (Rule 53).
revision:
- label: is_or_was_associated_with
type: slot
@ -529,10 +530,14 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/associated_taxa
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Taxon class"
status: true
timestamp: '2026-01-14T22:45:00Z'
session: "session-2026-01-14-association-migration"
notes: >-
FULLY MIGRATED: BiologicalObject - associated_taxa REMOVED.
Replaced with is_or_was_associated_with slot (created this session).
Created Taxon class (schema:Taxon alignment) for range narrowing.
Slot archived to modules/slots/archive/associated_taxa_archived_20260114.yaml (Rule 53).
revision:
- label: is_or_was_associated_with
type: slot
@ -553,10 +558,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/authentication_required
processed:
status: false
timestamp: null
session: null
notes: "Maps to RequirementStatus class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to is_or_was_required. DataServiceEndpoint.yaml updated with new import and slot. FileAPI.yaml import removed (inherits from DataServiceEndpoint). DataServiceEndpointType.yaml example updated. Slot archived to modules/slots/archive/authentication_required_archived_20260115.yaml."
revision:
- label: is_or_was_required
type: slot
@ -577,10 +582,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/auto_generated
processed:
status: false
timestamp: null
session: null
notes: "Requires AutoGeneration class creation"
status: true
timestamp: '2026-01-15T12:30:00Z'
session: "session-2026-01-15-autogeneration-migration"
notes: "FULLY MIGRATED: VideoSubtitle + VideoChapter - auto_generated and is_auto_generated REMOVED, using is_or_was_created_through. Created AutoGeneration class. Both slots archived to archive/."
revision:
- label: is_or_was_created_through
type: slot
@ -750,10 +755,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/binding_description
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Description class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_description. Binding.yaml updated with slot_usage. Slot archived to modules/slots/archive/binding_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -762,10 +767,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/binding_provenance
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Provenance class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_provenance. Binding.yaml updated with slot_usage. Slot archived to modules/slots/archive/binding_provenance_archived_20260115.yaml."
revision:
- label: has_or_had_provenance
type: slot
@ -938,10 +943,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_description
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Description class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_description. OrganizationBranch.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -962,10 +967,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_id
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Identifier class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_identifier. OrganizationBranch.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_id_archived_20260115.yaml."
revision:
- label: has_or_had_identifier
type: slot
@ -974,10 +979,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_name
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Label class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_label. OrganizationBranch.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_name_archived_20260115.yaml."
revision:
- label: has_or_had_label
type: slot
@ -986,10 +991,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_office_description
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Description class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_description. BranchOffice.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_office_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -998,10 +1003,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_office_id
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Identifier class"
status: true
timestamp: '2026-01-14T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_identifier. BranchOffice.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_office_id_archived_20260114.yaml."
revision:
- label: has_or_had_identifier
type: slot
@ -1010,10 +1015,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/branch_office_name
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Label class"
status: true
timestamp: '2026-01-14T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_label. BranchOffice.yaml updated with slot_usage. Slot archived to modules/slots/archive/branch_office_name_archived_20260114.yaml."
revision:
- label: has_or_had_label
type: slot
@ -1062,10 +1067,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/broader_concept
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Hypernym/has_or_had_hypernym slot"
status: true
timestamp: '2026-01-14T22:30:00Z'
session: "session-2026-01-14-hypernym-migration"
notes: >-
FULLY MIGRATED: AcademicArchive - broader_concept REMOVED.
Replaced with existing has_or_had_hypernym slot (Rule 53).
Slot archived to modules/slots/archive/broader_concept_archived_20260114.yaml.
revision:
- label: has_or_had_hypernym
type: slot
@ -1074,10 +1082,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/broader_concept_label
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Label class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_label. AcademicArchive.yaml updated with slot_usage. Slot archived to modules/slots/archive/broader_concept_label_archived_20260115.yaml."
revision:
- label: has_or_had_label
type: slot
@ -1086,10 +1094,13 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/broader_type
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Hypernym/has_or_had_hypernym slot"
status: true
timestamp: '2026-01-14T22:30:00Z'
session: "session-2026-01-14-hypernym-migration"
notes: >-
FULLY MIGRATED: FindingAidType - broader_type REMOVED.
Replaced with existing has_or_had_hypernym slot (Rule 53).
Slot archived to modules/slots/archive/broader_type_archived_20260114.yaml.
revision:
- label: has_or_had_hypernym
type: slot
@ -1134,10 +1145,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/budget_description
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Description class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_description. Budget.yaml updated with slot_usage. Slot archived to modules/slots/archive/budget_description_archived_20260115.yaml."
revision:
- label: has_or_had_description
type: slot
@ -1146,10 +1157,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/budget_name
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Label class"
status: true
timestamp: '2026-01-15T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_label. Budget.yaml updated with slot_usage. Slot archived to modules/slots/archive/budget_name_archived_20260115.yaml."
revision:
- label: has_or_had_label
type: slot
@ -1242,10 +1253,10 @@ fixes:
- original_slot_id: https://nde.nl/ontology/hc/slot/cadastral_id
processed:
status: false
timestamp: null
session: null
notes: "Maps to existing Identifier class"
status: true
timestamp: '2026-01-14T00:00:00Z'
session: "session-2026-01-14-identifier-migrations"
notes: "COMPLETE: Migrated to has_or_had_identifier. CadastralProperty.yaml updated with slot_usage. Slot archived to modules/slots/archive/cadastral_id_archived_20260114.yaml."
revision:
- label: has_or_had_identifier
type: slot
@ -1253,47 +1264,47 @@ fixes:
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/accepts_or_accepted_external_work
revision:
- label: accepts_or_accepted
type: slot
- label: ExternalWork
type: class
- label: accepts_or_accepted
type: slot
- label: ExternalWork
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/accepts_or_accepted_payment_method
revision:
- label: accepts_or_accepted
type: slot
- label: PaymentMethod
type: class
- label: accepts_or_accepted
type: slot
- label: PaymentMethod
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/accepts_or_accepted_visiting_scholar
revision:
- label: accepts_or_accepted
type: slot
- label: VisitingScholar
type: class
- label: accepts_or_accepted
type: slot
- label: VisitingScholar
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/zone_name
revision:
- label: has_or_had_label
type: slot
- label: Label
type: class
- label: has_or_had_label
type: slot
- label: Label
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/zone_id
revision:
- label: has_or_had_identifier
type: slot
- label: Identifier
type: class
- label: has_or_had_identifier
type: slot
- label: Identifier
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/zone_description
revision:
- label: has_or_had_description
type: slot
- label: Description
type: class
- label: has_or_had_description
type: slot
- label: Description
type: class
- original_slot_id: https://nde.nl/ontology/hc/slot/years_restricted
revision:
- label: has_or_had_restriction
type: slot
type: slot
- label: Restriction
type: class
- label: temporal_extent
type: slot
- label: TimeSpan
type: class
type: class
- label: temporal_extent
type: slot
- label: TimeSpan
type: class

View file

@ -33,6 +33,11 @@ from pydantic import BaseModel
LINKUP_API_KEY = os.getenv("LINKUP_API_KEY", "")
LINKUP_API_URL = "https://api.linkup.so/v1/search"
# Exa API configuration for LinkedIn profile extraction
EXA_API_KEY = os.getenv("EXA_API_KEY", "")
EXA_API_URL = "https://api.exa.ai/contents"
ENTITY_DIR = Path(os.getenv("ENTITY_DIR", "/Users/kempersc/apps/glam/data/custodian/person/entity"))
# Email semantics for on-demand analysis
try:
from glam_extractor.entity_resolution.email_semantics import parse_email_semantics
@ -1069,6 +1074,245 @@ async def linkup_search(request: LinkupSearchRequest):
)
# ============================================================================
# LinkedIn Profile Extraction via Exa API
# ============================================================================
import re as regex_module # Avoid shadowing
async def fetch_linkedin_profile_exa(linkedin_url: str) -> Optional[dict]:
"""
Fetch LinkedIn profile data using Exa Contents API.
Returns parsed profile data or None if extraction fails.
"""
if not EXA_API_KEY:
return None
try:
async with httpx.AsyncClient() as client:
response = await client.post(
EXA_API_URL,
headers={
"Authorization": f"Bearer {EXA_API_KEY}",
"Content-Type": "application/json",
},
json={
"ids": [linkedin_url],
"text": True,
"livecrawl": "fallback"
},
timeout=60.0
)
if response.status_code != 200:
print(f"Exa API error: HTTP {response.status_code}")
return None
data = response.json()
if not data.get('results') or len(data['results']) == 0:
return None
result = data['results'][0]
return {
'raw_result': result,
'request_id': data.get('requestId', ''),
'cost': data.get('costDollars', {}).get('total', 0)
}
except Exception as e:
print(f"Exa API exception: {e}")
return None
def parse_linkedin_profile_from_exa(raw_data: dict) -> dict:
"""Parse Exa response into structured profile data."""
result = raw_data.get('raw_result', {})
text = result.get('text', '')
profile_data = {
"name": result.get('author', ''),
"linkedin_url": result.get('url', ''),
"headline": "",
"location": "",
"connections": "",
"about": "",
"experience": [],
"education": [],
"skills": [],
"languages": [],
"profile_image_url": result.get('image', '')
}
# Parse headline from title
title = result.get('title', '')
if '|' in title:
profile_data['headline'] = title.split('|')[1].strip()
elif title:
profile_data['headline'] = title.replace(profile_data['name'], '').strip(' |')
# Parse sections from text
lines = text.split('\n')
current_section = None
current_item = {}
for line in lines:
line = line.strip()
if not line:
continue
# Section headers
if line.startswith('## About'):
current_section = 'about'
continue
elif line.startswith('## Experience'):
current_section = 'experience'
continue
elif line.startswith('## Education'):
current_section = 'education'
continue
elif line.startswith('## Skills'):
current_section = 'skills'
continue
elif line.startswith('## Languages'):
current_section = 'languages'
continue
elif line.startswith('## '):
current_section = None
continue
# Parse location and connections
if 'connections' in line.lower() and 'followers' in line.lower():
profile_data['connections'] = line
continue
if regex_module.match(r'^[A-Za-z\s,]+\s*\([A-Z]{2}\)$', line):
profile_data['location'] = line
continue
# Parse content based on section
if current_section == 'about':
if not profile_data['about']:
profile_data['about'] = line
else:
profile_data['about'] += ' ' + line
elif current_section == 'experience':
if line.startswith('### '):
if current_item and current_item.get('title'):
profile_data['experience'].append(current_item)
exp_text = line[4:]
if ' at ' in exp_text:
parts = exp_text.split(' at ', 1)
exp_title = parts[0].strip()
company_part = parts[1].strip()
company_match = regex_module.search(r'\[([^\]]+)\]', company_part)
company = company_match.group(1) if company_match else company_part
current_item = {'title': exp_title, 'company': company}
else:
current_item = {'title': exp_text}
elif current_item and ' - ' in line and ('Present' in line or regex_module.search(r'\d{4}', line)):
current_item['date_range'] = line
elif current_item and line and not line.startswith('Company:') and not line.startswith('Department:'):
if 'location' not in current_item and regex_module.match(r'^[A-Za-z\s,\-]+$', line):
current_item['location'] = line
elif 'description' not in current_item:
current_item['description'] = line
elif current_section == 'education':
if line.startswith('### '):
if current_item and current_item.get('institution'):
profile_data['education'].append(current_item)
edu_text = line[4:]
if ' at ' in edu_text:
parts = edu_text.split(' at ', 1)
degree = parts[0].strip()
inst_part = parts[1].strip()
inst_match = regex_module.search(r'\[([^\]]+)\]', inst_part)
institution = inst_match.group(1) if inst_match else inst_part
current_item = {'degree': degree, 'institution': institution}
else:
inst_match = regex_module.search(r'\[([^\]]+)\]', edu_text)
current_item = {'institution': inst_match.group(1) if inst_match else edu_text}
elif current_item and regex_module.match(r'^\d{4}\s*-\s*\d{4}', line):
current_item['date_range'] = line
elif current_section == 'skills':
skills = [s.strip() for s in regex_module.split(r'[•,]', line) if s.strip()]
profile_data['skills'].extend(skills)
elif current_section == 'languages':
lang_match = regex_module.match(r'^([A-Za-z\s]+)\s*-\s*(.+)$', line)
if lang_match:
profile_data['languages'].append({
'language': lang_match.group(1).strip(),
'proficiency': lang_match.group(2).strip()
})
# Save last items
if current_section == 'experience' and current_item and current_item.get('title'):
profile_data['experience'].append(current_item)
if current_section == 'education' and current_item and current_item.get('institution'):
profile_data['education'].append(current_item)
return profile_data
async def save_entity_profile(
linkedin_slug: str,
profile_data: dict,
raw_response: dict,
source_info: dict
) -> Optional[str]:
"""
Save extracted LinkedIn profile as an entity file.
Returns the filepath if saved, None if failed.
"""
try:
# Ensure entity directory exists
ENTITY_DIR.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
filename = f"{linkedin_slug}_{timestamp}.json"
filepath = ENTITY_DIR / filename
entity_data = {
"extraction_metadata": {
"source_file": "manual_add_candidate",
"staff_id": f"manual_add_{linkedin_slug}",
"extraction_date": datetime.now(timezone.utc).isoformat(),
"extraction_method": "exa_contents",
"extraction_agent": "entity_review_api",
"linkedin_url": source_info.get('linkedin_url', ''),
"cost_usd": raw_response.get('cost', 0),
"request_id": raw_response.get('request_id', '')
},
"source_staff_info": {
"name": source_info.get('wcms_name', ''),
"headline": profile_data.get('headline', ''),
"heritage_type": None,
"custodian": source_info.get('wcms_institution', '')
},
"profile_data": profile_data,
"heritage_relevance": {
"is_heritage_relevant": None, # To be determined during review
"heritage_types": [],
"rationale": "Manually added candidate - heritage relevance to be determined"
}
}
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(entity_data, f, indent=2, ensure_ascii=False)
return str(filepath)
except Exception as e:
print(f"Error saving entity profile: {e}")
return None
@router.post("/add-candidate", response_model=AddCandidateResponse)
async def add_manual_candidate(request: AddCandidateRequest):
"""
@ -1112,6 +1356,26 @@ async def add_manual_candidate(request: AddCandidateRequest):
message=f"Candidate {linkedin_slug} already exists for this profile"
)
# Fetch LinkedIn profile using Exa API (if available)
linkedin_url = f"https://www.linkedin.com/in/{linkedin_slug}"
profile_data = None
entity_filepath = None
exa_response = None
if EXA_API_KEY:
exa_response = await fetch_linkedin_profile_exa(linkedin_url)
if exa_response:
profile_data = parse_linkedin_profile_from_exa(exa_response)
# Save entity profile file
source_info = {
'linkedin_url': linkedin_url,
'wcms_name': wcms_data.get('wcms_name', ''),
'wcms_institution': wcms_data.get('wcms_email_domain', '')
}
entity_filepath = await save_entity_profile(
linkedin_slug, profile_data, exa_response, source_info
)
# Generate a PPID for the LinkedIn candidate
# Format: ID_XX-XX-XXX_XXXX_XX-XX-XXX_XXXX_NAME-SLUG
name_part = linkedin_slug.upper().replace('-', '-')
@ -1125,13 +1389,20 @@ async def add_manual_candidate(request: AddCandidateRequest):
linkedin_ppid = f"ID_XX-XX-XXX_XXXX_XX-XX-XXX_XXXX_{name_for_ppid.upper()}"
# Derive a human-readable name from the slug
# Remove the hash suffix if present (e.g., "marijn-cornelis-meijer-09b799200" -> "Marijn Cornelis Meijer")
name_parts = linkedin_slug.rsplit('-', 1)
if len(name_parts) == 2 and len(name_parts[1]) >= 6 and name_parts[1].isalnum():
display_name = name_parts[0].replace('-', ' ').title()
# Derive a human-readable name from the slug or use fetched name
if profile_data and profile_data.get('name'):
display_name = profile_data['name']
else:
display_name = linkedin_slug.replace('-', ' ').title()
# Remove the hash suffix if present (e.g., "marijn-cornelis-meijer-09b799200" -> "Marijn Cornelis Meijer")
name_parts = linkedin_slug.rsplit('-', 1)
if len(name_parts) == 2 and len(name_parts[1]) >= 6 and name_parts[1].isalnum():
display_name = name_parts[0].replace('-', ' ').title()
else:
display_name = linkedin_slug.replace('-', ' ').title()
# Get headline from fetched profile
headline = profile_data.get('headline', '') if profile_data else ''
location = profile_data.get('location', '') if profile_data else ''
# Create the new candidate entry matching the existing format
new_candidate = {
@ -1145,14 +1416,18 @@ async def add_manual_candidate(request: AddCandidateRequest):
"display_name": display_name,
"name_romanized": None,
"name_tokens": [t.upper() for t in display_name.split()],
"source": "manual_entry"
"source": "exa_extraction" if profile_data else "manual_entry"
},
"linkedin_slug": linkedin_slug,
"linkedin_headline": headline,
"linkedin_location": location,
"linkedin_url": linkedin_url,
"entity_profile_path": entity_filepath,
"name_match_score": 0.5, # Neutral score for manual entries
"email_domain_matches_employer": False,
"employer_name_overlap": [],
"confidence_score": 0.5, # Manual entries start at 50%
"match_signals": ["manual_entry"],
"confidence_score": 0.6 if profile_data else 0.5, # Higher if we got profile data
"match_signals": ["manual_entry", "exa_profile_fetched"] if profile_data else ["manual_entry"],
"requires_review": True,
"reviewed": False,
"review_decision": None,
@ -1175,22 +1450,55 @@ async def add_manual_candidate(request: AddCandidateRequest):
"added_at": datetime.now(timezone.utc).isoformat()
}
# Add to the candidates list
# Add to the candidates list (raw format for file storage)
_candidates_cache['candidates'].append(new_candidate)
# Update the index
idx = len(_candidates_cache['candidates']) - 1
_candidates_list_index[(wcms_ppid, linkedin_ppid)] = idx
# Also add to wcms lookup
# Create the transformed format for the cache (matching load_candidates transform)
candidate_for_cache = {
'linkedin_ppid': linkedin_ppid,
'linkedin_name': display_name, # String format for API responses
'linkedin_slug': linkedin_slug,
'linkedin_headline': headline,
'linkedin_location': location,
'linkedin_url': linkedin_url,
'entity_profile_path': entity_filepath,
'confidence_score': 0.6 if profile_data else 0.5,
'match_signals': ["manual_entry", "exa_profile_fetched"] if profile_data else ["manual_entry"],
'name_match_score': 0.5,
'email_domain_matches_employer': False,
'employer_name_overlap': [],
'reviewed': False,
'review_decision': None,
'reviewed_by': None,
'reviewed_at': None,
'review_notes': None,
'email_birth_year': None,
'email_birth_year_confidence': 0.0,
'email_name_components': [],
'email_name_matches_profile': False,
'email_institution_name': None,
'email_institution_type': None,
'email_is_institutional': False,
'is_likely_wrong_person': False,
'wrong_person_reason': None,
'confidence_original': None,
}
# Also add to wcms lookup (transformed format)
if wcms_ppid in _candidates_by_wcms:
_candidates_by_wcms[wcms_ppid]['candidates'].append(new_candidate)
_candidates_by_wcms[wcms_ppid]['candidates'].append(candidate_for_cache)
# Add to linkedin lookup
if _candidates_by_linkedin is not None:
_candidates_by_linkedin[linkedin_ppid] = {
'linkedin_ppid': linkedin_ppid,
'linkedin_name': display_name,
'linkedin_slug': linkedin_slug,
'linkedin_headline': headline,
'linkedin_name_raw': new_candidate['linkedin_name']
}
@ -1205,9 +1513,15 @@ async def add_manual_candidate(request: AddCandidateRequest):
invalidate_cache()
raise HTTPException(status_code=500, detail="Failed to save candidate")
# Build response message
if profile_data:
message = f"Added {linkedin_slug} with profile data ({headline[:50]}...) as a candidate for {wcms_data.get('wcms_name', wcms_ppid)}"
else:
message = f"Added {linkedin_slug} as a candidate for {wcms_data.get('wcms_name', wcms_ppid)} (profile fetch unavailable)"
return AddCandidateResponse(
success=True,
message=f"Added {linkedin_slug} as a candidate for {wcms_data.get('wcms_name', wcms_ppid)}",
message=message,
linkedin_ppid=linkedin_ppid
)