From 7653d3411002203376d4b683958208e877e636f6 Mon Sep 17 00:00:00 2001 From: Egor Yakovlev Date: Sun, 11 Oct 2026 18:08:45 +0200 Subject: [PATCH] Register soil import ontologies and document payload relationships --- .../Infrastructure/SoilImportOntologies.md | 68 ++++++++++ .../ontology/schemas/soilImportBundle.json | 118 ++++++++++++++++++ .../ontology/schemas/soilInterpretation.json | 47 +++++++ services/ontology/schemas/soilLabReport.json | 79 ++++++++++++ services/ontology/schemas/soilMethod.json | 39 ++++++ .../ontology/schemas/soilObservation.json | 105 ++++++++++++++++ services/ontology/schemas/soilParty.json | 62 +++++++++ .../ontology/schemas/soilRecommendation.json | 57 +++++++++ services/ontology/schemas/soilSample.json | 79 ++++++++++++ .../ontology/schemas/soilSampledObject.json | 59 +++++++++ .../ontology/schemas/soilSamplingEvent.json | 49 ++++++++ 11 files changed, 762 insertions(+) create mode 100644 docs/docs/Infrastructure/SoilImportOntologies.md create mode 100644 services/ontology/schemas/soilImportBundle.json create mode 100644 services/ontology/schemas/soilInterpretation.json create mode 100644 services/ontology/schemas/soilLabReport.json create mode 100644 services/ontology/schemas/soilMethod.json create mode 100644 services/ontology/schemas/soilObservation.json create mode 100644 services/ontology/schemas/soilParty.json create mode 100644 services/ontology/schemas/soilRecommendation.json create mode 100644 services/ontology/schemas/soilSample.json create mode 100644 services/ontology/schemas/soilSampledObject.json create mode 100644 services/ontology/schemas/soilSamplingEvent.json diff --git a/docs/docs/Infrastructure/SoilImportOntologies.md b/docs/docs/Infrastructure/SoilImportOntologies.md new file mode 100644 index 000000000..7888e8267 --- /dev/null +++ b/docs/docs/Infrastructure/SoilImportOntologies.md @@ -0,0 +1,68 @@ +# Soil Import Ontologies + +These agriculture schemas describe the records currently written by the W3DS +Soil Samples importer. The importer accepts Eurofins XML and canonical JSON. +The field names, optional fields and schema IDs preserve compatibility with +existing records. IDs that look repetitive are already used by the importer; +they are intentionally retained rather than silently changing stored types. + +| Schema | schemaId | Purpose | +| --- | --- | --- | +| SoilImportBundle | aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa | Import manifest | +| SoilLabReport | 11111111-1111-4111-8111-111111111111 | Report provenance | +| SoilSample | 22222222-2222-4222-8222-222222222222 | Sample identity and field link | +| SoilSamplingEvent | 33333333-3333-4333-8333-333333333333 | Dates, depth and sampling protocol | +| SoilSampledObject | 44444444-4444-4444-8444-444444444444 | Sample location and parcel context | +| SoilParty | 55555555-5555-4555-8555-555555555555 | Producer, customer, sender or recipient | +| SoilObservation | 66666666-6666-4666-8666-666666666666 | Original and normalized results | +| SoilMethod | 77777777-7777-4777-8777-777777777777 | Laboratory method | +| SoilInterpretation | 88888888-8888-4888-8888-888888888888 | Optional sourced interpretation | +| SoilRecommendation | 99999999-9999-4999-8999-999999999999 | Optional sourced recommendation | + +Schemas live in `services/ontology/schemas/soil*.json` and use JSON Schema +draft-07. The ontology service discovers JSON files automatically. Each schema +declares `domain: agriculture` and a `$id` under the ontology service URL. +Registration in source control and deployment of that service are separate +steps; the service URL becomes available after merge and deployment. + +## References + +Every record's `id` is its application ID inside the payload. It is distinct +from the containing MetaEnvelope ID. The import manifest references payload +IDs through `source_file_id`, `lab_report_id`, `soil_sample_id`, +`sampling_event_id`, `sampled_object_id`, and its arrays of related IDs. +Child records carry optional `bundle_id`, preserving older records that +predate import manifests. Observations reference their sample, report and +optional method; interpretations may reference a particular observation. + +`field_w3id` in SoilSample and SoilSampledObject is an exception: it is the +MetaEnvelope ID of a crop field in the owner's eVault. It is not a provider's +external field identifier. Linking or changing a field updates both records; +unlinking removes the property from both. The importer currently discovers +FarmMaps crop fields using ontology ID `562a705a-4bb5-4130-9b0b-2d419910e0cf`. +These schemas do not introduce or redefine the field ontology. + +## Measurements and interpretation + +SoilObservation retains source codes, labels, units, qualifiers and quality +flags separately from normalized values. It is a distinct payload contract +from the existing general `Observation` schema, so that schema is unchanged. +Numeric values are optional because laboratories can report textual or +qualified results. The schema does not assert agronomic thresholds, unit +convertibility or comparability between laboratory methods. + +SoilInterpretation and SoilRecommendation reserve the payload contracts used +by the importer; current Eurofins parsing does not populate them. Registering +these types does not manufacture recommendations or persist UI reference +classifications as laboratory judgments. + +## Original files + +The importer currently stores original bytes under the existing File ontology +ID `a1b2c3d4-e5f6-7890-abcd-ef1234567890`. No duplicate File schema is added. +There is a known separate compatibility issue: the importer writes legacy +snake_case fields such as `file_name`, `mime_type`, `byte_size`, `sha256` and +`owner_eid`, whereas the registered File schema requires fields such as +`name`, `mimeType`, `size`, `md5Hash` and `ownerId`. This registration does not +resolve or hide that mismatch. Adapting the File writer and migrating existing +file records requires a separate change in the importing application. diff --git a/services/ontology/schemas/soilImportBundle.json b/services/ontology/schemas/soilImportBundle.json new file mode 100644 index 000000000..e8e9b9e88 --- /dev/null +++ b/services/ontology/schemas/soilImportBundle.json @@ -0,0 +1,118 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", + "schemaId": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", + "title": "SoilImportBundle", + "domain": "agriculture", + "description": "Manifest linking the entities produced by one soil report import without duplicating their data.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "owner_eid": { + "type": "string" + }, + "vault_id": { + "type": "string" + }, + "source_system": { + "type": "string" + }, + "source_format": { + "type": "string", + "enum": [ + "xml", + "json" + ] + }, + "source_report_id": { + "type": "string" + }, + "source_file_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "lab_report_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "soil_sample_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "sampling_event_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "sampled_object_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "party_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "method_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "observation_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "interpretation_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "recommendation_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "imported_at": { + "type": "string" + }, + "raw_import_hash": { + "type": "string" + }, + "schema_version": { + "type": "string" + } + }, + "required": [ + "id", + "owner_eid", + "vault_id", + "source_system", + "source_format", + "source_report_id", + "source_file_id", + "lab_report_id", + "soil_sample_id", + "party_ids", + "method_ids", + "observation_ids", + "interpretation_ids", + "recommendation_ids", + "imported_at", + "raw_import_hash", + "schema_version" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilInterpretation.json b/services/ontology/schemas/soilInterpretation.json new file mode 100644 index 000000000..6990250be --- /dev/null +++ b/services/ontology/schemas/soilInterpretation.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/88888888-8888-4888-8888-888888888888", + "schemaId": "88888888-8888-4888-8888-888888888888", + "title": "SoilInterpretation", + "domain": "agriculture", + "description": "Optional sourced interpretation of a soil analysis result; registration does not imply the importer generates judgments.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "soil_sample_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "observation_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "status_label": { + "type": "string" + }, + "target_range_low": { + "type": "number" + }, + "target_range_high": { + "type": "number" + }, + "comment": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "required": [ + "id", + "soil_sample_id" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilLabReport.json b/services/ontology/schemas/soilLabReport.json new file mode 100644 index 000000000..60c53b8c5 --- /dev/null +++ b/services/ontology/schemas/soilLabReport.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/11111111-1111-4111-8111-111111111111", + "schemaId": "11111111-1111-4111-8111-111111111111", + "title": "SoilLabReport", + "domain": "agriculture", + "description": "Laboratory report provenance and reference to the original source file.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "owner_eid": { + "type": "string" + }, + "vault_id": { + "type": "string" + }, + "source_system": { + "type": "string" + }, + "source_format": { + "type": "string", + "enum": [ + "xml", + "json" + ] + }, + "source_report_id": { + "type": "string" + }, + "issue_datetime": { + "type": "string" + }, + "modification_datetime": { + "type": "string" + }, + "status_code": { + "type": "string" + }, + "is_copy": { + "type": "boolean" + }, + "sender_lab_id": { + "type": "string" + }, + "recipient_id": { + "type": "string" + }, + "original_file_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "imported_at": { + "type": "string" + }, + "raw_import_hash": { + "type": "string" + } + }, + "required": [ + "id", + "owner_eid", + "vault_id", + "source_system", + "source_format", + "source_report_id", + "is_copy", + "original_file_id", + "imported_at", + "raw_import_hash" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilMethod.json b/services/ontology/schemas/soilMethod.json new file mode 100644 index 000000000..cd39ba75f --- /dev/null +++ b/services/ontology/schemas/soilMethod.json @@ -0,0 +1,39 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/77777777-7777-4777-8777-777777777777", + "schemaId": "77777777-7777-4777-8777-777777777777", + "title": "SoilMethod", + "domain": "agriculture", + "description": "Laboratory measurement method and source metadata.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "name": { + "type": "string" + }, + "source": { + "type": "string" + }, + "accreditation_flag": { + "type": "boolean" + }, + "metadata": { + "type": "object", + "additionalProperties": true, + "description": "Source-specific metadata retained without imposing a provider-specific structure." + } + }, + "required": [ + "id", + "name", + "source" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilObservation.json b/services/ontology/schemas/soilObservation.json new file mode 100644 index 000000000..cced3bece --- /dev/null +++ b/services/ontology/schemas/soilObservation.json @@ -0,0 +1,105 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/66666666-6666-4666-8666-666666666666", + "schemaId": "66666666-6666-4666-8666-666666666666", + "title": "SoilObservation", + "domain": "agriculture", + "description": "One soil analysis result with original and normalized values, units, method and source codes. Distinct from the general agriculture Observation ontology.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "soil_sample_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "lab_report_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "property_id": { + "type": "string" + }, + "property_label": { + "type": "string" + }, + "property_group": { + "type": "string", + "enum": [ + "soil.acidity", + "soil.organic_matter", + "soil.texture", + "soil.exchange_capacity", + "soil.water", + "soil.structure", + "soil.biology", + "soil.nutrients", + "soil.metadata", + "unmapped" + ] + }, + "observation_kind": { + "type": "string", + "enum": [ + "measured", + "derived", + "converted", + "interpreted" + ] + }, + "source_parameter_code": { + "type": "string" + }, + "source_parameter_label": { + "type": "string" + }, + "source_code_list": { + "type": "string" + }, + "value_original": { + "type": "number" + }, + "value_original_string": { + "type": "string" + }, + "unit_original_code": { + "type": "string" + }, + "value_normalized": { + "type": "number" + }, + "unit_normalized": { + "type": "string" + }, + "qualifier": { + "type": "string" + }, + "quality_flag": { + "type": "string" + }, + "method_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "sort_order": { + "type": "number" + } + }, + "required": [ + "id", + "soil_sample_id", + "lab_report_id", + "property_id", + "property_label", + "property_group", + "observation_kind", + "sort_order" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilParty.json b/services/ontology/schemas/soilParty.json new file mode 100644 index 000000000..46a2e39c1 --- /dev/null +++ b/services/ontology/schemas/soilParty.json @@ -0,0 +1,62 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/55555555-5555-4555-8555-555555555555", + "schemaId": "55555555-5555-4555-8555-555555555555", + "title": "SoilParty", + "domain": "agriculture", + "description": "Producer, customer, sender or recipient associated with a soil laboratory report.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "owner_eid": { + "type": "string" + }, + "vault_id": { + "type": "string" + }, + "role": { + "type": "string", + "enum": [ + "producer", + "customer", + "sender", + "recipient" + ] + }, + "external_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "street": { + "type": "string" + }, + "building_number": { + "type": "string" + }, + "postcode": { + "type": "string" + }, + "city": { + "type": "string" + }, + "country": { + "type": "string" + } + }, + "required": [ + "id", + "owner_eid", + "vault_id", + "role" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilRecommendation.json b/services/ontology/schemas/soilRecommendation.json new file mode 100644 index 000000000..50091f772 --- /dev/null +++ b/services/ontology/schemas/soilRecommendation.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/99999999-9999-4999-8999-999999999999", + "schemaId": "99999999-9999-4999-8999-999999999999", + "title": "SoilRecommendation", + "domain": "agriculture", + "description": "Optional laboratory or other sourced recommendation associated with a soil sample.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "soil_sample_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "lab_report_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "recommendation_type": { + "type": "string" + }, + "nutrient_or_input": { + "type": "string" + }, + "crop": { + "type": "string" + }, + "frequency": { + "type": "string" + }, + "rate_value": { + "type": "number" + }, + "rate_unit": { + "type": "string" + }, + "comment": { + "type": "string" + }, + "valid_until": { + "type": "string" + } + }, + "required": [ + "id", + "soil_sample_id", + "lab_report_id" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilSample.json b/services/ontology/schemas/soilSample.json new file mode 100644 index 000000000..800aa4a8f --- /dev/null +++ b/services/ontology/schemas/soilSample.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/22222222-2222-4222-8222-222222222222", + "schemaId": "22222222-2222-4222-8222-222222222222", + "title": "SoilSample", + "domain": "agriculture", + "description": "Soil sample identity, source identifiers, soil context and optional crop-field link.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "owner_eid": { + "type": "string" + }, + "vault_id": { + "type": "string" + }, + "lab_report_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "source_intake_id": { + "type": "string" + }, + "source_serial_id": { + "type": "string" + }, + "source_sender_assigned_id": { + "type": "string" + }, + "material_type": { + "type": "string" + }, + "sample_type_code": { + "type": "string" + }, + "sample_type_label": { + "type": "string" + }, + "field_label": { + "type": "string" + }, + "soil_type_code": { + "type": "string" + }, + "soil_type_label": { + "type": "string" + }, + "field_w3id": { + "type": "string", + "description": "MetaEnvelope ID of the linked crop field in the owner eVault, not an external provider ID. Omit this property when unlinked." + }, + "producer_party_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "customer_party_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "sampled_object_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + } + }, + "required": [ + "id", + "owner_eid", + "vault_id", + "lab_report_id" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilSampledObject.json b/services/ontology/schemas/soilSampledObject.json new file mode 100644 index 000000000..1b04c41a5 --- /dev/null +++ b/services/ontology/schemas/soilSampledObject.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/44444444-4444-4444-8444-444444444444", + "schemaId": "44444444-4444-4444-8444-444444444444", + "title": "SoilSampledObject", + "domain": "agriculture", + "description": "The location or parcel from which a soil sample was collected.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "soil_sample_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "name": { + "type": "string" + }, + "field_w3id": { + "type": "string", + "description": "MetaEnvelope ID of the linked crop field in the owner eVault, not an external provider ID. Omit this property when unlinked." + }, + "parcel_id": { + "type": "string" + }, + "geometry": { + "type": "string" + }, + "address": { + "type": "string" + }, + "postcode": { + "type": "string" + }, + "city": { + "type": "string" + }, + "country": { + "type": "string" + }, + "previous_crop": { + "type": "string" + }, + "boundary_geometry": { + "type": "string" + } + }, + "required": [ + "id", + "soil_sample_id" + ], + "additionalProperties": false +} diff --git a/services/ontology/schemas/soilSamplingEvent.json b/services/ontology/schemas/soilSamplingEvent.json new file mode 100644 index 000000000..61f25c5a7 --- /dev/null +++ b/services/ontology/schemas/soilSamplingEvent.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ontology.w3ds.metastate.foundation/schemas/33333333-3333-4333-8333-333333333333", + "schemaId": "33333333-3333-4333-8333-333333333333", + "title": "SoilSamplingEvent", + "domain": "agriculture", + "description": "Soil sampling and receipt dates, sampling depth and protocol.", + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Application record ID stored in the payload; distinct from the containing MetaEnvelope ID." + }, + "bundle_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "soil_sample_id": { + "type": "string", + "description": "Application payload ID reference, not a MetaEnvelope ID. See the soil import model documentation." + }, + "sampling_datetime": { + "type": "string" + }, + "receipt_datetime": { + "type": "string" + }, + "depth_from_cm": { + "type": "number" + }, + "depth_to_cm": { + "type": "number" + }, + "sampling_method": { + "type": "string" + }, + "sampling_protocol": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "required": [ + "id", + "soil_sample_id" + ], + "additionalProperties": false +}