app.zeens.profile
Schema Diff
+21 -5
Compatibility Analysis
Breaking Changes Detected
1 breaking change, 4 non-breaking changes.
Breaking Changes (1)
- ConstraintTightened ConstraintTightened { vertex_id: "app.zeens.profile#socialLink.platform", sort: "knownValues", old_value: "[\"bluesky\",\"mastodon\",\"pixelfed\",\"flickr\",\"glass\",\"vsco\",\"500px\",\"behance\",\"youtube\",\"kofi\",\"patreon\",\"grain\",\"flashes\"]", new_value: "[\"bluesky\",\"mastodon\",\"pixelfed\",\"flickr\",\"glass\",\"vsco\",\"500px\",\"behance\",\"youtube\",\"kofi\",\"patreon\",\"grain\",\"flashes\",\"link\"]" }
Non-Breaking Changes (4)
- AddedVertex AddedVertex { vertex_id: "app.zeens.profile#socialLink.icon" }
- AddedVertex AddedVertex { vertex_id: "app.zeens.profile#socialLink.title" }
- AddedEdge AddedEdge { src: "app.zeens.profile#socialLink", tgt: "app.zeens.profile#socialLink.icon", kind: "prop", name: Some("icon") }
- AddedEdge AddedEdge { src: "app.zeens.profile#socialLink", tgt: "app.zeens.profile#socialLink.title", kind: "prop", name: Some("title") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "app.zeens.profile#socialLink.icon" }AddedVertex { vertex_id: "app.zeens.profile#socialLink.title" }
Constraint Changes
- ConstraintTightened ConstraintTightened { vertex_id: "app.zeens.profile#socialLink.platform", sort: "knownValues", old_value: "[\"bluesky\",\"mastodon\",\"pixelfed\",\"flickr\",\"glass\",\"vsco\",\"500px\",\"behance\",\"youtube\",\"kofi\",\"patreon\",\"grain\",\"flashes\"]", new_value: "[\"bluesky\",\"mastodon\",\"pixelfed\",\"flickr\",\"glass\",\"vsco\",\"500px\",\"behance\",\"youtube\",\"kofi\",\"patreon\",\"grain\",\"flashes\",\"link\"]" }
Additional Notes
- Non-breaking: AddedEdge { src: "app.zeens.profile#socialLink", tgt: "app.zeens.profile#socialLink.icon", kind: "prop", name: Some("icon") }
- Non-breaking: AddedEdge { src: "app.zeens.profile#socialLink", tgt: "app.zeens.profile#socialLink.title", kind: "prop", name: Some("title") }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"main": {
5
5
"description": "Zeens-specific profile extensions. Stored on the user's own PDS so the data is portable — Zeens reads it on top of app.bsky.actor.profile to render extras like social links. The Bluesky profile (name, avatar, banner, bio) remains the canonical identity.",
6
6
"key": "literal:self",
7
7
"record": {
8
8
"properties": {
9
9
"$type": {
10
10
"const": "app.zeens.profile",
11
11
"type": "string"
12
12
},
13
13
"bio": {
14
14
"description": "Zeens-specific bio. Replaces the Bluesky description on Zeens profile pages. Independent from app.bsky.actor.profile.description.",
15
15
"maxGraphemes": 256,
16
16
"maxLength": 2560,
17
17
"type": "string"
18
18
},
19
19
"socials": {
20
-
"description": "Links to the user's profiles on other photo and ATProto-friendly networks. Capped at 6 entries; order is preserved.",
20
+
"description": "The member's profile links, in the order shown. Any https link: services Zeens recognises are stored under their platform id and drawn with that service's icon, everything else as 'link' with the site's own favicon. Capped at 6 entries; order is preserved.",
21
21
"items": {
22
22
"ref": "#socialLink",
23
23
"type": "ref"
24
24
},
25
25
"maxLength": 6,
26
26
"type": "array"
27
27
},
28
28
"website": {
29
-
"description": "A single personal website URL. Must be https. Capped at 200 chars.",
29
+
"description": "LEGACY. A single personal website URL, from before profile links became one list. Readers show it as the first link; Zeens moves it into `socials` (as a 'link') and drops this field the next time the member saves. New writers should not set it.",
30
30
"format": "uri",
31
31
"maxLength": 200,
32
32
"type": "string"
33
33
}
34
34
},
35
35
"required": [],
36
36
"type": "object"
37
37
},
38
38
"type": "record"
39
39
},
40
40
"socialLink": {
41
+
"description": "One profile link.",
41
42
"properties": {
42
43
"handle": {
43
-
"description": "The user's handle on that platform. For Mastodon/Pixelfed: user@instance. For others: bare username.",
44
+
"description": "The link's full https URL. Records written before links were URL-only may hold a bare username here (user@instance for Mastodon/Pixelfed).",
44
45
"maxLength": 100,
45
46
"type": "string"
46
47
},
48
+
"icon": {
49
+
"accept": [
50
+
"image/png"
51
+
],
52
+
"description": "A plain link's favicon, fetched when the link was added and re-encoded as a 64px PNG. Absent = draw a generic link mark.",
53
+
"maxSize": 65536,
54
+
"type": "blob"
55
+
},
47
56
"platform": {
48
-
"description": "Identifier for the social network. Zeens maps this to a URL template at render time.",
57
+
"description": "The service the link belongs to, detected from the URL rather than chosen. 'link' is any site Zeens does not recognise. Readers should treat an unknown value as 'link'.",
49
58
"knownValues": [
50
59
"bluesky",
51
60
"mastodon",
52
61
"pixelfed",
53
62
"flickr",
54
63
"glass",
55
64
"vsco",
56
65
"500px",
57
66
"behance",
58
67
"youtube",
59
68
"kofi",
60
69
"patreon",
61
70
"grain",
62
-
"flashes"
71
+
"flashes",
72
+
"link"
63
73
],
64
74
"type": "string"
75
+
},
76
+
"title": {
77
+
"description": "A plain link's site name, read from the site (og:site_name, else its page title) when the link was added. Not member-entered. Absent = show the host. Ignored for recognised services, which show the service's name.",
78
+
"maxGraphemes": 80,
79
+
"maxLength": 800,
80
+
"type": "string"
65
81
}
66
82
},
67
83
"required": [
68
84
"platform",
69
85
"handle"
70
86
],
71
87
"type": "object"
72
88
}
73
89
},
74
90
"id": "app.zeens.profile",
75
91
"lexicon": 1
76
92
}