Skip to content

6.5.2.1 CanonicalObservation

6.5.2.1.1 Purpose

One measured or computed value about an animal, a group or a product lot, in our standard form: what was observed (an observation type), when, how (an observation context), on which body site, and with which value. When a source corrects a value, a new revision is added instead of overwriting the old one.

6.5.2.1.2 Questions it answers

  • What was observed for this animal, when, and with which value?
  • How was the value obtained, and is it comparable with another value?
  • Which raw record, source and write does it come from?
  • Which revisions has the source sent for this record?

6.5.2.1.3 Fields

Field Type Cardinality Description
id string (uuid) 1..1 Key.
observation_type ObservationType 1..1 Reference the exact registered profile version, never a family/template. Draft profiles are for design, not operational publication.
body_site BodySite 0..1 Empty does not assert whole udder/subject; see anatomical_scope.
time ObservationTime 1..1
value ObservationValue 0..1 Required for active numerical/category/flag results; absent only in a cancellation revision.
session ObservationSession 0..1 Only when the entire observation concerns that session; multiple contributing milkings belong to Sample.
device Device 0..1
source_producer SourceProducerEntity 1..1
raw_metadata RawMetadata 0..1 Required unless derivation (CanonicalObservation.derivation) is set; see lineage.
raw_locator string 0..1 Identifies the exact source record/field; detailed adapter inputs also live in its ParseJob audit.
source_record_key string 1..1 Stable source record key; no export date, mutable value or lactation context in the key.
status enum 1..1 Values: final, corrected, cancelled. Default: final.
A source correction/cancellation appends a revision; previous payloads and availability remain intact.
Corrected may be exposed as a current-view projection, never by erasing the prior revision's status.
recorded_at EventTime 0..1 When the source recorded or published this value (e.g. the date of the lab report, the time the robot stored the reading).
Not our arrival time (revision.available_in). Empty when the source does not say; never filled with an assumed delay.
coverage CoverageDetails 0..1
source_feed SourceFeed 1..1 Must match the producer's feed; stable across deliveries.
content_hash string 1..1 Hash all semantic fields including subject, time, profile version, context, value and qualifiers; exclude delivery clocks.
sample Sample 0..1
property_qualifiers PropertyQualifiers 1..1 Typed fields allowed by observation_type.qualifier_schema; no unvalidated free JSON.
anatomical_scope enum 1..1 Values: whole_subject, body_part, not_applicable, unknown.
body_part requires body_site; other values have none. A known whole udder is a BodySite, not the whole animal.
aggregation_details AggregationDetails 0..1 Per-row part of an aggregate (e.g. how many readings it combined); its method is in the context.
derivation CanonicalDerivation 0..1
revision RecordRevision 1..1
component_key string 1..1 Stable component of the source record, e.g. field/test/channel; distinguishes two assays or targets in the same record.
context ObservationContext 1..1 How the value was obtained: method, result basis, time basis, aggregation. Chosen by the parser mapping of the source field.
farm Farm 1..1 The farm of the feed that delivered the record (= source_feed.farm), copied here as the key of partitioning, row-level access and erasure; it never changes on a revision. See STORAGE.
For observations we compute, the farm of the inputs; a derivation never crosses farms.
created_at datetime 1..1
updated_at datetime 1..1

6.5.2.1.4 Subtypes

Discriminator subject: every CanonicalObservation is exactly one of the subtypes below (disjoint and complete).

AnimalObservation

Field Type Cardinality Description
animal Animal 1..1

AnimalGroupObservation

Field Type Cardinality Description
animal_group AnimalGroup 1..1
  • Milk concentration/quality here is a statistical aggregate, not a tank assay; requires aggregate context and no Sample.

ProductObservation

Field Type Cardinality Description
product_material ProductMaterial 1..1
  • First product profiles are for physically pooled milk; profiles for other products are FUTURE WORK.

6.5.2.1.5 Relationships

References

Referenced by

Uses types

ObservationTime, ObservationValue, EventTime, CoverageDetails, PropertyQualifiers, AggregationDetails, RecordRevision

Subtypes

6.5.2.1.6 Rules & constraints

  • One normalized observation revision; the property is a versioned catalog entry, not a subtype.
  • Logical source identity: (source_feed, source_record_key, component_key); one current revision per identity.
  • Historical uniqueness includes revision.revision_number. Same current semantic hash = replay; changed hash = new revision.
  • Reinstatement after cancellation creates a new revision even when its value equals an older historical revision.
  • Cross-feed duplicate selection is separate (ObservationSelection); independent lab and sensor measurements remain distinct.
  • Subject, sample, session, device assignment and anatomical site must be compatible; unresolved links stay in staging.
  • Profile constants + qualifiers + sample + context define comparability, not vendor name or unit alone.
  • context.result_basis=aggregate requires context.aggregation != none and aggregation_details; unknown method of aggregation remains explicit.
  • Moonitoring calculations on canonical inputs require derivation; adapter raw normalization uses ParseJob audit instead.
  • Examples: SCC=185000 /mL; protein=true mass fraction 3.4%; milk.yield.mass=31.4 kg over a day.
  • Storage: partitioned by farm and by month of time (see STORAGE in the section notes).
  • Method, result basis, time basis and aggregation are constant per source mapping, not per type: they live once in ObservationContext and each row references it.