One append-only event on a plant's timeline. A single record type unifies what other journals split into status changes, activities, measurements, and notes — because they are all the same shape (a timestamped thing that happened to a plant) and the distinguishing detail is an open `kind` vocabulary. Stage transitions (kind "stage") are how lifecycle is tracked: the AppView reads the latest stage entry as the plant's current stage and the full set as its lifecycle history. Activities (watering, feeding, training, …) optionally carry structured `measurements`. Freeform observation is the `note` field — deliberately loose so growers can record measurements prose, LST details, and anything else without the schema being prescriptive. Photos are NOT embedded here; they are separate `org.cannadb.growPhoto` records that may link back to an entry. Publishing this record IS the claim — contextualized by the publisher DID at display time.
tid
Timestamp-based ID
Properties
createdAt
string
datetime
Required
Client-declared timestamp when this entry record was created.
grow
string
at-uri
Optional
Optional denormalized AT-URI reference to the plant's `org.cannadb.grow`. Lets the AppView assemble a whole-grow timeline and gate on the grow's `listed` preference without resolving every plant first. The plant ref is canonical; this is a cache for query efficiency and ref resilience.
kind
string
Optional
What kind of event this is. Open vocabulary — clients should accept unknown values and fall back to generic display, and may offer user-defined kinds. "stage" marks a lifecycle transition and is the one kind that gives `stage` meaning.
stage, watering, feeding, note, measurement, training, transplant, topping, defoliation, flush, pest, disease, treatment, harvestmeasurements
array
of
ref
#measurement
Optional
Structured readings recorded with this event (height, pH, EC/PPM, runoff pH, water volume, …). Optional — most entries carry none. A feeding entry might carry pH and EC; a check-up entry might carry height. Mirrors how journaling tools attach measurements to an activity.
note
string
Optional
Markdown-formatted free-form note — the catch-all for anything the structured fields don't capture (measurement context, LST/defoliation details, observations, photos commentary). Deliberately unstructured.
maxLength: 100000 bytesmaxGraphemes: 10000 graphemesoccurredAt
string
datetime
Optional
When the event actually happened, if different from `createdAt` (e.g., logging yesterday's feeding today). Consumers default to `createdAt` when absent. This is the field timelines sort on.
plant
string
at-uri
Required
AT-URI reference to the `org.cannadb.plant` this event belongs to. (Consumers should validate the ref resolves to an `org.cannadb.plant` record.)
stage
string
Optional
The lifecycle stage this entry marks a transition into. Set on stage transitions (typically with `kind` "stage"). The AppView treats the most recent entry carrying a `stage` as the plant's current stage, and the full ordered set as its lifecycle history. Display ordering of stages is an AppView concern. Open vocabulary.
germinating, seedling, vegetative, flowering, drying, curing, harvested, deadView raw schema
{
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"plant",
"createdAt"
],
"properties": {
"grow": {
"type": "string",
"format": "at-uri",
"description": "Optional denormalized AT-URI reference to the plant's `org.cannadb.grow`. Lets the AppView assemble a whole-grow timeline and gate on the grow's `listed` preference without resolving every plant first. The plant ref is canonical; this is a cache for query efficiency and ref resilience."
},
"kind": {
"type": "string",
"description": "What kind of event this is. Open vocabulary — clients should accept unknown values and fall back to generic display, and may offer user-defined kinds. \"stage\" marks a lifecycle transition and is the one kind that gives `stage` meaning.",
"knownValues": [
"stage",
"watering",
"feeding",
"note",
"measurement",
"training",
"transplant",
"topping",
"defoliation",
"flush",
"pest",
"disease",
"treatment",
"harvest"
]
},
"note": {
"type": "string",
"maxLength": 100000,
"description": "Markdown-formatted free-form note — the catch-all for anything the structured fields don't capture (measurement context, LST/defoliation details, observations, photos commentary). Deliberately unstructured.",
"maxGraphemes": 10000
},
"plant": {
"type": "string",
"format": "at-uri",
"description": "AT-URI reference to the `org.cannadb.plant` this event belongs to. (Consumers should validate the ref resolves to an `org.cannadb.plant` record.)"
},
"stage": {
"type": "string",
"description": "The lifecycle stage this entry marks a transition into. Set on stage transitions (typically with `kind` \"stage\"). The AppView treats the most recent entry carrying a `stage` as the plant's current stage, and the full ordered set as its lifecycle history. Display ordering of stages is an AppView concern. Open vocabulary.",
"knownValues": [
"germinating",
"seedling",
"vegetative",
"flowering",
"drying",
"curing",
"harvested",
"dead"
]
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this entry record was created."
},
"occurredAt": {
"type": "string",
"format": "datetime",
"description": "When the event actually happened, if different from `createdAt` (e.g., logging yesterday's feeding today). Consumers default to `createdAt` when absent. This is the field timelines sort on."
},
"measurements": {
"type": "array",
"items": {
"ref": "#measurement",
"type": "ref"
},
"description": "Structured readings recorded with this event (height, pH, EC/PPM, runoff pH, water volume, …). Optional — most entries carry none. A feeding entry might carry pH and EC; a check-up entry might carry height. Mirrors how journaling tools attach measurements to an activity."
}
}
},
"description": "One append-only event on a plant's timeline. A single record type unifies what other journals split into status changes, activities, measurements, and notes — because they are all the same shape (a timestamped thing that happened to a plant) and the distinguishing detail is an open `kind` vocabulary. Stage transitions (kind \"stage\") are how lifecycle is tracked: the AppView reads the latest stage entry as the plant's current stage and the full set as its lifecycle history. Activities (watering, feeding, training, …) optionally carry structured `measurements`. Freeform observation is the `note` field — deliberately loose so growers can record measurements prose, LST details, and anything else without the schema being prescriptive. Photos are NOT embedded here; they are separate `org.cannadb.growPhoto` records that may link back to an entry. Publishing this record IS the claim — contextualized by the publisher DID at display time."
}