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.type", kind: "prop", name: Some("type") }
  • 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") }
  • 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.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.heroImage", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.heroImage", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.icon", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.icon", sort: "format" }

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.categorySlug", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.screenshots:items", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.heroImage", sort: "format" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "fyi.atstore.listing.detail:body.heroImage", 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" }

Additional Notes

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

Compare Other Versions

Lexicon Garden

@