fyi.atstore.listing.detail

atstore.fyi

Schema Diff

+106 -14

From

CID
bafyreic22wkhhdd...
Indexed At
2026-04-10 06:13 UTC
View this version

To

CID
bafyreics2gap553...
Indexed At
2026-05-02 07:46 UTC
View this version

Compatibility Analysis

Breaking Changes Detected

7 breaking changes, 27 non-breaking changes.

Breaking Changes (7)
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "fyi.atstore.listing.detail#link", src: "fyi.atstore.listing.detail#link", tgt: "fyi.atstore.listing.detail#link.url", kind: "prop", name: Some("url") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "fyi.atstore.listing.detail#link", src: "fyi.atstore.listing.detail#link", tgt: "fyi.atstore.listing.detail#link.type", kind: "prop", name: Some("type") }
  • RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "fyi.atstore.listing.detail:body", src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.heroImage", kind: "prop", name: Some("heroImage") }
  • KindChanged KindChanged { vertex_id: "fyi.atstore.listing.detail:body.categorySlug", old_kind: "string", new_kind: "array" }
  • KindChanged KindChanged { vertex_id: "fyi.atstore.listing.detail:body.heroImage", old_kind: "string", new_kind: "blob" }
  • KindChanged KindChanged { vertex_id: "fyi.atstore.listing.detail:body.icon", old_kind: "string", new_kind: "blob" }
  • KindChanged KindChanged { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", old_kind: "string", new_kind: "blob" }
Non-Breaking Changes (27)
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail#link" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail#link.label" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail#link.type" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail#link.url" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.appTags" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.appTags:items" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.categorySlug:items" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.links" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.links:items" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.migratedFromAtUri" }
  • AddedVertex AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.productAccountDid" }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail#link", tgt: "fyi.atstore.listing.detail#link.label", kind: "prop", name: Some("label") }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.appTags", kind: "prop", name: Some("appTags") }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.links", kind: "prop", name: Some("links") }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.migratedFromAtUri", kind: "prop", name: Some("migratedFromAtUri") }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.productAccountDid", kind: "prop", name: Some("productAccountDid") }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body.appTags", tgt: "fyi.atstore.listing.detail:body.appTags:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body.categorySlug", tgt: "fyi.atstore.listing.detail:body.categorySlug:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body.links", tgt: "fyi.atstore.listing.detail:body.links:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "fyi.atstore.listing.detail:body.links:items", tgt: "fyi.atstore.listing.detail#link", kind: "ref", name: None }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.categorySlug", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.icon", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.icon", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.heroImage", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.heroImage", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", sort: "maxLength" }

Migration Guidance

