com.getorbyt.community.defs
Schema Diff
+16 -1
Compatibility Analysis
Backward Compatible
Backward compatible. 6 non-breaking changes.
Non-Breaking Changes (6)
- AddedVertex AddedVertex { vertex_id: "com.getorbyt.community.defs#feedItem.playbackToken" }
- AddedVertex AddedVertex { vertex_id: "com.getorbyt.community.defs#view.avatarFallback" }
- AddedVertex AddedVertex { vertex_id: "com.getorbyt.community.defs#view.avatarVideo" }
- AddedEdge AddedEdge { src: "com.getorbyt.community.defs#feedItem", tgt: "com.getorbyt.community.defs#feedItem.playbackToken", kind: "prop", name: Some("playbackToken") }
- AddedEdge AddedEdge { src: "com.getorbyt.community.defs#view", tgt: "com.getorbyt.community.defs#view.avatarFallback", kind: "prop", name: Some("avatarFallback") }
- AddedEdge AddedEdge { src: "com.getorbyt.community.defs#view", tgt: "com.getorbyt.community.defs#view.avatarVideo", kind: "prop", name: Some("avatarVideo") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "com.getorbyt.community.defs#feedItem.playbackToken" }AddedVertex { vertex_id: "com.getorbyt.community.defs#view.avatarFallback" }AddedVertex { vertex_id: "com.getorbyt.community.defs#view.avatarVideo" }
Additional Notes
- Non-breaking: AddedEdge { src: "com.getorbyt.community.defs#feedItem", tgt: "com.getorbyt.community.defs#feedItem.playbackToken", kind: "prop", name: Some("playbackToken") }
- Non-breaking: AddedEdge { src: "com.getorbyt.community.defs#view", tgt: "com.getorbyt.community.defs#view.avatarFallback", kind: "prop", name: Some("avatarFallback") }
- Non-breaking: AddedEdge { src: "com.getorbyt.community.defs#view", tgt: "com.getorbyt.community.defs#view.avatarVideo", kind: "prop", name: Some("avatarVideo") }
1
1
{
2
2
"id": "com.getorbyt.community.defs",
3
3
"defs": {
4
4
"rule": {
5
5
"type": "object",
6
6
"required": [
7
7
"text"
8
8
],
9
9
"properties": {
10
10
"text": {
11
11
"type": "string",
12
12
"maxLength": 500
13
13
}
14
14
},
15
15
"description": "One Community rule. An object rather than a bare string so a title, an ordinal or a createdAt can be added later without a schema break."
16
16
},
17
17
"view": {
18
18
"type": "object",
19
19
"required": [
20
20
"uri",
21
21
"cid",
22
22
"name",
23
23
"ownerDid",
24
24
"createdAt"
25
25
],
26
26
"properties": {
27
27
"cid": {
28
28
"type": "string",
29
29
"format": "cid"
30
30
},
31
31
"uri": {
32
32
"type": "string",
33
33
"format": "at-uri"
34
34
},
35
35
"name": {
36
36
"type": "string",
37
37
"maxLength": 63,
38
38
"minLength": 2
39
39
},
40
40
"rules": {
41
41
"type": "array",
42
42
"items": {
43
43
"ref": "#rule",
44
44
"type": "ref"
45
45
},
46
46
"maxLength": 20
47
47
},
48
48
"access": {
49
49
"type": "string",
50
50
"description": "How Community content is accessed. Public is the only enabled value; clients must fail closed for unknown values.",
51
51
"knownValues": [
52
52
"public"
53
53
]
54
54
},
55
55
"avatar": {
56
56
"type": "string",
57
-
"format": "uri"
57
+
"format": "uri",
58
+
"description": "The Community's artwork as an image. Animated where the source was, and the only artwork field a client without a video player should read."
58
59
},
59
60
"labels": {
60
61
"type": "array",
61
62
"items": {
62
63
"ref": "com.atproto.label.defs#label",
63
64
"type": "ref"
64
65
},
65
66
"description": "Labels applied to this Community. Clients moderate against these exactly as they do app.bsky.feed.defs#postView labels."
66
67
},
67
68
"viewer": {
68
69
"ref": "#viewerState",
69
70
"type": "ref"
70
71
},
71
72
"ownerDid": {
72
73
"type": "string",
73
74
"format": "did",
74
75
"description": "The account whose repository holds the Community declaration record. Clients hydrate it to a profile through their authenticated Bluesky AppView."
75
76
},
76
77
"createdAt": {
77
78
"type": "string",
78
79
"format": "datetime"
79
80
},
80
81
"postCount": {
81
82
"type": "integer",
82
83
"minimum": 0
83
84
},
84
85
"updatedAt": {
85
86
"type": "string",
86
87
"format": "datetime"
87
88
},
88
89
"postPolicy": {
89
90
"type": "string",
90
91
"description": "The raw value its owner wrote, not the value this service resolved. Absent means anyone, which is also how a server that predates this field behaves.",
91
92
"knownValues": [
92
93
"anyone",
93
94
"members",
94
95
"moderators"
95
96
]
96
97
},
97
98
"accentColor": {
98
99
"type": "string",
99
100
"maxLength": 32
100
101
},
102
+
"avatarVideo": {
103
+
"type": "string",
104
+
"format": "uri",
105
+
"description": "A looping, silent MP4 rendition of the same artwork, when the owner supplied one. Clients that can play video use it for a full-bleed header and fall back to `avatar`; clients that cannot ignore it. It never replaces `avatar`, which stays the still or animated image every surface that is not a video player renders."
106
+
},
101
107
"description": {
102
108
"type": "string",
103
109
"maxLength": 2000
104
110
},
105
111
"memberCount": {
106
112
"type": "integer",
107
113
"minimum": 0
108
114
},
109
115
"viewerActions": {
110
116
"type": "array",
111
117
"items": {
112
118
"type": "string",
113
119
"knownValues": [
114
120
"edit",
115
121
"unpublish",
116
122
"publish",
117
123
"transfer",
118
124
"delete",
119
125
"view-reports",
120
126
"view-audit-log"
121
127
]
122
128
},
123
129
"maxLength": 32,
124
130
"description": "Actions the authenticated viewer may perform, decided by the service. Clients render only recognized values and infer nothing from role."
125
131
},
132
+
"avatarFallback": {
133
+
"type": "string",
134
+
"format": "uri",
135
+
"description": "A still JPEG or WebP rendition of avatar for constrained or reduced-data connections. Full-capability clients continue to prefer avatar for animated image surfaces."
136
+
},
126
137
"declarationUri": {
127
138
"type": "string",
128
139
"format": "at-uri",
129
140
"description": "The live declaration record. Absent means it is the same as uri."
130
141
},
131
142
"publicationState": {
132
143
"type": "string",
133
144
"description": "Service-owned lifecycle state. Absent means published. Unknown values must be treated as unavailable.",
134
145
"knownValues": [
135
146
"published",
136
147
"unpublished",
137
148
"deleting",
138
149
"deleted"
139
150
]
140
151
}
141
152
},
142
153
"description": "A hydrated Community. Only the fields that identify the Community are required; counts and viewer state are optional so a cheaper view can omit them without a schema break."
143
154
},
144
155
"feedItem": {
145
156
"type": "object",
146
157
"required": [
147
158
"post"
148
159
],
149
160
"properties": {
150
161
"post": {
151
162
"type": "string",
152
163
"format": "at-uri",
153
164
"description": "The linked app.bsky.feed.post URI. Clients hydrate it through their authenticated Bluesky AppView."
154
165
},
155
166
"pinned": {
156
167
"type": "boolean",
157
168
"default": false
158
169
},
159
170
"status": {
160
171
"type": "string",
161
172
"description": "Community-level state; absent means visible. `removed` is a moderator removal scoped to this Community; the underlying app.bsky.feed.post remains live on the network. Only the author and Community moderators receive removed items.",
162
173
"knownValues": [
163
174
"visible",
164
175
"removed"
165
176
]
166
177
},
167
178
"removedAt": {
168
179
"type": "string",
169
180
"format": "datetime"
170
181
},
171
182
"removedBy": {
172
183
"type": "string",
173
184
"format": "did"
174
185
},
186
+
"playbackToken": {
187
+
"type": "string",
188
+
"description": "Server-issued, viewer-bound token proving this item was served to this viewer for this post. Clients pass it back to com.getorbyt.video.recordLoop after a completed playback."
189
+
},
175
190
"removedReason": {
176
191
"type": "string",
177
192
"maxLength": 1000,
178
193
"description": "Present only for the post author and Community moderators."
179
194
},
180
195
"removalActionId": {
181
196
"type": "string",
182
197
"maxLength": 128,
183
198
"description": "Stable identifier for this specific removal. Present to the author and moderators and used to bind one appeal to one removal."
184
199
}
185
200
}
186
201
},
187
202
"appealView": {
188
203
"type": "object",
189
204
"required": [
190
205
"id",
191
206
"community",
192
207
"post",
193
208
"removalActionId",
194
209
"authorDid",
195
210
"text",
196
211
"status",
197
212
"createdAt"
198
213
],
199
214
"properties": {
200
215
"id": {
201
216
"type": "string",
202
217
"maxLength": 128
203
218
},
204
219
"post": {
205
220
"type": "string",
206
221
"format": "at-uri"
207
222
},
208
223
"text": {
209
224
"type": "string",
210
225
"maxLength": 2000
211
226
},
212
227
"status": {
213
228
"type": "string",
214
229
"knownValues": [
215
230
"open",
216
231
"resolved"
217
232
]
218
233
},
219
234
"authorDid": {
220
235
"type": "string",
221
236
"format": "did"
222
237
},
223
238
"community": {
224
239
"type": "string",
225
240
"format": "at-uri"
226
241
},
227
242
"createdAt": {
228
243
"type": "string",
229
244
"format": "datetime"
230
245
},
231
246
"resolution": {
232
247
"type": "string",
233
248
"knownValues": [
234
249
"upheld",
235
250
"restored"
236
251
]
237
252
},
238
253
"resolvedAt": {
239
254
"type": "string",
240
255
"format": "datetime"
241
256
},
242
257
"resolvedByDid": {
243
258
"type": "string",
244
259
"format": "did"
245
260
},
246
261
"resolutionNote": {
247
262
"type": "string",
248
263
"maxLength": 2000
249
264
},
250
265
"removalActionId": {
251
266
"type": "string",
252
267
"maxLength": 128
253
268
}
254
269
}
255
270
},
256
271
"auditEvent": {
257
272
"type": "object",
258
273
"required": [
259
274
"id",
260
275
"community",
261
276
"kind",
262
277
"actorDid",
263
278
"createdAt"
264
279
],
265
280
"properties": {
266
281
"id": {
267
282
"type": "string",
268
283
"maxLength": 128
269
284
},
270
285
"kind": {
271
286
"type": "string",
272
287
"knownValues": [
273
288
"published",
274
289
"unpublished",
275
290
"deletion-begun",
276
291
"deletion-cancelled",
277
292
"deleted",
278
293
"transfer-invited",
279
294
"transfer-accepted",
280
295
"transfer-cancelled",
281
296
"transfer-completed",
282
297
"member-role-changed",
283
298
"member-muted",
284
299
"member-unmuted",
285
300
"member-banned",
286
301
"member-unbanned",
287
302
"post-removed",
288
303
"post-restored",
289
304
"post-pinned",
290
305
"post-unpinned",
291
306
"report-created",
292
307
"report-resolved",
293
308
"appeal-created",
294
309
"appeal-resolved"
295
310
]
296
311
},
297
312
"summary": {
298
313
"type": "string",
299
314
"maxLength": 2000
300
315
},
301
316
"actorDid": {
302
317
"type": "string",
303
318
"format": "did"
304
319
},
305
320
"community": {
306
321
"type": "string",
307
322
"format": "at-uri"
308
323
},
309
324
"createdAt": {
310
325
"type": "string",
311
326
"format": "datetime"
312
327
},
313
328
"subjectDid": {
314
329
"type": "string",
315
330
"format": "did"
316
331
},
317
332
"subjectUri": {
318
333
"type": "string",
319
334
"format": "at-uri"
320
335
}
321
336
}
322
337
},
323
338
"memberView": {
324
339
"type": "object",
325
340
"required": [
326
341
"did"
327
342
],
328
343
"properties": {
329
344
"did": {
330
345
"type": "string",
331
346
"format": "did"
332
347
},
333
348
"role": {
334
349
"type": "string",
335
350
"description": "Absent means member.",
336
351
"knownValues": [
337
352
"owner",
338
353
"moderator",
339
354
"member"
340
355
]
341
356
},
342
357
"status": {
343
358
"type": "string",
344
359
"description": "Absent means active.",
345
360
"knownValues": [
346
361
"active",
347
362
"muted",
348
363
"banned"
349
364
]
350
365
},
351
366
"joinedAt": {
352
367
"type": "string",
353
368
"format": "datetime"
354
369
},
355
370
"membershipUri": {
356
371
"type": "string",
357
372
"format": "at-uri"
358
373
},
359
374
"viewerActions": {
360
375
"type": "array",
361
376
"items": {
362
377
"type": "string",
363
378
"knownValues": [
364
379
"setRole",
365
380
"mute",
366
381
"unmute",
367
382
"ban",
368
383
"unban"
369
384
]
370
385
},
371
386
"maxLength": 16,
372
387
"description": "The manageMember actions this viewer may take on this member, decided by the service. A client renders only the values it recognises and offers nothing else, so a change to who may do what reaches installed clients without a release. Absent means the service predates this field, not that no action is permitted — a client should fall back to its own rules only then."
373
388
}
374
389
}
375
390
},
376
391
"reportView": {
377
392
"type": "object",
378
393
"required": [
379
394
"id",
380
395
"community",
381
396
"post",
382
397
"reporterDid",
383
398
"reason",
384
399
"status",
385
400
"createdAt"
386
401
],
387
402
"properties": {
388
403
"id": {
389
404
"type": "string",
390
405
"maxLength": 128
391
406
},
392
407
"post": {
393
408
"type": "string",
394
409
"format": "at-uri"
395
410
},
396
411
"reason": {
397
412
"type": "string",
398
413
"maxLength": 2000
399
414
},
400
415
"status": {
401
416
"type": "string",
402
417
"knownValues": [
403
418
"open",
404
419
"resolved"
405
420
]
406
421
},
407
422
"community": {
408
423
"type": "string",
409
424
"format": "at-uri"
410
425
},
411
426
"createdAt": {
412
427
"type": "string",
413
428
"format": "datetime"
414
429
},
415
430
"resolution": {
416
431
"type": "string",
417
432
"knownValues": [
418
433
"removed",
419
434
"dismissed"
420
435
]
421
436
},
422
437
"resolvedAt": {
423
438
"type": "string",
424
439
"format": "datetime"
425
440
},
426
441
"reporterDid": {
427
442
"type": "string",
428
443
"format": "did"
429
444
},
430
445
"resolvedByDid": {
431
446
"type": "string",
432
447
"format": "did"
433
448
},
434
449
"resolutionNote": {
435
450
"type": "string",
436
451
"maxLength": 2000
437
452
}
438
453
}
439
454
},
440
455
"viewerState": {
441
456
"type": "object",
442
457
"properties": {
443
458
"role": {
444
459
"type": "string",
445
460
"knownValues": [
446
461
"owner",
447
462
"moderator",
448
463
"member"
449
464
]
450
465
},
451
466
"canPost": {
452
467
"type": "boolean",
453
468
"default": false
454
469
},
455
470
"canManage": {
456
471
"type": "boolean",
457
472
"default": false
458
473
},
459
474
"canModerate": {
460
475
"type": "boolean",
461
476
"default": false
462
477
},
463
478
"membershipUri": {
464
479
"type": "string",
465
480
"format": "at-uri"
466
481
},
467
482
"canAssignRoles": {
468
483
"type": "boolean",
469
484
"default": false,
470
485
"description": "Whether this viewer may promote or demote another member. Separate from canManage, which is authority over the declaration record itself and belongs only to the repository that holds it. A service may grant administration to an account that does not hold the record."
471
486
},
472
487
"membershipStatus": {
473
488
"type": "string",
474
489
"description": "Absent means none.",
475
490
"knownValues": [
476
491
"none",
477
492
"active",
478
493
"muted",
479
494
"banned"
480
495
]
481
496
},
482
497
"canListRestrictedMembers": {
483
498
"type": "boolean",
484
499
"default": false,
485
500
"description": "Whether listMembers will answer this viewer for a status other than active. Stated rather than inferred from canModerate so the rule can change without a client release; a client that predates this field may fall back to canModerate."
486
501
}
487
502
},
488
503
"description": "The requesting account's relationship to a Community. Every field is optional; an absent field means the viewer holds no membership and no privilege."
489
504
},
490
505
"writeStatus": {
491
506
"type": "object",
492
507
"required": [
493
508
"uri",
494
509
"status"
495
510
],
496
511
"properties": {
497
512
"uri": {
498
513
"type": "string",
499
514
"format": "at-uri"
500
515
},
501
516
"error": {
502
517
"type": "string",
503
518
"maxLength": 1000,
504
519
"description": "Why the record was rejected. Present only for `rejected`."
505
520
},
506
521
"status": {
507
522
"type": "string",
508
523
"description": "`pending` means the record has not reached this service yet, which is the normal state for a few seconds after a write. `rejected` means it will never be indexed as written.",
509
524
"knownValues": [
510
525
"indexed",
511
526
"pending",
512
527
"rejected",
513
528
"deleted"
514
529
]
515
530
},
516
531
"indexedAt": {
517
532
"type": "string",
518
533
"format": "datetime"
519
534
}
520
535
},
521
536
"description": "The fate of one record the caller wrote to their own repository."
522
537
},
523
538
"transferView": {
524
539
"type": "object",
525
540
"required": [
526
541
"id",
527
542
"community",
528
543
"fromDid",
529
544
"toDid",
530
545
"status",
531
546
"expiresAt",
532
547
"createdAt"
533
548
],
534
549
"properties": {
535
550
"id": {
536
551
"type": "string",
537
552
"maxLength": 128
538
553
},
539
554
"toDid": {
540
555
"type": "string",
541
556
"format": "did"
542
557
},
543
558
"status": {
544
559
"type": "string",
545
560
"knownValues": [
546
561
"pending",
547
562
"accepted",
548
563
"completed",
549
564
"cancelled",
550
565
"expired"
551
566
]
552
567
},
553
568
"fromDid": {
554
569
"type": "string",
555
570
"format": "did"
556
571
},
557
572
"community": {
558
573
"type": "string",
559
574
"format": "at-uri"
560
575
},
561
576
"createdAt": {
562
577
"type": "string",
563
578
"format": "datetime"
564
579
},
565
580
"expiresAt": {
566
581
"type": "string",
567
582
"format": "datetime"
568
583
},
569
584
"updatedAt": {
570
585
"type": "string",
571
586
"format": "datetime"
572
587
},
573
588
"cancelledByDid": {
574
589
"type": "string",
575
590
"format": "did",
576
591
"description": "Who ended the invitation. Present only once status is cancelled, and the one thing that tells a withdrawal by the inviting account apart from a decline by the invited one."
577
592
},
578
593
"replacementDeclarationUri": {
579
594
"type": "string",
580
595
"format": "at-uri"
581
596
}
582
597
}
583
598
}
584
599
},
585
600
"$type": "com.atproto.lexicon.schema",
586
601
"lexicon": 1
587
602
}