community.gifthood.listing
Schema Diff
+63 -0
Compatibility Analysis
Breaking Changes Detected
2 breaking changes, 20 non-breaking changes.
Breaking Changes (2)
- ConstraintAdded ConstraintAdded { vertex_id: "community.gifthood.listing:body.mode", sort: "enum", value: "gift,lend" }
- ConstraintAdded ConstraintAdded { vertex_id: "community.gifthood.listing:body.category", sort: "enum", value: "furniture,kitchen,clothing,baby,books,instruments,electronics,tools,garden,health,pets,hobbies,food,animals,service,office,other" }
Non-Breaking Changes (20)
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.category" }
- 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.labels" }
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.labels:variant0" }
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.langs" }
- AddedVertex AddedVertex { vertex_id: "community.gifthood.listing:body.langs: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.category", kind: "prop", name: Some("category") }
- 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.labels", kind: "prop", name: Some("labels") }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.langs", kind: "prop", name: Some("langs") }
- 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 }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body.labels", tgt: "community.gifthood.listing:body.labels:variant0", kind: "variant", name: Some("com.atproto.label.defs#selfLabels") }
- AddedEdge AddedEdge { src: "community.gifthood.listing:body.langs", tgt: "community.gifthood.listing:body.langs:items", kind: "items", name: None }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "community.gifthood.listing:body.category" }AddedVertex { vertex_id: "community.gifthood.listing:body.facets" }AddedVertex { vertex_id: "community.gifthood.listing:body.facets:items" }AddedVertex { vertex_id: "community.gifthood.listing:body.labels" }AddedVertex { vertex_id: "community.gifthood.listing:body.labels:variant0" }AddedVertex { vertex_id: "community.gifthood.listing:body.langs" }AddedVertex { vertex_id: "community.gifthood.listing:body.langs: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" }
- ConstraintAdded ConstraintAdded { vertex_id: "community.gifthood.listing:body.category", sort: "enum", 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.category", kind: "prop", name: Some("category") }
- 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.labels", kind: "prop", name: Some("labels") }
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body", tgt: "community.gifthood.listing:body.langs", kind: "prop", name: Some("langs") }
- 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 }
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body.labels", tgt: "community.gifthood.listing:body.labels:variant0", kind: "variant", name: Some("com.atproto.label.defs#selfLabels") }
- Non-breaking: AddedEdge { src: "community.gifthood.listing:body.langs", tgt: "community.gifthood.listing:body.langs: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
+
},
25
+
"langs": {
26
+
"type": "array",
27
+
"items": {
28
+
"type": "string",
29
+
"format": "language"
30
+
},
31
+
"maxLength": 3,
32
+
"description": "Language(s) the content is written in, as BCP-47 language tags. Author-asserted; clients default from the composer's locale."
33
+
},
17
34
"title": {
18
35
"type": "string",
19
36
"maxLength": 200,
20
37
"minLength": 1,
21
38
"description": "Required short title for the item being offered or requested.",
22
39
"maxGraphemes": 100,
23
40
"minGraphemes": 1
24
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
+
},
25
50
"images": {
26
51
"type": "array",
27
52
"items": {
28
53
"type": "blob",
29
54
"accept": [
30
55
"image/jpeg",
31
56
"image/png",
32
57
"image/webp"
33
58
],
34
59
"maxSize": 1000000
35
60
},
36
61
"maxLength": 4,
37
62
"description": "Up to 4 images of the item, stored as blobs in the poster's repo."
38
63
},
39
64
"intent": {
40
65
"enum": [
41
66
"offer",
42
67
"request"
43
68
],
44
69
"type": "string",
45
70
"description": "Whether the poster is giving away an item or looking for one."
46
71
},
72
+
"labels": {
73
+
"refs": [
74
+
"com.atproto.label.defs#selfLabels"
75
+
],
76
+
"type": "union",
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."
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
+
},
47
83
"status": {
48
84
"enum": [
49
85
"available",
50
86
"pending",
51
87
"gone"
52
88
],
53
89
"type": "string",
54
90
"description": "Current availability. Clients should treat a missing value as 'available'."
55
91
},
56
92
"geohash": {
57
93
"type": "string",
58
94
"maxLength": 6,
59
95
"minLength": 1,
60
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."
61
97
},
98
+
"category": {
99
+
"enum": [
100
+
"furniture",
101
+
"kitchen",
102
+
"clothing",
103
+
"baby",
104
+
"books",
105
+
"instruments",
106
+
"electronics",
107
+
"tools",
108
+
"garden",
109
+
"health",
110
+
"pets",
111
+
"hobbies",
112
+
"food",
113
+
"animals",
114
+
"service",
115
+
"office",
116
+
"other"
117
+
],
118
+
"type": "string",
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."
124
+
},
62
125
"createdAt": {
63
126
"type": "string",
64
127
"format": "datetime"
65
128
},
66
129
"imageAlts": {
67
130
"type": "array",
68
131
"items": {
69
132
"type": "string",
70
133
"maxGraphemes": 1000
71
134
},
72
135
"maxLength": 4,
73
136
"description": "Alt text for images, parallel to the images array by index."
74
137
},
75
138
"description": {
76
139
"type": "string",
77
140
"maxLength": 3000,
78
141
"minLength": 1,
79
142
"description": "Required free text describing the item being offered or requested.",
80
143
"maxGraphemes": 1500,
81
144
"minGraphemes": 1
82
145
},
83
146
"locationName": {
84
147
"type": "string",
85
148
"maxLength": 300,
86
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.",
87
150
"maxGraphemes": 100
88
151
}
89
152
}
90
153
},
91
154
"description": "An offer or request for a free item, discoverable by approximate location."
92
155
}
93
156
},
94
157
"$type": "com.atproto.lexicon.schema",
95
158
"lexicon": 1
96
159
}