Class GeoSourceMetadataBuilder
Investigation.sourceMetadata document from a parsed GeoSeries.
This is a verbatim cache of what GEO said, not curation: it is rebuildable from the source at any
time and carries no judgement of ours. Its purpose is to give the curation agent the raw per-sample
view — submitter-written characteristic columns and per-sample titles as they were written — so it
can tell "the submitter copy-pasted this column into every row" from "this column is a real
experimental factor". Gemma's own converter flattens that view into
BioMaterial.characteristics and cannot answer the question.
The document is built from objects already parsed at import; nothing is re-fetched. Several fields
it carries are ones the converter discards outright (dataProcessing, hybProtocol,
scanProtocol, supplementaryFiles, submission dates).
Contract. Schema v1 was agreed with CAB on 2026-08-09
(GEMMA_REPLY_2026_08_09_SOURCE_METADATA_BLOB.md). Rules that are not obvious from the
shape:
- Keys are camelCase; the consumer normalizes once at ingestion.
- Absent means absent. A field GEO did not state is omitted, never written as null or "".
characteristicsis always an object, never an array, even when empty.- Channel fields beyond the first are prefixed
ch{N}_. pmids/dois, notpubMedIds—to_snake("pubMedIds")yieldspub_med_ids, which nothing on the consuming side reads, so the field would silently arrive empty.samplesis a list withaccessionon each element, not a GSM-keyed map.- v1 is not one shape.
sampleTypewas added on 2026-08-29 without bumping the version (Paul's call), so a document stampedschemaVersion: 1may or may not carry it and a consumer cannot tell which by the version. Every field is optional by the absent-means-absent rule above, so this changes nothing for a reader that honours it; it does mean the version is not a way to detect the field.
- Author:
- Gemma
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classIdentity of the experiment the document is being written for. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intSchema version written into the document and intoInvestigation.sourceMetadataSchemaVersion. -
Constructor Summary
ConstructorsConstructorDescriptionGeoSourceMetadataBuilder(com.fasterxml.jackson.databind.ObjectMapper objectMapper) -
Method Summary
Modifier and TypeMethodDescriptionbuild(GeoSeries series, GeoSourceMetadataBuilder.ExperimentIdentity identity, Date harvestedAt) Build the document.
-
Field Details
-
SCHEMA_VERSION
public static final int SCHEMA_VERSIONSchema version written into the document and intoInvestigation.sourceMetadataSchemaVersion. A null version in the database marks the older, smaller scrape-path payload written byGeoScrapeServiceImpl.- See Also:
-
-
Constructor Details
-
GeoSourceMetadataBuilder
public GeoSourceMetadataBuilder(com.fasterxml.jackson.databind.ObjectMapper objectMapper)
-
-
Method Details
-
build
@Nullable public String build(@Nullable GeoSeries series, GeoSourceMetadataBuilder.ExperimentIdentity identity, Date harvestedAt) Build the document. Returnsnullwhen there is nothing worth storing, so the caller can leave both columns null rather than storing an empty shell.- Parameters:
series- the parsed series; its samples supply the per-sample viewidentity- experiment identity, resolved after persist (seeGeoSourceMetadataBuilder.ExperimentIdentity)harvestedAt- when Gemma built this document — our clock, not GEO's. GEO's own dates are carried separately assubmissionDate/lastUpdateDate.
-