ink.igav.whatmealtodo.defs
Schema Diff
+13 -4
Compatibility Analysis
Breaking Changes Detected
1 breaking change, 1 non-breaking change.
Breaking Changes (1)
- ConstraintTightened ConstraintTightened { vertex_id: "ink.igav.whatmealtodo.defs#quantity.unit", sort: "knownValues", old_value: "[\"g\",\"kg\",\"ml\",\"l\",\"tsp\",\"tbsp\",\"cup\",\"oz\",\"lb\",\"clove\",\"can\",\"jar\",\"package\",\"piece\",\"slice\",\"stick\",\"pinch\",\"dash\",\"basket\",\"bunch\",\"handful\",\"sprig\",\"stalk\",\"head\",\"bag\",\"box\",\"bottle\"]", new_value: "[\"g\",\"kg\",\"ml\",\"l\",\"tsp\",\"tbsp\",\"cup\",\"oz\",\"lb\",\"clove\",\"can\",\"jar\",\"package\",\"piece\",\"slice\",\"stick\",\"pinch\",\"dash\",\"basket\",\"bunch\",\"handful\",\"sprig\",\"stalk\",\"head\",\"bag\",\"box\",\"bottle\",\"packet\",\"sachet\",\"envelope\",\"tin\",\"tub\"]" }
Non-Breaking Changes (1)
- AddedVertex AddedVertex { vertex_id: "ink.igav.whatmealtodo.defs#ingredient" }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "ink.igav.whatmealtodo.defs#ingredient" }
Constraint Changes
- ConstraintTightened ConstraintTightened { vertex_id: "ink.igav.whatmealtodo.defs#quantity.unit", sort: "knownValues", old_value: "[\"g\",\"kg\",\"ml\",\"l\",\"tsp\",\"tbsp\",\"cup\",\"oz\",\"lb\",\"clove\",\"can\",\"jar\",\"package\",\"piece\",\"slice\",\"stick\",\"pinch\",\"dash\",\"basket\",\"bunch\",\"handful\",\"sprig\",\"stalk\",\"head\",\"bag\",\"box\",\"bottle\"]", new_value: "[\"g\",\"kg\",\"ml\",\"l\",\"tsp\",\"tbsp\",\"cup\",\"oz\",\"lb\",\"clove\",\"can\",\"jar\",\"package\",\"piece\",\"slice\",\"stick\",\"pinch\",\"dash\",\"basket\",\"bunch\",\"handful\",\"sprig\",\"stalk\",\"head\",\"bag\",\"box\",\"bottle\",\"packet\",\"sachet\",\"envelope\",\"tin\",\"tub\"]" }
1
1
{
2
2
"id": "ink.igav.whatmealtodo.defs",
3
3
"defs": {
4
4
"head": {
5
5
"type": "token",
6
6
"description": "Matched on the head noun only — pantry 'flour' against recipe 'all-purpose flour'. Weaker than exact, and shown as such."
7
7
},
8
8
"exact": {
9
9
"type": "token",
10
10
"description": "The recipe's canonical ingredient equals a canonical name in the pantry."
11
11
},
12
12
"staple": {
13
13
"type": "token",
14
-
"description": "Not in the pantry, and assumed present anyway because it is on the staples list. An assumption, so it is named on the page rather than folded silently into the coverage."
14
+
"description": "Something the kitchen always holds rather than happens to hold. As a pantryItem `kind`, that is what its owner asserted about it; as a match verdict, it is why the ingredient counted. Said out loud in both places rather than folded silently into the coverage, because 'you keep this around' is a weaker claim than 'you have this right now' and a reader is entitled to tell them apart."
15
15
},
16
16
"missing": {
17
17
"type": "token",
18
-
"description": "Not in the pantry and not a staple. This is what a shopping list is made of."
18
+
"description": "Neither held nor kept on hand. This is what a shopping list is made of."
19
19
},
20
20
"proposed": {
21
21
"type": "token",
22
22
"description": "The name was produced by the normalizer and accepted as offered."
23
23
},
24
24
"quantity": {
25
25
"type": "object",
26
26
"required": [
27
27
"value"
28
28
],
29
29
"properties": {
30
30
"unit": {
31
31
"type": "string",
32
32
"maxLength": 32,
33
33
"description": "Plain lowercase strings rather than tokens, and deliberately open. A person types what they have, and a vocabulary that refused 'punnet' would push the real value into the free text where nothing can read it. The known values are the ones the normalizer emits.",
34
34
"knownValues": [
35
35
"g",
36
36
"kg",
37
37
"ml",
38
38
"l",
39
39
"tsp",
40
40
"tbsp",
41
41
"cup",
42
42
"oz",
43
43
"lb",
44
44
"clove",
45
45
"can",
46
46
"jar",
47
47
"package",
48
48
"piece",
49
49
"slice",
50
50
"stick",
51
51
"pinch",
52
52
"dash",
53
53
"basket",
54
54
"bunch",
55
55
"handful",
56
56
"sprig",
57
57
"stalk",
58
58
"head",
59
59
"bag",
60
60
"box",
61
-
"bottle"
61
+
"bottle",
62
+
"packet",
63
+
"sachet",
64
+
"envelope",
65
+
"tin",
66
+
"tub"
62
67
]
63
68
},
64
69
"value": {
65
70
"type": "number",
66
71
"minimum": 0
67
72
}
68
73
},
69
74
"description": "How much of something there is. Optional wherever it appears: 'some flour' is a legitimate pantry entry, and a recipe that says 'a handful of parsley' has no number to give."
70
75
},
71
76
"unparsed": {
72
77
"type": "token",
73
78
"description": "The normalizer could not reduce the ingredient to a name, so no claim is made about it either way. Distinct from `missing`: one is an answer, the other is a failure to have one."
74
79
},
75
80
"corrected": {
76
81
"type": "token",
77
82
"description": "A person overrode the normalizer's proposal. Every one of these is a case the rules got wrong, which is why it is recorded rather than discarded."
78
83
},
84
+
"ingredient": {
85
+
"type": "token",
86
+
"description": "A pantry item the kitchen happens to hold — a stock level, and the kind that runs out. The default reading of a pantryItem with no `kind`."
87
+
},
79
88
"recipeView": {
80
89
"type": "object",
81
90
"required": [
82
91
"uri",
83
92
"cid",
84
93
"author",
85
94
"name",
86
95
"indexedAt"
87
96
],
88
97
"properties": {
89
98
"cid": {
90
99
"type": "string",
91
100
"format": "cid"
92
101
},
93
102
"uri": {
94
103
"type": "string",
95
104
"format": "at-uri"
96
105
},
97
106
"name": {
98
107
"type": "string",
99
108
"maxLength": 255
100
109
},
101
110
"text": {
102
111
"type": "string",
103
112
"maxLength": 3000
104
113
},
105
114
"author": {
106
115
"type": "string",
107
116
"format": "did"
108
117
},
109
118
"indexedAt": {
110
119
"type": "string",
111
120
"format": "datetime",
112
121
"description": "When this AppView indexed it. Says nothing about when it was written — that is the record's own createdAt."
113
122
},
114
123
"totalTime": {
115
124
"type": "string",
116
125
"format": "duration"
117
126
},
118
127
"recipeCuisine": {
119
128
"type": "string"
120
129
},
121
130
"recipeCategory": {
122
131
"type": "string"
123
132
},
124
133
"suitableForDiet": {
125
134
"type": "array",
126
135
"items": {
127
136
"type": "string"
128
137
}
129
138
}
130
139
},
131
140
"description": "A recipe as this AppView holds it. A projection of exchange.recipe.recipe, not a copy: only the fields a suggestion needs."
132
141
},
133
142
"suggestion": {
134
143
"type": "object",
135
144
"required": [
136
145
"recipe",
137
146
"ingredients",
138
147
"coverage",
139
148
"missing"
140
149
],
141
150
"properties": {
142
151
"recipe": {
143
152
"ref": "#recipeView",
144
153
"type": "ref"
145
154
},
146
155
"missing": {
147
156
"type": "array",
148
157
"items": {
149
158
"type": "string",
150
159
"maxLength": 100
151
160
},
152
161
"description": "The canonical names with verdict `missing`. Empty means cook now."
153
162
},
154
163
"coverage": {
155
164
"type": "number",
156
165
"maximum": 1,
157
166
"minimum": 0,
158
-
"description": "Matched ingredients over total, staples counted as matched, unparsed ingredients counted against — an ingredient we could not read is not an ingredient we have."
167
+
"description": "Matched ingredients over total, items kept on hand counted as matched, unparsed ingredients counted against — an ingredient we could not read is not an ingredient we have."
159
168
},
160
169
"unreadable": {
161
170
"type": "integer",
162
171
"minimum": 0,
163
172
"description": "How many ingredients came back unparsed. Surfaced next to the result rather than hidden, so a suspiciously poor match is legible as a normalizer failure instead of a missing ingredient."
164
173
},
165
174
"ingredients": {
166
175
"type": "array",
167
176
"items": {
168
177
"ref": "#ingredientMatch",
169
178
"type": "ref"
170
179
}
171
180
}
172
181
},
173
182
"description": "One recipe measured against one pantry."
174
183
},
175
184
"ingredientMatch": {
176
185
"type": "object",
177
186
"required": [
178
187
"raw",
179
188
"verdict"
180
189
],
181
190
"properties": {
182
191
"raw": {
183
192
"type": "string",
184
193
"maxLength": 500,
185
194
"description": "The ingredient exactly as the recipe wrote it."
186
195
},
187
196
"verdict": {
188
197
"type": "string",
189
198
"knownValues": [
190
199
"ink.igav.whatmealtodo.defs#exact",
191
200
"ink.igav.whatmealtodo.defs#head",
192
201
"ink.igav.whatmealtodo.defs#staple",
193
202
"ink.igav.whatmealtodo.defs#missing",
194
203
"ink.igav.whatmealtodo.defs#unparsed"
195
204
]
196
205
},
197
206
"canonical": {
198
207
"type": "string",
199
208
"maxLength": 100,
200
209
"description": "What the normalizer reduced it to. Absent when the verdict is unparsed."
201
210
}
202
211
},
203
212
"description": "One recipe ingredient, and what became of it. Carried per ingredient rather than summarised, because a coverage number with no account of how it was reached is indistinguishable from a bug."
204
213
}
205
214
},
206
215
"$type": "com.atproto.lexicon.schema",
207
216
"lexicon": 1
208
217
}