tangled
alpha
login
or
join now
hexmani.ac
/
clippr
12
fork
atom
social bookmarking for atproto
12
fork
atom
overview
issues
1
pulls
pipelines
[backend] Add models to OpenAPI document
hexmani.ac
8 months ago
66c3593b
b7a485ce
verified
This commit was signed with the committer's
known signature
.
hexmani.ac
SSH Key Fingerprint:
SHA256:tV3v2UX4P3x12jjh+mHVzpRQ4ZhNBCHoFwqRiYzzTcM=
+449
-143
2 changed files
expand all
collapse all
unified
split
.idea
dictionaries
project.xml
backend
static
api.json
+1
.idea/dictionaries/project.xml
···
1
1
<component name="ProjectDictionaryState">
2
2
<dictionary name="project">
3
3
<words>
4
4
+
<w>affero</w>
4
5
<w>agpl</w>
5
6
<w>appview</w>
6
7
<w>atcute</w>
+448
-143
backend/static/api.json
···
1
1
{
2
2
-
"openapi": "3.1.1",
3
3
-
"servers": [
4
4
-
{
5
5
-
"url": "http://localhost:9090",
6
6
-
"description": "Development server"
7
7
-
},
8
8
-
{
9
9
-
"url": "https://clippr.social",
10
10
-
"description": "Production server"
11
11
-
}
12
12
-
],
13
13
-
"info": {
14
14
-
"title": "Clippr AppView API",
15
15
-
"version": "0.1.0",
16
16
-
"description": "Official API reference documentation for Clippr's backend."
17
17
-
},
18
18
-
"tags": [
19
19
-
{
20
20
-
"name": "Profile",
21
21
-
"description": "API paths that relate to user profiles."
22
22
-
},
23
23
-
{
24
24
-
"name": "Misc",
25
25
-
"description": "API paths that don't fit into any other category."
26
26
-
}
27
27
-
],
28
28
-
"paths": {
29
29
-
"/xrpc/social.clippr.actor.getProfile": {
30
30
-
"get": {
31
31
-
"summary": "Get a profile",
32
32
-
"description": "Get an user's profile based on their DID or handle.",
33
33
-
"parameters": [
34
34
-
{
35
35
-
"name": "actor",
36
36
-
"in": "query",
37
37
-
"description": "The DID or handle of the account to get the profile record of.",
38
38
-
"required": true,
39
39
-
"content": {
40
40
-
"schema": {
41
41
-
"type": "string"
42
42
-
}
43
43
-
},
44
44
-
"deprecated": false,
45
45
-
"allowEmptyValue": false
46
46
-
}
47
47
-
],
48
48
-
"responses": {
49
49
-
"200": {
50
50
-
"description": "OK",
51
51
-
"content": {
52
52
-
"application/json": {
53
53
-
"schema": {
54
54
-
"type": "object",
55
55
-
"properties": {
56
56
-
"did": {
57
57
-
"type": "string",
58
58
-
"description": "The decentralized identifier associated to the profile.",
59
59
-
"example": "did:plc:z72i7hdynmk6r22z27h6tvur"
60
60
-
},
61
61
-
"handle": {
62
62
-
"type": "string",
63
63
-
"description": "The handle associated to the profile.",
64
64
-
"example": "alice.bsky.social"
65
65
-
},
66
66
-
"displayName": {
67
67
-
"type": "string",
68
68
-
"description": "The display name associated to the profile.",
69
69
-
"example": "Alice"
70
70
-
},
71
71
-
"avatar": {
72
72
-
"type": "string",
73
73
-
"format": "uri",
74
74
-
"description": "A URI linking to an JPEG or PNG file.",
75
75
-
"example": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:b6bhzquz665p6bgjuaqz6xjp/bafkreicoqygyiqhhmjod4hvezo3besjyza24neldcxkz55keos3dg5mmj4@jpeg"
76
76
-
},
77
77
-
"description": {
78
78
-
"type": "string",
79
79
-
"description": "A biography associated to the profile.",
80
80
-
"example": "This is an example bio."
81
81
-
},
82
82
-
"createdAt": {
83
83
-
"type": "string",
84
84
-
"format": "date-time",
85
85
-
"description": "The date and time of the creation of the profile record."
86
86
-
}
87
87
-
}
88
88
-
}
89
89
-
}
90
90
-
}
91
91
-
},
92
92
-
"400": {
93
93
-
"description": "Bad Request",
94
94
-
"content": {
95
95
-
"application/json": {
96
96
-
"schema": {
97
97
-
"type": "object",
98
98
-
"properties": {
99
99
-
"error": {
100
100
-
"type": "string",
101
101
-
"description": "A general error code.",
102
102
-
"example": "InvalidRequest"
103
103
-
},
104
104
-
"message": {
105
105
-
"type": "string",
106
106
-
"description": "A detailed description of the error.",
107
107
-
"example": "Error: Parameters must have the actor property included"
108
108
-
}
109
109
-
}
110
110
-
}
111
111
-
}
112
112
-
}
113
113
-
}
114
114
-
},
115
115
-
"tags": ["Profile"]
116
116
-
}
117
117
-
},
118
118
-
"/xrpc/_health": {
119
119
-
"get": {
120
120
-
"summary": "Health check",
121
121
-
"description": "Check the health of the server. If it is functioning properly, you will receive the server's version number.",
122
122
-
"responses": {
123
123
-
"200": {
124
124
-
"description": "OK",
125
125
-
"content": {
126
126
-
"application/json": {
127
127
-
"schema": {
128
128
-
"type": "object",
129
129
-
"properties": {
130
130
-
"version": {
131
131
-
"type": "string",
132
132
-
"description": "The version number of the AppView.",
133
133
-
"example": "0.1.0"
134
134
-
}
135
135
-
}
136
136
-
}
137
137
-
}
138
138
-
}
139
139
-
}
140
140
-
},
141
141
-
"tags": ["Misc"]
142
142
-
}
143
143
-
}
144
144
-
}
2
2
+
"openapi": "3.1.1",
3
3
+
"info": {
4
4
+
"title": "Clippr AppView API",
5
5
+
"version": "1.0.0",
6
6
+
"description": "Official API reference documentation for Clippr's backend.",
7
7
+
"license": {
8
8
+
"name": "GNU Affero General Public License v3.0 only",
9
9
+
"identifier": "AGPL-3.0-only"
10
10
+
}
11
11
+
},
12
12
+
"servers": [
13
13
+
{
14
14
+
"url": "http://localhost:9090",
15
15
+
"description": "Development server"
16
16
+
},
17
17
+
{
18
18
+
"url": "https://clippr.social",
19
19
+
"description": "Production server"
20
20
+
}
21
21
+
],
22
22
+
"tags": [
23
23
+
{
24
24
+
"name": "Clips",
25
25
+
"description": "API paths that relate to user clips."
26
26
+
},
27
27
+
{
28
28
+
"name": "Tags",
29
29
+
"description": "API paths that relate to user tags."
30
30
+
},
31
31
+
{
32
32
+
"name": "Profile",
33
33
+
"description": "API paths that relate to user profiles."
34
34
+
},
35
35
+
{
36
36
+
"name": "Misc",
37
37
+
"description": "API paths that don't fit into any other category."
38
38
+
}
39
39
+
],
40
40
+
"paths": {
41
41
+
"/xrpc/social.clippr.actor.getProfile": {
42
42
+
"get": {
43
43
+
"summary": "Get a profile",
44
44
+
"description": "Get an user's profile based on their DID or handle.",
45
45
+
"parameters": [
46
46
+
{
47
47
+
"name": "actor",
48
48
+
"in": "query",
49
49
+
"description": "The DID or handle of the account to get the profile record of.",
50
50
+
"required": true,
51
51
+
"content": {
52
52
+
"schema": {
53
53
+
"type": "string"
54
54
+
}
55
55
+
},
56
56
+
"deprecated": false,
57
57
+
"allowEmptyValue": false
58
58
+
}
59
59
+
],
60
60
+
"responses": {
61
61
+
"200": {
62
62
+
"description": "OK",
63
63
+
"content": {
64
64
+
"application/json": {
65
65
+
"schema": {
66
66
+
"type": "object",
67
67
+
"properties": {
68
68
+
"did": {
69
69
+
"type": "string",
70
70
+
"description": "The decentralized identifier associated to the profile.",
71
71
+
"example": "did:plc:z72i7hdynmk6r22z27h6tvur"
72
72
+
},
73
73
+
"handle": {
74
74
+
"type": "string",
75
75
+
"description": "The handle associated to the profile.",
76
76
+
"example": "alice.bsky.social"
77
77
+
},
78
78
+
"displayName": {
79
79
+
"type": "string",
80
80
+
"description": "The display name associated to the profile.",
81
81
+
"example": "Alice"
82
82
+
},
83
83
+
"avatar": {
84
84
+
"type": "string",
85
85
+
"format": "uri",
86
86
+
"description": "A URI linking to an JPEG or PNG file.",
87
87
+
"example": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:b6bhzquz665p6bgjuaqz6xjp/bafkreicoqygyiqhhmjod4hvezo3besjyza24neldcxkz55keos3dg5mmj4@jpeg"
88
88
+
},
89
89
+
"description": {
90
90
+
"type": "string",
91
91
+
"description": "A biography associated to the profile.",
92
92
+
"example": "This is an example bio."
93
93
+
},
94
94
+
"createdAt": {
95
95
+
"type": "string",
96
96
+
"format": "date-time",
97
97
+
"description": "The date and time of the creation of the profile record."
98
98
+
}
99
99
+
}
100
100
+
}
101
101
+
}
102
102
+
}
103
103
+
},
104
104
+
"400": {
105
105
+
"description": "Bad Request",
106
106
+
"content": {
107
107
+
"application/json": {
108
108
+
"schema": {
109
109
+
"type": "object",
110
110
+
"properties": {
111
111
+
"error": {
112
112
+
"type": "string",
113
113
+
"description": "A general error code.",
114
114
+
"example": "InvalidRequest"
115
115
+
},
116
116
+
"message": {
117
117
+
"type": "string",
118
118
+
"description": "A detailed description of the error.",
119
119
+
"example": "Error: Parameters must have the actor property included"
120
120
+
}
121
121
+
}
122
122
+
}
123
123
+
}
124
124
+
}
125
125
+
}
126
126
+
},
127
127
+
"tags": [
128
128
+
"Profile"
129
129
+
]
130
130
+
}
131
131
+
},
132
132
+
"/xrpc/_health": {
133
133
+
"get": {
134
134
+
"summary": "Health check",
135
135
+
"description": "Check the health of the server. If it is functioning properly, you will receive the server's version number.",
136
136
+
"responses": {
137
137
+
"200": {
138
138
+
"description": "OK",
139
139
+
"content": {
140
140
+
"application/json": {
141
141
+
"schema": {
142
142
+
"type": "object",
143
143
+
"properties": {
144
144
+
"version": {
145
145
+
"type": "string",
146
146
+
"description": "The version number of the AppView.",
147
147
+
"example": "0.1.0"
148
148
+
}
149
149
+
}
150
150
+
}
151
151
+
}
152
152
+
}
153
153
+
}
154
154
+
},
155
155
+
"tags": [
156
156
+
"Misc"
157
157
+
]
158
158
+
}
159
159
+
}
160
160
+
},
161
161
+
"components": {
162
162
+
"schemas": {
163
163
+
"com.atproto.repo.strongRef": {
164
164
+
"type": "object",
165
165
+
"required": [
166
166
+
"uri",
167
167
+
"cid"
168
168
+
],
169
169
+
"properties": {
170
170
+
"uri": {
171
171
+
"type": "string",
172
172
+
"format": "at-uri"
173
173
+
},
174
174
+
"cid": {
175
175
+
"type": "string",
176
176
+
"format": "cid"
177
177
+
}
178
178
+
}
179
179
+
},
180
180
+
"social.clippr.actor.defs#profileView": {
181
181
+
"type": "object",
182
182
+
"description": "A view of an actor's profile.",
183
183
+
"required": [
184
184
+
"did",
185
185
+
"handle"
186
186
+
],
187
187
+
"properties": {
188
188
+
"did": {
189
189
+
"type": "string",
190
190
+
"description": "The DID of the profile",
191
191
+
"format": "did"
192
192
+
},
193
193
+
"handle": {
194
194
+
"type": "string",
195
195
+
"description": "The handle of the profile",
196
196
+
"format": "handle"
197
197
+
},
198
198
+
"displayName": {
199
199
+
"type": "string",
200
200
+
"description": "The display name associated to the profile",
201
201
+
"minLength": 1,
202
202
+
"maxLength": 64
203
203
+
},
204
204
+
"description": {
205
205
+
"type": "string",
206
206
+
"description": "The biography associated to the profile",
207
207
+
"maxLength": 500
208
208
+
},
209
209
+
"avatar": {
210
210
+
"type": "string",
211
211
+
"description": "A link to the profile's avatar",
212
212
+
"format": "uri"
213
213
+
},
214
214
+
"createdAt": {
215
215
+
"type": "string",
216
216
+
"description": "When the profile record was first created",
217
217
+
"format": "date-time"
218
218
+
}
219
219
+
}
220
220
+
},
221
221
+
"social.clippr.actor.defs#preferences": {
222
222
+
"type": "array",
223
223
+
"items": {
224
224
+
"oneOf": [
225
225
+
{
226
226
+
"$ref": "#/components/schemas/social.clippr.actor.defs#publishingScopesPref"
227
227
+
}
228
228
+
]
229
229
+
}
230
230
+
},
231
231
+
"social.clippr.actor.defs#publishingScopesPref": {
232
232
+
"type": "object",
233
233
+
"description": "Preferences for an user's publishing scopes",
234
234
+
"required": [
235
235
+
"defaultScope"
236
236
+
],
237
237
+
"properties": {
238
238
+
"defaultScope": {
239
239
+
"type": "string",
240
240
+
"description": "What publishing scope to mark a clip as by default",
241
241
+
"enum": [
242
242
+
"public",
243
243
+
"unlisted"
244
244
+
]
245
245
+
}
246
246
+
}
247
247
+
},
248
248
+
"social.clippr.feed.defs#clipView": {
249
249
+
"type": "object",
250
250
+
"description": "A view of a single bookmark (or 'clip').",
251
251
+
"required": [
252
252
+
"uri",
253
253
+
"cid",
254
254
+
"author",
255
255
+
"record",
256
256
+
"indexedAt"
257
257
+
],
258
258
+
"properties": {
259
259
+
"uri": {
260
260
+
"type": "string",
261
261
+
"description": "The AT-URI of the clip",
262
262
+
"format": "at-uri"
263
263
+
},
264
264
+
"cid": {
265
265
+
"type": "string",
266
266
+
"description": "The CID of the clip",
267
267
+
"format": "cid"
268
268
+
},
269
269
+
"author": {
270
270
+
"description": "A reference to the actor's profile",
271
271
+
"$ref": "#/components/schemas/social.clippr.actor.defs#profileView"
272
272
+
},
273
273
+
"record": {
274
274
+
"type": "object",
275
275
+
"description": "The raw record of the clip"
276
276
+
},
277
277
+
"indexedAt": {
278
278
+
"type": "string",
279
279
+
"description": "The time in which the clip's record was indexed by the AppView",
280
280
+
"format": "date-time"
281
281
+
}
282
282
+
}
283
283
+
},
284
284
+
"social.clippr.feed.defs#tagView": {
285
285
+
"type": "object",
286
286
+
"description": "A view of a single tag.",
287
287
+
"required": [
288
288
+
"uri",
289
289
+
"cid",
290
290
+
"author",
291
291
+
"record",
292
292
+
"indexedAt"
293
293
+
],
294
294
+
"properties": {
295
295
+
"uri": {
296
296
+
"type": "string",
297
297
+
"description": "The AT-URI to the tag",
298
298
+
"format": "at-uri"
299
299
+
},
300
300
+
"cid": {
301
301
+
"type": "string",
302
302
+
"description": "The CID of the tag",
303
303
+
"format": "cid"
304
304
+
},
305
305
+
"author": {
306
306
+
"description": "A reference to the actor's profile",
307
307
+
"$ref": "#/components/schemas/social.clippr.actor.defs#profileView"
308
308
+
},
309
309
+
"record": {
310
310
+
"type": "object",
311
311
+
"description": "The raw record of the clip"
312
312
+
},
313
313
+
"indexedAt": {
314
314
+
"type": "string",
315
315
+
"description": "The time in which the tag's recoord was indexed by the AppView",
316
316
+
"format": "date-time"
317
317
+
}
318
318
+
}
319
319
+
},
320
320
+
"social.clippr.actor.profile": {
321
321
+
"type": "object",
322
322
+
"required": [
323
323
+
"createdAt",
324
324
+
"displayName"
325
325
+
],
326
326
+
"properties": {
327
327
+
"displayName": {
328
328
+
"type": "string",
329
329
+
"description": "A display name to be shown on a profile",
330
330
+
"minLength": 1,
331
331
+
"maxLength": 64
332
332
+
},
333
333
+
"description": {
334
334
+
"type": "string",
335
335
+
"description": "Text for user to describe themselves",
336
336
+
"maxLength": 500
337
337
+
},
338
338
+
"avatar": {
339
339
+
"type": "blob",
340
340
+
"maxSize": 1000000,
341
341
+
"description": "Image to show on user's profiles"
342
342
+
},
343
343
+
"createdAt": {
344
344
+
"type": "string",
345
345
+
"description": "The creation date of the profile",
346
346
+
"format": "date-time"
347
347
+
}
348
348
+
}
349
349
+
},
350
350
+
"social.clippr.feed.clip": {
351
351
+
"type": "object",
352
352
+
"required": [
353
353
+
"url",
354
354
+
"title",
355
355
+
"description",
356
356
+
"unlisted",
357
357
+
"createdAt"
358
358
+
],
359
359
+
"properties": {
360
360
+
"url": {
361
361
+
"type": "string",
362
362
+
"description": "The URL of the bookmark. Cannot be left empty or be modified after creation.",
363
363
+
"format": "uri",
364
364
+
"minLength": 3,
365
365
+
"maxLength": 2000
366
366
+
},
367
367
+
"title": {
368
368
+
"type": "string",
369
369
+
"description": "The title of the bookmark. If left empty, reuse the URL.",
370
370
+
"minLength": 1,
371
371
+
"maxLength": 2048
372
372
+
},
373
373
+
"description": {
374
374
+
"type": "string",
375
375
+
"description": "A description of the bookmark's content. This should be ripped from the URL metadata and be static for all records using the URL.",
376
376
+
"minLength": 1,
377
377
+
"maxLength": 4096
378
378
+
},
379
379
+
"notes": {
380
380
+
"type": "string",
381
381
+
"description": "User-written notes for the bookmark. Public and personal.",
382
382
+
"minLength": 1,
383
383
+
"maxLength": 10000
384
384
+
},
385
385
+
"tags": {
386
386
+
"type": "array",
387
387
+
"description": "An array of tags. A format of solely alphanumeric characters and dashes should be used.",
388
388
+
"items": {
389
389
+
"$ref": "#/components/schemas/com.atproto.repo.strongRef"
390
390
+
}
391
391
+
},
392
392
+
"unlisted": {
393
393
+
"type": "boolean",
394
394
+
"description": "Whether the bookmark can be used for feed indexing and aggregation"
395
395
+
},
396
396
+
"unread": {
397
397
+
"type": "boolean",
398
398
+
"description": "Whether the bookmark has been read by the user",
399
399
+
"default": true
400
400
+
},
401
401
+
"languages": {
402
402
+
"type": "array",
403
403
+
"items": {
404
404
+
"type": "string",
405
405
+
"format": "language"
406
406
+
},
407
407
+
"maxItems": 5
408
408
+
},
409
409
+
"createdAt": {
410
410
+
"type": "string",
411
411
+
"description": "Client-declared timestamp when the bookmark is created",
412
412
+
"format": "date-time"
413
413
+
}
414
414
+
}
415
415
+
},
416
416
+
"social.clippr.feed.tag": {
417
417
+
"type": "object",
418
418
+
"required": [
419
419
+
"name",
420
420
+
"createdAt"
421
421
+
],
422
422
+
"properties": {
423
423
+
"name": {
424
424
+
"type": "string",
425
425
+
"description": "A de-duplicated string containing the name of the tag",
426
426
+
"minLength": 1,
427
427
+
"maxLength": 64
428
428
+
},
429
429
+
"color": {
430
430
+
"type": "string",
431
431
+
"description": "A hexadecimal color code",
432
432
+
"minLength": 4,
433
433
+
"maxLength": 7
434
434
+
},
435
435
+
"description": {
436
436
+
"type": "string",
437
437
+
"description": "A description of the tag for additional context",
438
438
+
"minLength": 1,
439
439
+
"maxLength": 5000
440
440
+
},
441
441
+
"createdAt": {
442
442
+
"type": "string",
443
443
+
"description": "A client-defined timestamp for the creation of the tag",
444
444
+
"format": "date-time"
445
445
+
}
446
446
+
}
447
447
+
}
448
448
+
}
449
449
+
}
145
450
}