community.gifthood.listing

gifthood.community

Schema Diff

+27 -1

From

CID
bafyreibaq7x5yvi...
Indexed At
2026-06-13 00:08 UTC
View this version

To

CID
bafyreibsln4ltai...
Indexed At
2026-07-20 06:01 UTC
View this version

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
}

Compare Other Versions

Lexicon Garden

@