Added Elements

  • AddedVertex { vertex_id: "fyi.atstore.listing.detail#link" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail#link.label" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail#link.type" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail#link.url" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.appTags" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.appTags:items" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.categorySlug:items" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.links" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.links:items" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.migratedFromAtUri" }
  • AddedVertex { vertex_id: "fyi.atstore.listing.detail:body.productAccountDid" }

Constraint Changes

  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.categorySlug", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.icon", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.icon", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.heroImage", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.heroImage", sort: "format" }

Additional Notes

  • Breaking: RequiredEdgeAdded { vertex_id: "fyi.atstore.listing.detail#link", src: "fyi.atstore.listing.detail#link", tgt: "fyi.atstore.listing.detail#link.url", kind: "prop", name: Some("url") }
  • Breaking: RequiredEdgeAdded { vertex_id: "fyi.atstore.listing.detail#link", src: "fyi.atstore.listing.detail#link", tgt: "fyi.atstore.listing.detail#link.type", kind: "prop", name: Some("type") }
  • Breaking: RequiredEdgeRemoved { vertex_id: "fyi.atstore.listing.detail:body", src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.heroImage", kind: "prop", name: Some("heroImage") }
  • Breaking: KindChanged { vertex_id: "fyi.atstore.listing.detail:body.categorySlug", old_kind: "string", new_kind: "array" }
  • Breaking: KindChanged { vertex_id: "fyi.atstore.listing.detail:body.heroImage", old_kind: "string", new_kind: "blob" }
  • Breaking: KindChanged { vertex_id: "fyi.atstore.listing.detail:body.icon", old_kind: "string", new_kind: "blob" }
  • Breaking: KindChanged { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", old_kind: "string", new_kind: "blob" }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail#link", tgt: "fyi.atstore.listing.detail#link.label", kind: "prop", name: Some("label") }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.appTags", kind: "prop", name: Some("appTags") }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.links", kind: "prop", name: Some("links") }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.migratedFromAtUri", kind: "prop", name: Some("migratedFromAtUri") }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body", tgt: "fyi.atstore.listing.detail:body.productAccountDid", kind: "prop", name: Some("productAccountDid") }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body.appTags", tgt: "fyi.atstore.listing.detail:body.appTags:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body.categorySlug", tgt: "fyi.atstore.listing.detail:body.categorySlug:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body.links", tgt: "fyi.atstore.listing.detail:body.links:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "fyi.atstore.listing.detail:body.links:items", tgt: "fyi.atstore.listing.detail#link", kind: "ref", name: None }
