io.kich.recipe.recipe

kich.io

Schema Diff

+64 -4

From

CID
bafyreidws2oh6qi...
Indexed At
2026-02-18 19:31 UTC
View this version

To

CID
bafyreielu5kh73r...
Indexed At
2026-03-19 20:28 UTC
View this version

Compatibility Analysis

Backward Compatible

Backward compatible. 25 non-breaking changes.

Non-Breaking Changes (25)
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.heuristicAmount" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.heuristicUnit" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.measuredAmount" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.measuredUnit" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe#tag" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe#tag.id" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe#tag.name" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe:body.embedding" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe:body.images" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe:body.images:items" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe:body.tags" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe:body.tags:items" }
  • AddedVertex AddedVertex { vertex_id: "io.kich.recipe.recipe:body.variationOf" }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.heuristicAmount", kind: "prop", name: Some("heuristicAmount") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.heuristicUnit", kind: "prop", name: Some("heuristicUnit") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.measuredAmount", kind: "prop", name: Some("measuredAmount") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.measuredUnit", kind: "prop", name: Some("measuredUnit") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe#tag", tgt: "io.kich.recipe.recipe#tag.id", kind: "prop", name: Some("id") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe#tag", tgt: "io.kich.recipe.recipe#tag.name", kind: "prop", name: Some("name") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.embedding", kind: "prop", name: Some("embedding") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.images", kind: "prop", name: Some("images") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.tags", kind: "prop", name: Some("tags") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.variationOf", kind: "prop", name: Some("variationOf") }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe:body.images", tgt: "io.kich.recipe.recipe:body.images:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "io.kich.recipe.recipe:body.tags", tgt: "io.kich.recipe.recipe:body.tags:items", kind: "items", name: None }

Migration Guidance

Added Elements

  • AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.heuristicAmount" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.heuristicUnit" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.measuredAmount" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe#ingredient.measuredUnit" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe#tag" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe#tag.id" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe#tag.name" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe:body.embedding" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe:body.images" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe:body.images:items" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe:body.tags" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe:body.tags:items" }
  • AddedVertex { vertex_id: "io.kich.recipe.recipe:body.variationOf" }

Additional Notes

  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.heuristicAmount", kind: "prop", name: Some("heuristicAmount") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.heuristicUnit", kind: "prop", name: Some("heuristicUnit") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.measuredAmount", kind: "prop", name: Some("measuredAmount") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe#ingredient", tgt: "io.kich.recipe.recipe#ingredient.measuredUnit", kind: "prop", name: Some("measuredUnit") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe#tag", tgt: "io.kich.recipe.recipe#tag.id", kind: "prop", name: Some("id") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe#tag", tgt: "io.kich.recipe.recipe#tag.name", kind: "prop", name: Some("name") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.embedding", kind: "prop", name: Some("embedding") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.images", kind: "prop", name: Some("images") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.tags", kind: "prop", name: Some("tags") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe:body", tgt: "io.kich.recipe.recipe:body.variationOf", kind: "prop", name: Some("variationOf") }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe:body.images", tgt: "io.kich.recipe.recipe:body.images:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "io.kich.recipe.recipe:body.tags", tgt: "io.kich.recipe.recipe:body.tags:items", kind: "items", name: None }
