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
CanonicalObservation.observation_type→ ObservationType (1..1)CanonicalObservation.body_site→ BodySite (0..1)CanonicalObservation.session→ ObservationSession (0..1)CanonicalObservation.device→ Device (0..1)CanonicalObservation.source_producer→ SourceProducerEntity (1..1)CanonicalObservation.raw_metadata→ RawMetadata (0..1)CanonicalObservation.source_feed→ SourceFeed (1..1)CanonicalObservation.sample→ Sample (0..1)CanonicalObservation.derivation→ CanonicalDerivation (0..1)CanonicalObservation.context→ ObservationContext (1..1)CanonicalObservation.farm→ Farm (1..1)AnimalObservation.animal→ Animal (1..1)AnimalGroupObservation.animal_group→ AnimalGroup (1..1)ProductObservation.product_material→ ProductMaterial (1..1)
Referenced by
DiagnosisEvent.supporting_observations(0..*)DataIssue.observations(0..*)ObservationSelection.candidates(1..*)ObservationSelection.preferred(0..1)OfficialSubmission.included_observations(0..*)
Uses types
ObservationTime, ObservationValue, EventTime, CoverageDetails, PropertyQualifiers, AggregationDetails, RecordRevision
Subtypes
- by
subject: AnimalObservation, AnimalGroupObservation, ProductObservation
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 requirescontext.aggregation!= none andaggregation_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.