community.gifthood.listing
Schema Diff
+27 -1
Compatibility Analysis
Breaking Changes Detected
2 breaking changes, 10 non-breaking changes.
Breaking Changes (2)
- ConstraintTightened ConstraintTightened { vertex_id: "community.gifthood.listing:body.category", sort: "enum", old_value: "furniture,kitchen,clothing,baby,books,electronics,tools,garden,health,pets,hobbies,food,animals,service,other", new_value: "furniture,kitchen,clothing,baby,books,instruments,electronics,tools,garden,health,pets,hobbies,food,animals,service,office,other" }
- ConstraintAdded ConstraintAdded { vertex_id: "community.gifthood.listing:body.mode", sort: "enum", value: "gift,lend" }
Non-Breaking Changes (10)
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.facets" }
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.facets:items" }
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.mode" }
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.paused" }
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.standing" }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.facets", kind: "prop", name: Some("facets") }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.mode", kind: "prop", name: Some("mode") }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.paused", kind: "prop", name: Some("paused") }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.standing", kind: "prop", name: Some("standing") }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body.facets", tgt: "community.gifthood.listing:body.facets:items", kind: "items", name: None }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "community.gifthood.listing:body.facets" }AddedVertex { vertex_id: "community.gifthood.listing:body.facets:items" }AddedVertex { vertex_id: "community.gifthood.listing:body.mode" }AddedVertex { vertex_id: "community.gifthood.listing:body.paused" }AddedVertex { vertex_id: "community.gifthood.listing:body.standing" }
Constraint Changes
- ConstraintAdded ConstraintAdded { vertex_id: "community.gifthood.listing:body.mode", sort: "enum", value: "gift,lend" }
- ConstraintTightened ConstraintTightened { vertex_id: "community.gifthood.listing:body.category", sort: "enum", old_value: "furniture,kitchen,clothing,baby,books,electronics,tools,garden,health,pets,hobbies,food,animals,service,other", new_value: "furniture,kitchen,clothing,baby,books,instruments,electronics,tools,garden,health,pets,hobbies,food,animals,service,office,other" }
Additional Notes
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.facets", kind: "prop", name: Some("facets") }
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.mode", kind: "prop", name: Some("mode") }
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.paused", kind: "prop", name: Some("paused") }
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.standing", kind: "prop", name: Some("standing") }
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body.facets", tgt: "community.gifthood.listing:body.facets:items", kind: "items", name: None }
1
1
{
2
2
"id": "community.gifthood.listing",
3
3
"defs": {
4
4
"main": {
5
5
"key": "tid",
6
6
"type": "record",
7
7
"record": {
8
8
"type": "object",
9
9
"required": [
10
10
"title",
11
11
"intent",
12
12
"description",
13
13
"geohash",
14
14
"createdAt"
15
15
],
16
16
"properties": {
17
+
"mode": {
18
+
"enum": [
19
+
"gift",
20
+
"lend"
21
+
],
22
+
"type": "string",
23
+
"description": "How the item changes hands. 'gift' (the default when absent) transfers ownership; 'lend' expects the item back — the listing behaves as a standing offer and each exchange gains a return leg (see exchange.returnedAt). Readers MUST treat unknown or missing values as 'gift'."
24
+
},
17
25
"langs": {
18
26
"type": "array",
19
27
"items": {
20
28
"type": "string",
21
29
"format": "language"
22
30
},
23
31
"maxLength": 3,
24
32
"description": "Language(s) the content is written in, as BCP-47 language tags. Author-asserted; clients default from the composer's locale."
25
33
},
26
34
"title": {
27
35
"type": "string",
28
36
"maxLength": 200,
29
37
"minLength": 1,
30
38
"description": "Required short title for the item being offered or requested.",
31
39
"maxGraphemes": 100,
32
40
"minGraphemes": 1
33
41
},
42
+
"facets": {
43
+
"type": "array",
44
+
"items": {
45
+
"ref": "app.bsky.richtext.facet",
46
+
"type": "ref"
47
+
},
48
+
"description": "Annotations over `description` (mentions, links) keyed by UTF-8 byte range. Reuses app.bsky.richtext.facet for atmosphere-wide interop. Author-asserted at compose time; clients MUST treat them as display hints, re-validate ranges, and never trust a facet URI over the visible text. Addresses and phone numbers are deliberately NOT faceted here — those affordances are private-message-only."
49
+
},
34
50
"images": {
35
51
"type": "array",
36
52
"items": {
37
53
"type": "blob",
38
54
"accept": [
39
55
"image/jpeg",
40
56
"image/png",
41
57
"image/webp"
42
58
],
43
59
"maxSize": 1000000
44
60
},
45
61
"maxLength": 4,
46
62
"description": "Up to 4 images of the item, stored as blobs in the poster's repo."
47
63
},
48
64
"intent": {
49
65
"enum": [
50
66
"offer",
51
67
"request"
52
68
],
53
69
"type": "string",
54
70
"description": "Whether the poster is giving away an item or looking for one."
55
71
},
56
72
"labels": {
57
73
"refs": [
58
74
"com.atproto.label.defs#selfLabels"
59
75
],
60
76
"type": "union",
61
77
"description": "Self-labels set by the author. Used to flag mature/adult content (e.g. the global 'sexual' value), which the AppView gates behind an opt-in."
62
78
},
79
+
"paused": {
80
+
"type": "boolean",
81
+
"description": "Owner-set temporary unavailability (using the item themselves, away for a while). AppViews hide paused listings from feeds but keep the detail view reachable with interest disabled. Absent means active. Orthogonal to status; 'gone' still wins."
82
+
},
63
83
"status": {
64
84
"enum": [
65
85
"available",
66
86
"pending",
67
87
"gone"
68
88
],
69
89
"type": "string",
70
90
"description": "Current availability. Clients should treat a missing value as 'available'."
71
91
},
72
92
"geohash": {
73
93
"type": "string",
74
94
"maxLength": 6,
75
95
"minLength": 1,
76
96
"description": "Approximate location as a geohash, precision 6 (~1.2km cell). This is a privacy floor: indexers MUST truncate any finer-precision value to 6 characters before indexing or display."
77
97
},
78
98
"category": {
79
99
"enum": [
80
100
"furniture",
81
101
"kitchen",
82
102
"clothing",
83
103
"baby",
84
104
"books",
105
+
"instruments",
85
106
"electronics",
86
107
"tools",
87
108
"garden",
88
109
"health",
89
110
"pets",
90
111
"hobbies",
91
112
"food",
92
113
"animals",
93
114
"service",
115
+
"office",
94
116
"other"
95
117
],
96
118
"type": "string",
97
-
"description": "Optional single-level category for opt-out feed filtering. Append-only enum; unknown or missing values index as 'other'. Never used for proximity or safety logic."
119
+
"description": "Optional single-level category for opt-out feed filtering. Additive-only enum (values may be inserted, never removed or renamed); unknown or missing values index as 'other'. Never used for proximity or safety logic."
120
+
},
121
+
"standing": {
122
+
"type": "boolean",
123
+
"description": "Standing (renewing) offer: the owner can run exchange chains with multiple neighbors over time. Absent or false means the listing is exhausted by a single exchange. AppViews keep a standing listing available while chains run; only the owner's manual 'gone' ends it."
98
124
},
99
125
"createdAt": {
100
126
"type": "string",
101
127
"format": "datetime"
102
128
},
103
129
"imageAlts": {
104
130
"type": "array",
105
131
"items": {
106
132
"type": "string",
107
133
"maxGraphemes": 1000
108
134
},
109
135
"maxLength": 4,
110
136
"description": "Alt text for images, parallel to the images array by index."
111
137
},
112
138
"description": {
113
139
"type": "string",
114
140
"maxLength": 3000,
115
141
"minLength": 1,
116
142
"description": "Required free text describing the item being offered or requested.",
117
143
"maxGraphemes": 1500,
118
144
"minGraphemes": 1
119
145
},
120
146
"locationName": {
121
147
"type": "string",
122
148
"maxLength": 300,
123
149
"description": "Optional human-readable area name. App-populated via reverse geocoding of the geohash cell. Display only; MUST NOT be used for proximity matching or filtering.",
124
150
"maxGraphemes": 100
125
151
}
126
152
}
127
153
},
128
154
"description": "An offer or request for a free item, discoverable by approximate location."
129
155
}
130
156
},
131
157
"$type": "com.atproto.lexicon.schema",
132
158
"lexicon": 1
133
159
}