org.cannadb.growEntry
{
"$type": "com.atproto.lexicon.schema",
"defs": {
"main": {
"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.",
"key": "tid",
"record": {
"properties": {
"createdAt": {
"description": "Client-declared timestamp when this entry record was created.",
"format": "datetime",
"type": "string"
},
"grow": {
"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.",
"format": "at-uri",
"type": "string"
},
"kind": {
"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"
],
"type": "string"
},
"measurements": {
"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.",
"items": {
"ref": "#measurement",
"type": "ref"
},
"type": "array"
},
"note": {
"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,
"maxLength": 100000,
"type": "string"
},
"occurredAt": {
"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.",
"format": "datetime",
"type": "string"
},
"plant": {
"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.)",
"format": "at-uri",
"type": "string"
},
"stage": {
"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"
],
"type": "string"
}
},
"required": [
"plant",
"createdAt"
],
"type": "object"
},
"type": "record"
},
"measurement": {
"description": "A single structured reading. Both `metric` and `unit` are open vocabularies. `value` is a scaled integer in hundredths of `unit` (atproto has no float type), matching the scaled-integer convention used for cannabinoid percentages on `org.cannadb.strain`: pH 6.25 = 625 with unit \"ph\"; height 30.5 cm = 3050 with unit \"cm\"; EC 1.85 = 185 with unit \"mS_cm\".",
"properties": {
"metric": {
"description": "What was measured. Open vocabulary — consumers accept unknown metrics and may offer user-defined ones.",
"knownValues": [
"height",
"ph",
"ec",
"ppm",
"tds",
"runoff_ph",
"water_volume",
"temperature",
"humidity",
"pot_size"
],
"type": "string"
},
"unit": {
"description": "Unit of `value`. Open vocabulary; required to interpret the scaled integer. Consumers should accept unknown units and fall back to displaying the unit string as written.",
"knownValues": [
"cm",
"in",
"ph",
"mS_cm",
"ppm",
"ml",
"l",
"gal",
"celsius",
"fahrenheit",
"percent"
],
"type": "string"
},
"value": {
"description": "The measured value in hundredths of `unit` (e.g., 625 = 6.25). Scaled integer because atproto has no float type.",
"type": "integer"
}
},
"required": [
"metric",
"value"
],
"type": "object"
}
},
"id": "org.cannadb.growEntry",
"lexicon": 1
}
Metadata
- DID
-
did:plc:lrtzzib3ycggsodkfidzuorw - CID
-
bafyreifxvyf2eniem2v3rd5p2bcopvgjuc2vmzmn5ugr7tyoetkcmglnpi - Indexed At
- 2026-06-20 00:44 UTC
- AT-URI
-
at://did:plc:lrtzzib3ycggsodkfidzuorw/com.atproto.lexicon.schema/org.cannadb.growEntry
Similar Lexicons
Lexicons whose schemas describe something close to this one. Check them before publishing a new one that overlaps.
-
org.cannadb.plant record
A single plant within a grow. The plant is the lifecycle unit: it references the `org.cannadb.grow` it belongs to and (optionally) the `org.cannadb.strain` it is. Its lifecycle stage is NOT stored as a mutable field her…
-
org.cannadb.grow record
A grow — one documented cultivation run (a tent, a garden, a season's cycle). The grow is a lightweight container: it groups one or more `org.cannadb.plant` records and carries the shared setup and a publisher-chosen …
-
org.cannadb.growPhoto record
A single photo in a grow's gallery. Modeled as its own record (rather than blobs embedded in entries) so galleries can grow without bloating other records and so each photo carries its own caption, ordering, and capture…