{
  "lexicon": 1,
  "id": "org.cannadb.review",
  "defs": {
    "main": {
      "type": "record",
      "description": "A review of a cannabis strain or cut. Reviews are where subjective experience lives — the reviewer's perceived flavors and effects, multi-axis ratings, prose body, and optional images. Reviews reference exactly one strain record via `subject` and aggregate at the AppView layer into per-strain summaries (community-derived effect/flavor percentages, average ratings). Publishing this record IS the claim — every field is contextualized by the publisher DID at display time. CannaDB editorial accounts do not publish reviews.",
      "key": "tid",
      "record": {
        "type": "object",
        "required": ["subject", "createdAt"],
        "properties": {
          "subject": {
            "type": "string",
            "format": "at-uri",
            "description": "AT-URI reference to an `org.cannadb.strain` record (any `kind`). Required. (The lexicon spec does not enforce collection constraints on at-uri; consumers must validate the ref resolves to an `org.cannadb.strain` record and reject reviews whose subject points elsewhere.)"
          },
          "createdAt": {
            "type": "string",
            "format": "datetime",
            "description": "Client-declared timestamp when this review was originally written."
          },
          "body": {
            "type": "string",
            "description": "Markdown-formatted review prose. Optional — a review can be ratings-only or tag-only. Soft cap ~5,000 characters; the lexicon does not enforce this length, but consumers should expect publishers to keep reviews modest."
          },
          "ratings": {
            "type": "ref",
            "ref": "#ratings",
            "description": "Multi-axis numeric ratings on a 1–5 scale. All axes are independently optional — a reviewer may rate only `overall`, only some axes, or skip ratings entirely. The AppView averages each axis across reviews for the per-strain summary."
          },
          "flavors": {
            "type": "array",
            "description": "Flavor descriptors as the reviewer experienced them. Open vocabulary — the lexicon does not enforce a closed set; the AppView normalizes near-duplicates at index time and aggregates across reviews into community-derived flavor percentages on the strain.",
            "items": {
              "type": "string",
              "description": "A single flavor descriptor."
            }
          },
          "effects": {
            "type": "array",
            "description": "Effect descriptors as the reviewer experienced them. Open vocabulary — see `flavors` for rationale. The AppView aggregates across reviews into community-derived effect percentages on the strain (the canonical \"top effects\" surface visitors expect on a strain page).",
            "items": {
              "type": "string",
              "description": "A single effect descriptor."
            }
          },
          "growRef": {
            "type": "string",
            "format": "at-uri",
            "description": "Forward-compatible AT-URI reference to a grow record (`org.cannadb.grow`, Phase 6) backing this review. Optional and speculative — the grow record type does not exist yet and this field is a placeholder for the eventual review-grow linkage. Consumers should ignore this field until the grow lexicon ships."
          },
          "images": {
            "type": "array",
            "description": "Up to three image blobs attached to this review. Each image accepts common web image formats and is capped at 1 MB. Reviews are deliberately limited to three images to keep PDS storage burden modest; richer photo galleries belong in grow records (Phase 6).",
            "maxLength": 3,
            "items": {
              "type": "blob",
              "description": "A single review image.",
              "accept": ["image/png", "image/jpeg", "image/webp"],
              "maxSize": 1000000
            }
          }
        }
      }
    },
    "ratings": {
      "type": "object",
      "description": "Multi-axis numeric ratings on a 1–5 scale. All axes are independently optional. Aggregations (averages, distributions) happen at the AppView layer.",
      "properties": {
        "overall": {
          "type": "integer",
          "description": "Overall rating, 1–5.",
          "minimum": 1,
          "maximum": 5
        },
        "yield": {
          "type": "integer",
          "description": "Yield rating, 1–5. Reviewer's subjective sense of how the strain produced — a grower-axis rating distinct from the strain record's structured `yield` claim.",
          "minimum": 1,
          "maximum": 5
        },
        "potency": {
          "type": "integer",
          "description": "Potency rating, 1–5. Reviewer's subjective sense of strength — distinct from measured cannabinoid percentages.",
          "minimum": 1,
          "maximum": 5
        },
        "flavor": {
          "type": "integer",
          "description": "Flavor rating, 1–5.",
          "minimum": 1,
          "maximum": 5
        },
        "bagAppeal": {
          "type": "integer",
          "description": "Bag appeal rating, 1–5. Reviewer's subjective sense of visual quality of the cured flower.",
          "minimum": 1,
          "maximum": 5
        },
        "ease": {
          "type": "integer",
          "description": "Ease-of-grow rating, 1–5. Distinct from the strain record's `growDifficulty` claim — this is the reviewer's experienced ease.",
          "minimum": 1,
          "maximum": 5
        }
      }
    }
  }
}