1 1
{
2 2
  "id": "io.kich.recipe.recipe",
3 3
  "defs": {
4 +
    "tag": {
5 +
      "type": "object",
6 +
      "required": [
7 +
        "id",
8 +
        "name"
9 +
      ],
10 +
      "properties": {
11 +
        "id": {
12 +
          "type": "string",
13 +
          "description": "Tag identifier"
14 +
        },
15 +
        "name": {
16 +
          "type": "string",
17 +
          "description": "Tag display name"
18 +
        }
19 +
      }
20 +
    },
4 21
    "main": {
5 22
      "key": "tid",
6 23
      "type": "record",
7 24
      "record": {
8 25
        "type": "object",
9 26
        "required": [
10 27
          "name",
11 28
          "servings",
12 29
          "createdAt"
13 30
        ],
14 31
        "properties": {
15 32
          "url": {
16 33
            "type": "string",
17 34
            "format": "uri",
18 35
            "description": "Source URL of the recipe"
19 36
          },
20 37
          "name": {
21 38
            "type": "string",
22 39
            "description": "Recipe name"
23 40
          },
41 +
          "tags": {
42 +
            "type": "array",
43 +
            "items": {
44 +
              "ref": "#tag",
45 +
              "type": "ref"
46 +
            },
47 +
            "description": "Tags for categorizing the recipe"
48 +
          },
49 +
          "images": {
50 +
            "type": "array",
51 +
            "items": {
52 +
              "type": "blob",
53 +
              "accept": [
54 +
                "image/*"
55 +
              ]
56 +
            },
57 +
            "maxLength": 10,
58 +
            "description": "Recipe images as blobs (hero first; preferred over imageUrl)"
59 +
          },
24 60
          "source": {
25 61
            "type": "string",
26 62
            "description": "Source name (book, magazine, blog)"
27 63
          },
28 64
          "imageUrl": {
29 65
            "type": "string",
30 66
            "format": "uri",
31 -
            "description": "Image URL for the recipe"
67 +
            "description": "[Deprecated] Image URL for the recipe. Use images blob array instead. Kept for legacy fallback."
32 68
          },
33 69
          "servings": {
34 70
            "type": "integer",
35 71
            "default": 1,
36 72
            "description": "Number of servings this recipe makes"
37 73
          },
38 74
          "createdAt": {
39 75
            "type": "string",
40 76
            "format": "datetime",
41 77
            "description": "When this recipe was created"
42 78
          },
43 79
          "createdBy": {
44 80
            "ref": "com.atproto.repo.strongRef",
45 81
            "type": "ref",
46 82
            "description": "Reference to the user who created this recipe"
47 83
          },
84 +
          "embedding": {
85 +
            "type": "string",
86 +
            "description": "Vector embedding for semantic similarity search (1024 dimensions, stored as JSON array of numbers)"
87 +
          },
48 88
          "isPrivate": {
49 89
            "type": "boolean",
50 90
            "default": false,
51 91
            "description": "Whether this recipe is private (only visible to household members)"
52 92
          },
53 93
          "updatedAt": {
54 94
            "type": "string",
55 95
            "format": "datetime",
56 96
            "description": "When this recipe was last updated"
57 97
          },
58 98
          "description": {
59 99
            "type": "string",
60 100
            "description": "Recipe description"
61 101
          },
62 102
          "ingredients": {
63 103
            "type": "array",
64 104
            "items": {
65 105
              "ref": "#ingredient",
66 106
              "type": "ref"
67 107
            },
68 108
            "description": "Recipe ingredients"
69 109
          },
110 +
          "variationOf": {
111 +
            "ref": "com.atproto.repo.strongRef",
112 +
            "type": "ref",
113 +
            "description": "Optional reference to the original recipe this is a variation of (for attribution and variation discovery)"
114 +
          },
70 115
          "instructions": {
71 116
            "type": "array",
72 117
            "items": {
73 118
              "ref": "#instructionStep",
74 119
              "type": "ref"
75 120
            },
76 121
            "description": "Cooking instructions as an array of steps"
77 122
          },
78 123
          "cookTimeMinutes": {
79 124
            "type": "integer",
80 125
            "description": "Cooking time in minutes"
81 126
          },
82 127
          "prepTimeMinutes": {
83 128
            "type": "integer",
84 129
            "description": "Preparation time in minutes"
85 130
          }
86 131
        }
87 132
      }
88 133
    },
89 134
    "ingredient": {
90 135
      "type": "object",
91 136
      "required": [
92 137
        "id",
93 -
        "name",
94 -
        "grams"
138 +
        "name"
95 139
      ],
96 140
      "properties": {
97 141
        "id": {
98 142
          "type": "string",
99 143
          "description": "Unique identifier for this ingredient"
100 144
        },
101 145
        "name": {
102 146
          "type": "string",
103 147
          "description": "Ingredient name"
104 148
        },
105 149
        "grams": {
106 150
          "type": "integer",
107 -
          "description": "Amount needed in grams"
151 +
          "description": "[Deprecated] Amount needed in grams. Use measuredAmount/measuredUnit instead."
108 152
        },
109 153
        "group": {
110 154
          "type": "string",
111 155
          "description": "Optional group name for organizing ingredients (e.g., 'For the sauce:', 'For the pasta:')"
112 156
        },
113 157
        "notes": {
114 158
          "type": "string",
115 159
          "description": "Optional notes about this ingredient (e.g., original quantity)"
116 160
        },
117 161
        "isDetached": {
118 162
          "type": "boolean",
119 163
          "default": false,
120 164
          "description": "Whether this ingredient is detached (doesn't count towards recipe completeness)"
121 165
        },
122 166
        "isOptional": {
123 167
          "type": "boolean",
124 168
          "default": false,
125 169
          "description": "Whether this ingredient is optional"
170 +
        },
171 +
        "measuredUnit": {
172 +
          "type": "string",
173 +
          "description": "Measured unit (g, kg, oz, lb, ml)"
174 +
        },
175 +
        "heuristicUnit": {
176 +
          "type": "string",
177 +
          "description": "Heuristic unit from parsed ingredient text (e.g., cup, cookies)"
178 +
        },
179 +
        "measuredAmount": {
180 +
          "type": "integer",
181 +
          "description": "Measured amount needed (e.g., 250, 1.5)"
182 +
        },
183 +
        "heuristicAmount": {
184 +
          "type": "integer",
185 +
          "description": "Heuristic amount from parsed ingredient text (e.g., 2 in \"2 cups\")"
126 186
        }
127 187
      }
128 188
    },
129 189
    "instructionStep": {
130 190
      "type": "object",
131 191
      "required": [
132 192
        "id",
133 193
        "value"
134 194
      ],
135 195
      "properties": {
136 196
        "id": {
137 197
          "type": "string",
138 198
          "description": "Unique identifier for this instruction step"
139 199
        },
140 200
        "value": {
141 201
          "type": "string",
142 202
          "description": "Instruction text"
143 203
        }
144 204
      }
145 205
    }
146 206
  },
147 207
  "$type": "com.atproto.lexicon.schema",
148 208
  "lexicon": 1,
149 209
  "description": "A recipe record containing cooking instructions, ingredients, and metadata."
150 210
}

Compare Other Versions

Lexicon Garden

@