diff --git a/frontend/public/schemas/20251121/linkml/manifest.json b/frontend/public/schemas/20251121/linkml/manifest.json index 9a5f8ce677..c5dcf2c5a3 100644 --- a/frontend/public/schemas/20251121/linkml/manifest.json +++ b/frontend/public/schemas/20251121/linkml/manifest.json @@ -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", diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml index ed70bcb741..ce54c268f1 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/AccessPolicy.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/AccessPolicy.yaml index 1ad6124d47..19d3506077 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/AccessPolicy.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/AccessPolicy.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/AutoGeneration.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/AutoGeneration.yaml new file mode 100644 index 0000000000..7ed12e8104 --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/classes/AutoGeneration.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml index 28971cdef1..5a2e139d34 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/AvailabilityStatus.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/AvailabilityStatus.yaml new file mode 100644 index 0000000000..4a007d8834 --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/classes/AvailabilityStatus.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/Budget.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/Budget.yaml index 8d78730891..e9811238ef 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/Budget.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/Budget.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml index 4ccc4ae360..f644c5bc27 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/CollectionType.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/CollectionType.yaml index b203de00f3..c3af6e1db2 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/CollectionType.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/CollectionType.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/CurationActivity.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/CurationActivity.yaml index 9098d010a7..b5ea1d8af9 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/CurationActivity.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/CurationActivity.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/CustodianAdministration.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/CustodianAdministration.yaml index c4a6e641e7..c5a4aa4e58 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/CustodianAdministration.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/CustodianAdministration.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/CustodianType.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/CustodianType.yaml index 09e7704e69..836db87c5f 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/CustodianType.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/CustodianType.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpoint.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpoint.yaml index bd3da4c9b2..bd4e49b09c 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpoint.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpoint.yaml @@ -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\"\ diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml index b82ed3398c..269458980f 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml @@ -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\ diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/Documentation.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/Documentation.yaml new file mode 100644 index 0000000000..6d494aa4a1 --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/classes/Documentation.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/EducationCenter.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/EducationCenter.yaml index f5a9b65647..91b6e6f94f 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/EducationCenter.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/EducationCenter.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/ExhibitionCatalog.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/ExhibitionCatalog.yaml index 1ce495e42e..5487267fc1 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/ExhibitionCatalog.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/ExhibitionCatalog.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/FileAPI.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/FileAPI.yaml index c3458ff062..baf6eb0f9f 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/FileAPI.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/FileAPI.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/FindingAidType.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/FindingAidType.yaml index e102bdee97..8803dc0ad9 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/FindingAidType.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/FindingAidType.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/InformationCarrier.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/InformationCarrier.yaml index b7af166a4b..e6cc7f7a77 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/InformationCarrier.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/InformationCarrier.yaml @@ -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. diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/OrganizationBranch.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/OrganizationBranch.yaml index e4ca0e9f0d..b4b36973bf 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/OrganizationBranch.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/OrganizationBranch.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/RequirementStatus.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/RequirementStatus.yaml new file mode 100644 index 0000000000..4388ad1e6a --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/classes/RequirementStatus.yaml @@ -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) diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml index e2183e212a..da273b768f 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml @@ -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' diff --git a/frontend/public/schemas/20251121/linkml/modules/classes/WebPortal.yaml b/frontend/public/schemas/20251121/linkml/modules/classes/WebPortal.yaml index c364ed82c8..b1f841d898 100644 --- a/frontend/public/schemas/20251121/linkml/modules/classes/WebPortal.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/classes/WebPortal.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/api_available.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/api_available_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/api_available.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/api_available_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/api_documentation.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/api_documentation_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/api_documentation.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/api_documentation_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/applicable_countries.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/applicable_countries_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/applicable_countries.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/applicable_countries_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/appointment_required.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/appointment_required_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/appointment_required.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/appointment_required_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/associated_encompassing_bodies.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/associated_encompassing_bodies_archived_20260114.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/associated_encompassing_bodies.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/associated_encompassing_bodies_archived_20260114.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/authentication_required.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/authentication_required_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/authentication_required.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/authentication_required_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/backup_status.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/backup_status_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/backup_status.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/backup_status_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/bibframe_equivalent.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/bibframe_equivalent_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/bibframe_equivalent.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/bibframe_equivalent_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/binding.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/binding_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/binding.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/binding_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/binding_description.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/binding_description_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/binding_description.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/binding_description_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/booking_required.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/booking_required_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/booking_required.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/booking_required_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/branch_description.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/branch_description_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/branch_description.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/branch_description_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/broader_concept.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/broader_concept_archived_20260114.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/broader_concept.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/broader_concept_archived_20260114.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/broader_concept_label.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/broader_concept_label_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/broader_concept_label.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/broader_concept_label_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/broader_type.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/broader_type_archived_20260114.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/broader_type.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/broader_type_archived_20260114.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/budget.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/budget_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/budget.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/budget_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/budget_description.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/budget_description_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/budget_description.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/budget_description_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/budget_name.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/budget_name_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/budget_name.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/budget_name_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/has_api_available_flag.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/has_api_available_flag_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/has_api_available_flag.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/has_api_available_flag_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/has_api_documentation_url.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/has_api_documentation_url_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/has_api_documentation_url.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/has_api_documentation_url_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/has_appointment_required_flag.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/has_appointment_required_flag_archived_20260115.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/has_appointment_required_flag.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/has_appointment_required_flag_archived_20260115.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/has_or_had_associated_encompassing_body.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/archive/has_or_had_associated_encompassing_body_archived_20260114.yaml similarity index 100% rename from frontend/public/schemas/20251121/linkml/modules/slots/has_or_had_associated_encompassing_body.yaml rename to frontend/public/schemas/20251121/linkml/modules/slots/archive/has_or_had_associated_encompassing_body_archived_20260114.yaml diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/has_or_had_documentation.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/has_or_had_documentation.yaml new file mode 100644 index 0000000000..982184e494 --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/slots/has_or_had_documentation.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_allocated_budget.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_allocated_budget.yaml new file mode 100644 index 0000000000..b9a6225f2b --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_allocated_budget.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_associated_with.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_associated_with.yaml new file mode 100644 index 0000000000..ea758b5a14 --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_associated_with.yaml @@ -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. diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_available.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_available.yaml new file mode 100644 index 0000000000..2fa24d994b --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_available.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_created_through.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_created_through.yaml new file mode 100644 index 0000000000..c7e7de5605 --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_created_through.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_required.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_required.yaml new file mode 100644 index 0000000000..7e507d81dd --- /dev/null +++ b/frontend/public/schemas/20251121/linkml/modules/slots/is_or_was_required.yaml @@ -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 diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/manifest.json b/frontend/public/schemas/20251121/linkml/modules/slots/manifest.json index e3059d60bb..55929a803a 100644 --- a/frontend/public/schemas/20251121/linkml/modules/slots/manifest.json +++ b/frontend/public/schemas/20251121/linkml/modules/slots/manifest.json @@ -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", diff --git a/frontend/public/schemas/20251121/linkml/modules/slots/slot_fixes.yaml b/frontend/public/schemas/20251121/linkml/modules/slots/slot_fixes.yaml index 75bbea72b1..b46690503f 100644 --- a/frontend/public/schemas/20251121/linkml/modules/slots/slot_fixes.yaml +++ b/frontend/public/schemas/20251121/linkml/modules/slots/slot_fixes.yaml @@ -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 diff --git a/frontend/src/lib/linkml/linkml-schema-service.ts b/frontend/src/lib/linkml/linkml-schema-service.ts index 4d38c13da2..45d058c00a 100644 --- a/frontend/src/lib/linkml/linkml-schema-service.ts +++ b/frontend/src/lib/linkml/linkml-schema-service.ts @@ -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 { + 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). diff --git a/frontend/src/pages/LinkMLViewerPage.tsx b/frontend/src/pages/LinkMLViewerPage.tsx index e17a948d3f..225e6b6545 100644 --- a/frontend/src/pages/LinkMLViewerPage.tsx +++ b/frontend/src/pages/LinkMLViewerPage.tsx @@ -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>({}); const [loadingImports, setLoadingImports] = useState>(new Set()); + // State for expandable Exports section in slot details (which classes use this slot) + const [expandedSlotExports, setExpandedSlotExports] = useState>(new Set()); + const [slotExports, setSlotExports] = useState>({}); + const [loadingSlotExports, setLoadingSlotExports] = useState>(new Set()); + // State for expandable UML diagram section in class details const [expandedUML, setExpandedUML] = useState>(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 = () => { )} + {/* Exports section - Only show for standalone slots (not within class context) */} + {!className && ( +
+ + + {expandedSlotExports.has(slot.name) && ( +
+ {loadingSlotExports.has(slot.name) ? ( +
{t('loading')}...
+ ) : slotExports[slot.name] ? ( + <> + {/* Range Type - Navigation to class/enum */} + {slotExports[slot.name].rangeType && ( +
+ {t('range')} + +
+ )} + + {/* Classes that use this slot */} + {slotExports[slot.name].classesUsingSlot.length > 0 && ( +
+ {t('classesUsingSlot')} +
+ {slotExports[slot.name].classesUsingSlot.map(cls => ( + + ))} +
+
+ )} + + {/* Classes with slot_usage overrides */} + {slotExports[slot.name].classesWithSlotUsage.length > 0 && ( +
+ {t('classesWithSlotUsage')} +
+ {slotExports[slot.name].classesWithSlotUsage.map(({ className: cls, overrides }) => ( + + ))} +
+
+ )} + + {/* Empty state */} + {slotExports[slot.name].classesUsingSlot.length === 0 && + slotExports[slot.name].classesWithSlotUsage.length === 0 && ( +
+ {t('noClassesUsingSlot')} +
+ )} + + ) : null} +
+ )} +
+ )} + {/* Side-by-side comparison view - only shown when expanded */} {showComparison && hasSlotUsageOverrides && genericSlot && (
diff --git a/schemas/20251121/linkml/manifest.json b/schemas/20251121/linkml/manifest.json index f4f9b6dac7..b51dadbc5c 100644 --- a/schemas/20251121/linkml/manifest.json +++ b/schemas/20251121/linkml/manifest.json @@ -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", diff --git a/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml b/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml index 180689599f..ce54c268f1 100644 --- a/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml +++ b/schemas/20251121/linkml/modules/classes/AcademicArchive.yaml @@ -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: >- diff --git a/schemas/20251121/linkml/modules/classes/AutoGeneration.yaml b/schemas/20251121/linkml/modules/classes/AutoGeneration.yaml new file mode 100644 index 0000000000..7ed12e8104 --- /dev/null +++ b/schemas/20251121/linkml/modules/classes/AutoGeneration.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml b/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml index 28971cdef1..5a2e139d34 100644 --- a/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml +++ b/schemas/20251121/linkml/modules/classes/AuxiliaryDigitalPlatform.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/AvailabilityStatus.yaml b/schemas/20251121/linkml/modules/classes/AvailabilityStatus.yaml new file mode 100644 index 0000000000..4a007d8834 --- /dev/null +++ b/schemas/20251121/linkml/modules/classes/AvailabilityStatus.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/BiologicalObject.yaml b/schemas/20251121/linkml/modules/classes/BiologicalObject.yaml index e1021f3ba8..3222d2f72d 100644 --- a/schemas/20251121/linkml/modules/classes/BiologicalObject.yaml +++ b/schemas/20251121/linkml/modules/classes/BiologicalObject.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml b/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml index 4ccc4ae360..f644c5bc27 100644 --- a/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml +++ b/schemas/20251121/linkml/modules/classes/CollectionManagementSystem.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml b/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml index b82ed3398c..269458980f 100644 --- a/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml +++ b/schemas/20251121/linkml/modules/classes/DataServiceEndpointType.yaml @@ -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\ diff --git a/schemas/20251121/linkml/modules/classes/Documentation.yaml b/schemas/20251121/linkml/modules/classes/Documentation.yaml new file mode 100644 index 0000000000..6d494aa4a1 --- /dev/null +++ b/schemas/20251121/linkml/modules/classes/Documentation.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/FileAPI.yaml b/schemas/20251121/linkml/modules/classes/FileAPI.yaml index c3458ff062..baf6eb0f9f 100644 --- a/schemas/20251121/linkml/modules/classes/FileAPI.yaml +++ b/schemas/20251121/linkml/modules/classes/FileAPI.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/FindingAidType.yaml b/schemas/20251121/linkml/modules/classes/FindingAidType.yaml index e102bdee97..8803dc0ad9 100644 --- a/schemas/20251121/linkml/modules/classes/FindingAidType.yaml +++ b/schemas/20251121/linkml/modules/classes/FindingAidType.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/Taxon.yaml b/schemas/20251121/linkml/modules/classes/Taxon.yaml new file mode 100644 index 0000000000..6799380edc --- /dev/null +++ b/schemas/20251121/linkml/modules/classes/Taxon.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/classes/VideoChapter.yaml b/schemas/20251121/linkml/modules/classes/VideoChapter.yaml index 0549baffe6..cf2d612a4a 100644 --- a/schemas/20251121/linkml/modules/classes/VideoChapter.yaml +++ b/schemas/20251121/linkml/modules/classes/VideoChapter.yaml @@ -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: diff --git a/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml b/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml index e2183e212a..da273b768f 100644 --- a/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml +++ b/schemas/20251121/linkml/modules/classes/VideoSubtitle.yaml @@ -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' diff --git a/schemas/20251121/linkml/modules/classes/WebPortal.yaml b/schemas/20251121/linkml/modules/classes/WebPortal.yaml index c364ed82c8..b1f841d898 100644 --- a/schemas/20251121/linkml/modules/classes/WebPortal.yaml +++ b/schemas/20251121/linkml/modules/classes/WebPortal.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/slots/api_available.yaml b/schemas/20251121/linkml/modules/slots/archive/api_available_archived_20260115.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/api_available.yaml rename to schemas/20251121/linkml/modules/slots/archive/api_available_archived_20260115.yaml diff --git a/schemas/20251121/linkml/modules/slots/api_documentation.yaml b/schemas/20251121/linkml/modules/slots/archive/api_documentation_archived_20260115.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/api_documentation.yaml rename to schemas/20251121/linkml/modules/slots/archive/api_documentation_archived_20260115.yaml diff --git a/schemas/20251121/linkml/modules/slots/associated_encompassing_bodies.yaml b/schemas/20251121/linkml/modules/slots/archive/associated_encompassing_bodies_archived_20260114.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/associated_encompassing_bodies.yaml rename to schemas/20251121/linkml/modules/slots/archive/associated_encompassing_bodies_archived_20260114.yaml diff --git a/schemas/20251121/linkml/modules/slots/associated_taxa.yaml b/schemas/20251121/linkml/modules/slots/archive/associated_taxa_archived_20260114.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/associated_taxa.yaml rename to schemas/20251121/linkml/modules/slots/archive/associated_taxa_archived_20260114.yaml diff --git a/schemas/20251121/linkml/modules/slots/authentication_required.yaml b/schemas/20251121/linkml/modules/slots/archive/authentication_required_archived_20260115.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/authentication_required.yaml rename to schemas/20251121/linkml/modules/slots/archive/authentication_required_archived_20260115.yaml diff --git a/schemas/20251121/linkml/modules/slots/auto_generated.yaml b/schemas/20251121/linkml/modules/slots/archive/auto_generated_archived_20260115.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/auto_generated.yaml rename to schemas/20251121/linkml/modules/slots/archive/auto_generated_archived_20260115.yaml diff --git a/schemas/20251121/linkml/modules/slots/broader_concept.yaml b/schemas/20251121/linkml/modules/slots/archive/broader_concept_archived_20260114.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/broader_concept.yaml rename to schemas/20251121/linkml/modules/slots/archive/broader_concept_archived_20260114.yaml diff --git a/schemas/20251121/linkml/modules/slots/broader_type.yaml b/schemas/20251121/linkml/modules/slots/archive/broader_type_archived_20260114.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/broader_type.yaml rename to schemas/20251121/linkml/modules/slots/archive/broader_type_archived_20260114.yaml diff --git a/schemas/20251121/linkml/modules/slots/has_api_available_flag.yaml b/schemas/20251121/linkml/modules/slots/archive/has_api_available_flag_archived_20260115.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/has_api_available_flag.yaml rename to schemas/20251121/linkml/modules/slots/archive/has_api_available_flag_archived_20260115.yaml diff --git a/schemas/20251121/linkml/modules/slots/has_api_documentation_url.yaml b/schemas/20251121/linkml/modules/slots/archive/has_api_documentation_url_archived_20260115.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/has_api_documentation_url.yaml rename to schemas/20251121/linkml/modules/slots/archive/has_api_documentation_url_archived_20260115.yaml diff --git a/schemas/20251121/linkml/modules/slots/has_or_had_associated_encompassing_body.yaml b/schemas/20251121/linkml/modules/slots/archive/has_or_had_associated_encompassing_body_archived_20260114.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/has_or_had_associated_encompassing_body.yaml rename to schemas/20251121/linkml/modules/slots/archive/has_or_had_associated_encompassing_body_archived_20260114.yaml diff --git a/schemas/20251121/linkml/modules/slots/is_auto_generated.yaml b/schemas/20251121/linkml/modules/slots/archive/is_auto_generated_archived_20260115.yaml similarity index 100% rename from schemas/20251121/linkml/modules/slots/is_auto_generated.yaml rename to schemas/20251121/linkml/modules/slots/archive/is_auto_generated_archived_20260115.yaml diff --git a/schemas/20251121/linkml/modules/slots/has_or_had_documentation.yaml b/schemas/20251121/linkml/modules/slots/has_or_had_documentation.yaml new file mode 100644 index 0000000000..982184e494 --- /dev/null +++ b/schemas/20251121/linkml/modules/slots/has_or_had_documentation.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/slots/is_or_was_associated_with.yaml b/schemas/20251121/linkml/modules/slots/is_or_was_associated_with.yaml new file mode 100644 index 0000000000..ea758b5a14 --- /dev/null +++ b/schemas/20251121/linkml/modules/slots/is_or_was_associated_with.yaml @@ -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. diff --git a/schemas/20251121/linkml/modules/slots/is_or_was_available.yaml b/schemas/20251121/linkml/modules/slots/is_or_was_available.yaml new file mode 100644 index 0000000000..2fa24d994b --- /dev/null +++ b/schemas/20251121/linkml/modules/slots/is_or_was_available.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/slots/is_or_was_created_through.yaml b/schemas/20251121/linkml/modules/slots/is_or_was_created_through.yaml new file mode 100644 index 0000000000..c7e7de5605 --- /dev/null +++ b/schemas/20251121/linkml/modules/slots/is_or_was_created_through.yaml @@ -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 diff --git a/schemas/20251121/linkml/modules/slots/manifest.json b/schemas/20251121/linkml/modules/slots/manifest.json index 8394823fab..527fcb7fd3 100644 --- a/schemas/20251121/linkml/modules/slots/manifest.json +++ b/schemas/20251121/linkml/modules/slots/manifest.json @@ -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", diff --git a/schemas/20251121/linkml/modules/slots/slot_fixes.yaml b/schemas/20251121/linkml/modules/slots/slot_fixes.yaml index 5abb2eacd4..0c4129cdb5 100644 --- a/schemas/20251121/linkml/modules/slots/slot_fixes.yaml +++ b/schemas/20251121/linkml/modules/slots/slot_fixes.yaml @@ -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 diff --git a/src/glam_extractor/api/entity_review.py b/src/glam_extractor/api/entity_review.py index 7ed3e5ed42..be07527427 100644 --- a/src/glam_extractor/api/entity_review.py +++ b/src/glam_extractor/api/entity_review.py @@ -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 )