page.mooring.site
Schema Diff
+14 -0
Compatibility Analysis
Backward Compatible
Backward compatible. 4 non-breaking changes.
Non-Breaking Changes (4)
- AddedVertex AddedVertex { vertex_id: "page.mooring.site#heroSection.style" }
- AddedVertex AddedVertex { vertex_id: "page.mooring.site:body.contactEmail" }
- AddedEdge AddedEdge { src: "page.mooring.site#heroSection", tgt: "page.mooring.site#heroSection.style", kind: "prop", name: Some("style") }
- AddedEdge AddedEdge { src: "page.mooring.site:body", tgt: "page.mooring.site:body.contactEmail", kind: "prop", name: Some("contactEmail") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "page.mooring.site#heroSection.style" }AddedVertex { vertex_id: "page.mooring.site:body.contactEmail" }
Additional Notes
- Non-breaking: AddedEdge { src: "page.mooring.site#heroSection", tgt: "page.mooring.site#heroSection.style", kind: "prop", name: Some("style") }
- Non-breaking: AddedEdge { src: "page.mooring.site:body", tgt: "page.mooring.site:body.contactEmail", kind: "prop", name: Some("contactEmail") }
1
1
{
2
2
"id": "page.mooring.site",
3
3
"defs": {
4
4
"rgb": {
5
5
"type": "object",
6
6
"required": [
7
7
"r",
8
8
"g",
9
9
"b"
10
10
],
11
11
"properties": {
12
12
"b": {
13
13
"type": "integer",
14
14
"maximum": 255,
15
15
"minimum": 0
16
16
},
17
17
"g": {
18
18
"type": "integer",
19
19
"maximum": 255,
20
20
"minimum": 0
21
21
},
22
22
"r": {
23
23
"type": "integer",
24
24
"maximum": 255,
25
25
"minimum": 0
26
26
}
27
27
}
28
28
},
29
29
"main": {
30
30
"key": "any",
31
31
"type": "record",
32
32
"record": {
33
33
"type": "object",
34
34
"required": [
35
35
"createdAt"
36
36
],
37
37
"properties": {
38
38
"icon": {
39
39
"type": "blob",
40
40
"accept": [
41
41
"image/*"
42
42
],
43
43
"maxSize": 1000000,
44
44
"description": "Square image used as the site icon/favicon. Should be at least 256x256."
45
45
},
46
46
"name": {
47
47
"type": "string",
48
48
"maxLength": 5000,
49
49
"description": "Site title. When absent, renderers should fall back to the owner's profile displayName or handle.",
50
50
"maxGraphemes": 500
51
51
},
52
52
"theme": {
53
53
"ref": "#theme",
54
54
"type": "ref"
55
55
},
56
56
"labels": {
57
57
"refs": [
58
58
"com.atproto.label.defs#selfLabels"
59
59
],
60
60
"type": "union"
61
61
},
62
62
"sections": {
63
63
"type": "array",
64
64
"items": {
65
65
"refs": [
66
66
"#heroSection",
67
67
"#postsSection",
68
68
"#writingSection",
69
69
"#careerSection",
70
70
"#pagesSection"
71
71
],
72
72
"type": "union",
73
73
"closed": false
74
74
},
75
75
"maxLength": 50,
76
76
"description": "Ordered sections of the site, rendered top to bottom; order is array position. When absent, renderers should use a sensible default order based on which sources have data."
77
77
},
78
78
"createdAt": {
79
79
"type": "string",
80
80
"format": "datetime",
81
81
"description": "Client-declared timestamp when this record was created."
82
82
},
83
83
"description": {
84
84
"type": "string",
85
85
"maxLength": 30000,
86
86
"description": "Short description of the site, used for meta tags and previews.",
87
87
"maxGraphemes": 3000
88
88
},
89
+
"contactEmail": {
90
+
"type": "string",
91
+
"maxLength": 2540,
92
+
"description": "Public contact email, rendered as a contact affordance on the site. Publishing an address here makes it world-readable.",
93
+
"maxGraphemes": 254
94
+
},
89
95
"discoverable": {
90
96
"type": "boolean",
91
97
"description": "Default true when absent. When false, the renderer emits noindex directives for the site. Does not affect the public visibility of the underlying atproto records."
92
98
}
93
99
}
94
100
},
95
101
"description": "A Mooring site. Every field except createdAt is optional: an empty record is a valid site, and the renderer falls back to the owner's profile records and a default section order."
96
102
},
97
103
"theme": {
98
104
"type": "object",
99
105
"properties": {
100
106
"colors": {
101
107
"ref": "#colors",
102
108
"type": "ref"
103
109
},
104
110
"preset": {
105
111
"type": "string",
106
112
"description": "Named theme preset. Unknown values should fall back to the renderer's default preset.",
107
113
"knownValues": [
108
114
"classic"
109
115
]
110
116
}
111
117
},
112
118
"description": "Theme selection and overrides. All fields optional; renderer defaults apply."
113
119
},
114
120
"colors": {
115
121
"type": "object",
116
122
"properties": {
117
123
"accent": {
118
124
"refs": [
119
125
"#rgb"
120
126
],
121
127
"type": "union",
122
128
"closed": false,
123
129
"description": "Color used for links and button backgrounds."
124
130
},
125
131
"background": {
126
132
"refs": [
127
133
"#rgb"
128
134
],
129
135
"type": "union",
130
136
"closed": false,
131
137
"description": "Color used for content background."
132
138
},
133
139
"foreground": {
134
140
"refs": [
135
141
"#rgb"
136
142
],
137
143
"type": "union",
138
144
"closed": false,
139
145
"description": "Color used for content text."
140
146
},
141
147
"accentForeground": {
142
148
"refs": [
143
149
"#rgb"
144
150
],
145
151
"type": "union",
146
152
"closed": false,
147
153
"description": "Color used for button text."
148
154
}
149
155
},
150
156
"description": "Semantic color overrides, mirroring the role vocabulary of site.standard.theme.basic. Any subset may be set."
151
157
},
152
158
"heroSection": {
153
159
"type": "object",
154
160
"properties": {
161
+
"style": {
162
+
"type": "string",
163
+
"description": "Banner treatment when the profile carries a banner: 'band' renders it full-width above the heading, 'postcard' renders it as a framed photograph beside the heading. Default 'band'. Without a banner both fall back to the avatar-led hero.",
164
+
"knownValues": [
165
+
"band",
166
+
"postcard"
167
+
]
168
+
},
155
169
"title": {
156
170
"type": "string",
157
171
"maxLength": 1280,
158
172
"description": "Heading override. When absent, renderers should fall back to profile data.",
159
173
"maxGraphemes": 128
160
174
},
161
175
"tagline": {
162
176
"type": "string",
163
177
"maxLength": 3000,
164
178
"description": "Short line under the heading. When absent, renderers should fall back to the profile description or sifa headline.",
165
179
"maxGraphemes": 300
166
180
},
167
181
"showAvatar": {
168
182
"type": "boolean",
169
183
"description": "Default true when absent."
170
184
}
171
185
},
172
186
"description": "Introductory section rendered from the owner's profile records (app.bsky.actor.profile, with id.sifa.profile.self as professional-context overlay when present)."
173
187
},
174
188
"pagesSection": {
175
189
"type": "object",
176
190
"properties": {
177
191
"pages": {
178
192
"type": "array",
179
193
"items": {
180
194
"type": "string",
181
195
"format": "at-uri"
182
196
},
183
197
"maxLength": 100,
184
198
"description": "Explicit ordered list of page records (AT-URIs) to show. Renderers should skip dangling references. When absent, all public pages are listed in a renderer-defined order."
185
199
},
186
200
"title": {
187
201
"type": "string",
188
202
"maxLength": 1280,
189
203
"maxGraphemes": 128
190
204
}
191
205
},
192
206
"description": "Listing of the site's authored page.mooring.page records."
193
207
},
194
208
"postsSection": {
195
209
"type": "object",
196
210
"properties": {
197
211
"limit": {
198
212
"type": "integer",
199
213
"maximum": 50,
200
214
"minimum": 1,
201
215
"description": "Maximum number of posts to display. Renderer default applies when absent."
202
216
},
203
217
"title": {
204
218
"type": "string",
205
219
"maxLength": 1280,
206
220
"maxGraphemes": 128
207
221
}
208
222
},
209
223
"description": "Recent microblog posts from the owner's app.bsky.feed.post collection."
210
224
},
211
225
"careerSection": {
212
226
"type": "object",
213
227
"properties": {
214
228
"parts": {
215
229
"type": "array",
216
230
"items": {
217
231
"type": "string",
218
232
"knownValues": [
219
233
"positions",
220
234
"education",
221
235
"skills",
222
236
"projects",
223
237
"certifications",
224
238
"publications"
225
239
]
226
240
},
227
241
"maxLength": 10,
228
242
"description": "Which parts of the sifa profile to render, in order. When absent, renderers should show the parts that have data, in a default order."
229
243
},
230
244
"title": {
231
245
"type": "string",
232
246
"maxLength": 1280,
233
247
"maxGraphemes": 128
234
248
}
235
249
},
236
250
"description": "Professional profile rendered from the owner's id.sifa.* records."
237
251
},
238
252
"writingSection": {
239
253
"type": "object",
240
254
"properties": {
241
255
"limit": {
242
256
"type": "integer",
243
257
"maximum": 50,
244
258
"minimum": 1,
245
259
"description": "Maximum number of documents to display. Renderer default applies when absent."
246
260
},
247
261
"title": {
248
262
"type": "string",
249
263
"maxLength": 1280,
250
264
"maxGraphemes": 128
251
265
},
252
266
"publication": {
253
267
"type": "string",
254
268
"format": "at-uri",
255
269
"description": "AT-URI of a site.standard.publication record to scope the listing to. When absent, renderers should list the owner's documents across publications."
256
270
}
257
271
},
258
272
"description": "Long-form writing from the owner's site.standard.document collection (with pub.leaflet.* legacy records as fallback)."
259
273
}
260
274
},
261
275
"$type": "com.atproto.lexicon.schema",
262
276
"lexicon": 1,
263
277
"description": "Configuration for a Mooring site. The record at rkey 'self' is the owner's default site; other rkeys are reserved for possible future multi-site support."
264
278
}