1 1
{
2 2
  "id": "fyi.atstore.listing.detail",
3 3
  "defs": {
4 +
    "link": {
5 +
      "type": "object",
6 +
      "required": [
7 +
        "type",
8 +
        "url"
9 +
      ],
10 +
      "properties": {
11 +
        "url": {
12 +
          "type": "string",
13 +
          "format": "uri",
14 +
          "maxLength": 2048,
15 +
          "description": "The destination URL."
16 +
        },
17 +
        "type": {
18 +
          "type": "string",
19 +
          "maxLength": 32,
20 +
          "description": "The kind of link.",
21 +
          "knownValues": [
22 +
            "privacy",
23 +
            "terms",
24 +
            "support",
25 +
            "contact",
26 +
            "docs",
27 +
            "blog",
28 +
            "changelog",
29 +
            "source",
30 +
            "status",
31 +
            "community",
32 +
            "donate",
33 +
            "license",
34 +
            "other"
35 +
          ]
36 +
        },
37 +
        "label": {
38 +
          "type": "string",
39 +
          "maxLength": 100,
40 +
          "description": "Optional human-readable label, especially useful when type is 'other'.",
41 +
          "maxGraphemes": 50
42 +
        }
43 +
      }
44 +
    },
4 45
    "main": {
5 46
      "key": "tid",
6 47
      "type": "record",
7 48
      "record": {
8 49
        "type": "object",
9 50
        "required": [
10 51
          "slug",
11 52
          "name",
12 53
          "tagline",
13 54
          "externalUrl",
14 55
          "icon",
15 -
          "heroImage",
16 56
          "categorySlug",
17 57
          "createdAt",
18 58
          "updatedAt"
19 59
        ],
20 60
        "properties": {
21 61
          "icon": {
22 -
            "type": "string",
23 -
            "format": "uri",
24 -
            "maxLength": 2048
62 +
            "type": "blob",
63 +
            "accept": [
64 +
              "image/png",
65 +
              "image/jpeg",
66 +
              "image/webp",
67 +
              "image/gif",
68 +
              "image/svg+xml"
69 +
            ],
70 +
            "maxSize": 2000000,
71 +
            "description": "Square / app icon (uploaded to repo via com.atproto.repo.uploadBlob)."
25 72
          },
26 73
          "name": {
27 74
            "type": "string",
28 75
            "maxLength": 640
29 76
          },
30 77
          "slug": {
31 78
            "type": "string",
32 79
            "maxLength": 512,
33 80
            "minLength": 1,
34 81
            "description": "Stable URL slug; unique within the publishing account."
35 82
          },
83 +
          "links": {
84 +
            "type": "array",
85 +
            "items": {
86 +
              "ref": "#link",
87 +
              "type": "ref"
88 +
            },
89 +
            "maxLength": 12,
90 +
            "description": "Relevant links for the app, including trust/compliance, support, and project resources."
91 +
          },
92 +
          "appTags": {
93 +
            "type": "array",
94 +
            "items": {
95 +
              "type": "string",
96 +
              "maxLength": 96
97 +
            },
98 +
            "maxLength": 64
99 +
          },
36 100
          "tagline": {
37 101
            "type": "string",
38 102
            "maxLength": 300
39 103
          },
40 104
          "createdAt": {
41 105
            "type": "string",
42 106
            "format": "datetime"
43 107
          },
44 108
          "heroImage": {
45 -
            "type": "string",
46 -
            "format": "uri",
47 -
            "maxLength": 2048,
48 -
            "description": "Hero / cover image (HTTPS URL)."
109 +
            "type": "blob",
110 +
            "accept": [
111 +
              "image/png",
112 +
              "image/jpeg",
113 +
              "image/webp",
114 +
              "image/gif",
115 +
              "image/svg+xml"
116 +
            ],
117 +
            "maxSize": 12000000,
118 +
            "description": "Hero / cover image blob."
49 119
          },
50 120
          "updatedAt": {
51 121
            "type": "string",
52 122
            "format": "datetime"
53 123
          },
54 124
          "description": {
55 125
            "type": "string",
56 126
            "maxLength": 20000
57 127
          },
58 128
          "externalUrl": {
59 129
            "type": "string",
60 130
            "format": "uri",
61 131
            "maxLength": 2048,
62 132
            "description": "Primary product or project URL."
63 133
          },
64 134
          "screenshots": {
65 135
            "type": "array",
66 136
            "items": {
67 -
              "type": "string",
68 -
              "format": "uri",
69 -
              "maxLength": 2048
137 +
              "type": "blob",
138 +
              "accept": [
139 +
                "image/png",
140 +
                "image/jpeg",
141 +
                "image/webp",
142 +
                "image/gif",
143 +
                "image/svg+xml"
144 +
              ],
145 +
              "maxSize": 12000000
70 146
            },
71 147
            "maxLength": 20
72 148
          },
73 149
          "categorySlug": {
150 +
            "type": "array",
151 +
            "items": {
152 +
              "type": "string",
153 +
              "maxLength": 256
154 +
            },
155 +
            "maxLength": 32,
156 +
            "minLength": 1,
157 +
            "description": "Browse category keys (e.g. protocol/pds). First entry is the primary category for legacy surfaces."
158 +
          },
159 +
          "migratedFromAtUri": {
74 160
            "type": "string",
75 -
            "maxLength": 256,
76 -
            "description": "Single browse category key (e.g. protocol/pds)."
161 +
            "format": "at-uri",
162 +
            "maxLength": 8192,
163 +
            "description": "When this listing.detail record supersedes a prior record in another repo (e.g. moved from the AT Store publisher to a product owner PDS), the at:// URI of that prior fyi.atstore.listing.detail record."
164 +
          },
165 +
          "productAccountDid": {
166 +
            "type": "string",
167 +
            "maxLength": 2048,
168 +
            "description": "Bluesky DID for the product, app, or tool (not the AT Store publisher). Handle is resolved and stored in Postgres only."
77 169
          }
78 170
        }
79 171
      },
80 -
      "description": "Public protocol or app listing in the AT Store directory."
172 +
      "description": "Public protocol or app listing in the AT Store directory. Images are stored as repo blobs (Kitchen-style); the web app caches HTTPS URLs in Postgres separately."
81 173
    }
82 174
  },
83 175
  "$type": "com.atproto.lexicon.schema",
84 176
  "lexicon": 1
85 177
}

Compare Other Versions

Lexicon Garden

@